mrkt 0.8.0 → 1.0.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +59 -5
- data/.travis.yml +19 -10
- data/Gemfile.lock +68 -63
- data/LICENSE +21 -0
- data/README.md +11 -7
- data/lib/mrkt.rb +16 -3
- data/lib/mrkt/concerns/authentication.rb +27 -12
- data/lib/mrkt/concerns/connection.rb +2 -5
- data/lib/mrkt/concerns/crud_activities.rb +10 -7
- data/lib/mrkt/concerns/crud_asset_folders.rb +43 -0
- data/lib/mrkt/concerns/crud_asset_static_lists.rb +30 -0
- data/lib/mrkt/concerns/crud_campaigns.rb +2 -4
- data/lib/mrkt/concerns/crud_custom_activities.rb +3 -2
- data/lib/mrkt/concerns/crud_custom_objects.rb +12 -13
- data/lib/mrkt/concerns/crud_helpers.rb +7 -0
- data/lib/mrkt/concerns/crud_leads.rb +28 -15
- data/lib/mrkt/concerns/crud_lists.rb +13 -10
- data/lib/mrkt/concerns/crud_programs.rb +6 -5
- data/lib/mrkt/concerns/import_custom_objects.rb +24 -0
- data/lib/mrkt/concerns/import_leads.rb +7 -4
- data/lib/mrkt/errors.rb +3 -2
- data/lib/mrkt/version.rb +1 -1
- data/mrkt.gemspec +11 -12
- data/spec/concerns/authentication_spec.rb +57 -5
- data/spec/concerns/crud_activities_spec.rb +46 -7
- data/spec/concerns/crud_asset_folders_spec.rb +273 -0
- data/spec/concerns/crud_asset_static_lists_spec.rb +183 -0
- data/spec/concerns/crud_custom_activities_spec.rb +3 -1
- data/spec/concerns/crud_custom_objects_spec.rb +1 -1
- data/spec/concerns/crud_leads_spec.rb +103 -1
- data/spec/concerns/crud_lists_spec.rb +33 -0
- data/spec/concerns/import_custom_objects_spec.rb +89 -0
- data/spec/concerns/import_leads_spec.rb +3 -3
- data/spec/spec_helper.rb +3 -1
- data/spec/support/webmock.rb +1 -7
- metadata +43 -46
@@ -29,9 +29,49 @@ describe Mrkt::Authentication do
|
|
29
29
|
expect(client.authenticated?).to be true
|
30
30
|
end
|
31
31
|
|
32
|
+
context 'with optional partner_id client option' do
|
33
|
+
before { remove_request_stub(@authentication_request_stub) }
|
34
|
+
|
35
|
+
let(:partner_id) { SecureRandom.uuid }
|
36
|
+
|
37
|
+
let(:client_options) do
|
38
|
+
{
|
39
|
+
host: host,
|
40
|
+
client_id: client_id,
|
41
|
+
client_secret: client_secret,
|
42
|
+
partner_id: partner_id
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:query) do
|
47
|
+
{
|
48
|
+
client_id: client_id,
|
49
|
+
client_secret: client_secret,
|
50
|
+
partner_id: partner_id,
|
51
|
+
grant_type: 'client_credentials'
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
subject(:client) { Mrkt::Client.new(client_options) }
|
56
|
+
|
57
|
+
before do
|
58
|
+
stub_request(:get, "https://#{host}/identity/oauth/token")
|
59
|
+
.with(query: query)
|
60
|
+
.to_return(json_stub(authentication_stub))
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should authenticate and then be authenticated?' do
|
64
|
+
expect(client.authenticated?).to_not be true
|
65
|
+
client.authenticate!
|
66
|
+
expect(client.authenticated?).to be true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
32
70
|
context 'when the token has expired and @retry_authentication = true' do
|
33
71
|
before { remove_request_stub(@authentication_request_stub) }
|
34
72
|
|
73
|
+
let(:retry_count) { 3 }
|
74
|
+
|
35
75
|
let(:expired_authentication_stub) do
|
36
76
|
{ access_token: SecureRandom.uuid, token_type: 'bearer', expires_in: 0, scope: 'RestClient' }
|
37
77
|
end
|
@@ -40,7 +80,17 @@ describe Mrkt::Authentication do
|
|
40
80
|
{ access_token: SecureRandom.uuid, token_type: 'bearer', expires_in: 1234, scope: 'RestClient' }
|
41
81
|
end
|
42
82
|
|
43
|
-
|
83
|
+
let(:client_options) do
|
84
|
+
{
|
85
|
+
host: host,
|
86
|
+
client_id: client_id,
|
87
|
+
client_secret: client_secret,
|
88
|
+
retry_authentication: true,
|
89
|
+
retry_authentication_count: retry_count
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
subject(:client) { Mrkt::Client.new(client_options) }
|
44
94
|
|
45
95
|
before do
|
46
96
|
stub_request(:get, "https://#{host}/identity/oauth/token")
|
@@ -55,12 +105,14 @@ describe Mrkt::Authentication do
|
|
55
105
|
expect(client.authenticated?).to be true
|
56
106
|
end
|
57
107
|
|
58
|
-
|
59
|
-
|
108
|
+
context 'when retry_authentication_count is low' do
|
109
|
+
let(:retry_count) { 2 }
|
60
110
|
|
61
|
-
|
111
|
+
it 'should stop retrying after @retry_authentication_count tries and then raise an error' do
|
112
|
+
expect(client.authenticated?).to_not be true
|
62
113
|
|
63
|
-
|
114
|
+
expect { client.authenticate! }.to raise_error(Mrkt::Errors::Error, 'Client not authenticated')
|
115
|
+
end
|
64
116
|
end
|
65
117
|
end
|
66
118
|
end
|
@@ -110,7 +110,7 @@ describe Mrkt::CrudActivities do
|
|
110
110
|
|
111
111
|
before do
|
112
112
|
stub_request(:get, "https://#{host}/rest/v1/activities.json")
|
113
|
-
.with(query: { nextPageToken:
|
113
|
+
.with(query: { nextPageToken: token })
|
114
114
|
.to_return(json_stub(response_stub))
|
115
115
|
end
|
116
116
|
|
@@ -152,7 +152,7 @@ describe Mrkt::CrudActivities do
|
|
152
152
|
before do
|
153
153
|
stub_request(:get, "https://#{host}/rest/v1/activities.json")
|
154
154
|
.with(query: {
|
155
|
-
nextPageToken:
|
155
|
+
nextPageToken: token,
|
156
156
|
activityTypeIds: activity_type_ids.join(',')
|
157
157
|
})
|
158
158
|
.to_return(json_stub(response_stub))
|
@@ -196,7 +196,7 @@ describe Mrkt::CrudActivities do
|
|
196
196
|
|
197
197
|
before do
|
198
198
|
stub_request(:get, "https://#{host}/rest/v1/activities.json")
|
199
|
-
.with(query: { nextPageToken:
|
199
|
+
.with(query: { nextPageToken: token, leadIds: lead_ids.join(',') })
|
200
200
|
.to_return(json_stub(response_stub))
|
201
201
|
end
|
202
202
|
|
@@ -204,15 +204,15 @@ describe Mrkt::CrudActivities do
|
|
204
204
|
end
|
205
205
|
|
206
206
|
context 'specifying arrays values as empty strings' do
|
207
|
-
let(:activity_type_ids) {
|
208
|
-
let(:lead_ids) {
|
207
|
+
let(:activity_type_ids) { '' }
|
208
|
+
let(:lead_ids) { '' }
|
209
209
|
subject do
|
210
210
|
client.get_activities(token, activity_type_ids: activity_type_ids, lead_ids: lead_ids)
|
211
211
|
end
|
212
212
|
|
213
213
|
before do
|
214
214
|
stub_request(:get, "https://#{host}/rest/v1/activities.json")
|
215
|
-
.with(query: { nextPageToken:
|
215
|
+
.with(query: { nextPageToken: token })
|
216
216
|
.to_return(json_stub(response_stub))
|
217
217
|
end
|
218
218
|
|
@@ -227,7 +227,7 @@ describe Mrkt::CrudActivities do
|
|
227
227
|
before do
|
228
228
|
stub_request(:get, "https://#{host}/rest/v1/activities.json")
|
229
229
|
.with(query: {
|
230
|
-
nextPageToken:
|
230
|
+
nextPageToken: token,
|
231
231
|
activityTypeIds: activity_type_ids.join(','),
|
232
232
|
leadIds: lead_ids.join(',')
|
233
233
|
})
|
@@ -237,4 +237,43 @@ describe Mrkt::CrudActivities do
|
|
237
237
|
it { is_expected.to eq(response_stub) }
|
238
238
|
end
|
239
239
|
end
|
240
|
+
|
241
|
+
describe '#get_deleted_leads' do
|
242
|
+
let(:token) { '4GAX7YNCIJKO2VAED5LH5PQIYPUM7WCVKTQWEDMP2L24AXZT54LA====' }
|
243
|
+
let(:response_stub) do
|
244
|
+
{
|
245
|
+
requestId: '8105#1650074c30c',
|
246
|
+
result: [
|
247
|
+
{
|
248
|
+
id: 12_751,
|
249
|
+
marketoGUID: '12751',
|
250
|
+
leadId: 277,
|
251
|
+
activityDate: '2018-08-03T14:58:53Z',
|
252
|
+
activityTypeId: 37,
|
253
|
+
campaignId: 5227,
|
254
|
+
primaryAttributeValueId: 277,
|
255
|
+
primaryAttributeValue: 'Delete Me',
|
256
|
+
attributes: [
|
257
|
+
{
|
258
|
+
name: 'Campaign',
|
259
|
+
value: 'Run Action Delete Lead 2018-08-03 04:58:50 pm'
|
260
|
+
}
|
261
|
+
]
|
262
|
+
}
|
263
|
+
],
|
264
|
+
success: true,
|
265
|
+
nextPageToken: 'XQH6SLHODNIM7CY6MKJ6GAOR3JYOQXIN3THAHKYZXSOYN4HOPR2Q====',
|
266
|
+
moreResult: false
|
267
|
+
}
|
268
|
+
end
|
269
|
+
subject { client.get_deleted_leads(token) }
|
270
|
+
|
271
|
+
before do
|
272
|
+
stub_request(:get, "https://#{host}/rest/v1/activities/deletedleads.json")
|
273
|
+
.with(query: { nextPageToken: token })
|
274
|
+
.to_return(json_stub(response_stub))
|
275
|
+
end
|
276
|
+
|
277
|
+
it { is_expected.to eq(response_stub) }
|
278
|
+
end
|
240
279
|
end
|
@@ -0,0 +1,273 @@
|
|
1
|
+
describe Mrkt::CrudAssetFolders do
|
2
|
+
include_context 'initialized client'
|
3
|
+
|
4
|
+
let(:response_folder_result) do
|
5
|
+
{
|
6
|
+
name: 'Test Folder Name',
|
7
|
+
description: 'Optional folder description',
|
8
|
+
createdAt: '2019-03-15T23:31:00Z+0000',
|
9
|
+
updatedAt: '2019-03-15T23:31:00Z+0000',
|
10
|
+
url: 'https://app-devlocal1.marketo.com/#ML0A1ZN75',
|
11
|
+
folderId: {
|
12
|
+
id: 75,
|
13
|
+
type: 'Folder'
|
14
|
+
},
|
15
|
+
folderType: 'Zone',
|
16
|
+
parent: {
|
17
|
+
id: 5,
|
18
|
+
type: 'Folder'
|
19
|
+
},
|
20
|
+
path: '/Lead Database/Default/Test Folder Name',
|
21
|
+
isArchive: false,
|
22
|
+
isSystem: false,
|
23
|
+
accessZoneId: 1,
|
24
|
+
workspace: 'Default',
|
25
|
+
id: 75
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#create_folder' do
|
30
|
+
subject { client.create_folder(name, parent, description: description) }
|
31
|
+
|
32
|
+
let(:name) { 'Test Folder Name' }
|
33
|
+
let(:parent) do
|
34
|
+
{ id: 5, type: 'Folder' }
|
35
|
+
end
|
36
|
+
let(:description) { 'Optional folder description' }
|
37
|
+
let(:response_stub) do
|
38
|
+
{
|
39
|
+
requestId: 'bf7d#16983b1c7e3',
|
40
|
+
result: [
|
41
|
+
response_folder_result
|
42
|
+
],
|
43
|
+
success: true,
|
44
|
+
errors: [],
|
45
|
+
warnings: []
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:json_parent) { JSON.generate(parent) }
|
50
|
+
let(:request_body) do
|
51
|
+
{
|
52
|
+
name: name,
|
53
|
+
parent: json_parent,
|
54
|
+
description: description
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
before do
|
59
|
+
stub_request(:post, "https://#{host}/rest/asset/v1/folders.json")
|
60
|
+
.with(body: request_body)
|
61
|
+
.to_return(json_stub(response_stub))
|
62
|
+
end
|
63
|
+
|
64
|
+
it { is_expected.to eq(response_stub) }
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#get_folder_by_id' do
|
68
|
+
subject { client.get_folder_by_id(id, type: type) }
|
69
|
+
|
70
|
+
let(:id) { 77 }
|
71
|
+
|
72
|
+
before do
|
73
|
+
stub_request(:get, "https://#{host}/rest/asset/v1/folder/#{id}.json?type=#{type}")
|
74
|
+
.to_return(json_stub(response_stub))
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when a folder with the given id exists' do
|
78
|
+
let(:type) { 'Folder' }
|
79
|
+
let(:response_stub) do
|
80
|
+
{
|
81
|
+
requestId: '12756#16983bd0ee5',
|
82
|
+
result: [
|
83
|
+
response_folder_result
|
84
|
+
],
|
85
|
+
success: true,
|
86
|
+
errors: [],
|
87
|
+
warnings: []
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
it { is_expected.to eq(response_stub) }
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when a folder with the given id does not exist' do
|
95
|
+
let(:type) { 'Folder' }
|
96
|
+
let(:response_stub) do
|
97
|
+
{
|
98
|
+
requestId: '18087#16983c04cdf',
|
99
|
+
success: true,
|
100
|
+
errors: [],
|
101
|
+
warnings: [
|
102
|
+
'No assets found for the given search criteria.'
|
103
|
+
]
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
it { is_expected.to eq(response_stub) }
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when the given type is not acceptable' do
|
111
|
+
let(:type) { 'Unacceptable' }
|
112
|
+
let(:response_stub) do
|
113
|
+
{
|
114
|
+
requestId: '12776#16983c25b1d',
|
115
|
+
success: false,
|
116
|
+
warnings: [],
|
117
|
+
errors: [
|
118
|
+
{
|
119
|
+
code: '1001',
|
120
|
+
message: "Invalid value 'Unacceptable'. Required of type 'FolderVariantType'"
|
121
|
+
}
|
122
|
+
]
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should raise an Error' do
|
127
|
+
expect { subject }.to raise_error(Mrkt::Errors::TypeMismatch)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#get_folder_by_name' do
|
133
|
+
subject { client.get_folder_by_name(name, type: type, root: root, work_space: work_space) }
|
134
|
+
|
135
|
+
let(:name) { 'Test Folder Name' }
|
136
|
+
let(:type) { 'Folder' }
|
137
|
+
let(:root) do
|
138
|
+
{
|
139
|
+
id: 5,
|
140
|
+
type: 'Folder'
|
141
|
+
}
|
142
|
+
end
|
143
|
+
let(:work_space) { 'Default' }
|
144
|
+
|
145
|
+
let(:json_root) { JSON.generate(root) }
|
146
|
+
let(:request_query) { "name=#{name}&type=#{type}&root=#{json_root}&workSpace=#{work_space}" }
|
147
|
+
|
148
|
+
before do
|
149
|
+
stub_request(:get, "https://#{host}/rest/asset/v1/folder/byName.json?#{request_query}")
|
150
|
+
.to_return(json_stub(response_stub))
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'when a folder with the given name exists' do
|
154
|
+
let(:response_stub) do
|
155
|
+
{
|
156
|
+
requestId: '541#16983d2f549',
|
157
|
+
result: [
|
158
|
+
response_folder_result
|
159
|
+
],
|
160
|
+
success: true,
|
161
|
+
errors: [],
|
162
|
+
warnings: []
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
it { is_expected.to eq(response_stub) }
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when a folder with the given name does not exist' do
|
170
|
+
let(:response_stub) do
|
171
|
+
{
|
172
|
+
requestId: '105ad#16983d557c5',
|
173
|
+
success: true,
|
174
|
+
errors: [],
|
175
|
+
warnings: [
|
176
|
+
'No assets found for the given search criteria.'
|
177
|
+
]
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
it { is_expected.to eq(response_stub) }
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when the given work_space does not exist' do
|
185
|
+
let(:response_stub) do
|
186
|
+
{
|
187
|
+
requestId: '17af3#16983da0349',
|
188
|
+
success: false,
|
189
|
+
warnings: [],
|
190
|
+
errors: [
|
191
|
+
{
|
192
|
+
code: '611',
|
193
|
+
message: 'Unable to get folder'
|
194
|
+
}
|
195
|
+
]
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should raise an Error' do
|
200
|
+
expect { subject }.to raise_error(Mrkt::Errors::System)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when the given type is not acceptable' do
|
205
|
+
let(:response_stub) do
|
206
|
+
{
|
207
|
+
requestId: '2225#16983db0b71',
|
208
|
+
success: false,
|
209
|
+
warnings: [],
|
210
|
+
errors: [
|
211
|
+
{
|
212
|
+
code: '1003',
|
213
|
+
message: 'Invalid request. Please check and try again.'
|
214
|
+
}
|
215
|
+
]
|
216
|
+
}
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should raise an Error' do
|
220
|
+
expect { subject }.to raise_error(Mrkt::Errors::UnspecifiedAction)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe '#delete_folder' do
|
226
|
+
subject { client.delete_folder(id) }
|
227
|
+
|
228
|
+
let(:id) { 75 }
|
229
|
+
|
230
|
+
before do
|
231
|
+
stub_request(:post, "https://#{host}/rest/asset/v1/folder/#{id}/delete.json")
|
232
|
+
.to_return(json_stub(response_stub))
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'when a folder with the given id exists' do
|
236
|
+
let(:response_stub) do
|
237
|
+
{
|
238
|
+
requestId: '1a1a#16983eaa800',
|
239
|
+
result: [
|
240
|
+
{
|
241
|
+
id: 75
|
242
|
+
}
|
243
|
+
],
|
244
|
+
success: true,
|
245
|
+
errors: [],
|
246
|
+
warnings: []
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
it { is_expected.to eq(response_stub) }
|
251
|
+
end
|
252
|
+
|
253
|
+
context 'when a folder with the given id does not exist' do
|
254
|
+
let(:response_stub) do
|
255
|
+
{
|
256
|
+
requestId: '102ee#16983f320fb',
|
257
|
+
success: false,
|
258
|
+
warnings: [],
|
259
|
+
errors: [
|
260
|
+
{
|
261
|
+
code: '702',
|
262
|
+
message: '75 Folder not found'
|
263
|
+
}
|
264
|
+
]
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should raise an Error' do
|
269
|
+
expect { subject }.to raise_error(Mrkt::Errors::RecordNotFound)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|