marketo 1.1.0

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.
data/lib/marketo.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'savon'
3
+
4
+ Savon.configure do |config|
5
+ config.log = false # disable logging
6
+ end
7
+
8
+ require File.expand_path('marketo/client', File.dirname(__FILE__))
9
+ require File.expand_path('marketo/authentication_header', File.dirname(__FILE__))
10
+ require File.expand_path('marketo/enums', File.dirname(__FILE__))
11
+ require File.expand_path('marketo/lead_key', File.dirname(__FILE__))
12
+ require File.expand_path('marketo/lead_record', File.dirname(__FILE__))
13
+
14
+
15
+
16
+
@@ -0,0 +1,48 @@
1
+ module Rapleaf
2
+ module Marketo
3
+ # This class exists only to encapsulate the authentication header part of a soap request to marketo
4
+ # Marketo requires a somewhat complex calculation of an encrypted signature and so it seemed sensible to pull this code out here
5
+ class AuthenticationHeader
6
+ DIGEST = OpenSSL::Digest::Digest.new('sha1')
7
+
8
+ def initialize(access_key, secret_key, time = DateTime.now)
9
+ @access_key = access_key
10
+ @secret_key = secret_key
11
+ @time = time
12
+ end
13
+
14
+ public
15
+ # time should be a DateTime instance
16
+ def set_time(time)
17
+ @time = time
18
+ end
19
+
20
+ def get_mktows_user_id
21
+ @access_key
22
+ end
23
+
24
+ def get_request_signature
25
+ calculate_signature
26
+ end
27
+
28
+ def get_request_timestamp
29
+ @time.to_s
30
+ end
31
+
32
+ def to_hash
33
+ {
34
+ "mktowsUserId" => get_mktows_user_id,
35
+ "requestSignature" => get_request_signature,
36
+ "requestTimestamp" => get_request_timestamp
37
+ }
38
+ end
39
+
40
+ private
41
+ def calculate_signature
42
+ request_timestamp = get_request_timestamp
43
+ string_to_encrypt = request_timestamp + @access_key
44
+ OpenSSL::HMAC.hexdigest(DIGEST, @secret_key, string_to_encrypt)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,126 @@
1
+ require File.expand_path('authentication_header', File.dirname(__FILE__))
2
+
3
+ module Rapleaf
4
+ module Marketo
5
+ def self.new_client(access_key, secret_key)
6
+ client = Savon::Client.new do
7
+ wsdl.endpoint = "https://na-i.marketo.com/soap/mktows/1_5"
8
+ wsdl.document = "http://app.marketo.com/soap/mktows/1_4?WSDL"
9
+ http.read_timeout = 90
10
+ http.open_timeout = 90
11
+ http.headers = {"Connection" => "Keep-Alive"}
12
+ end
13
+
14
+ Client.new(client, Rapleaf::Marketo::AuthenticationHeader.new(access_key, secret_key))
15
+ end
16
+
17
+ # = The client for talking to marketo
18
+ # based on the SOAP wsdl file: <i>http://app.marketo.com/soap/mktows/1_4?WSDL</i>
19
+ #
20
+ # Usage:
21
+ #
22
+ # client = Rapleaf::Marketo.new_client(<access_key>, <secret_key>)
23
+ #
24
+ # client.sync_lead('john@gmail.com', 'john', 'smith', 'rapleaf', '1122 334 455', 'api')
25
+ class Client
26
+ def initialize(savon_client, authentication_header)
27
+ @client = savon_client
28
+ @header = authentication_header
29
+ end
30
+
31
+ public
32
+
33
+ def get_lead_by_idnum(idnum)
34
+ get_lead(LeadKey.new(LeadKeyType::IDNUM, idnum))
35
+ end
36
+
37
+
38
+ def get_lead_by_email(email)
39
+ get_lead(LeadKey.new(LeadKeyType::EMAIL, email))
40
+ end
41
+
42
+ # create (if new) or update (if existing) a lead
43
+ #
44
+ # * email - email address of lead
45
+ # * first - first name of lead
46
+ # * last - surname/last name of lead
47
+ # * company - company the lead is associated with
48
+ # * mobile - mobile/cell phone number
49
+ # * api_key - rapleaf API key
50
+ def sync_lead(email, first, last, company, mobile, api_key)
51
+ begin
52
+ response = send_request("ns1:paramsSyncLead", {
53
+ :return_lead => true,
54
+ :lead_record =>
55
+ {:email => email,
56
+ :lead_attribute_list => {
57
+ :attribute => [
58
+ {:attr_name => 'FirstName', :attr_type => 'string', :attr_value => first},
59
+ {:attr_name => 'LastName', :attr_type => 'string', :attr_value => last},
60
+ {:attr_name => 'Email', :attr_type => 'string', :attr_value => email},
61
+ {:attr_name => 'Company', :attr_type => 'string', :attr_value => company},
62
+ {:attr_name => 'MobilePhone', :attr_type => 'string', :attr_value => mobile},
63
+ {:attr_name => 'API_Key__c', :attr_type => 'string', :attr_value => api_key}
64
+ ]}}})
65
+ return response
66
+ rescue Exception => e
67
+ return nil
68
+ end
69
+ end
70
+
71
+ def add_to_list(list_key, email)
72
+ list_operation(list_key, ListOperationType::ADD_TO, email)
73
+ end
74
+
75
+ def remove_from_list(list_key, email)
76
+ list_operation(list_key, ListOperationType::REMOVE_FROM, email)
77
+ end
78
+
79
+ def is_member_of_list?(list_key, email)
80
+ list_operation(list_key, ListOperationType::IS_MEMBER_OF, email)
81
+ end
82
+
83
+ private
84
+ def list_operation(list_key, list_operation_type, email)
85
+ begin
86
+ response = send_request("ns1:paramsListOperation", {
87
+ :list_operation => list_operation_type,
88
+ :list_key => list_key,
89
+ :strict => 'false',
90
+ :list_member_list => {
91
+ :lead_key => [
92
+ {:key_type => 'EMAIL', :key_value => email}
93
+ ]
94
+ }
95
+ })
96
+ return response
97
+ rescue Exception => e
98
+ return nil
99
+ end
100
+ end
101
+
102
+ def get_lead(lead_key)
103
+ begin
104
+ response = send_request("ns1:paramsGetLead", {:lead_key => lead_key.to_hash})
105
+ return LeadRecord.from_hash(response[:success_get_lead][:result][:lead_record_list][:lead_record])
106
+ rescue Exception => e
107
+ return nil
108
+ end
109
+ end
110
+
111
+ def send_request(namespace, body)
112
+ @header.set_time(DateTime.now)
113
+ response = request(namespace, body, @header.to_hash)
114
+ response.to_hash
115
+ end
116
+
117
+ def request(namespace, body, header)
118
+ @client.request namespace do |soap|
119
+ soap.namespaces["xmlns:ns1"] = "http://www.marketo.com/mktows/"
120
+ soap.body = body
121
+ soap.header["ns1:AuthenticationHeader"] = header
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,23 @@
1
+ module Rapleaf
2
+ module Marketo
3
+ # Types of operations you can do on a marketo list
4
+ module ListOperationType
5
+ ADD_TO = 'ADDTOLIST'
6
+ REMOVE_FROM = 'REMOVEFROMLIST'
7
+ IS_MEMBER_OF = 'ISMEMBEROFLIST'
8
+ end
9
+
10
+ # Types of keys that can be used to look up a lead
11
+ module LeadKeyType
12
+ IDNUM = "IDNUM"
13
+ COOKIE = "COOKIE"
14
+ EMAIL = "EMAIL"
15
+ LEADOWNEREMAIL = "LEADOWNEREMAIL"
16
+ SFDCACCOUNTID = "SFDCACCOUNTID"
17
+ SFDCCONTACTID = "SFDCCONTACTID"
18
+ SFDCLEADID = "SFDCLEADID"
19
+ SFDCLEADOWNERID = "SFDCLEADOWNERID"
20
+ SFDCOPPTYID = "SFDCOPPTYID"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Rapleaf
2
+ module Marketo
3
+ # Encapsulates a key used to look up or describe a specific marketo lead.
4
+ class LeadKey
5
+ # - *key_type* the type of key to use see LeadKeyType
6
+ # - *key_value* normally a string value for the given type
7
+ def initialize(key_type, key_value)
8
+ @key_type = key_type
9
+ @key_value = key_value
10
+ end
11
+
12
+ # get the key type
13
+ def key_type
14
+ @key_type
15
+ end
16
+
17
+ # get the key value
18
+ def key_value
19
+ @key_value
20
+ end
21
+
22
+ # create a hash from this instance, for sending this object to marketo using savon
23
+ def to_hash
24
+ {
25
+ :key_type => @key_type,
26
+ :key_value => @key_value
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,58 @@
1
+ module Rapleaf
2
+ module Marketo
3
+ # Represents a record of the data known about a lead within marketo
4
+ class LeadRecord
5
+ def initialize(email, idnum)
6
+ @email = email
7
+ @idnum = idnum
8
+ @attributes = {}
9
+ end
10
+
11
+ # hydrates an instance from a savon hash returned form the marketo API
12
+ def self.from_hash(savon_hash)
13
+ lead_record = LeadRecord.new(savon_hash[:email], savon_hash[:id].to_i)
14
+ savon_hash[:lead_attribute_list][:attribute].each do |attribute|
15
+ lead_record.set_attribute(attribute[:attr_name], attribute[:attr_value])
16
+ end
17
+ lead_record
18
+ end
19
+
20
+ # get the record idnum
21
+ def idnum
22
+ @idnum
23
+ end
24
+
25
+ # get the record email
26
+ def email
27
+ @email
28
+ end
29
+
30
+ def attributes
31
+ @attributes
32
+ end
33
+
34
+ # update the value of the named attribute
35
+ def set_attribute(name, value)
36
+ @attributes[name] = value
37
+ end
38
+
39
+ # get the value for the named attribute
40
+ def get_attribute(name)
41
+ @attributes[name]
42
+ end
43
+
44
+ # will yield pairs of |attribute_name, attribute_value|
45
+ def each_attribute_pair(&block)
46
+ @attributes.each_pair do |name, value|
47
+ block.call(name, value)
48
+ end
49
+ end
50
+
51
+ def ==(other)
52
+ @attributes == other.attributes &&
53
+ @idnum == other.idnum &&
54
+ @email == other.email
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ module Rapleaf
4
+ module Marketo
5
+ ACCESS_KEY = 'ACCESS_KEY'
6
+ SECRET_KEY = 'SECRET_KEY'
7
+
8
+ describe AuthenticationHeader do
9
+ it "should set mktowsUserId to access key" do
10
+ header = Rapleaf::Marketo::AuthenticationHeader.new(ACCESS_KEY, SECRET_KEY)
11
+ header.get_mktows_user_id.should == ACCESS_KEY
12
+ end
13
+
14
+ it "should set requestSignature" do
15
+ header = Rapleaf::Marketo::AuthenticationHeader.new(ACCESS_KEY, SECRET_KEY)
16
+ header.get_request_signature.should_not be_nil
17
+ header.get_request_signature.should_not == ''
18
+ end
19
+
20
+ it "should set requestTimestamp in correct format" do
21
+ header = Rapleaf::Marketo::AuthenticationHeader.new(ACCESS_KEY, SECRET_KEY)
22
+ time = DateTime.new(1998, 1, 17, 20, 15, 1)
23
+ header.set_time(time)
24
+ header.get_request_timestamp().should == '1998-01-17T20:15:01+00:00'
25
+ end
26
+
27
+ it "should calculate encrypted signature" do
28
+ # I got this example of the marketo API docs
29
+
30
+ access_key = 'bigcorp1_461839624B16E06BA2D663'
31
+ secret_key = '899756834129871744AAEE88DDCC77CDEEDEC1AAAD66'
32
+
33
+ header = Rapleaf::Marketo::AuthenticationHeader.new(access_key, secret_key)
34
+ header.set_time(DateTime.new(2010, 4, 9, 14, 4, 55, -7/24.0))
35
+
36
+ header.get_request_timestamp.should == '2010-04-09T14:04:54-07:00'
37
+ header.get_request_signature.should == 'ffbff4d4bef354807481e66dc7540f7890523a87'
38
+ end
39
+
40
+ it "should cope if no date is given" do
41
+ header = Rapleaf::Marketo::AuthenticationHeader.new(ACCESS_KEY, SECRET_KEY)
42
+ expected = DateTime.now
43
+ actual = DateTime.parse(header.get_request_timestamp)
44
+
45
+ expected.year.should == actual.year
46
+ expected.hour.should == actual.hour
47
+ end
48
+
49
+ it "should to_hash correctly" do
50
+ # I got this example from the marketo API docs
51
+
52
+ access_key = 'bigcorp1_461839624B16E06BA2D663'
53
+ secret_key = '899756834129871744AAEE88DDCC77CDEEDEC1AAAD66'
54
+
55
+ header = Rapleaf::Marketo::AuthenticationHeader.new(access_key, secret_key)
56
+ header.set_time(DateTime.new(2010, 4, 9, 14, 4, 55, -7/24.0))
57
+
58
+ header.to_hash.should == {
59
+ 'mktowsUserId' => header.get_mktows_user_id,
60
+ 'requestSignature' => header.get_request_signature,
61
+ 'requestTimestamp' => header.get_request_timestamp,
62
+ }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,263 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ module Rapleaf
4
+ module Marketo
5
+
6
+ describe Client do
7
+ EMAIL = "some@email.com"
8
+ IDNUM = 29
9
+ FIRST = 'Joe'
10
+ LAST = 'Smith'
11
+ COMPANY = 'Rapleaf'
12
+ MOBILE = '415 123 456'
13
+ API_KEY = 'API123KEY'
14
+
15
+ context 'Exception handling' do
16
+ it "should return nil if any exception is raised on get_lead request" do
17
+ savon_client = mock('savon_client').as_null_object
18
+ authentication_header = mock('authentication_header').as_null_object
19
+ client = Rapleaf::Marketo::Client.new(savon_client, authentication_header)
20
+ savon_client.should_receive(:request).and_raise Exception
21
+ client.get_lead_by_email(EMAIL).should be_nil
22
+ end
23
+
24
+ it "should return nil if any exception is raised on sync_lead request" do
25
+ savon_client = mock('savon_client').as_null_object
26
+ authentication_header = mock('authentication_header').as_null_object
27
+ client = Rapleaf::Marketo::Client.new(savon_client, authentication_header)
28
+ savon_client.should_receive(:request).and_raise Exception
29
+ client.sync_lead(EMAIL, FIRST, LAST, COMPANY, MOBILE, API_KEY).should be_nil
30
+ end
31
+ end
32
+
33
+ context 'Client interaction' do
34
+ it "should have the correct body format on get_lead_by_idnum" do
35
+ savon_client = mock('savon_client')
36
+ authentication_header = mock('authentication_header')
37
+ client = Rapleaf::Marketo::Client.new(savon_client, authentication_header)
38
+ response_hash = {
39
+ :success_get_lead => {
40
+ :result => {
41
+ :count => 1,
42
+ :lead_record_list => {
43
+ :lead_record => {
44
+ :email => EMAIL,
45
+ :lead_attribute_list => {
46
+ :attribute => [
47
+ {:attr_name => 'name1', :attr_type => 'string', :attr_value => 'val1'},
48
+ {:attr_name => 'name2', :attr_type => 'string', :attr_value => 'val2'},
49
+ {:attr_name => 'name3', :attr_type => 'string', :attr_value => 'val3'},
50
+ {:attr_name => 'name4', :attr_type => 'string', :attr_value => 'val4'}
51
+ ]
52
+ },
53
+ :foreign_sys_type => nil,
54
+ :foreign_sys_person_id => nil,
55
+ :id => IDNUM.to_s
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ expect_request(savon_client,
62
+ authentication_header,
63
+ {:lead_key => {
64
+ :key_value => IDNUM,
65
+ :key_type => LeadKeyType::IDNUM}},
66
+ 'ns1:paramsGetLead',
67
+ response_hash)
68
+ expected_lead_record = LeadRecord.new(EMAIL, IDNUM)
69
+ expected_lead_record.set_attribute('name1', 'val1')
70
+ expected_lead_record.set_attribute('name2', 'val2')
71
+ expected_lead_record.set_attribute('name3', 'val3')
72
+ expected_lead_record.set_attribute('name4', 'val4')
73
+ client.get_lead_by_idnum(IDNUM).should == expected_lead_record
74
+ end
75
+
76
+ it "should have the correct body format on get_lead_by_email" do
77
+ savon_client = mock('savon_client')
78
+ authentication_header = mock('authentication_header')
79
+ client = Rapleaf::Marketo::Client.new(savon_client, authentication_header)
80
+ response_hash = {
81
+ :success_get_lead => {
82
+ :result => {
83
+ :count => 1,
84
+ :lead_record_list => {
85
+ :lead_record => {
86
+ :email => EMAIL,
87
+ :lead_attribute_list => {
88
+ :attribute => [
89
+ {:attr_name => 'name1', :attr_type => 'string', :attr_value => 'val1'},
90
+ {:attr_name => 'name2', :attr_type => 'string', :attr_value => 'val2'},
91
+ {:attr_name => 'name3', :attr_type => 'string', :attr_value => 'val3'},
92
+ {:attr_name => 'name4', :attr_type => 'string', :attr_value => 'val4'}
93
+ ]
94
+ },
95
+ :foreign_sys_type => nil,
96
+ :foreign_sys_person_id => nil,
97
+ :id => IDNUM.to_s
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ expect_request(savon_client,
104
+ authentication_header,
105
+ {:lead_key => {
106
+ :key_value => EMAIL,
107
+ :key_type => LeadKeyType::EMAIL}},
108
+ 'ns1:paramsGetLead',
109
+ response_hash)
110
+ expected_lead_record = LeadRecord.new(EMAIL, IDNUM)
111
+ expected_lead_record.set_attribute('name1', 'val1')
112
+ expected_lead_record.set_attribute('name2', 'val2')
113
+ expected_lead_record.set_attribute('name3', 'val3')
114
+ expected_lead_record.set_attribute('name4', 'val4')
115
+ client.get_lead_by_email(EMAIL).should == expected_lead_record
116
+ end
117
+
118
+ it "should have the correct body format on sync_lead" do
119
+ savon_client = mock('savon_client')
120
+ authentication_header = mock('authentication_header')
121
+ client = Rapleaf::Marketo::Client.new(savon_client, authentication_header)
122
+ response_hash = {} # TODO
123
+ expect_request(savon_client,
124
+ authentication_header,
125
+ {
126
+ :return_lead => true,
127
+ :lead_record => {
128
+ :email => "some@email.com",
129
+ :lead_attribute_list =>
130
+ {
131
+ :attribute => [
132
+ {:attr_value => "Joe",
133
+ :attr_name => "FirstName",
134
+ :attr_type => "string"},
135
+ {:attr_value => "Smith",
136
+ :attr_name => "LastName",
137
+ :attr_type => "string"},
138
+ {:attr_value => "some@email.com",
139
+ :attr_name =>"Email",
140
+ :attr_type => "string"},
141
+ {:attr_value => "Rapleaf",
142
+ :attr_name =>"Company",
143
+ :attr_type =>"string"},
144
+ {:attr_value =>"415 123 456",
145
+ :attr_name =>"MobilePhone",
146
+ :attr_type =>"string"},
147
+ {:attr_value =>"API123KEY",
148
+ :attr_name =>"API_Key__c",
149
+ :attr_type =>"string"}
150
+ ]}}},
151
+ 'ns1:paramsSyncLead',
152
+ response_hash)
153
+ client.sync_lead(EMAIL, FIRST, LAST, COMPANY, MOBILE, API_KEY).should == response_hash
154
+ end
155
+
156
+ context "list operations" do
157
+ before(:each) do
158
+ LIST_KEY = 'awesome leads list'
159
+ @savon_client = mock('savon_client')
160
+ @authentication_header = mock('authentication_header')
161
+ @client = Rapleaf::Marketo::Client.new(@savon_client, @authentication_header)
162
+ end
163
+
164
+ it "should have the correct body format on add_to_list" do
165
+ response_hash = {} # TODO
166
+ expect_request(@savon_client,
167
+ @authentication_header,
168
+ {
169
+ :list_operation => ListOperationType::ADD_TO,
170
+ :list_key => LIST_KEY,
171
+ :strict => 'false',
172
+ :list_member_list => {
173
+ :lead_key => [
174
+ {
175
+ :key_type => 'EMAIL',
176
+ :key_value => EMAIL
177
+ }
178
+ ]
179
+ }
180
+ },
181
+ 'ns1:paramsListOperation',
182
+ response_hash)
183
+
184
+ @client.add_to_list(LIST_KEY, EMAIL).should == response_hash
185
+ end
186
+
187
+ it "should have the correct body format on remove_from_list" do
188
+ response_hash = {} # TODO
189
+ expect_request(@savon_client,
190
+ @authentication_header,
191
+ {
192
+ :list_operation => ListOperationType::REMOVE_FROM,
193
+ :list_key => LIST_KEY,
194
+ :strict => 'false',
195
+ :list_member_list => {
196
+ :lead_key => [
197
+ {
198
+ :key_type => 'EMAIL',
199
+ :key_value => EMAIL
200
+ }
201
+ ]
202
+ }
203
+ },
204
+ 'ns1:paramsListOperation',
205
+ response_hash)
206
+
207
+ @client.remove_from_list(LIST_KEY, EMAIL).should == response_hash
208
+ end
209
+
210
+ it "should have the correct body format on is_member_of_list?" do
211
+ response_hash = {} # TODO
212
+ expect_request(@savon_client,
213
+ @authentication_header,
214
+ {
215
+ :list_operation => ListOperationType::IS_MEMBER_OF,
216
+ :list_key => LIST_KEY,
217
+ :strict => 'false',
218
+ :list_member_list => {
219
+ :lead_key => [
220
+ {
221
+ :key_type => 'EMAIL',
222
+ :key_value => EMAIL
223
+ }
224
+ ]
225
+ }
226
+ },
227
+ 'ns1:paramsListOperation',
228
+ response_hash)
229
+
230
+ @client.is_member_of_list?(LIST_KEY, EMAIL).should == response_hash
231
+ end
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def expect_request(savon_client, authentication_header, expected_body, expected_namespace, response_hash)
238
+ header_hash = stub('header_hash')
239
+ soap_response = stub('soap_response')
240
+ request_namespace = mock('namespace')
241
+ request_header = mock('request_header')
242
+ soap_request = mock('soap_request')
243
+ authentication_header.should_receive(:set_time)
244
+ authentication_header.should_receive(:to_hash).and_return(header_hash)
245
+ request_namespace.should_receive(:[]=).with("xmlns:ns1", "http://www.marketo.com/mktows/")
246
+ request_header.should_receive(:[]=).with("ns1:AuthenticationHeader", header_hash)
247
+ soap_request.should_receive(:namespaces).and_return(request_namespace)
248
+ soap_request.should_receive(:header).and_return(request_header)
249
+ soap_request.should_receive(:body=).with(expected_body)
250
+ soap_response.should_receive(:to_hash).and_return(response_hash)
251
+ savon_client.should_receive(:request).with(expected_namespace).and_yield(soap_request).and_return(soap_response)
252
+ end
253
+ end
254
+
255
+ describe ListOperationType do
256
+ it 'should define the correct types' do
257
+ ListOperationType::ADD_TO.should == 'ADDTOLIST'
258
+ ListOperationType::IS_MEMBER_OF.should == 'ISMEMBEROFLIST'
259
+ ListOperationType::REMOVE_FROM.should == 'REMOVEFROMLIST'
260
+ end
261
+ end
262
+ end
263
+ end
@@ -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,88 @@
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
+ LeadRecord.new(EMAIL, IDNUM).idnum.should == IDNUM
11
+ end
12
+
13
+ it "should store the email" do
14
+ LeadRecord.new(EMAIL, IDNUM).email.should == EMAIL
15
+ end
16
+
17
+ it "should implement == sensibly" do
18
+ lead_record1 = LeadRecord.new(EMAIL, IDNUM)
19
+ lead_record1.set_attribute('favourite color', 'red')
20
+ lead_record1.set_attribute('age', '100')
21
+
22
+ lead_record2 = LeadRecord.new(EMAIL, IDNUM)
23
+ lead_record2.set_attribute('favourite color', 'red')
24
+ lead_record2.set_attribute('age', '100')
25
+
26
+ lead_record1.should == lead_record2
27
+ end
28
+
29
+ it "should store when attributes are set" do
30
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
31
+ lead_record.set_attribute('favourite color', 'red')
32
+ lead_record.get_attribute('favourite color').should == 'red'
33
+ end
34
+
35
+ it "should store when attributes are updated" do
36
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
37
+ lead_record.set_attribute('favourite color', 'red')
38
+ lead_record.set_attribute('favourite color', 'green')
39
+ lead_record.get_attribute('favourite color').should == 'green'
40
+ end
41
+
42
+ it "should yield all attributes through each_attribute_pair" do
43
+ lead_record = LeadRecord.new(EMAIL, IDNUM)
44
+ lead_record.set_attribute('favourite color', 'red')
45
+ lead_record.set_attribute('favourite color', 'green')
46
+ lead_record.set_attribute('age', '99')
47
+
48
+ pairs = []
49
+ lead_record.each_attribute_pair do |attribute_name, attribute_value|
50
+ pairs << [attribute_name, attribute_value]
51
+ end
52
+
53
+ pairs.size.should == 2
54
+ pairs.should include(['favourite color', 'green'])
55
+ pairs.should include(['age', '99'])
56
+ end
57
+
58
+ it "should be instantiable from a savon hash" do
59
+ savon_hash = {
60
+ :email => EMAIL,
61
+ :foreign_sys_type => nil,
62
+ :lead_attribute_list => {
63
+ :attribute => [
64
+ { :attr_name => 'Company', :attr_type => 'string', :attr_value => 'Rapleaf'},
65
+ { :attr_name => 'FirstName', :attr_type => 'string', :attr_value => 'James'},
66
+ { :attr_name => 'LastName', :attr_type => 'string', :attr_value => 'O\'Brien'}
67
+ ]
68
+ },
69
+ :foreign_sys_person_id => nil,
70
+ :id => IDNUM
71
+ }
72
+
73
+ actual = LeadRecord.from_hash(savon_hash)
74
+
75
+ actual.email.should == EMAIL
76
+ actual.idnum.should == IDNUM
77
+ pairs = []
78
+ actual.each_attribute_pair do |attribute_name, attribute_value|
79
+ pairs << [attribute_name, attribute_value]
80
+ end
81
+ pairs.size.should == 3
82
+ pairs.should include(['Company', 'Rapleaf'])
83
+ pairs.should include(['FirstName', 'James'])
84
+ pairs.should include(['LastName', 'O\'Brien'])
85
+ end
86
+ end
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: marketo
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 0
10
+ version: 1.1.0
11
+ platform: ruby
12
+ authors:
13
+ - James O'Brien
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-31 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: savon
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description: Allows easy integration with marketo from ruby. You can synchronize leads and fetch them back by email.
50
+ email: james@rapleaf.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - lib/marketo/authentication_header.rb
59
+ - lib/marketo/client.rb
60
+ - lib/marketo/enums.rb
61
+ - lib/marketo/lead_key.rb
62
+ - lib/marketo/lead_record.rb
63
+ - lib/marketo.rb
64
+ - spec/marketo/authentication_header_spec.rb
65
+ - spec/marketo/client_spec.rb
66
+ - spec/marketo/lead_key_spec.rb
67
+ - spec/marketo/lead_record_spec.rb
68
+ has_rdoc: true
69
+ homepage: http://www.rapleaf.com
70
+ licenses:
71
+ - - Rapleaf internal - do not use without permission
72
+ post_install_message:
73
+ rdoc_options:
74
+ - --title
75
+ - Marketo Client Gem
76
+ - --main
77
+ - Rapleaf::Marketo::Client
78
+ require_paths:
79
+ - - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: A client for using the marketo API within Rapleaf
105
+ test_files:
106
+ - spec/marketo/authentication_header_spec.rb
107
+ - spec/marketo/client_spec.rb
108
+ - spec/marketo/lead_key_spec.rb
109
+ - spec/marketo/lead_record_spec.rb