vertigo 0.0.1.a → 0.0.1.b
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/Gemfile.lock +18 -0
- data/{README.md → README.rdoc} +19 -12
- data/Rakefile +8 -1
- data/TODO.rdoc +1 -0
- data/lib/vertigo.rb +2 -3
- data/lib/vertigo/client.rb +93 -0
- data/lib/vertigo/version.rb +1 -1
- data/spec/lib/vertigo/client_spec.rb +117 -0
- data/spec/spec_helper.rb +11 -0
- data/vertigo.gemspec +5 -0
- metadata +79 -9
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -2,15 +2,33 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
vertigo (0.0.1.a)
|
5
|
+
soap4r (~> 1.5.8)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: http://rubygems.org/
|
8
9
|
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
fakeweb (1.3.0)
|
12
|
+
httpclient (2.2.1)
|
9
13
|
rake (0.8.7)
|
14
|
+
rspec (2.6.0)
|
15
|
+
rspec-core (~> 2.6.0)
|
16
|
+
rspec-expectations (~> 2.6.0)
|
17
|
+
rspec-mocks (~> 2.6.0)
|
18
|
+
rspec-core (2.6.4)
|
19
|
+
rspec-expectations (2.6.0)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
rspec-mocks (2.6.0)
|
22
|
+
soap4r (1.5.8)
|
23
|
+
httpclient (>= 2.1.1)
|
24
|
+
yard (0.7.2)
|
10
25
|
|
11
26
|
PLATFORMS
|
12
27
|
ruby
|
13
28
|
|
14
29
|
DEPENDENCIES
|
30
|
+
fakeweb (~> 1.3.0)
|
15
31
|
rake (~> 0.8.7)
|
32
|
+
rspec (~> 2.6.0)
|
16
33
|
vertigo!
|
34
|
+
yard (< 1.0.0)
|
data/{README.md → README.rdoc}
RENAMED
@@ -1,5 +1,4 @@
|
|
1
|
-
Vertigo
|
2
|
-
=======
|
1
|
+
= Vertigo
|
3
2
|
|
4
3
|
A simple Ruby wrapper around the VerticalResponse API ("VRAPI").
|
5
4
|
|
@@ -7,8 +6,9 @@ Vertigo makes working with the VerticalResponse SOAP API much more Ruby-like. I
|
|
7
6
|
|
8
7
|
Author: Benjamin Oakes <hello@benjaminoakes.com>, @benjaminoakes
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
http://travis-ci.org/benjaminoakes/vertigo.png ({More info}[http://travis-ci.org/benjaminoakes/vertigo])
|
10
|
+
|
11
|
+
== Installation
|
12
12
|
|
13
13
|
Simply add Vertigo to your Gemfile:
|
14
14
|
|
@@ -18,25 +18,32 @@ If you are unlucky enough not to be using Bundler:
|
|
18
18
|
|
19
19
|
gem install vertigo
|
20
20
|
|
21
|
-
Usage
|
22
|
-
-----
|
21
|
+
== Usage
|
23
22
|
|
24
23
|
Basic usage example:
|
25
24
|
|
26
25
|
require 'vertigo'
|
27
26
|
|
28
27
|
session_duration_minutes = 4
|
29
|
-
client = Vertigo::Client.new('username', 'password',
|
28
|
+
client = Vertigo::Client.new('username', 'password', :duration_minutes => 5)
|
30
29
|
|
31
30
|
# Launch a campaign whose ID you already know:
|
32
31
|
client.launch_email_campaign(:campaign_id => campaign_id)
|
33
32
|
|
34
|
-
|
35
|
-
|
33
|
+
For more info, please see {Vertigo::Client} or {http://rubydoc.info/gems/vertigo the docs on RubyDoc.info}.
|
34
|
+
|
35
|
+
== Compatibility
|
36
|
+
|
37
|
+
* Written against the 2011.08.10 deploy of the VerticalResponse API "v1.0". More information: http://developers.verticalresponse.com/api/soap/developers-reference/articles/verticalresponse-api-update-for-august-2011/
|
38
|
+
|
39
|
+
== Contributing
|
40
|
+
|
41
|
+
To set up your development environment, please run `bash dev-setup.sh`.
|
42
|
+
|
43
|
+
When writing documentation:
|
36
44
|
|
37
|
-
|
45
|
+
bundle exec yard server --reload
|
38
46
|
|
39
|
-
Thanks
|
40
|
-
------
|
47
|
+
== Thanks
|
41
48
|
|
42
49
|
* Forrest Chang (@fkchang2000) for the name
|
data/Rakefile
CHANGED
data/TODO.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* The "soap4r" gem does not play very well with Ruby 1.9.2. Migrate to a new SOAP interface.
|
data/lib/vertigo.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'soap/wsdlDriver'
|
2
|
+
|
3
|
+
# Simple wrapper around the VerticalResponse SOAP API.
|
4
|
+
#
|
5
|
+
# = API Versioning
|
6
|
+
#
|
7
|
+
# As of 2011.08.15, VerticalResponse changes and remove API calls, but still call it API "v1.0" each time. These mandatory API changes could break your code (although we have never experienced that personally).
|
8
|
+
#
|
9
|
+
# Inquiring about their versioning policy got this response: "For a variety of internal reasons, this is still considered the 1.0 release of our API. We're currently exploring adding real versioning to our API to avoid these kinds of issues going forward."
|
10
|
+
#
|
11
|
+
# Because of this, Vertigo::Client regenerates the RPC driver when instantiated as the generated code for VRAPI.wsdl becomes stale over time. Generating the driver incurs a startup cost, but it's minimal.
|
12
|
+
#
|
13
|
+
# @author Benjamin Oakes <hello@benjaminoakes.com>, @benjaminoakes
|
14
|
+
class Vertigo::Client
|
15
|
+
DURATION_MINUTES = 4
|
16
|
+
WSDL_URL = 'https://api.verticalresponse.com/partner-wsdl/1.0/VRAPI.wsdl'
|
17
|
+
|
18
|
+
# @param [String] username Account username
|
19
|
+
# @param [String] password Account password
|
20
|
+
# @param [Hash] opts Session options
|
21
|
+
# @option opts [Fixnum] :duration_minutes Duration of session in minutes
|
22
|
+
# @option opts [String] :wsdl_url Alternative WSDL URL
|
23
|
+
#
|
24
|
+
# @raise [SOAP::FaultError] when an API call fails
|
25
|
+
#
|
26
|
+
# @example Connect using session defaults
|
27
|
+
# client = Vertigo::Client.new('you@yourcompany.com', 'your password')
|
28
|
+
#
|
29
|
+
# @example Connect using the specified session options
|
30
|
+
# client = Vertigo::Client.new('you@yourcompany.com', 'your password', :duration_minutes => 5)
|
31
|
+
def initialize(username, password, opts = {})
|
32
|
+
session_duration_minutes = opts[:duration_minutes] || DURATION_MINUTES
|
33
|
+
wsdl_url = opts[:wsdl_url] || WSDL_URL
|
34
|
+
|
35
|
+
@api = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
|
36
|
+
@session_id = @api.login(
|
37
|
+
'username' => username.to_s,
|
38
|
+
'password' => password.to_s,
|
39
|
+
'session_duration_minutes' => session_duration_minutes
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
# This modification lets us write API calls in a more "Rubyish" manner.
|
44
|
+
#
|
45
|
+
# @note camelCase method names are still supported.
|
46
|
+
#
|
47
|
+
# @raise [ArgumentError] when too many arguments or unsupported arguments
|
48
|
+
# @raise [NoMethodError] when the API call is not defined
|
49
|
+
#
|
50
|
+
# @example Unlaunching an email campaign
|
51
|
+
# client.unlaunch_email_campaign(:campaign_id => 1)
|
52
|
+
# # Without Vertigo::Client, it would be:
|
53
|
+
# vrapi.unlaunchEmailCampaign('session_id' => session_id, 'campaign_id' => 1)
|
54
|
+
def method_missing(name, *args, &block)
|
55
|
+
options = args[0]
|
56
|
+
vr_name = camelize_meth(name).intern
|
57
|
+
|
58
|
+
if args.length > 1
|
59
|
+
raise ArgumentError, 'Unexpected number of arguments (not 0 or 1)'
|
60
|
+
elsif options && !options.respond_to?(:keys)
|
61
|
+
raise ArgumentError, "options does not respond to :keys (options.class: #{options.class}, options: #{options.inspect})"
|
62
|
+
end
|
63
|
+
|
64
|
+
if @api.respond_to?(vr_name)
|
65
|
+
vr_args = options ? stringify_keys(options) : {}
|
66
|
+
@api.send(vr_name, {'session_id' => @session_id}.merge(vr_args))
|
67
|
+
else
|
68
|
+
raise NoMethodError, "Undefined VerticalResponse API call: #{vr_name.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Camelize a method name
|
75
|
+
#
|
76
|
+
# @param [String, Symbol] name
|
77
|
+
def camelize_meth(name)
|
78
|
+
name.to_s.gsub(/_([a-z])/) { $1.upcase }
|
79
|
+
end
|
80
|
+
|
81
|
+
# Recursively stringify keys of Hashes and members of Arrays
|
82
|
+
#
|
83
|
+
# @param [Hash, Array, Object] original
|
84
|
+
def stringify_keys(original)
|
85
|
+
if original.respond_to?(:keys)
|
86
|
+
Hash[original.map { |key, val| [key.to_s, stringify_keys(val)] }]
|
87
|
+
elsif original.kind_of?(Array)
|
88
|
+
original.map { |val| stringify_keys(val) }
|
89
|
+
else
|
90
|
+
original
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/vertigo/version.rb
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vertigo::Client do
|
4
|
+
before :each do
|
5
|
+
@username = 'you@yourcompany.com'
|
6
|
+
@password = 'secret'
|
7
|
+
@api = mock('API', :login => 'mock session ID')
|
8
|
+
@api.stub!(:unlaunchEmailCampaign)
|
9
|
+
@api.stub!(:enumerateEmailCampaigns)
|
10
|
+
@factory = mock('WSDLDriverFactory', :create_rpc_driver => @api)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should create a RPC driver with the default WSDL' do
|
14
|
+
SOAP::WSDLDriverFactory.should_receive(:new).with(Vertigo::Client::WSDL_URL).and_return(@factory)
|
15
|
+
Vertigo::Client.new(@username, @password)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should create a RPC driver with the specified WSDL' do
|
19
|
+
url = 'https://api.verticalresponse.com/partner-wsdl/1.1/VRAPI.wsdl'
|
20
|
+
SOAP::WSDLDriverFactory.should_receive(:new).with(url).and_return(@factory)
|
21
|
+
Vertigo::Client.new(@username, @password, :wsdl_url => url)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with default WSDL' do
|
25
|
+
before :each do
|
26
|
+
SOAP::WSDLDriverFactory.stub!(:new).and_return(@factory)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should log in with the given credentials' do
|
30
|
+
@api.should_receive(:login, {
|
31
|
+
'username' => @username,
|
32
|
+
'password' => @username,
|
33
|
+
'session_duration_minutes' => Vertigo::Client::DURATION_MINUTES
|
34
|
+
})
|
35
|
+
|
36
|
+
Vertigo::Client.new(@username, @password)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should log in with the given credentials and session duration' do
|
40
|
+
@api.should_receive(:login, {
|
41
|
+
'username' => @username,
|
42
|
+
'password' => @username,
|
43
|
+
'session_duration_minutes' => 5
|
44
|
+
})
|
45
|
+
|
46
|
+
Vertigo::Client.new(@username, @password, :duration_minutes => 5)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with client' do
|
51
|
+
before :each do
|
52
|
+
SOAP::WSDLDriverFactory.stub!(:new).and_return(@factory)
|
53
|
+
|
54
|
+
@client = Vertigo::Client.new(@username, @password)
|
55
|
+
# White box test
|
56
|
+
@session_id = @client.instance_eval { @session_id }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should allow Rubyish method calls' do
|
60
|
+
@api.should_receive(:unlaunchEmailCampaign).with('session_id' => @session_id, 'campaign_id' => 1)
|
61
|
+
@client.unlaunch_email_campaign(:campaign_id => 1)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should allow Rubyish method calls with no arguments' do
|
65
|
+
@api.should_receive(:enumerateEmailCampaigns).with('session_id' => @session_id)
|
66
|
+
@client.enumerate_email_campaigns
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should still allow camelcase method calls' do
|
70
|
+
@api.should_receive(:unlaunchEmailCampaign).with('session_id' => @session_id, 'campaign_id' => 1)
|
71
|
+
@client.unlaunchEmailCampaign(:campaign_id => 1)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should raise an error if given two arguments' do
|
75
|
+
lambda { @client.unlaunch_email_campaign(2, :campaign_id => 1) }.should raise_error(ArgumentError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should raise an error if called with an undefined VerticalResponse API call' do
|
79
|
+
lambda { @client.some_random_method(:campaign_id => 1) }.should raise_error(NoMethodError)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should raise an error if given an unsupported argument' do
|
83
|
+
lambda { @client.unlaunch_email_campaign(2) }.should raise_error(ArgumentError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should' do
|
87
|
+
@api.should_receive(:createEmailCampaign).with(
|
88
|
+
'session_id' => @session_id,
|
89
|
+
'email_campaign' => {
|
90
|
+
'name' => 'Campaign Name',
|
91
|
+
'type' => 'freeform',
|
92
|
+
'from_label' => 'from@example.com',
|
93
|
+
'support_email' => 'support@example.com',
|
94
|
+
'send_friend' => false,
|
95
|
+
'contents' => [
|
96
|
+
{ 'type' => 'freeform_html', 'copy' => 'body' },
|
97
|
+
{ 'type' => 'freeform_text', 'copy' => 'body' },
|
98
|
+
{ 'type' => 'subject', 'copy' => 'subject' },
|
99
|
+
]
|
100
|
+
}
|
101
|
+
)
|
102
|
+
|
103
|
+
@client.create_email_campaign(:email_campaign => {
|
104
|
+
:name => 'Campaign Name',
|
105
|
+
:type => 'freeform',
|
106
|
+
:from_label => 'from@example.com',
|
107
|
+
:support_email => 'support@example.com',
|
108
|
+
:send_friend => false,
|
109
|
+
:contents => [
|
110
|
+
{ :type => 'freeform_html', :copy => 'body' },
|
111
|
+
{ :type => 'freeform_text', :copy => 'body' },
|
112
|
+
{ :type => 'subject', :copy => 'subject' },
|
113
|
+
]
|
114
|
+
})
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/vertigo.gemspec
CHANGED
@@ -13,7 +13,12 @@ Gem::Specification.new do |s|
|
|
13
13
|
|
14
14
|
s.rubyforge_project = "vertigo"
|
15
15
|
|
16
|
+
s.add_dependency('soap4r', '~> 1.5.8')
|
17
|
+
|
18
|
+
s.add_development_dependency('fakeweb', '~> 1.3.0')
|
16
19
|
s.add_development_dependency('rake', '~> 0.8.7')
|
20
|
+
s.add_development_dependency('rspec', '~> 2.6.0')
|
21
|
+
s.add_development_dependency('yard', '< 1.0.0')
|
17
22
|
|
18
23
|
s.files = `git ls-files`.split("\n")
|
19
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vertigo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 47
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- 1
|
10
|
-
-
|
11
|
-
version: 0.0.1.
|
10
|
+
- b
|
11
|
+
version: 0.0.1.b
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Benjamin Oakes
|
@@ -16,13 +16,45 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-08-
|
19
|
+
date: 2011-08-16 00:00:00 -04:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
|
-
name:
|
23
|
+
name: soap4r
|
24
24
|
prerelease: false
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 19
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 5
|
34
|
+
- 8
|
35
|
+
version: 1.5.8
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: fakeweb
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 27
|
47
|
+
segments:
|
48
|
+
- 1
|
49
|
+
- 3
|
50
|
+
- 0
|
51
|
+
version: 1.3.0
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
26
58
|
none: false
|
27
59
|
requirements:
|
28
60
|
- - ~>
|
@@ -34,7 +66,39 @@ dependencies:
|
|
34
66
|
- 7
|
35
67
|
version: 0.8.7
|
36
68
|
type: :development
|
37
|
-
version_requirements: *
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 23
|
79
|
+
segments:
|
80
|
+
- 2
|
81
|
+
- 6
|
82
|
+
- 0
|
83
|
+
version: 2.6.0
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id004
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: yard
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - <
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 23
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 0
|
98
|
+
- 0
|
99
|
+
version: 1.0.0
|
100
|
+
type: :development
|
101
|
+
version_requirements: *id005
|
38
102
|
description: Vertigo makes working with VerticalResponse's SOAP API much more Ruby-like. It manages your session_id, as well as letting you write methods as launch_email_campaign rather than launchEmailCampaign, and use symbols as keys rather than strings.
|
39
103
|
email:
|
40
104
|
- boakes@hedgeye.com
|
@@ -47,13 +111,18 @@ extra_rdoc_files: []
|
|
47
111
|
files:
|
48
112
|
- .gitignore
|
49
113
|
- .rvmrc
|
114
|
+
- .travis.yml
|
50
115
|
- Gemfile
|
51
116
|
- Gemfile.lock
|
52
|
-
- README.
|
117
|
+
- README.rdoc
|
53
118
|
- Rakefile
|
119
|
+
- TODO.rdoc
|
54
120
|
- dev-setup.sh
|
55
121
|
- lib/vertigo.rb
|
122
|
+
- lib/vertigo/client.rb
|
56
123
|
- lib/vertigo/version.rb
|
124
|
+
- spec/lib/vertigo/client_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
57
126
|
- vertigo.gemspec
|
58
127
|
has_rdoc: true
|
59
128
|
homepage: ""
|
@@ -91,5 +160,6 @@ rubygems_version: 1.6.2
|
|
91
160
|
signing_key:
|
92
161
|
specification_version: 3
|
93
162
|
summary: A simple Ruby wrapper around the VerticalResponse API ("VRAPI").
|
94
|
-
test_files:
|
95
|
-
|
163
|
+
test_files:
|
164
|
+
- spec/lib/vertigo/client_spec.rb
|
165
|
+
- spec/spec_helper.rb
|