marketo-api-ruby 0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ module Rapleaf
4
+ module Marketo
5
+ describe LeadKeyType do
6
+ it "should define the correct types" do
7
+ LeadKeyType::IDNUM.should == 'IDNUM'
8
+ LeadKeyType::COOKIE.should == 'COOKIE'
9
+ LeadKeyType::EMAIL.should == 'EMAIL'
10
+ LeadKeyType::LEADOWNEREMAIL.should == 'LEADOWNEREMAIL'
11
+ LeadKeyType::SFDCACCOUNTID.should == 'SFDCACCOUNTID'
12
+ LeadKeyType::SFDCCONTACTID.should == 'SFDCCONTACTID'
13
+ LeadKeyType::SFDCLEADID.should == 'SFDCLEADID'
14
+ LeadKeyType::SFDCLEADOWNERID.should == 'SFDCLEADOWNERID'
15
+ LeadKeyType::SFDCOPPTYID.should == 'SFDCOPPTYID'
16
+ end
17
+ end
18
+
19
+ describe LeadKey do
20
+ it "should store type and value on construction" do
21
+ KEY_VALUE = 'a value'
22
+ KEY_TYPE = LeadKeyType::IDNUM
23
+ lead_key = LeadKey.new(KEY_TYPE, KEY_VALUE)
24
+ lead_key.key_type.should == KEY_TYPE
25
+ lead_key.key_value.should == KEY_VALUE
26
+ end
27
+
28
+ it "should to_hash correctly" do
29
+ KEY_VALUE = 'a value'
30
+ KEY_TYPE = LeadKeyType::IDNUM
31
+ lead_key = LeadKey.new(KEY_TYPE, KEY_VALUE)
32
+
33
+ lead_key.to_hash.should == {
34
+ :key_type => KEY_TYPE,
35
+ :key_value => KEY_VALUE
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,86 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ module Rapleaf
4
+ module Marketo
5
+ EMAIL = 'some@email.com'
6
+ IDNUM = 93480938
7
+
8
+ describe LeadRecord do
9
+ it "should store the idnum" do
10
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
11
+ lead_record.idnum.should == IDNUM
12
+ end
13
+
14
+ it "should store the email" do
15
+ LeadRecord.new(EMAIL, IDNUM).email.should == EMAIL
16
+ end
17
+
18
+ it "should implement == sensibly" do
19
+ lead_record1 = LeadRecord.new(EMAIL, IDNUM)
20
+ lead_record1.set_attribute('favourite color', 'red')
21
+ lead_record1.set_attribute('age', '100')
22
+
23
+ lead_record2 = LeadRecord.new(EMAIL, IDNUM)
24
+ lead_record2.set_attribute('favourite color', 'red')
25
+ lead_record2.set_attribute('age', '100')
26
+
27
+ lead_record1.should == lead_record2
28
+ end
29
+
30
+ it "should store when attributes are set" do
31
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
32
+ lead_record.set_attribute('favourite color', 'red')
33
+ lead_record.get_attribute('favourite color').should == 'red'
34
+ end
35
+
36
+ it "should store when attributes are updated" do
37
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
38
+ lead_record.set_attribute('favourite color', 'red')
39
+ lead_record.set_attribute('favourite color', 'green')
40
+ lead_record.get_attribute('favourite color').should == 'green'
41
+ end
42
+
43
+ it "should yield all attributes through each_attribute_pair" do
44
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
45
+ lead_record.set_attribute('favourite color', 'red')
46
+ lead_record.set_attribute('favourite color', 'green')
47
+ lead_record.set_attribute('age', '99')
48
+
49
+ pairs = []
50
+ lead_record.each_attribute_pair do |attribute_name, attribute_value|
51
+ pairs << [attribute_name, attribute_value]
52
+ end
53
+
54
+ pairs.size.should == 3
55
+ pairs.should include(['favourite color', 'green'])
56
+ pairs.should include(['age', '99'])
57
+ pairs.should include(['Email', EMAIL])
58
+ end
59
+
60
+ it "should be instantiable from a savon hash" do
61
+ savon_hash = {
62
+ :email => EMAIL,
63
+ :foreign_sys_type => nil,
64
+ :lead_attribute_list => {
65
+ :attribute => [
66
+ { :attr_name => 'Company', :attr_type => 'string', :attr_value => 'Rapleaf'},
67
+ { :attr_name => 'FirstName', :attr_type => 'string', :attr_value => 'James'},
68
+ { :attr_name => 'LastName', :attr_type => 'string', :attr_value => 'O\'Brien'}
69
+ ]
70
+ },
71
+ :foreign_sys_person_id => nil,
72
+ :id => IDNUM
73
+ }
74
+
75
+ actual = LeadRecord.from_hash(savon_hash)
76
+
77
+ expected = LeadRecord.new(EMAIL, IDNUM)
78
+ expected.set_attribute('Company', 'Rapleaf')
79
+ expected.set_attribute('FirstName', 'James')
80
+ expected.set_attribute('LastName', 'O\'Brien')
81
+
82
+ actual.should == expected
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,4 @@
1
+ require "rubygems"
2
+ require "rspec"
3
+
4
+ require File.expand_path('../lib/marketo', File.dirname(__FILE__))
@@ -0,0 +1,173 @@
1
+ require "minitest_helper"
2
+
3
+ class TestMarketoAPICampaigns < Minitest::Test
4
+ include MarketoTestHelper
5
+
6
+ def setup
7
+ super
8
+ @subject = @client.campaigns
9
+ end
10
+
11
+ def test_for_marketo
12
+ assert subject.respond_to? :for_marketo
13
+ stub_specialized :for_source do
14
+ assert_equal :MKTOWS, subject.for_marketo.first
15
+ end
16
+ stub_soap_call do
17
+ method, options = subject.for_marketo
18
+ assert_equal :get_campaigns_for_source, method
19
+ assert_equal({ source: :MKTOWS }, options)
20
+ end
21
+ end
22
+
23
+ def test_for_sales
24
+ assert subject.respond_to? :for_sales
25
+ stub_specialized :for_source do
26
+ assert_equal :SALES, subject.for_sales.first
27
+ end
28
+ stub_soap_call do
29
+ method, options = subject.for_sales
30
+ assert_equal :get_campaigns_for_source, method
31
+ assert_equal({ source: :SALES }, options)
32
+ end
33
+ end
34
+
35
+ def test_for_source_bad_source
36
+ assert_raises(ArgumentError) { subject.for_source :bad_source }
37
+ end
38
+
39
+ def test_for_source_marketo_name
40
+ stub_soap_call do
41
+ method, options = subject.for_source :marketo, 'John'
42
+ assert_equal :get_campaigns_for_source, method
43
+ assert_equal({ source: :MKTOWS, name: 'John' }, options)
44
+ end
45
+ end
46
+
47
+ def test_for_source_sales_name_exact
48
+ stub_soap_call do
49
+ method, options = subject.for_source :marketo, 'John', true
50
+ assert_equal :get_campaigns_for_source, method
51
+ assert_equal({ source: :MKTOWS, name: 'John', exact_name: true },
52
+ options)
53
+ end
54
+ end
55
+
56
+ def test_request_marketo
57
+ assert subject.respond_to? :request_marketo
58
+ stub_specialized :request do
59
+ options = subject.request_marketo.first
60
+ assert_equal({ source: :MKTOWS }, options)
61
+ end
62
+ end
63
+
64
+ def test_request_sales
65
+ assert subject.respond_to? :request_sales
66
+ stub_specialized :request do
67
+ options = subject.request_sales.first
68
+ assert_equal({ source: :SALES }, options)
69
+ end
70
+ end
71
+
72
+ def test_request_missing_leads
73
+ assert_raises(ArgumentError) {
74
+ subject.request
75
+ }
76
+ end
77
+
78
+ def test_request_missing_campaign_or_program
79
+ assert_raises(ArgumentError) {
80
+ subject.request(lead: :foo)
81
+ }
82
+ end
83
+
84
+ def test_request_program_token_with_no_program_name
85
+ assert_raises(KeyError) {
86
+ subject.request(lead: :foo, campaign_id: 5, program_tokens: [ 3 ])
87
+ }
88
+ end
89
+
90
+ def test_request_with_campaign_id_and_name
91
+ assert_raises(ArgumentError) {
92
+ subject.request(lead: :foo, campaign_id: 5, campaign_name: 'Five')
93
+ }
94
+ end
95
+
96
+ def test_request_bad_source
97
+ assert_raises(ArgumentError) {
98
+ subject.request(lead: :foo, campaign_id: 5, source: :bad_source)
99
+ }
100
+ end
101
+
102
+ def test_request_merged_leads_campaign_id_default_source
103
+ stub_soap_call do
104
+ method, options = subject.request(lead: lead_key(3),
105
+ leads: lead_keys(4, 5),
106
+ campaign_id: 3)
107
+ assert_equal :request_campaign, method
108
+ assert_equal :MKTOWS, options[:source]
109
+ assert_equal lead_keys(4, 5, 3), options[:lead_list]
110
+ assert_equal 3, options[:campaign_id]
111
+ assert_missing_keys options, :campaign_name, :program_name,
112
+ :program_tokens
113
+ end
114
+ end
115
+
116
+ def test_request_using_campaign_name
117
+ stub_soap_call do
118
+ method, options = subject.request(lead: lead_key(3),
119
+ campaign_name: 'earthday')
120
+ assert_equal :request_campaign, method
121
+ assert_equal :MKTOWS, options[:source]
122
+ assert_equal [ lead_key(3) ], options[:lead_list]
123
+ assert_equal 'earthday', options[:campaign_name]
124
+ assert_missing_keys options, :campaign_id, :program_name,
125
+ :program_tokens
126
+ end
127
+ end
128
+
129
+ def test_request_using_program_name
130
+ stub_soap_call do
131
+ method, options = subject.request(lead: lead_key(3),
132
+ program_name: 'earthday')
133
+ assert_equal :request_campaign, method
134
+ assert_equal :MKTOWS, options[:source]
135
+ assert_equal [ lead_key(3) ], options[:lead_list]
136
+ assert_equal 'earthday', options[:program_name]
137
+ assert_missing_keys options, :campaign_name, :campaign_id,
138
+ :program_tokens
139
+ end
140
+ end
141
+
142
+ def test_schedule
143
+ stub_soap_call do
144
+ method, options = subject.schedule('program', 'campaign')
145
+ assert_equal :schedule_campaign, method
146
+ assert_equal({ program_name: 'program', campaign_name: 'campaign' }, options)
147
+ end
148
+ end
149
+
150
+ def test_schedule_with_run_at
151
+ stub_soap_call do
152
+ method, options = subject.schedule('program', 'campaign', run_at: 3)
153
+ assert_equal :schedule_campaign, method
154
+ assert_equal({
155
+ program_name: 'program',
156
+ campaign_name: 'campaign',
157
+ campaign_run_at: 3
158
+ }, options)
159
+ end
160
+ end
161
+
162
+ def test_schedule_with_program_tokens
163
+ stub_soap_call do
164
+ method, options = subject.schedule('program', 'campaign', program_tokens: [ :x ])
165
+ assert_equal :schedule_campaign, method
166
+ assert_equal({
167
+ program_name: 'program',
168
+ campaign_name: 'campaign',
169
+ program_token_list: [ :x ]
170
+ }, options)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,83 @@
1
+ require "minitest_helper"
2
+
3
+ class TestMarketoAPIClient < Minitest::Test
4
+ include MarketoTestHelper
5
+
6
+ def setup
7
+ super
8
+ @subject = @client
9
+ end
10
+
11
+ def test_api_version
12
+ assert_equal '2_3', subject.api_version
13
+ assert_equal '2_4', setup_client(api_version: '2_4').api_version
14
+ end
15
+
16
+ def test_subdomain
17
+ assert_equal '123-ABC-456', subject.subdomain
18
+ assert_equal 'testable', setup_client(api_subdomain: 'testable').subdomain
19
+ end
20
+
21
+ def test_wsdl
22
+ assert_equal "http://app.marketo.com/soap/mktows/2_3?WSDL",
23
+ subject.wsdl
24
+ assert_equal "http://app.marketo.com/soap/mktows/2_4?WSDL",
25
+ setup_client(api_version: '2_4').wsdl
26
+ end
27
+
28
+ def test_endpoint
29
+ assert_equal "https://123-ABC-456.mktoapi.com/soap/mktows/2_3",
30
+ subject.endpoint
31
+ assert_equal "https://testable.mktoapi.com/soap/mktows/2_4",
32
+ setup_client(api_subdomain: 'testable', api_version: '2_4').endpoint
33
+ end
34
+
35
+ def test_generated_methods
36
+ assert subject.respond_to? :campaigns
37
+ assert subject.respond_to? :leads
38
+ assert subject.respond_to? :lists
39
+ assert subject.respond_to? :mobjects
40
+ refute subject.respond_to? :customobjects
41
+ end
42
+
43
+ def stub_savon callable = nil, &block
44
+ callable ||= ARGS_STUB
45
+ subject.instance_variable_get(:@savon).stub :call, callable do
46
+ block.call if block
47
+ end
48
+ end
49
+
50
+ def test_call_exception_suppressed
51
+ stub_savon -> { raise ArgumentError } do
52
+ assert_nil subject.call(:web_method, {})
53
+ assert subject.error?
54
+ refute_nil subject.error
55
+ assert_instance_of ArgumentError, subject.error
56
+ end
57
+ end
58
+
59
+ def test_call_with_auth
60
+ time = Time.now.to_i
61
+
62
+ signature = {
63
+ mktowsUserId: 'user',
64
+ requestTimestamp: time.to_s,
65
+ requestSignature: OpenSSL::HMAC.hexdigest(
66
+ OpenSSL::Digest.new('sha1'),
67
+ 'key',
68
+ "#{time}user"
69
+ )
70
+ }
71
+
72
+ Time.stub :now, -> { time } do
73
+ stub_savon do
74
+ method, params = subject.call(:web_method, {})
75
+ assert_equal :web_method, method
76
+ assert_equal({
77
+ message: {},
78
+ soap_header: { 'ns1:AuthenticationHeader' => signature }
79
+ }, params)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,158 @@
1
+ require "minitest_helper"
2
+
3
+ class TestMarketoAPILead < Minitest::Test
4
+ include MarketoTestHelper
5
+
6
+ def setup
7
+ super
8
+ @id = 99
9
+ @date = DateTime.new(2014, 01, 01)
10
+ @email = 'great@gretzky.com'
11
+ @attributes = {
12
+ String: 'string',
13
+ Int: 5,
14
+ Date: @date
15
+ }
16
+ @subject = MarketoAPI::Lead.new(id: @id, email: @email) do |lead|
17
+ @attributes.each { |k, v| lead[k] = v }
18
+ end
19
+ end
20
+
21
+ def test_id
22
+ assert_equal 99, subject.id
23
+ end
24
+
25
+ def test_cookie
26
+ assert_nil subject.cookie
27
+ subject.cookie = 'cookie'
28
+ refute_nil subject.cookie
29
+ assert_equal 'cookie', subject.cookie
30
+ end
31
+
32
+ def test_attributes
33
+ assert_equal @attributes.merge(Email: @email), subject.attributes
34
+ end
35
+
36
+ def test_types
37
+ types = Hash[*@attributes.merge(Email: @email).map { |(k, v)|
38
+ [ k, subject.send(:infer_value_type, v) ]
39
+ }.flatten]
40
+ assert_equal types, subject.types
41
+ end
42
+
43
+ def test_proxy_bad_assignment
44
+ assert_raises(ArgumentError) { subject.proxy = :invalid }
45
+ end
46
+
47
+ def test_proxy_leads_assignment
48
+ assert_same @client.leads, subject.proxy = @client.leads
49
+ end
50
+
51
+ def test_proxy_proxy_assignment
52
+ subject.proxy = @client.campaigns
53
+ assert_same @client.leads, subject.proxy
54
+ end
55
+
56
+ def test_proxy_client_assignment
57
+ subject.proxy = @client
58
+ assert_same @client.leads, subject.proxy
59
+ end
60
+
61
+ def test_forwarded_methods
62
+ [
63
+ :[], :each, :each_pair, :each_key, :each_value, :keys, :values
64
+ ].each do |m|
65
+ assert subject.respond_to? m
66
+ end
67
+ end
68
+
69
+ def test_index_assignment
70
+ subject[:Test] = 33
71
+ assert subject.attributes.has_key? :Test
72
+ assert subject.types.has_key? :Test
73
+ assert_equal 33, subject.attributes[:Test]
74
+ assert_equal 'integer', subject.types[:Test]
75
+ end
76
+
77
+ def test_foreign
78
+ assert_equal({ type: :id, id: 3 }, subject.foreign('id', 3))
79
+ end
80
+
81
+ def test_sync_no_proxy
82
+ assert_raises(ArgumentError) { subject.sync }
83
+ assert_raises(ArgumentError) { subject.sync! }
84
+ end
85
+
86
+ def test_sync_with_proxy
87
+ @client.leads.stub :sync, ->(lead) { lead.dup } do
88
+ subject.proxy = @client.leads
89
+ assert_equal subject, subject.sync
90
+ refute_same subject, subject.sync
91
+ end
92
+ end
93
+
94
+ def test_sync_bang_failed
95
+ @client.leads.stub :sync, ->(lead) { nil } do
96
+ subject.proxy = @client.leads
97
+ assert_nil subject.sync!
98
+ end
99
+ end
100
+
101
+ def test_sync_bang_success
102
+ @client.leads.stub :sync, ->(lead) { lead.dup } do
103
+ subject.proxy = @client.leads
104
+ assert_same subject, subject.sync!
105
+ end
106
+ end
107
+
108
+ def test_params_for_get
109
+ assert_equal MarketoAPI::Lead.key(:IDNUM, @id), subject.params_for_get
110
+ end
111
+
112
+ def test_params_for_sync
113
+ result = {
114
+ return_lead: true,
115
+ lead_record: {
116
+ email: @email,
117
+ id: @id,
118
+ lead_attribute_list: {
119
+ attribute: [
120
+ { attr_name: 'Email', attr_type: 'string', attr_value: @email },
121
+ { attr_name: 'String', attr_type: 'string', attr_value: 'string' },
122
+ { attr_name: 'Int', attr_type: 'integer', attr_value: 5 },
123
+ { attr_name: 'Date', attr_type: 'datetime', attr_value: @date }
124
+ ]
125
+ }
126
+ }
127
+ }
128
+
129
+ assert_equal result, subject.params_for_sync
130
+ end
131
+
132
+ def test_class_key
133
+ subject.class::NAMED_KEYS.each { |k, v|
134
+ result = { lead_key: { key_type: v, key_value: 'value' } }
135
+
136
+ assert_equal result, subject.class.key(k, 'value')
137
+ assert_equal result, subject.class.key(v, 'value')
138
+ }
139
+
140
+ assert_raises(ArgumentError) { subject.class.key('invalid', 'value') }
141
+ end
142
+
143
+ def test_class_from_soap_hash
144
+ hash = {
145
+ id: @id.to_s,
146
+ email: @email,
147
+ lead_attribute_list: {
148
+ attribute: [
149
+ { attr_name: 'Email', attr_type: 'string', attr_value: @email },
150
+ { attr_name: 'String', attr_type: 'string', attr_value: 'string' },
151
+ { attr_name: 'Int', attr_type: 'integer', attr_value: 5 },
152
+ { attr_name: 'Date', attr_type: 'datetime', attr_value: @date }
153
+ ]
154
+ }
155
+ }
156
+ assert_equal subject, subject.class.from_soap_hash(hash)
157
+ end
158
+ end