MyPreciousRuby1 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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +92 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.md +13 -0
  7. data/README.md +139 -0
  8. data/Rakefile +1 -0
  9. data/lib/marketingcloudsdk.rb +74 -0
  10. data/lib/marketingcloudsdk/client.rb +296 -0
  11. data/lib/marketingcloudsdk/http_request.rb +118 -0
  12. data/lib/marketingcloudsdk/objects.rb +757 -0
  13. data/lib/marketingcloudsdk/rest.rb +118 -0
  14. data/lib/marketingcloudsdk/soap.rb +282 -0
  15. data/lib/marketingcloudsdk/targeting.rb +99 -0
  16. data/lib/marketingcloudsdk/utils.rb +47 -0
  17. data/lib/marketingcloudsdk/version.rb +39 -0
  18. data/lib/new.rb +1240 -0
  19. data/marketingcloudsdk.gemspec +30 -0
  20. data/samples/sample-AddSubscriberToList.rb +56 -0
  21. data/samples/sample-CreateAndStartDataExtensionImport.rb +29 -0
  22. data/samples/sample-CreateAndStartListImport.rb +27 -0
  23. data/samples/sample-CreateContentAreas.rb +48 -0
  24. data/samples/sample-CreateDataExtensions.rb +54 -0
  25. data/samples/sample-CreateProfileAttributes.rb +48 -0
  26. data/samples/sample-SendEmailToDataExtension.rb +23 -0
  27. data/samples/sample-SendEmailToList.rb +23 -0
  28. data/samples/sample-SendTriggeredSends.rb +30 -0
  29. data/samples/sample-bounceevent.rb +70 -0
  30. data/samples/sample-campaign.rb +211 -0
  31. data/samples/sample-clickevent.rb +71 -0
  32. data/samples/sample-contentarea.rb +122 -0
  33. data/samples/sample-dataextension.rb +209 -0
  34. data/samples/sample-directverb.rb +54 -0
  35. data/samples/sample-email.rb +122 -0
  36. data/samples/sample-email.senddefinition.rb +134 -0
  37. data/samples/sample-folder.rb +143 -0
  38. data/samples/sample-import.rb +103 -0
  39. data/samples/sample-list.rb +105 -0
  40. data/samples/sample-list.subscriber.rb +97 -0
  41. data/samples/sample-openevent.rb +70 -0
  42. data/samples/sample-profileattribute.rb +56 -0
  43. data/samples/sample-sentevent.rb +70 -0
  44. data/samples/sample-subscriber.rb +135 -0
  45. data/samples/sample-triggeredsend.rb +129 -0
  46. data/samples/sample-unsubevent.rb +72 -0
  47. data/samples/sample_helper.rb.template +10 -0
  48. data/spec/client_spec.rb +218 -0
  49. data/spec/default_values_fallback_spec.rb +30 -0
  50. data/spec/helper_funcs_spec.rb +11 -0
  51. data/spec/http_request_spec.rb +61 -0
  52. data/spec/objects_helper_spec.rb +32 -0
  53. data/spec/objects_spec.rb +484 -0
  54. data/spec/rest_spec.rb +48 -0
  55. data/spec/soap_spec.rb +140 -0
  56. data/spec/spec_helper.rb +14 -0
  57. data/spec/targeting_spec.rb +44 -0
  58. metadata +262 -0
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarketingCloudSDK::Client do
4
+
5
+ context 'Empty string REST endpoint, no Auth attribute' do
6
+
7
+ client1 = MarketingCloudSDK::Client.new 'client' => {'id' => '1234', 'secret' => 'ssssh',
8
+ 'base_api_url' => ''}
9
+
10
+ it 'Should use REST endpoint default value if base_api_url endpoint is an empty string in config' do
11
+ expect(client1.base_api_url).to eq 'https://www.exacttargetapis.com'
12
+ end
13
+
14
+ it 'Should use Auth endpoint default value if request_token_url attribute is not in config' do
15
+ expect(client1.request_token_url).to eq 'https://auth.exacttargetapis.com/v1/requestToken'
16
+ end
17
+ end
18
+
19
+ context 'Blank string REST endpoint' do
20
+
21
+ client2 = MarketingCloudSDK::Client.new 'client' => {'id' => '1234', 'secret' => 'ssssh',
22
+ 'base_api_url' => ' '}
23
+
24
+ it 'Should use REST endpoint default value if REST endpoint is a blank string in config' do
25
+ expect(client2.base_api_url).to eq 'https://www.exacttargetapis.com'
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,11 @@
1
+ #require 'spec_helper'
2
+ #
3
+ #describe 'indifferent_access' do
4
+ #
5
+ # it 'returns value when symbol is used to access a string key' do
6
+ # expect( indifferent_access :key, 'key' => true).to be_true
7
+ # end
8
+ # it 'returns value when string is used to access a symbol key' do
9
+ # expect( indifferent_access 'key', :key => true).to be_true
10
+ # end
11
+ #end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'marketingcloudsdk/version'
3
+
4
+ describe MarketingCloudSDK::HTTPRequest do
5
+ let(:client) { Class.new.new.extend MarketingCloudSDK::HTTPRequest }
6
+ subject { client }
7
+ it { should respond_to(:get) }
8
+ it { should respond_to(:post) }
9
+ it { should respond_to(:patch) }
10
+ it { should respond_to(:delete) }
11
+ it { should respond_to(:request) }
12
+
13
+ describe '#get' do
14
+ it 'makes and Net::HTTP::Get request' do
15
+ client.stub(:request).with(Net::HTTP::Get, 'http://some_url', {}).and_return({'success' => 'get'})
16
+ expect(client.get('http://some_url')).to eq 'success' => 'get'
17
+ end
18
+ end
19
+
20
+ describe '#post' do
21
+ describe 'makes and Net::HTTP::Post request' do
22
+
23
+ it 'with only url' do
24
+ Net::HTTP.any_instance.stub(:request)
25
+ client.stub(:request).with(Net::HTTP::Post, 'http://some_url', {}).and_return({'success' => 'post'})
26
+ expect(client.post('http://some_url')).to eq 'success' => 'post'
27
+ end
28
+
29
+ it 'with params' do
30
+ client.stub(:request)
31
+ .with(Net::HTTP::Post, 'http://some_url', {'params' => {'legacy' => 1}})
32
+ .and_return({'success' => 'post'})
33
+ expect(client.post('http://some_url', {'params' => {'legacy' => 1}})).to eq 'success' => 'post'
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#request' do
39
+ it 'should set Authorization header' do
40
+ params = {'access_token' => 'token'}
41
+ Net::HTTP.any_instance.stub(:request)
42
+ get = double("get")
43
+ get.should_receive(:add_field).with('User-Agent', 'FuelSDK-Ruby-v' + MarketingCloudSDK::VERSION)
44
+ get.should_receive(:add_field).with('Authorization', 'Bearer ' + params['access_token'])
45
+ net = double(Net::HTTP::Get)
46
+ net.stub(:new).with(any_args()).and_return(get)
47
+ client.request(net, 'http://some_url', params)
48
+ end
49
+
50
+ it 'should skip setting Authorization header' do
51
+ params = {}
52
+ Net::HTTP.any_instance.stub(:request)
53
+ get = double("get")
54
+ get.should_receive(:add_field).with('User-Agent', 'FuelSDK-Ruby-v' + MarketingCloudSDK::VERSION)
55
+ get.should_not_receive(:add_field).with('Authorization', any_args())
56
+ net = double(Net::HTTP::Get)
57
+ net.stub(:new).with(any_args()).and_return(get)
58
+ client.request(net, 'http://some_url', params)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+
2
+ # Everything will be readable so test for shared from Read behavior
3
+ shared_examples_for 'Soap Read Object' do
4
+ # begin backwards compat
5
+ it { should respond_to :props= }
6
+ it { should respond_to :authStub= }
7
+ # end
8
+ it { should respond_to :id }
9
+ it { should respond_to :properties }
10
+ it { should respond_to :client }
11
+ it { should respond_to :filter }
12
+ it { should respond_to :info }
13
+ it { should respond_to :get }
14
+ end
15
+
16
+ shared_examples_for 'Soap CUD Object' do
17
+ it { should respond_to :post }
18
+ it { should respond_to :patch }
19
+ it { should respond_to :delete }
20
+ end
21
+
22
+ shared_examples_for 'Soap Object' do
23
+ it_behaves_like 'Soap Read Object'
24
+ it_behaves_like 'Soap CUD Object'
25
+ end
26
+
27
+ shared_examples_for 'Soap Read Only Object' do
28
+ it_behaves_like 'Soap Read Object'
29
+ it { should_not respond_to :post }
30
+ it { should_not respond_to :patch }
31
+ it { should_not respond_to :delete }
32
+ end
@@ -0,0 +1,484 @@
1
+ require 'spec_helper.rb'
2
+ require 'objects_helper_spec.rb'
3
+
4
+ describe MarketingCloudSDK::Objects::Base do
5
+
6
+ let(:object) { MarketingCloudSDK::Objects::Base.new }
7
+ subject{ object }
8
+
9
+ describe '#properties' do
10
+ it 'is empty by default' do
11
+ expect(object.properties).to be_nil
12
+ end
13
+
14
+ it 'returns object when assigned an object' do
15
+ object.properties = {'name' => 'value'}
16
+ expect(object.properties).to eq({'name' => 'value'})
17
+ end
18
+
19
+ it 'returns array when assigned array' do
20
+ object.properties = [{'name' => 'value'}]
21
+ expect(object.properties).to eq([{'name' => 'value'}])
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ describe MarketingCloudSDK::BounceEvent do
28
+
29
+ let(:object) { MarketingCloudSDK::BounceEvent.new }
30
+ subject{ object }
31
+
32
+ it_behaves_like 'Soap Read Only Object'
33
+ its(:id){ should eq 'BounceEvent' }
34
+ end
35
+
36
+ describe MarketingCloudSDK::ClickEvent do
37
+
38
+ let(:object) { MarketingCloudSDK::ClickEvent.new }
39
+ subject{ object }
40
+
41
+ it_behaves_like 'Soap Read Only Object'
42
+ its(:id){ should eq 'ClickEvent' }
43
+ end
44
+
45
+ describe MarketingCloudSDK::ContentArea do
46
+
47
+ let(:object) { MarketingCloudSDK::ContentArea.new }
48
+ subject{ object }
49
+
50
+ it_behaves_like 'Soap Object'
51
+ its(:id){ should eq 'ContentArea' }
52
+ end
53
+
54
+ describe MarketingCloudSDK::DataFolder do
55
+
56
+ let(:object) { MarketingCloudSDK::DataFolder.new }
57
+ subject{ object }
58
+
59
+ it_behaves_like 'Soap Object'
60
+ its(:id){ should eq 'DataFolder' }
61
+ end
62
+
63
+ describe MarketingCloudSDK::Folder do
64
+
65
+ let(:object) { MarketingCloudSDK::Folder.new }
66
+ subject{ object }
67
+
68
+ it_behaves_like 'Soap Object'
69
+ its(:id){ should eq 'DataFolder' }
70
+ end
71
+
72
+ describe MarketingCloudSDK::Email do
73
+
74
+ let(:object) { MarketingCloudSDK::Email.new }
75
+ subject{ object }
76
+
77
+ it_behaves_like 'Soap Object'
78
+ its(:id){ should eq 'Email' }
79
+ end
80
+
81
+ describe MarketingCloudSDK::List do
82
+
83
+ let(:object) { MarketingCloudSDK::List.new }
84
+ subject{ object }
85
+
86
+ it_behaves_like 'Soap Object'
87
+ its(:id){ should eq 'List' }
88
+ end
89
+
90
+ describe MarketingCloudSDK::List::Subscriber do
91
+
92
+ let(:object) { MarketingCloudSDK::List::Subscriber.new }
93
+ subject{ object }
94
+
95
+ it_behaves_like 'Soap Read Only Object'
96
+ its(:id){ should eq 'ListSubscriber' }
97
+ end
98
+
99
+ describe MarketingCloudSDK::OpenEvent do
100
+
101
+ let(:object) { MarketingCloudSDK::OpenEvent.new }
102
+ subject{ object }
103
+
104
+ it_behaves_like 'Soap Read Only Object'
105
+ its(:id){ should eq 'OpenEvent' }
106
+ end
107
+
108
+ describe MarketingCloudSDK::SentEvent do
109
+
110
+ let(:object) { MarketingCloudSDK::SentEvent.new }
111
+ subject{ object }
112
+
113
+ it_behaves_like 'Soap Read Only Object'
114
+ its(:id){ should eq 'SentEvent' }
115
+ end
116
+
117
+ describe MarketingCloudSDK::Subscriber do
118
+
119
+ let(:object) { MarketingCloudSDK::Subscriber.new }
120
+ subject{ object }
121
+
122
+ it_behaves_like 'Soap Object'
123
+ its(:id){ should eq 'Subscriber' }
124
+ end
125
+
126
+ describe MarketingCloudSDK::DataExtension::Column do
127
+
128
+ let(:object) { MarketingCloudSDK::DataExtension::Column.new }
129
+ subject{ object }
130
+
131
+ it_behaves_like 'Soap Read Only Object'
132
+ its(:id){ should eq 'DataExtensionField' }
133
+ end
134
+
135
+ describe MarketingCloudSDK::DataExtension do
136
+ let(:object) { MarketingCloudSDK::DataExtension.new }
137
+ subject{ object }
138
+
139
+ it_behaves_like 'Soap Object'
140
+ its(:id){ should eq 'DataExtension' }
141
+ it { should respond_to :columns= }
142
+ it { should respond_to :fields }
143
+ it { should respond_to :fields= }
144
+
145
+ describe '#post' do
146
+ subject {
147
+ object.stub_chain(:client,:soap_post) do |id, properties|
148
+ [id, properties]
149
+ end
150
+ object.stub_chain(:client,:package_name).and_return(nil)
151
+ object.stub_chain(:client,:package_folders).and_return(nil)
152
+
153
+ object
154
+ }
155
+
156
+ # maybe one day will make it smart enough to zip properties and fields if count is same?
157
+ it 'raises an error when it has a list of properties and fields' do
158
+ subject.fields = [{'Name' => 'Name'}]
159
+ subject.properties = [{'Name' => 'Some DE'}, {'Name' => 'Some DE'}]
160
+ expect{subject.post}.to raise_error(
161
+ 'Unable to handle muliple DataExtension definitions and a field definition')
162
+ end
163
+
164
+ it 'fields must be empty if not nil' do
165
+ subject.fields = []
166
+ subject.properties = {'Name' => 'Some DE', 'fields' => [{'Name' => 'A field'}]}
167
+ expect(subject.post).to eq(
168
+ [
169
+ 'DataExtension',
170
+ {
171
+ 'Name' => 'Some DE',
172
+ 'Fields' => {
173
+ 'Field' => [{'Name' => 'A field'}]
174
+ }
175
+ }
176
+ ])
177
+ end
178
+
179
+ it 'DataExtension can be created using properties and fields accessors' do
180
+ subject.fields = [{'Name' => 'A field'}]
181
+ subject.properties = {'Name' => 'Some DE'}
182
+ expect(subject.post).to eq(
183
+ [
184
+ 'DataExtension',
185
+ {
186
+ 'Name' => 'Some DE',
187
+ 'Fields' => {
188
+ 'Field' => [{'Name' => 'A field'}]
189
+ }
190
+ }
191
+ ])
192
+ end
193
+
194
+ it 'DataExtension fields can be apart of the DataExtention properties' do
195
+ subject.properties = [{'Name' => 'Some DE', 'Fields' => {'Field' => [{'Name' => 'A field'}]}}]
196
+ expect(subject.post).to eq(
197
+ [
198
+ 'DataExtension',
199
+ [{
200
+ 'Name' => 'Some DE',
201
+ 'Fields' => {
202
+ 'Field' => [{'Name' => 'A field'}]
203
+ }
204
+ }]
205
+ ])
206
+ end
207
+
208
+ it 'List of DataExtension definitions can be passed' do
209
+ subject.properties = [{'Name' => 'Some DE', 'Fields' => {'Field' => [{'Name' => 'A field'}]}},
210
+ {'Name' => 'Another DE', 'Fields' => {'Field' => [{'Name' => 'A second field'}]}}]
211
+ expect(subject.post).to eq(
212
+ [
213
+ 'DataExtension',
214
+ [{
215
+ 'Name' => 'Some DE',
216
+ 'Fields' => {
217
+ 'Field' => [{'Name' => 'A field'}]
218
+ }
219
+ },{
220
+ 'Name' => 'Another DE',
221
+ 'Fields' => {
222
+ 'Field' => [{'Name' => 'A second field'}]
223
+ }
224
+ }]
225
+ ])
226
+ end
227
+
228
+ it 'DataExtension definitions will translate fields entry to correct format' do
229
+ subject.properties = {'Name' => 'Some DE', 'fields' => [{'Name' => 'A field'}]}
230
+ expect(subject.post).to eq(
231
+ [
232
+ 'DataExtension',
233
+ {
234
+ 'Name' => 'Some DE',
235
+ 'Fields' => {
236
+ 'Field' => [{'Name' => 'A field'}]
237
+ }
238
+ }
239
+ ])
240
+ end
241
+
242
+ it 'DataExtension definitions will translate columns entry to correct format' do
243
+ subject.properties = {'Name' => 'Some DE', 'columns' => [{'Name' => 'A field'}]}
244
+ expect(subject.post).to eq(
245
+ [
246
+ 'DataExtension',
247
+ {
248
+ 'Name' => 'Some DE',
249
+ 'Fields' => {
250
+ 'Field' => [{'Name' => 'A field'}]
251
+ }
252
+ }
253
+ ])
254
+ end
255
+
256
+ it 'supports columns attribute for a single DataExtension definition' do
257
+ subject.columns = [{'Name' => 'A field'}]
258
+ subject.properties = [{'Name' => 'Some DE'}]
259
+ expect(subject.post).to eq(
260
+ [
261
+ 'DataExtension',
262
+ [{
263
+ 'Name' => 'Some DE',
264
+ 'Fields' => {
265
+ 'Field' => [{'Name' => 'A field'}]
266
+ }
267
+ }]
268
+ ])
269
+ end
270
+
271
+ describe 'fields are defined twice' do
272
+ it 'when defined in properties and by fields' do
273
+ subject.fields = [{'Name' => 'A field'}]
274
+ subject.properties = [{'Name' => 'Some DE', 'Fields' => {'Field' => [{'Name' => 'A field'}]}}]
275
+ expect{subject.post}.to raise_error 'Fields are defined in too many ways. Please only define once.'
276
+ end
277
+ it 'when defined in properties explicitly and with columns key' do
278
+ subject.properties =[{'Name' => 'Some DE',
279
+ 'columns' => [{'Name' => 'A fields'}],
280
+ 'Fields' => {'Field' => [{'Name' => 'A field'}]
281
+ }}]
282
+ expect{subject.post}.to raise_error 'Fields are defined in too many ways. Please only define once.'
283
+ end
284
+ it 'when defined in properties explicitly and with fields key' do
285
+ subject.properties = [{'Name' => 'Some DE',
286
+ 'fields' => [{'Name' => 'A fields'}],
287
+ 'Fields' => {'Field' => [{'Name' => 'A field'}]
288
+ }}]
289
+ expect{subject.post}.to raise_error 'Fields are defined in too many ways. Please only define once.'
290
+ end
291
+ it 'when defined in with fields and colums key' do
292
+ subject.properties = [{'Name' => 'Some DE',
293
+ 'fields' => [{'Name' => 'A fields'}],
294
+ 'columns' => [{'Name' => 'A field'}]
295
+ }]
296
+ expect{subject.post}.to raise_error 'Fields are defined in too many ways. Please only define once.'
297
+ end
298
+ it 'when defined in with fields key and accessor' do
299
+ subject.fields = [{'Name' => 'A field'}]
300
+ subject.properties = [{'Name' => 'Some DE',
301
+ 'fields' => [{'Name' => 'A fields'}]
302
+ }]
303
+ expect{subject.post}.to raise_error 'Fields are defined in too many ways. Please only define once.'
304
+ end
305
+ end
306
+ end
307
+
308
+ describe '#patch' do
309
+ subject {
310
+ object.stub_chain(:client, :soap_patch) do |id, properties|
311
+ [id, properties]
312
+ end
313
+
314
+ object
315
+ }
316
+
317
+ it 'DataExtension can be created using properties and fields accessors' do
318
+ subject.fields = [{'Name' => 'A field'}]
319
+ subject.properties = {'Name' => 'Some DE'}
320
+ expect(subject.patch).to eq(
321
+ [
322
+ 'DataExtension',
323
+ {
324
+ 'Name' => 'Some DE',
325
+ 'Fields' => {
326
+ 'Field' => [{'Name' => 'A field'}]
327
+ }
328
+ }
329
+ ])
330
+ end
331
+ end
332
+ end
333
+
334
+ describe MarketingCloudSDK::DataExtension::Row do
335
+ let(:object) { MarketingCloudSDK::DataExtension::Row.new }
336
+ subject{ object }
337
+
338
+ it_behaves_like 'Soap Object'
339
+ its(:id){ should eq 'DataExtensionObject' }
340
+ it { should respond_to :name }
341
+ it { should respond_to :name= }
342
+ it { should respond_to :customer_key }
343
+ it { should respond_to :customer_key= }
344
+
345
+ describe '#name' do
346
+ it 'raises error when missing both name and customer key' do
347
+ expect{ subject.name }.to raise_error('Unable to process DataExtension::Row '\
348
+ 'request due to missing CustomerKey and Name')
349
+ end
350
+
351
+ it 'returns value' do
352
+ subject.name = 'name'
353
+ expect( subject.name ).to eq 'name'
354
+ end
355
+ end
356
+
357
+ describe '#customer_key' do
358
+ it 'raises error when missing both name and customer key' do
359
+ expect{ subject.customer_key }.to raise_error('Unable to process DataExtension::Row '\
360
+ 'request due to missing CustomerKey and Name')
361
+ end
362
+
363
+ it 'returns value' do
364
+ subject.customer_key = 'key'
365
+ expect( subject.customer_key ).to eq 'key'
366
+ end
367
+ end
368
+
369
+ describe '#retrieve_required' do
370
+ it 'raises error when missing both name and customer key' do
371
+ expect{ subject.send(:retrieve_required)}.to raise_error('Unable to process DataExtension::Row '\
372
+ 'request due to missing CustomerKey and Name')
373
+ expect{ subject.name }.to raise_error('Unable to process DataExtension::Row '\
374
+ 'request due to missing CustomerKey and Name')
375
+ end
376
+
377
+ it 'updates missing' do
378
+ rsp = double(MarketingCloudSDK::SoapResponse)
379
+ rsp.stub(:results).and_return([{:name => 'Products', :customer_key => 'ProductsKey'}])
380
+ rsp.stub(:success?).and_return true
381
+
382
+ subject.stub_chain(:client,:soap_get).and_return(rsp)
383
+ subject.name = 'Not Nil'
384
+
385
+ # this really wouldn't work this way. name shouldn't be updated since its whats being used for filter,
386
+ # but its a good test to show retrieve_required being fired
387
+ expect(subject.name).to eq 'Not Nil' # not fired
388
+ expect(subject.customer_key).to eq 'ProductsKey' # fired... stubbed get returns customer_key and name for update
389
+ expect(subject.name).to eq 'Products' # returned name
390
+ end
391
+ end
392
+
393
+ describe '#get' do
394
+ subject {
395
+ object.stub_chain(:client, :soap_get) do |id, properties, filter|
396
+ [id, properties, filter]
397
+ end
398
+
399
+ object
400
+ }
401
+
402
+ it 'passes id including name to super get' do
403
+ subject.name = 'Justin'
404
+ expect(subject.get).to eq(['DataExtensionObject[Justin]', nil, nil])
405
+ end
406
+ end
407
+
408
+ describe '#post' do
409
+ subject {
410
+ object.stub_chain(:client, :soap_post) do |id, properties|
411
+ [id, properties]
412
+ end
413
+
414
+ object
415
+ }
416
+
417
+ it 'raises an error when missing both name and customer key' do
418
+ subject.properties = [{'Name' => 'Some DE'}, {'Name' => 'Some DE'}]
419
+ expect{subject.post}.to raise_error('Unable to process DataExtension::Row ' \
420
+ 'request due to missing CustomerKey and Name')
421
+ end
422
+
423
+ it 'uses explicitly defined properties' do
424
+ subject.properties = [{'CustomerKey' => 'Subscribers',
425
+ 'Properties' => {'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
426
+ expect(subject.post).to eq([
427
+ 'DataExtensionObject', [{
428
+ 'CustomerKey' => 'Subscribers',
429
+ 'Properties' => {'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
430
+ ])
431
+ end
432
+
433
+ it 'inserts customer key into properties when set using accessor' do
434
+ subject.customer_key = 'Subscribers'
435
+ subject.properties = [{'Properties' => {
436
+ 'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
437
+ expect(subject.post).to eq([
438
+ 'DataExtensionObject', [{
439
+ 'CustomerKey' => 'Subscribers',
440
+ 'Properties' => {'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
441
+ ])
442
+ end
443
+
444
+ it 'uses name to get customer key for inseration' do
445
+ subject.name = 'Subscribers'
446
+
447
+ rsp = double(MarketingCloudSDK::SoapResponse)
448
+ rsp.stub(:results).and_return([{:name => 'Products', :customer_key => 'ProductsKey'}])
449
+ rsp.stub(:success?).and_return true
450
+
451
+ subject.stub_chain(:client, :soap_get).and_return(rsp)
452
+ subject.properties = [{'Properties' => {
453
+ 'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
454
+
455
+ expect(subject.post).to eq([
456
+ 'DataExtensionObject', [{
457
+ 'CustomerKey' => 'ProductsKey',
458
+ 'Properties' => {'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
459
+ ])
460
+ end
461
+
462
+ it 'correctly formats array property' do
463
+ subject.customer_key = 'Subscribers'
464
+
465
+ subject.properties = [{'Name' => 'Justin'}]
466
+
467
+ expect(subject.post).to eq([
468
+ 'DataExtensionObject', [{
469
+ 'CustomerKey' => 'Subscribers',
470
+ 'Properties' => {'Property' => [{'Name' => 'Name', 'Value' => 'Justin'}]}}]
471
+ ])
472
+ end
473
+ end
474
+ end
475
+
476
+ # verify backward compats
477
+ describe ET_Subscriber do
478
+
479
+ let(:object) { ET_Subscriber.new }
480
+ subject{ object }
481
+
482
+ it_behaves_like 'Soap Object'
483
+ its(:id){ should eq 'Subscriber' }
484
+ end