eloqua 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/.gitignore +11 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +21 -0
- data/README.md +245 -0
- data/Rakefile +13 -0
- data/TODO.md +8 -0
- data/eloqua.gemspec +32 -0
- data/eloqua_initializer.tpl.rb +3 -0
- data/lib/eloqua.rb +51 -0
- data/lib/eloqua/api.rb +119 -0
- data/lib/eloqua/api/action.rb +41 -0
- data/lib/eloqua/api/service.rb +240 -0
- data/lib/eloqua/asset.rb +31 -0
- data/lib/eloqua/builder/templates.rb +31 -0
- data/lib/eloqua/builder/xml.rb +129 -0
- data/lib/eloqua/entity.rb +72 -0
- data/lib/eloqua/exceptions.rb +5 -0
- data/lib/eloqua/helper/attribute_map.rb +78 -0
- data/lib/eloqua/query.rb +291 -0
- data/lib/eloqua/remote_object.rb +274 -0
- data/lib/eloqua/version.rb +3 -0
- data/lib/eloqua/wsdl/action.wsdl +1 -0
- data/lib/eloqua/wsdl/data.wsdl +1 -0
- data/lib/eloqua/wsdl/email.wsdl +1 -0
- data/lib/eloqua/wsdl/service.wsdl +1 -0
- data/lib/tasks/test.rake +24 -0
- data/rspec.watchr +74 -0
- data/spec/fixtures/add_group_member/success.xml +18 -0
- data/spec/fixtures/create/contact_duplicate.xml +30 -0
- data/spec/fixtures/create/contact_success.xml +25 -0
- data/spec/fixtures/create_asset/failure.xml +30 -0
- data/spec/fixtures/create_asset/group_success.xml +25 -0
- data/spec/fixtures/delete_asset/access_deny.xml +31 -0
- data/spec/fixtures/describe_asset/success.xml +72 -0
- data/spec/fixtures/describe_asset_type/success.xml +23 -0
- data/spec/fixtures/describe_entity/success.xml +54 -0
- data/spec/fixtures/describe_entity_type/success.xml +45 -0
- data/spec/fixtures/get_member_count_in_step_by_status/success.xml +15 -0
- data/spec/fixtures/list_asset_types/success.xml +28 -0
- data/spec/fixtures/list_entity_types/success.xml +21 -0
- data/spec/fixtures/list_group_membership/success.xml +25 -0
- data/spec/fixtures/list_members_in_step_by_status/success.xml +15 -0
- data/spec/fixtures/query/contact_email_one.xml +38 -0
- data/spec/fixtures/query/contact_email_two.xml +56 -0
- data/spec/fixtures/query/contact_missing.xml +19 -0
- data/spec/fixtures/query/fault.xml +43 -0
- data/spec/fixtures/remove_group_member/success.xml +18 -0
- data/spec/fixtures/retrieve/contact_missing.xml +17 -0
- data/spec/fixtures/retrieve/contact_multiple.xml +3460 -0
- data/spec/fixtures/retrieve/contact_single.xml +38 -0
- data/spec/fixtures/retrieve_asset/failure.xml +17 -0
- data/spec/fixtures/retrieve_asset/success.xml +50 -0
- data/spec/fixtures/update/contact_success.xml +26 -0
- data/spec/lib/eloqua/api/action_spec.rb +36 -0
- data/spec/lib/eloqua/api/service_spec.rb +498 -0
- data/spec/lib/eloqua/api_spec.rb +133 -0
- data/spec/lib/eloqua/asset_spec.rb +63 -0
- data/spec/lib/eloqua/builder/templates_spec.rb +68 -0
- data/spec/lib/eloqua/builder/xml_spec.rb +254 -0
- data/spec/lib/eloqua/entity_spec.rb +224 -0
- data/spec/lib/eloqua/helper/attribute_map_spec.rb +14 -0
- data/spec/lib/eloqua/query_spec.rb +596 -0
- data/spec/lib/eloqua/remote_object_spec.rb +742 -0
- data/spec/lib/eloqua_spec.rb +171 -0
- data/spec/shared/attribute_map.rb +173 -0
- data/spec/shared/class_to_api_delegation.rb +50 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/helper.rb +73 -0
- metadata +366 -0
@@ -0,0 +1,742 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'remote operation that converts attribute values' do |operation|
|
4
|
+
|
5
|
+
let(:method) { "#{operation}_object".to_sym }
|
6
|
+
|
7
|
+
let(:klass) do
|
8
|
+
Class.new(subject) do
|
9
|
+
map :C_California1 => :california
|
10
|
+
attr_checkbox(:california)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when #{operation.to_s.pluralize} object" do
|
15
|
+
it 'should convert value before saving' do
|
16
|
+
if(operation == :update)
|
17
|
+
object = klass.new(:id => 1)
|
18
|
+
flexmock(object.class).should_receive(method).\
|
19
|
+
with(1, {'C_California1' => 'Yes'}).once
|
20
|
+
else
|
21
|
+
object = klass.new
|
22
|
+
flexmock(object.class).should_receive(method).\
|
23
|
+
with({'C_California1' => 'Yes'}).once
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
object.california = true
|
28
|
+
object.save
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
shared_examples_for "class method delegates to set_callback" do |method, callback, state|
|
35
|
+
|
36
|
+
context "#self.#{method}" do
|
37
|
+
|
38
|
+
it "should delegate to set_callback #{callback}, #{state}, &block" do
|
39
|
+
block = Proc.new {}
|
40
|
+
klass = flexmock(subject)
|
41
|
+
klass.should_receive(:set_callback).with(callback, state, block).once
|
42
|
+
klass.send(method, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
it "should be able to set a symbol as the final argument for a method" do
|
47
|
+
callback_method = :object_id
|
48
|
+
|
49
|
+
klass = flexmock(subject)
|
50
|
+
klass.should_receive(:set_callback).with(callback, state, callback_method).once
|
51
|
+
klass.send(method, callback_method)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe Eloqua::RemoteObject do
|
59
|
+
|
60
|
+
subject do
|
61
|
+
Class.new(Eloqua::RemoteObject) do
|
62
|
+
self.remote_type = Eloqua::Api.remote_type('Contact')
|
63
|
+
self.remote_group = :entity
|
64
|
+
|
65
|
+
attr_accessor :callbacks_called
|
66
|
+
attr_accessor :test_callbacks
|
67
|
+
|
68
|
+
def test_callback(type, state, &block)
|
69
|
+
class_eval do
|
70
|
+
set_callback(type, state, &block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
[:save, :update, :create].each do |callback_type|
|
75
|
+
[:before, :after].each do |callback_state|
|
76
|
+
set_callback(callback_type, callback_state) do
|
77
|
+
self.callbacks_called ||= {}
|
78
|
+
self.callbacks_called[callback_type] ||= []
|
79
|
+
self.callbacks_called[callback_type] << callback_state
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.name
|
85
|
+
'ContactEntity'
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:remote_type) do
|
92
|
+
subject.api.remote_type('Contact')
|
93
|
+
end
|
94
|
+
|
95
|
+
it_behaves_like 'uses attribute map'
|
96
|
+
it_behaves_like 'class level delegation of remote operations for', :entity
|
97
|
+
|
98
|
+
[:save, :update, :create].each do |callback_type|
|
99
|
+
[:before, :after].each do |callback_state|
|
100
|
+
it_behaves_like "class method delegates to set_callback",
|
101
|
+
"#{callback_state}_#{callback_type}".to_sym, callback_type, callback_state
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "#self.remote_group" do
|
106
|
+
specify { subject.remote_group.should == :entity }
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
context "#initialize" do
|
111
|
+
|
112
|
+
context "when :remote" do
|
113
|
+
before do
|
114
|
+
@class = Class.new(subject) do
|
115
|
+
map :ContactID => :id
|
116
|
+
map :C_EmailAddress => :email
|
117
|
+
attr_checkbox :california, :arizona
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:input) do
|
122
|
+
{
|
123
|
+
:C_EmailAddress => 'email@address.com',
|
124
|
+
:ContactID => '1',
|
125
|
+
:normal_id => 'wow',
|
126
|
+
:C_California => 'Yes',
|
127
|
+
:C_Arizona => 'No'
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
let(:expected) do
|
132
|
+
{
|
133
|
+
:email => 'email@address.com',
|
134
|
+
:id => '1',
|
135
|
+
:normal_id => 'wow',
|
136
|
+
:california => true,
|
137
|
+
:arizona => false
|
138
|
+
}.with_indifferent_access
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should map objects for adding them to #attributes' do
|
142
|
+
object = @class.new(input, :remote) # true is remote == true
|
143
|
+
object.attributes.should == expected
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
context "#reload" do
|
154
|
+
|
155
|
+
let(:new_attr) { {:C_EmailAddress => 'new'} }
|
156
|
+
|
157
|
+
before do
|
158
|
+
flexmock(subject).should_receive(:find_object, 1).\
|
159
|
+
and_return(new_attr).\
|
160
|
+
once
|
161
|
+
|
162
|
+
@object = subject.new({:id => 1, :C_EmailAddress => 'old'}, :remote)
|
163
|
+
@object.reload
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should have updated email to new' do
|
167
|
+
@object.email_address.should == 'new'
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should not be dirty' do
|
171
|
+
@object.attribute_changed?(:email_address).should be_false
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
context '#persisted?' do
|
177
|
+
|
178
|
+
it 'should be false when created with new' do
|
179
|
+
subject.new.should_not be_persisted
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should be true when initializing with id' do
|
183
|
+
subject.new(:id => '1').should be_persisted
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'when initialized with :remote' do
|
187
|
+
it 'should be considered persisted' do
|
188
|
+
subject.new({:C_EmailAddress => 'email'}, :remote).should be_persisted
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "#valid?" do
|
194
|
+
let(:klass) do
|
195
|
+
Class.new(subject) do
|
196
|
+
map :C_EmailAddress => :email
|
197
|
+
validates_presence_of :email
|
198
|
+
|
199
|
+
def self.name
|
200
|
+
'Contact'
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'when valid' do
|
207
|
+
|
208
|
+
before do
|
209
|
+
@object = klass.new(:email => 'wow')
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should be valid?' do
|
213
|
+
@object.should be_valid
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should not have any errors' do
|
217
|
+
@object.valid?
|
218
|
+
@object.errors[:email].should be_empty
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'when invalid' do
|
224
|
+
|
225
|
+
before do
|
226
|
+
@object = klass.new()
|
227
|
+
@results = @object.valid?
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should be invalid?' do
|
231
|
+
@object.should be_invalid
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should have errors on :email' do
|
235
|
+
@object.errors[:email].should_not be_empty
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
context "#read_attribute" do
|
243
|
+
let(:object) { subject.new(:email => 'address') }
|
244
|
+
specify { object.read_attribute(:email).should == 'address' }
|
245
|
+
end
|
246
|
+
|
247
|
+
context '#write_attribute' do
|
248
|
+
let(:object) { subject.new(:email => 'address') }
|
249
|
+
|
250
|
+
it 'should set attribute' do
|
251
|
+
object.write_attribute(:email, 'test')
|
252
|
+
object.attributes[:email].should == 'test'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context "#is_attribute_method?" do
|
257
|
+
|
258
|
+
let(:object) { subject.new(:email => 'address') }
|
259
|
+
|
260
|
+
it 'should return true for writers' do
|
261
|
+
object.is_attribute_method?(:email=).should == :write
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should return true for readers' do
|
265
|
+
object.is_attribute_method?(:email).should == :read
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should not return true for missing attrs' do
|
269
|
+
object.attributes.delete(:email)
|
270
|
+
object.is_attribute_method?(:email).should be_false
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
context "when calling attribute method without concrete definition" do
|
276
|
+
|
277
|
+
let(:klass) do
|
278
|
+
Class.new(subject) do
|
279
|
+
map :C_EmailAddress => 'email'
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
let(:object) do
|
285
|
+
klass.new({:C_EmailAddress => 'james@lightsofapollo.com'}, :remote)
|
286
|
+
end
|
287
|
+
|
288
|
+
specify { object.respond_to?(:email) }
|
289
|
+
specify { object.respond_to?(:email=) }
|
290
|
+
|
291
|
+
it 'should allow us to access attributes via accessors (email)' do
|
292
|
+
object.email.should == 'james@lightsofapollo.com'
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should allow us to alter email via email=' do
|
296
|
+
object.email = 'newemail'
|
297
|
+
object.email.should == 'newemail'
|
298
|
+
object.attributes[:email].should == 'newemail'
|
299
|
+
end
|
300
|
+
|
301
|
+
context 'when initalizing empty object' do
|
302
|
+
let(:object) { klass.new }
|
303
|
+
|
304
|
+
it 'should respond to mapped attribute email' do
|
305
|
+
object.respond_to?(:email).should be_true
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should allow us to set and read attribute' do
|
309
|
+
object.email = 'email'
|
310
|
+
object.email.should == 'email'
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
context 'dirty attributes' do
|
318
|
+
|
319
|
+
let(:klass) do
|
320
|
+
Class.new(subject) do
|
321
|
+
map :C_EmailAddress => :email
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
let(:object) do
|
326
|
+
klass.new
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'should call attribute_will_change! when using attribute_write' do
|
330
|
+
flexmock(object).should_receive(:attribute_will_change!).with("email").once
|
331
|
+
object.email = 'email'
|
332
|
+
end
|
333
|
+
|
334
|
+
context 'when email has changed' do
|
335
|
+
before do
|
336
|
+
object.email = 'old'
|
337
|
+
object.email = 'new'
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'should have old value available via attribute_was' do
|
341
|
+
object.attribute_was(:email).should == 'old'
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'should have old and new value available via attribue_change' do
|
345
|
+
object.attribute_change(:email).should == ['old', 'new']
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'should provide a list of all changed attributes via changed' do
|
349
|
+
object.changed.should == ['email']
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when persisting object" do
|
355
|
+
let(:input) do
|
356
|
+
{:email => 'email', :name => 'first'}
|
357
|
+
end
|
358
|
+
|
359
|
+
let(:klass) do
|
360
|
+
Class.new(subject) do
|
361
|
+
map :C_EmailAddress => :email
|
362
|
+
map :C_FirstName => :name
|
363
|
+
map :ContactID => :id
|
364
|
+
|
365
|
+
validates_presence_of :email
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
let(:object) { klass.new(:id => 1) }
|
370
|
+
|
371
|
+
let(:expected) do
|
372
|
+
{
|
373
|
+
:C_EmailAddress => 'email',
|
374
|
+
:C_FirstName => 'first'
|
375
|
+
}.with_indifferent_access
|
376
|
+
end
|
377
|
+
|
378
|
+
|
379
|
+
it_behaves_like 'remote operation that converts attribute values', :update
|
380
|
+
|
381
|
+
|
382
|
+
context "#update" do
|
383
|
+
|
384
|
+
before do
|
385
|
+
flexmock(klass).should_receive(:update_object).\
|
386
|
+
with(1, expected).and_return(true)
|
387
|
+
|
388
|
+
object.email = 'email'
|
389
|
+
object.name = 'first'
|
390
|
+
|
391
|
+
@result = object.update
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should have called before and after callbacks for update" do
|
395
|
+
object.callbacks_called[:update].should == [:before, :after]
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'should call update entity to make the api call' do
|
399
|
+
@result.should be_true
|
400
|
+
end
|
401
|
+
|
402
|
+
specify { object.email.should == 'email' }
|
403
|
+
specify { object.name.should == 'first' }
|
404
|
+
end
|
405
|
+
|
406
|
+
|
407
|
+
it_behaves_like 'remote operation that converts attribute values', :create
|
408
|
+
|
409
|
+
context "#create" do
|
410
|
+
context "when successfully creating record" do
|
411
|
+
let(:object) { klass.new }
|
412
|
+
|
413
|
+
before do
|
414
|
+
flexmock(klass).should_receive(:create_object).\
|
415
|
+
with(expected).and_return({:id => 1})
|
416
|
+
|
417
|
+
object.email = 'email'
|
418
|
+
object.name = 'first'
|
419
|
+
@result = object.create
|
420
|
+
end
|
421
|
+
|
422
|
+
it "should call before and after callbacks" do
|
423
|
+
object.callbacks_called[:create].should == [:before, :after]
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'should call update entity to make the api call' do
|
427
|
+
@result.should be_true
|
428
|
+
end
|
429
|
+
|
430
|
+
specify { object.id.should == 1 }
|
431
|
+
specify { object.email.should == 'email' }
|
432
|
+
specify { object.name.should == 'first' }
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "#save" do
|
437
|
+
|
438
|
+
context 'when save will create' do
|
439
|
+
let(:object) do
|
440
|
+
klass.new(:email => 'james@lightsofapollo.com')
|
441
|
+
end
|
442
|
+
|
443
|
+
before do
|
444
|
+
flexmock(klass).should_receive(:create_object).\
|
445
|
+
with({'C_EmailAddress' => 'james@lightsofapollo.com'}).\
|
446
|
+
and_return({:id => 1}).once
|
447
|
+
object.save
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'should now be persisted?' do
|
451
|
+
object.should be_persisted
|
452
|
+
end
|
453
|
+
|
454
|
+
it 'should now have an id' do
|
455
|
+
object.id.should == 1
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should call before and after callbacks" do
|
459
|
+
object.callbacks_called[:save].should == [:before, :after]
|
460
|
+
end
|
461
|
+
|
462
|
+
end
|
463
|
+
|
464
|
+
context 'when save will update' do
|
465
|
+
|
466
|
+
let(:object) do
|
467
|
+
klass.new(:id => 1, :email => 'james@lightsofapollo.com')
|
468
|
+
end
|
469
|
+
|
470
|
+
before do
|
471
|
+
flexmock(klass).should_receive(:update_object).\
|
472
|
+
with(1, {'C_EmailAddress' => 'new'}).\
|
473
|
+
and_return(true).once
|
474
|
+
|
475
|
+
object.email = 'new'
|
476
|
+
object.save
|
477
|
+
end
|
478
|
+
|
479
|
+
it 'should now be persisted?' do
|
480
|
+
object.should be_persisted
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should have updated email address to "new"' do
|
484
|
+
object.email.should == 'new'
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|
488
|
+
|
489
|
+
context "when record is invalid" do
|
490
|
+
|
491
|
+
let(:object) do
|
492
|
+
klass.new(:id => 1)
|
493
|
+
end
|
494
|
+
|
495
|
+
it "should not have called any callbacks" do
|
496
|
+
object.callbacks_called.should be_nil
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'should not be valid' do
|
500
|
+
object.should_not be_valid
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'should return false when saving' do
|
504
|
+
object.save.should be_false
|
505
|
+
end
|
506
|
+
|
507
|
+
end
|
508
|
+
|
509
|
+
end
|
510
|
+
|
511
|
+
context "#update_attributes" do
|
512
|
+
|
513
|
+
context "when successfuly updating the record and ignoring sanitization" do
|
514
|
+
let(:klass) do
|
515
|
+
Class.new(subject) do
|
516
|
+
map :C_EmailAddress => :email
|
517
|
+
map :C_FirstName => :name
|
518
|
+
map :ContactID => :id
|
519
|
+
|
520
|
+
attr_accessible :email
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
let(:object) { klass.new(:id => 1, :name => 'james') }
|
525
|
+
|
526
|
+
before do
|
527
|
+
flexmock(klass).should_receive(:update_object).\
|
528
|
+
with(1, {'C_EmailAddress' => 'new', 'C_FirstName' => 'gomez'}).\
|
529
|
+
and_return(true)
|
530
|
+
|
531
|
+
@result = object.update_attributes({
|
532
|
+
:email => 'new',
|
533
|
+
:name => 'gomez'
|
534
|
+
}, true)
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'should call update entity to make the api call' do
|
538
|
+
@result.should be_true
|
539
|
+
end
|
540
|
+
|
541
|
+
specify { object.email.should == 'new' }
|
542
|
+
specify { object.name.should == 'gomez' }
|
543
|
+
|
544
|
+
end
|
545
|
+
|
546
|
+
context "when successfuly updating record" do
|
547
|
+
let(:klass) do
|
548
|
+
Class.new(subject) do
|
549
|
+
map :C_EmailAddress => :email
|
550
|
+
map :C_FirstName => :name
|
551
|
+
map :ContactID => :id
|
552
|
+
|
553
|
+
attr_accessible :email
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
let(:object) { klass.new(:id => 1, :name => 'james') }
|
558
|
+
|
559
|
+
let(:expected) do
|
560
|
+
{
|
561
|
+
:email => 'email',
|
562
|
+
}.with_indifferent_access
|
563
|
+
end
|
564
|
+
|
565
|
+
before do
|
566
|
+
flexmock(klass).should_receive(:update_object).\
|
567
|
+
with(1, {'C_EmailAddress' => 'email'}).and_return(true)
|
568
|
+
|
569
|
+
@result = object.update_attributes(input)
|
570
|
+
end
|
571
|
+
|
572
|
+
it 'should call update entity to make the api call' do
|
573
|
+
@result.should be_true
|
574
|
+
end
|
575
|
+
|
576
|
+
specify { object.email.should == 'email' }
|
577
|
+
specify { object.name.should == 'james' }
|
578
|
+
|
579
|
+
end
|
580
|
+
|
581
|
+
|
582
|
+
context 'when updating attributes of invalid object' do
|
583
|
+
|
584
|
+
let(:input) do
|
585
|
+
{}
|
586
|
+
end
|
587
|
+
|
588
|
+
let(:object) { klass.new }
|
589
|
+
|
590
|
+
before do
|
591
|
+
flexmock(object).should_receive(:create).never
|
592
|
+
flexmock(object).should_receive(:update).never
|
593
|
+
end
|
594
|
+
|
595
|
+
it 'should be invalid' do
|
596
|
+
object.should_not be_valid
|
597
|
+
end
|
598
|
+
|
599
|
+
it 'should return false' do
|
600
|
+
object = klass.new
|
601
|
+
object.update_attributes(input).should be_false
|
602
|
+
end
|
603
|
+
|
604
|
+
end
|
605
|
+
|
606
|
+
end
|
607
|
+
|
608
|
+
|
609
|
+
end
|
610
|
+
|
611
|
+
|
612
|
+
context "#self.attr_type_hash" do
|
613
|
+
|
614
|
+
let(:expected) do
|
615
|
+
{
|
616
|
+
:type => :my_name,
|
617
|
+
:import => :import_my_name,
|
618
|
+
:export => :export_my_name
|
619
|
+
}
|
620
|
+
end
|
621
|
+
|
622
|
+
it 'should return a hash with the expected output' do
|
623
|
+
subject.attr_type_hash(:my_name).should == expected
|
624
|
+
end
|
625
|
+
|
626
|
+
end
|
627
|
+
|
628
|
+
context '#convert_attribute_values' do
|
629
|
+
let(:klass) do
|
630
|
+
Class.new(subject) do
|
631
|
+
map :C_California1 => :california
|
632
|
+
attr_checkbox(:california)
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
context 'when :import' do
|
637
|
+
it 'should call import_boolean_checkbox' do
|
638
|
+
object = klass.new(:california => 'Yes')
|
639
|
+
flexmock(object.class).should_receive(:import_boolean_checkbox).with(:california, 'Yes').and_return(true)
|
640
|
+
attrs = object.convert_attribute_values(object.attributes)
|
641
|
+
attrs[:california].should === true
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
context 'when :export' do
|
646
|
+
|
647
|
+
it 'should call export_boolean_checkbox' do
|
648
|
+
object = klass.new(:california => 'Yes')
|
649
|
+
flexmock(object.class).should_receive(:export_boolean_checkbox).with(:california, true).and_return('Yes')
|
650
|
+
attrs = object.convert_attribute_values(object.attributes, :export)
|
651
|
+
attrs[:california].should === 'Yes'
|
652
|
+
end
|
653
|
+
|
654
|
+
end
|
655
|
+
|
656
|
+
end
|
657
|
+
|
658
|
+
context '#export_boolean_checkbox' do
|
659
|
+
let(:object) { subject.new }
|
660
|
+
|
661
|
+
it 'should return Yes when given true' do
|
662
|
+
object.send(:export_boolean_checkbox, :mock, true).should == 'Yes'
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'should return No when given false' do
|
666
|
+
object.send(:export_boolean_checkbox, :mock, false).should == 'No'
|
667
|
+
end
|
668
|
+
|
669
|
+
end
|
670
|
+
|
671
|
+
context "#self.attr_checkbox" do
|
672
|
+
|
673
|
+
let(:klass) do
|
674
|
+
Class.new(subject) do
|
675
|
+
map :C_California1 => :california
|
676
|
+
attr_checkbox :california
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
it 'should have registered "california" as :checkbox in attribute_types' do
|
681
|
+
klass.attribute_types[:california].should == {
|
682
|
+
:type => :boolean_checkbox,
|
683
|
+
:import => :import_boolean_checkbox,
|
684
|
+
:export => :export_boolean_checkbox
|
685
|
+
}.with_indifferent_access
|
686
|
+
end
|
687
|
+
|
688
|
+
context "when creating object with checkbox as Yes" do
|
689
|
+
let(:object) { klass.new(:california => 'Yes') }
|
690
|
+
specify { object.attributes[:california].should == true }
|
691
|
+
end
|
692
|
+
|
693
|
+
context 'when creating object with checkbox as No' do
|
694
|
+
let(:object) { klass.new(:california => 'No') }
|
695
|
+
specify { object.attributes[:california].should == false }
|
696
|
+
end
|
697
|
+
|
698
|
+
context 'when creating object with checkbox as true' do
|
699
|
+
let(:object) { klass.new(:california => true) }
|
700
|
+
specify { object.attributes[:california].should == true }
|
701
|
+
end
|
702
|
+
|
703
|
+
context 'when creating object with checkbox as false' do
|
704
|
+
let(:object) { klass.new(:california => false) }
|
705
|
+
specify { object.attributes[:california].should == false }
|
706
|
+
end
|
707
|
+
|
708
|
+
end
|
709
|
+
|
710
|
+
context '#self.primary_key' do
|
711
|
+
it 'is "id" by default' do
|
712
|
+
subject.primary_key.should == 'id'
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
context '#self.eloqua_attribute' do
|
717
|
+
|
718
|
+
before do
|
719
|
+
@class = Class.new(subject) do
|
720
|
+
map :C_EmailAddress => :email
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
724
|
+
it 'should return eloqua name "C_EmailAddress"' do
|
725
|
+
@class.eloqua_attribute(:email).should == 'C_EmailAddress'
|
726
|
+
end
|
727
|
+
|
728
|
+
end
|
729
|
+
|
730
|
+
context "#self.api" do
|
731
|
+
it 'should have api on the class level' do
|
732
|
+
subject.api.should == Eloqua::Api::Service
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
context "#api" do
|
737
|
+
it "should have api on the instance level" do
|
738
|
+
subject.new.api.should == Eloqua::Api::Service
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
end
|