mrkt 0.6.2 → 1.2.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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.rubocop.yml +31 -6
  5. data/Gemfile.lock +95 -69
  6. data/LICENSE +21 -0
  7. data/README.md +35 -7
  8. data/lib/mrkt/concerns/authentication.rb +32 -6
  9. data/lib/mrkt/concerns/connection.rb +13 -4
  10. data/lib/mrkt/concerns/crud_activities.rb +32 -0
  11. data/lib/mrkt/concerns/crud_asset_folders.rb +43 -0
  12. data/lib/mrkt/concerns/crud_asset_static_lists.rb +30 -0
  13. data/lib/mrkt/concerns/crud_campaigns.rb +2 -4
  14. data/lib/mrkt/concerns/crud_custom_activities.rb +36 -0
  15. data/lib/mrkt/concerns/crud_custom_objects.rb +14 -15
  16. data/lib/mrkt/concerns/crud_helpers.rb +7 -0
  17. data/lib/mrkt/concerns/crud_leads.rb +41 -15
  18. data/lib/mrkt/concerns/crud_lists.rb +13 -10
  19. data/lib/mrkt/concerns/crud_programs.rb +6 -5
  20. data/lib/mrkt/concerns/import_custom_objects.rb +24 -0
  21. data/lib/mrkt/concerns/import_leads.rb +8 -5
  22. data/lib/mrkt/errors.rb +23 -3
  23. data/lib/mrkt/faraday/params_encoder.rb +20 -0
  24. data/lib/mrkt/faraday.rb +4 -0
  25. data/lib/mrkt/faraday_middleware/response.rb +4 -4
  26. data/lib/mrkt/faraday_middleware.rb +3 -7
  27. data/lib/mrkt/version.rb +1 -1
  28. data/lib/mrkt.rb +29 -3
  29. data/mrkt.gemspec +13 -12
  30. data/spec/concerns/authentication_spec.rb +95 -0
  31. data/spec/concerns/crud_activities_spec.rb +279 -0
  32. data/spec/concerns/crud_asset_folders_spec.rb +273 -0
  33. data/spec/concerns/crud_asset_static_lists_spec.rb +183 -0
  34. data/spec/concerns/crud_custom_activities_spec.rb +172 -0
  35. data/spec/concerns/crud_custom_objects_spec.rb +99 -89
  36. data/spec/concerns/crud_leads_spec.rb +151 -1
  37. data/spec/concerns/crud_lists_spec.rb +33 -0
  38. data/spec/concerns/import_custom_objects_spec.rb +89 -0
  39. data/spec/concerns/import_leads_spec.rb +3 -3
  40. data/spec/faraday/params_encoder_spec.rb +24 -0
  41. data/spec/spec_helper.rb +3 -6
  42. data/spec/support/initialized_client.rb +1 -1
  43. data/spec/support/webmock.rb +1 -7
  44. metadata +82 -40
  45. data/.travis.yml +0 -8
@@ -0,0 +1,279 @@
1
+ describe Mrkt::CrudActivities do
2
+ include_context 'initialized client'
3
+
4
+ describe '#get_activity_types' do
5
+ let(:response_stub) do
6
+ {
7
+ requestId: 'c245#14cd6830ae2',
8
+ result: [
9
+ {
10
+ id: 1,
11
+ name: 'Visit Webpage',
12
+ description: 'User visits a web page',
13
+ primareAttributes: {
14
+ name: 'Webpage ID',
15
+ dataType: 'integer'
16
+ },
17
+ attributes: [
18
+ {
19
+ name: 'Query Parameters',
20
+ dataType: 'string'
21
+ },
22
+ {
23
+ name: 'Webpage URL',
24
+ dataType: 'string'
25
+ }
26
+ ]
27
+ }
28
+ ],
29
+ success: true
30
+ }
31
+ end
32
+ subject { client.get_activity_types }
33
+
34
+ before do
35
+ stub_request(:get, "https://#{host}/rest/v1/activities/types.json")
36
+ .to_return(json_stub(response_stub))
37
+ end
38
+
39
+ it { is_expected.to eq(response_stub) }
40
+ end
41
+
42
+ describe '#get_paging_token' do
43
+ let(:since_datetime) { Time.utc(2017, 1, 1, 4, 30) }
44
+ let(:response_stub) do
45
+ {
46
+ requestId: '12eb3#1599b371c62',
47
+ success: true,
48
+ nextPageToken: '4GAX7YNCIJKO2VAED5LH5PQIYPUM7WCVKTQWEDMP2L24AXZT54LA===='
49
+ }
50
+ end
51
+ subject { client.get_paging_token(since_datetime) }
52
+
53
+ before do
54
+ stub_request(:get, "https://#{host}/rest/v1/activities/pagingtoken.json")
55
+ .with(query: { sinceDatetime: '2017-01-01T04:30:00Z' })
56
+ .to_return(json_stub(response_stub))
57
+ end
58
+
59
+ it { is_expected.to eq(response_stub) }
60
+ end
61
+
62
+ describe '#get_activities' do
63
+ let(:activity_type_ids) { [1, 2] }
64
+ let(:lead_ids) { [100, 102] }
65
+ let(:token) { '4GAX7YNCIJKO2VAED5LH5PQIYPUM7WCVKTQWEDMP2L24AXZT54LA====' }
66
+ let(:response_stub) do
67
+ {
68
+ data: {
69
+ requestId: '417b#1599b3bca62',
70
+ result: [
71
+ {
72
+ id: 500,
73
+ leadId: 100,
74
+ activityDate: '2017-01-01T07:53:29Z',
75
+ activityTypeId: 1,
76
+ primaryAttributeValueId: 29,
77
+ primaryAttributeValue: 'test',
78
+ attributes: [
79
+ {
80
+ name: 'Query Parameters',
81
+ value: ''
82
+ },
83
+ {
84
+ name: 'Webpage URL',
85
+ value: '/test.html'
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ id: 456,
91
+ leadId: 101,
92
+ activityDate: '2017-01-01T08:13:36Z',
93
+ activityTypeId: 12,
94
+ primaryAttributeValueId: 101,
95
+ attributes: [
96
+ {
97
+ name: 'Form Name',
98
+ value: 'Sign Up'
99
+ }
100
+ ]
101
+ }
102
+ ]
103
+ },
104
+ success: true,
105
+ nextPageToken: 'WQV2VQVPPCKHC6AQYVK7JDSA3I5PBAJNUNY3CR563KMVM7F43OIQ====',
106
+ moreResult: false
107
+ }
108
+ end
109
+ subject { client.get_activities(token) }
110
+
111
+ before do
112
+ stub_request(:get, "https://#{host}/rest/v1/activities.json")
113
+ .with(query: { nextPageToken: token })
114
+ .to_return(json_stub(response_stub))
115
+ end
116
+
117
+ it { is_expected.to eq(response_stub) }
118
+
119
+ context 'specifying activity type ids' do
120
+ let(:response_stub) do
121
+ {
122
+ data: {
123
+ requestId: '417b#1599b3bca62',
124
+ result: [
125
+ {
126
+ id: 500,
127
+ leadId: 100,
128
+ activityDate: '2017-01-01T07:53:29Z',
129
+ activityTypeId: 1,
130
+ primaryAttributeValueId: 29,
131
+ primaryAttributeValue: 'test',
132
+ attributes: [
133
+ {
134
+ name: 'Query Parameters',
135
+ value: ''
136
+ },
137
+ {
138
+ name: 'Webpage URL',
139
+ value: '/test.html'
140
+ }
141
+ ]
142
+ }
143
+ ]
144
+ },
145
+ success: true,
146
+ nextPageToken: 'WQV2VQVPPCKHC6AQYVK7JDSA3I5PBAJNUNY3CR563KMVM7F43OIQ====',
147
+ moreResult: false
148
+ }
149
+ end
150
+ subject { client.get_activities(token, activity_type_ids: activity_type_ids) }
151
+
152
+ before do
153
+ stub_request(:get, "https://#{host}/rest/v1/activities.json")
154
+ .with(query: {
155
+ nextPageToken: token,
156
+ activityTypeIds: activity_type_ids.join(',')
157
+ })
158
+ .to_return(json_stub(response_stub))
159
+ end
160
+
161
+ it { is_expected.to eq(response_stub) }
162
+ end
163
+
164
+ context 'specifying lead ids' do
165
+ let(:response_stub) do
166
+ {
167
+ data: {
168
+ requestId: '417b#1599b3bca62',
169
+ result: [
170
+ {
171
+ id: 500,
172
+ leadId: 100,
173
+ activityDate: '2017-01-01T07:53:29Z',
174
+ activityTypeId: 1,
175
+ primaryAttributeValueId: 29,
176
+ primaryAttributeValue: 'test',
177
+ attributes: [
178
+ {
179
+ name: 'Query Parameters',
180
+ value: ''
181
+ },
182
+ {
183
+ name: 'Webpage URL',
184
+ value: '/test.html'
185
+ }
186
+ ]
187
+ }
188
+ ]
189
+ },
190
+ success: true,
191
+ nextPageToken: 'WQV2VQVPPCKHC6AQYVK7JDSA3I5PBAJNUNY3CR563KMVM7F43OIQ====',
192
+ moreResult: false
193
+ }
194
+ end
195
+ subject { client.get_activities(token, lead_ids: lead_ids) }
196
+
197
+ before do
198
+ stub_request(:get, "https://#{host}/rest/v1/activities.json")
199
+ .with(query: { nextPageToken: token, leadIds: lead_ids.join(',') })
200
+ .to_return(json_stub(response_stub))
201
+ end
202
+
203
+ it { is_expected.to eq(response_stub) }
204
+ end
205
+
206
+ context 'specifying arrays values as empty strings' do
207
+ let(:activity_type_ids) { '' }
208
+ let(:lead_ids) { '' }
209
+ subject do
210
+ client.get_activities(token, activity_type_ids: activity_type_ids, lead_ids: lead_ids)
211
+ end
212
+
213
+ before do
214
+ stub_request(:get, "https://#{host}/rest/v1/activities.json")
215
+ .with(query: { nextPageToken: token })
216
+ .to_return(json_stub(response_stub))
217
+ end
218
+
219
+ it { is_expected.to eq(response_stub) }
220
+ end
221
+
222
+ context 'specifying all options' do
223
+ subject do
224
+ client.get_activities(token, activity_type_ids: activity_type_ids, lead_ids: lead_ids)
225
+ end
226
+
227
+ before do
228
+ stub_request(:get, "https://#{host}/rest/v1/activities.json")
229
+ .with(query: {
230
+ nextPageToken: token,
231
+ activityTypeIds: activity_type_ids.join(','),
232
+ leadIds: lead_ids.join(',')
233
+ })
234
+ .to_return(json_stub(response_stub))
235
+ end
236
+
237
+ it { is_expected.to eq(response_stub) }
238
+ end
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
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