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.
Files changed (72) hide show
  1. data/.gitignore +11 -0
  2. data/.yardopts +2 -0
  3. data/CHANGELOG.md +23 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +81 -0
  6. data/LICENSE +21 -0
  7. data/README.md +245 -0
  8. data/Rakefile +13 -0
  9. data/TODO.md +8 -0
  10. data/eloqua.gemspec +32 -0
  11. data/eloqua_initializer.tpl.rb +3 -0
  12. data/lib/eloqua.rb +51 -0
  13. data/lib/eloqua/api.rb +119 -0
  14. data/lib/eloqua/api/action.rb +41 -0
  15. data/lib/eloqua/api/service.rb +240 -0
  16. data/lib/eloqua/asset.rb +31 -0
  17. data/lib/eloqua/builder/templates.rb +31 -0
  18. data/lib/eloqua/builder/xml.rb +129 -0
  19. data/lib/eloqua/entity.rb +72 -0
  20. data/lib/eloqua/exceptions.rb +5 -0
  21. data/lib/eloqua/helper/attribute_map.rb +78 -0
  22. data/lib/eloqua/query.rb +291 -0
  23. data/lib/eloqua/remote_object.rb +274 -0
  24. data/lib/eloqua/version.rb +3 -0
  25. data/lib/eloqua/wsdl/action.wsdl +1 -0
  26. data/lib/eloqua/wsdl/data.wsdl +1 -0
  27. data/lib/eloqua/wsdl/email.wsdl +1 -0
  28. data/lib/eloqua/wsdl/service.wsdl +1 -0
  29. data/lib/tasks/test.rake +24 -0
  30. data/rspec.watchr +74 -0
  31. data/spec/fixtures/add_group_member/success.xml +18 -0
  32. data/spec/fixtures/create/contact_duplicate.xml +30 -0
  33. data/spec/fixtures/create/contact_success.xml +25 -0
  34. data/spec/fixtures/create_asset/failure.xml +30 -0
  35. data/spec/fixtures/create_asset/group_success.xml +25 -0
  36. data/spec/fixtures/delete_asset/access_deny.xml +31 -0
  37. data/spec/fixtures/describe_asset/success.xml +72 -0
  38. data/spec/fixtures/describe_asset_type/success.xml +23 -0
  39. data/spec/fixtures/describe_entity/success.xml +54 -0
  40. data/spec/fixtures/describe_entity_type/success.xml +45 -0
  41. data/spec/fixtures/get_member_count_in_step_by_status/success.xml +15 -0
  42. data/spec/fixtures/list_asset_types/success.xml +28 -0
  43. data/spec/fixtures/list_entity_types/success.xml +21 -0
  44. data/spec/fixtures/list_group_membership/success.xml +25 -0
  45. data/spec/fixtures/list_members_in_step_by_status/success.xml +15 -0
  46. data/spec/fixtures/query/contact_email_one.xml +38 -0
  47. data/spec/fixtures/query/contact_email_two.xml +56 -0
  48. data/spec/fixtures/query/contact_missing.xml +19 -0
  49. data/spec/fixtures/query/fault.xml +43 -0
  50. data/spec/fixtures/remove_group_member/success.xml +18 -0
  51. data/spec/fixtures/retrieve/contact_missing.xml +17 -0
  52. data/spec/fixtures/retrieve/contact_multiple.xml +3460 -0
  53. data/spec/fixtures/retrieve/contact_single.xml +38 -0
  54. data/spec/fixtures/retrieve_asset/failure.xml +17 -0
  55. data/spec/fixtures/retrieve_asset/success.xml +50 -0
  56. data/spec/fixtures/update/contact_success.xml +26 -0
  57. data/spec/lib/eloqua/api/action_spec.rb +36 -0
  58. data/spec/lib/eloqua/api/service_spec.rb +498 -0
  59. data/spec/lib/eloqua/api_spec.rb +133 -0
  60. data/spec/lib/eloqua/asset_spec.rb +63 -0
  61. data/spec/lib/eloqua/builder/templates_spec.rb +68 -0
  62. data/spec/lib/eloqua/builder/xml_spec.rb +254 -0
  63. data/spec/lib/eloqua/entity_spec.rb +224 -0
  64. data/spec/lib/eloqua/helper/attribute_map_spec.rb +14 -0
  65. data/spec/lib/eloqua/query_spec.rb +596 -0
  66. data/spec/lib/eloqua/remote_object_spec.rb +742 -0
  67. data/spec/lib/eloqua_spec.rb +171 -0
  68. data/spec/shared/attribute_map.rb +173 -0
  69. data/spec/shared/class_to_api_delegation.rb +50 -0
  70. data/spec/spec_helper.rb +48 -0
  71. data/spec/support/helper.rb +73 -0
  72. metadata +366 -0
@@ -0,0 +1,38 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
2
+ <s:Header>
3
+ <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
+ <u:Timestamp u:Id="_0">
5
+ <u:Created>2011-03-30T18:43:15.335Z</u:Created>
6
+ <u:Expires>2011-03-30T18:48:15.335Z</u:Expires>
7
+ </u:Timestamp>
8
+ </o:Security>
9
+ </s:Header>
10
+ <s:Body>
11
+ <RetrieveResponse xmlns="https://secure.eloqua.com/API/1.2">
12
+ <RetrieveResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
13
+ <DynamicEntity>
14
+ <EntityType>
15
+ <ID>0</ID>
16
+ <Name>Contact</Name>
17
+ <Type>Base</Type>
18
+ </EntityType>
19
+ <FieldValueCollection>
20
+ <EntityFields>
21
+ <InternalName>C_EmailAddress</InternalName>
22
+ <Value>test@email.com</Value>
23
+ </EntityFields>
24
+ <EntityFields>
25
+ <InternalName>C_FirstName</InternalName>
26
+ <Value>First</Value>
27
+ </EntityFields>
28
+ <EntityFields>
29
+ <InternalName>C_LastName</InternalName>
30
+ <Value>Last</Value>
31
+ </EntityFields>
32
+ </FieldValueCollection>
33
+ <Id>1</Id>
34
+ </DynamicEntity>
35
+ </RetrieveResult>
36
+ </RetrieveResponse>
37
+ </s:Body>
38
+ </s:Envelope>
@@ -0,0 +1,17 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
2
+ <s:Header>
3
+ <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
+ <u:Timestamp u:Id="_0">
5
+ <u:Created>2011-04-12T01:51:52.684Z</u:Created>
6
+ <u:Expires>2011-04-12T01:56:52.684Z</u:Expires>
7
+ </u:Timestamp>
8
+ </o:Security>
9
+ </s:Header>
10
+ <s:Body>
11
+ <RetrieveAssetResponse xmlns="https://secure.eloqua.com/API/1.2">
12
+ <RetrieveAssetResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
13
+ <DynamicAsset i:nil="true"/>
14
+ </RetrieveAssetResult>
15
+ </RetrieveAssetResponse>
16
+ </s:Body>
17
+ </s:Envelope>
@@ -0,0 +1,50 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
2
+ <s:Header>
3
+ <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
+ <u:Timestamp u:Id="_0">
5
+ <u:Created>2011-04-12T01:50:37.574Z</u:Created>
6
+ <u:Expires>2011-04-12T01:55:37.574Z</u:Expires>
7
+ </u:Timestamp>
8
+ </o:Security>
9
+ </s:Header>
10
+ <s:Body>
11
+ <RetrieveAssetResponse xmlns="https://secure.eloqua.com/API/1.2">
12
+ <RetrieveAssetResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
13
+ <DynamicAsset>
14
+ <AssetType>
15
+ <ID>0</ID>
16
+ <Name>ContactGroupName</Name>
17
+ <Type>ContactGroup</Type>
18
+ </AssetType>
19
+ <FieldValueCollection>
20
+ <AssetFields>
21
+ <InternalName>name</InternalName>
22
+ <Value>James created this contact group (again) !</Value>
23
+ </AssetFields>
24
+ <AssetFields>
25
+ <InternalName>description</InternalName>
26
+ <Value>through the api =)</Value>
27
+ </AssetFields>
28
+ <AssetFields>
29
+ <InternalName>createdby</InternalName>
30
+ <Value>Radius.API</Value>
31
+ </AssetFields>
32
+ <AssetFields>
33
+ <InternalName>createdat</InternalName>
34
+ <Value>4/11/2011 9:36:34 PM</Value>
35
+ </AssetFields>
36
+ <AssetFields>
37
+ <InternalName>modifiedby</InternalName>
38
+ <Value>Radius.API</Value>
39
+ </AssetFields>
40
+ <AssetFields>
41
+ <InternalName>modifiedat</InternalName>
42
+ <Value>4/11/2011 9:36:34 PM</Value>
43
+ </AssetFields>
44
+ </FieldValueCollection>
45
+ <Id>123</Id>
46
+ </DynamicAsset>
47
+ </RetrieveAssetResult>
48
+ </RetrieveAssetResponse>
49
+ </s:Body>
50
+ </s:Envelope>
@@ -0,0 +1,26 @@
1
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
2
+ <s:Header>
3
+ <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
+ <u:Timestamp u:Id="_0">
5
+ <u:Created>2011-04-07T04:08:25.936Z</u:Created>
6
+ <u:Expires>2011-04-07T04:13:25.936Z</u:Expires>
7
+ </u:Timestamp>
8
+ </o:Security>
9
+ </s:Header>
10
+ <s:Body>
11
+ <UpdateResponse xmlns="https://secure.eloqua.com/API/1.2">
12
+ <UpdateResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
13
+ <UpdateResult>
14
+ <EntityType>
15
+ <ID>0</ID>
16
+ <Name>Contact</Name>
17
+ <Type>Base</Type>
18
+ </EntityType>
19
+ <Errors/>
20
+ <ID>1</ID>
21
+ <Success>true</Success>
22
+ </UpdateResult>
23
+ </UpdateResult>
24
+ </UpdateResponse>
25
+ </s:Body>
26
+ </s:Envelope>
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'eloqua/api/action'
3
+ require 'ruby-debug'
4
+
5
+ describe Eloqua::Api::Action do
6
+ subject { Eloqua::Api::Action }
7
+
8
+ describe "Eloqua Action" do
9
+
10
+ it "should get member count in step by status" do
11
+ xml_query = xml! do |xml|
12
+ xml.tag!(:stepId, 100)
13
+ xml.tag!(:status, 'AwaitingAction')
14
+ end
15
+ mock_eloqua_request(:get_member_count_in_step_by_status, :success).\
16
+ with(:action, :get_member_count_in_step_by_status, xml_query).once
17
+
18
+ result = subject.get_member_count_in_step_by_status(100, 'AwaitingAction')
19
+ result.should equal(0)
20
+ end
21
+
22
+ it "should list members in step by status if there is a membercount higher than 0" do
23
+ xml_query = xml! do |xml|
24
+ xml.tag!(:stepId, 100)
25
+ xml.tag!(:status, 'AwaitingAction')
26
+ xml.tag!(:pageNumber, 0)
27
+ xml.tag!(:pageSize, 100)
28
+ end
29
+ mock_eloqua_request(:list_members_in_step_by_status, :success).\
30
+ with(:action, :list_members_in_step_by_status, xml_query).once
31
+ result = subject.list_members_in_step_by_status(100, 'AwaitingAction', 0, 100)
32
+ #returns with {:i => http://www.w3.org/2001/XMLSchema-instance} as there is no result from the array
33
+ result.should be_instance_of(Hash)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,498 @@
1
+ require 'spec_helper'
2
+ require 'eloqua/api/service'
3
+
4
+ shared_examples_for "entity association with response" do |type, name|
5
+
6
+ let(:xml_body) do
7
+ subject.entity_association_xml(asset_type, 1, entity_type, 1)
8
+ end
9
+
10
+ before do
11
+ mock_eloqua_request(type, name).\
12
+ with(:service, type, xml_body).once
13
+
14
+ @result = subject.entity_asset_operation(type, asset_type, 1, entity_type, 1)
15
+ end
16
+
17
+ specify { @result.should be_true }
18
+
19
+ end
20
+
21
+ shared_examples_for "entity association operation" do |method|
22
+
23
+ before do
24
+ flexmock(subject).should_receive(:entity_asset_operation).with(method, asset_type, 1, entity_type, 1).once.returns(true)
25
+ end
26
+
27
+ it 'should use entity asset operation to make request' do
28
+ subject.send(method, asset_type, 1, entity_type, 1)
29
+ end
30
+
31
+ end
32
+
33
+ shared_examples_for "operations for entity and asset" do |group, type|
34
+
35
+ let(:group_name) { group }
36
+
37
+ let(:dynamic_key) { ("dynamic_#{group}".to_sym) }
38
+
39
+ let(:field_key) { "#{group}_fields".to_sym }
40
+
41
+ context "#self.group_methods" do
42
+ specify { subject.group_methods.class.should == Array }
43
+ end
44
+
45
+ context "#self.group_type_methods" do
46
+ specify { subject.group_type_methods.class.should == Array }
47
+ end
48
+
49
+ context "#self.type_methods" do
50
+ specify { subject.type_methods.class.should == Array }
51
+ end
52
+
53
+ context '#self.create_object' do
54
+
55
+ let(:result_key) { subject.key_with_object(group, :create_result) }
56
+ let(:input) { [group, type, {:C_EmailAddress => 'create'}] }
57
+ let(:create_result) do
58
+ {
59
+ result_key => {
60
+ ("#{group}_type").to_sym => type,
61
+ :errors => nil,
62
+ :id => 1
63
+ }
64
+ }
65
+ end
66
+
67
+ context 'when successfuly creating one record' do
68
+
69
+ let(:xml_body) do
70
+ xml! do |xml|
71
+ xml.object_collection!(group) do
72
+ xml.dynamic_object!(group) do
73
+ xml.template!(:dynamic, group, type, nil, {
74
+ :C_EmailAddress => 'create',
75
+ })
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ before do
82
+ mock_api_request(remote_method(:create), xml_body, create_result)
83
+ @results = subject.create_object(*input)
84
+ end
85
+
86
+
87
+ it 'should return {:id => 1}' do
88
+ @results[:id].should == 1
89
+ end
90
+
91
+ end
92
+
93
+ context "when the record is duplicate" do
94
+
95
+ let(:create_result) do
96
+ {
97
+ result_key => {
98
+ ("#{group}_type").to_sym => type,
99
+ :errors => {
100
+ :error => {
101
+ :error_code => 'DuplicateValue',
102
+ :message => 'You are attempting to create a duplicate entity.'
103
+ }
104
+ }
105
+ }
106
+ }
107
+ end
108
+
109
+ before do
110
+ mock_api_request(create_result)
111
+ end
112
+
113
+ it 'should raise duplicate error exception' do
114
+ lambda { subject.create_object(*input) }.should raise_exception(Eloqua::DuplicateRecordError)
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ context "#self.update_object" do
122
+
123
+ let(:result_key) { subject.key_with_object(group, :update_result) }
124
+
125
+ let(:update_result) do
126
+ {
127
+ result_key => {
128
+ ("#{group}_type").to_sym => type,
129
+ :errors => nil,
130
+ :id => 1,
131
+ :success => true
132
+ }
133
+ }
134
+ end
135
+
136
+ context "when successfully updating one record" do
137
+ let(:input) { [group, type, 1, {:C_EmailAddress => 'new'}] }
138
+ let(:xml_body) do
139
+ xml! do |xml|
140
+ xml.object_collection!(group) do
141
+ xml.dynamic_object!(group) do
142
+ xml.template!(:dynamic, group, type, '1', {
143
+ :C_EmailAddress => 'new',
144
+ })
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ before do
151
+ mock_api_request(remote_method(:update), xml_body, update_result)
152
+ @results = subject.update_object(*input)
153
+ end
154
+
155
+ it 'should return true' do
156
+ @results.should be_true
157
+ end
158
+
159
+ end
160
+
161
+ end
162
+
163
+ context "#self.delete_object" do
164
+
165
+ context "when given single int" do
166
+ let(:result_key) { subject.key_with_object(group, :delete_result) }
167
+
168
+ let(:delete_result) do
169
+ {
170
+ result_key => {
171
+ ("#{group}_type").to_sym => type,
172
+ :errors => nil,
173
+ :id => 1,
174
+ :success => true
175
+ }
176
+ }
177
+ end
178
+ let(:input) { 1 }
179
+ let(:xml_body) do
180
+ xml! do |xml|
181
+ xml.object_type_lower!(group) do
182
+ xml.template!(:object_type, type)
183
+ end
184
+ xml.ids do
185
+ xml.template!(:int_array, [input])
186
+ end
187
+ end
188
+ end
189
+
190
+ before do
191
+ mock_api_request(remote_method(:delete), xml_body, delete_result)
192
+ @result = subject.delete_object(group, type, 1)
193
+ end
194
+
195
+ it 'should return an array of deleted ids' do
196
+ @result.should == [1]
197
+ end
198
+
199
+ end
200
+ end
201
+
202
+ context "#self.find_object" do
203
+
204
+ let(:find_result) do
205
+ {
206
+ dynamic_key => {
207
+ :field_value_collection => {
208
+ field_key => [{
209
+ :internal_name => 'C_EmailAddress',
210
+ :value => email
211
+ }]
212
+ },
213
+ :id => '1'
214
+ }
215
+ }
216
+ end
217
+
218
+ context "successful find_object with all fields" do
219
+ let(:xml_body) do
220
+ xml! do |xml|
221
+ xml.object_type_lower!(group) do
222
+ xml.template!(:object_type, type)
223
+ end
224
+ xml.ids do
225
+ xml.template!(:int_array, [1])
226
+ end
227
+ end
228
+ end
229
+
230
+ before do
231
+ mock_api_request(remote_method(:retrieve), xml_body, find_result)
232
+ @result = subject.find_object(group, type, 1)
233
+ end
234
+
235
+ it 'should return a hash with fields from retrieve' do
236
+ @result.class.should == Hash
237
+ end
238
+
239
+ it 'should return hash with expected fields' do
240
+ expected = {
241
+ :C_EmailAddress => email,
242
+ :id => 1
243
+ }
244
+ expected.each do |key, value|
245
+ @result[key].should == value
246
+ end
247
+
248
+ end
249
+ end
250
+
251
+ context 'find_object without a result' do
252
+
253
+ before do
254
+ mock = mock_api_request(dynamic_key => nil)
255
+ @result = subject.find_object(group, type, 5)
256
+ end
257
+
258
+ it 'should return false' do
259
+ @result.should be_false
260
+ end
261
+
262
+ end
263
+
264
+ end
265
+
266
+ end
267
+
268
+ describe Eloqua::Api::Service do
269
+
270
+ subject { Eloqua::Api::Service }
271
+
272
+ let(:email) { 'test@email.com' }
273
+
274
+ let(:group) { :asset }
275
+
276
+ let(:type) do
277
+ subject.remote_type('Contact')
278
+ end
279
+
280
+ let(:asset_type) do
281
+ subject.remote_type('ContactGroupName', 'ContactGroup', 0)
282
+ end
283
+
284
+ let(:entity_type) do
285
+ subject.remote_type('Contact')
286
+ end
287
+
288
+ context "#self.entity_association_xml" do
289
+
290
+ let(:expected_xml) do
291
+ xml_query = xml! do |xml|
292
+ xml.template!(:object, :entity, entity_type, 1)
293
+ xml.template!(:object, :asset, asset_type, 1)
294
+ end
295
+ end
296
+
297
+
298
+ context 'when entity given is a class' do
299
+ it 'should return expected xml' do
300
+ output = subject.entity_association_xml(asset_type, 1, entity_type, 1)
301
+ output.should == expected_xml
302
+ end
303
+ end
304
+
305
+ context 'when entity given is a hash' do
306
+ it 'should return expected xml' do
307
+ output = subject.entity_association_xml(asset_type, 1, entity_type, 1)
308
+ output.should == expected_xml
309
+ end
310
+ end
311
+
312
+ end
313
+
314
+ context "#self.key_with_object" do
315
+
316
+ it 'should return given when obj type is entity' do
317
+ subject.key_with_object(:entity, :create_result).should == :create_result
318
+ end
319
+
320
+ it 'should inject asset in the middle of given method' do
321
+ subject.key_with_object(:asset, :create_result).should == :create_asset_result
322
+ end
323
+
324
+ end
325
+
326
+ context "#self.object_method" do
327
+ it 'should return given name when obj type is entity' do
328
+ subject.object_method(:entity, :create).should == :create
329
+ end
330
+
331
+ it 'should append obj type when type is other then entity' do
332
+ subject.object_method(:asset, :create).should == :create_asset
333
+ end
334
+ end
335
+
336
+ context "#self.request" do
337
+ it 'should make requests with the :service client' do
338
+ flexmock(Eloqua::Api).should_receive(:request).with(:service, :method, {})
339
+ subject.request(:method, {})
340
+ end
341
+ end
342
+
343
+ it_behaves_like 'operations for entity and asset', :asset, Eloqua::Api.remote_type('ContactGroupName', 'ContactGroup', 0)
344
+ it_behaves_like 'operations for entity and asset', :entity, Eloqua::Api.remote_type('Contact')
345
+
346
+ context "#self.list_memberships" do
347
+ let(:xml_body) do
348
+ xml! do |xml|
349
+ xml.template!(:object, :entity, type, 1)
350
+ end
351
+ end
352
+
353
+ before do
354
+ mock_eloqua_request(:list_group_membership, :success).\
355
+ with(:service, :list_group_membership, xml_body).once
356
+
357
+ @result = subject.list_memberships(type, 1)
358
+ end
359
+
360
+ it "should provide array of contact groups" do
361
+ @result
362
+ end
363
+ end
364
+
365
+ context "during group member class operations" do
366
+
367
+ let(:xml_body) do
368
+ subject.entity_association_xml(asset_type, 1, entity_type, 1)
369
+ end
370
+
371
+ context "#self.entity_asset_operation" do
372
+
373
+ context "when adding group member" do
374
+ it_behaves_like 'entity association with response', :add_group_member, :success
375
+ end
376
+
377
+ context "when removing group member" do
378
+ it_behaves_like 'entity association with response', :remove_group_member, :success
379
+ end
380
+
381
+ end
382
+
383
+ context "#self.add_group_member" do
384
+ it_behaves_like 'entity association operation', :add_group_member
385
+ end
386
+
387
+ context "#self.remove_group_member" do
388
+ it_behaves_like 'entity association operation', :remove_group_member
389
+ end
390
+
391
+ end
392
+
393
+ context "#self.list_types" do
394
+ let(:remote_method) { "list_#{group}_types".to_sym }
395
+
396
+ before do
397
+ mock_eloqua_request(remote_method, :success).with(:service, remote_method, nil)
398
+ end
399
+
400
+ it 'should return results as an array' do
401
+ result = subject.list_types(group)
402
+ result.class.should == Array
403
+ end
404
+
405
+ end
406
+
407
+ context "#self.describe" do
408
+ let(:remote_method) { "describe_#{group}".to_sym }
409
+
410
+ let(:xml_body) do
411
+ xml! do |xml|
412
+ xml.object_type_lower!(group) do
413
+ xml.template!(:object_type, type)
414
+ end
415
+ end
416
+ end
417
+
418
+ before do
419
+ mock_eloqua_request(remote_method, :success).with(:service, remote_method, xml_body)
420
+ @result = subject.describe(group, type)
421
+ end
422
+
423
+ it 'should have fields in the top level in result as an array' do
424
+ @result.should have_key(:fields)
425
+ @result[:fields].class.should == Array
426
+ end
427
+
428
+ end
429
+
430
+ context "#self.describe_type" do
431
+
432
+ shared_examples_for "will return collection of types" do
433
+ it "should return an array" do
434
+ @result.class.should == Array
435
+ end
436
+
437
+ it "should contain type hash in first element with :id, :name and :type keys" do
438
+ first = @result.first
439
+
440
+ first.should have_key(:id)
441
+ first.should have_key(:name)
442
+ first.should have_key(:type)
443
+ end
444
+
445
+ end
446
+
447
+ context "when group is :asset" do
448
+ let(:request_hash) do
449
+ {:asset_type => 'Type'}
450
+ end
451
+
452
+ before do
453
+ mock_eloqua_request(:describe_asset_type, :success).\
454
+ with(:service, :describe_asset_type, request_hash).once
455
+ @result = subject.describe_type(:asset, 'Type')
456
+ end
457
+
458
+ it_behaves_like 'will return collection of types'
459
+ end
460
+
461
+ context "when group is :entity" do
462
+ let(:request_hash) do
463
+ {:global_entity_type => 'Base'}
464
+ end
465
+
466
+ before do
467
+ mock_eloqua_request(:describe_entity_type, :success).\
468
+ with(:service, :describe_entity_type, request_hash).once
469
+
470
+ @result = subject.describe_type(:entity, 'Base')
471
+ end
472
+
473
+ it_behaves_like 'will return collection of types'
474
+ end
475
+
476
+ end
477
+
478
+ context "#self.handle_exception" do
479
+ context 'duplicate error' do
480
+
481
+ let(:response) do
482
+ {:errors=>
483
+ {:error=>
484
+ {:error_code=>"DuplicateValue",
485
+ :message=>"You are attempting to create a duplicate entity."}},
486
+ :id=>"-1",
487
+ :entity_type=>{:type=>"Base", :name=>"Contact", :id=>"0"}
488
+ }
489
+ end
490
+
491
+ it 'should raise duplicate exception' do
492
+ lambda { subject.handle_exception(response) }.should raise_exception(Eloqua::DuplicateRecordError)
493
+ end
494
+
495
+ end
496
+ end
497
+
498
+ end