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,133 @@
1
+ require 'spec_helper'
2
+ require 'pp'
3
+
4
+
5
+ describe Eloqua::Api do
6
+
7
+ subject { Eloqua::Api }
8
+
9
+ before do
10
+ subject.reset_clients
11
+ end
12
+
13
+ context '#builder' do
14
+
15
+ it 'should call Eloqua::Builder::Xml.create' do
16
+ flexmock(Eloqua::Builder::Xml).should_receive(:create).once
17
+ subject.builder
18
+ end
19
+
20
+ end
21
+
22
+ context "#request" do
23
+
24
+ context "When returning multiple records" do
25
+
26
+ before do
27
+ mock_response(:retrieve, :contact_multiple)
28
+ @response = subject.request(:service, :retrieve) do
29
+ end
30
+ end
31
+
32
+ it 'should return dynamic entity key as the top level hash' do
33
+ @response.should have_key(:dynamic_entity)
34
+ end
35
+
36
+ it "should have stored response in #last_response" do
37
+ body = Savon::Spec::Fixture.load(:retrieve, :contact_multiple)
38
+ subject.last_response.should == body
39
+ end
40
+
41
+ it "should have stored response in #last_request" do
42
+ subject.last_request.should_not be_blank
43
+ end
44
+
45
+
46
+ end
47
+
48
+ end
49
+
50
+ context "#raise_response_errors" do
51
+
52
+ context "when response given is an HTTP error" do
53
+ it "should raise Eloqua::HTTPError" do
54
+
55
+ end
56
+ end
57
+
58
+ context "when response given is a SOAP Fault" do
59
+
60
+ it "should raise an SoapError" do
61
+ mock_response(:query, :fault)
62
+ lambda { @response = subject.request(:service, :query) }.should raise_exception(Eloqua::SoapError)
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+ context "#client" do
70
+
71
+ context 'when no Eloqua.user or Eloqua.password is set' do
72
+
73
+ before do
74
+ Eloqua.authenticate(nil, nil)
75
+ end
76
+
77
+ it 'should raise RuntimeError about missing user or password' do
78
+ lambda { subject.client(:service) }.should raise_exception(RuntimeError, 'Eloqua.user or Eloqua.password is not set see Eloqua.authenticate')
79
+ end
80
+
81
+ end
82
+
83
+ before do
84
+ @connection = subject.client(:email)
85
+ end
86
+
87
+ it 'should return a Savon::Client' do
88
+ @connection.class.should == Savon::Client
89
+ end
90
+
91
+ it "should return a savon instance of the given wsdl type" do
92
+ @connection.wsdl.instance_variable_get(:@document).should == subject::WSDL[:email]
93
+ end
94
+
95
+ it 'should have wsse username set to Eloqua.user constant' do
96
+ @connection.wsse.username.should == Eloqua.user
97
+ end
98
+
99
+ it 'should have wsse password set to Eloqua.password constant' do
100
+ @connection.wsse.password.should == Eloqua.password
101
+ end
102
+
103
+ it "should have an :arr namespace for arrays" do
104
+
105
+ end
106
+
107
+ end
108
+
109
+ context "#remote_type" do
110
+
111
+ before do
112
+ @entity = subject.remote_type('Contact')
113
+ end
114
+
115
+ it "should be a hash" do
116
+ @entity.class.should == Hash
117
+ end
118
+
119
+ it "should have an ID of 0" do
120
+ @entity[:id].should == 0
121
+ end
122
+
123
+ it "should have a Name equal to Contact" do
124
+ @entity[:name].should == 'Contact'
125
+ end
126
+
127
+ it "should have Type equal to Base" do
128
+ @entity[:type].should == 'Base'
129
+ end
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eloqua::Asset do
4
+
5
+ subject do
6
+ Class.new(Eloqua::Asset) do
7
+ self.remote_type = api.remote_type('ContactGroupName', 'ContactGroup', 0)
8
+ def self.name
9
+ 'ContactGroup'
10
+ end
11
+ end
12
+ end
13
+
14
+ let(:entity) do
15
+ Class.new(Eloqua::Entity) do
16
+ self.remote_type = api.remote_type('Contact')
17
+ end
18
+ end
19
+
20
+ let(:object) { subject.new(:id => 1) }
21
+
22
+
23
+ context "#member_operation" do
24
+
25
+ let(:input) { [entity.new(:id => 1 )] }
26
+
27
+ context "when given non entity" do
28
+ it "should raise argument error" do
29
+ lambda do
30
+ object.send(:member_operation, :add_group_member, nil)
31
+ end.should raise_exception(ArgumentError, /Eloqua\:\:Entity/)
32
+ end
33
+ end
34
+
35
+ context "when given unpersisted entity" do
36
+ it "should raise argument error" do
37
+ lambda do
38
+ object.send(:member_operation, :add_group_member, Eloqua::Entity)
39
+ end.should raise_exception(ArgumentError, /Eloqua\:\:Entity/)
40
+ end
41
+ end
42
+
43
+ context "#add_member" do
44
+ it 'should delegate call to member_operation' do
45
+ flexmock(object).should_receive(:member_operation).with(:add_group_member, *input).once
46
+ object.add_member(*input)
47
+ end
48
+ end
49
+
50
+ context "#remove_member" do
51
+ it 'should delegate call to member_operation' do
52
+ flexmock(object).should_receive(:member_operation).with(:remove_group_member, *input).once
53
+ object.remove_member(*input)
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ specify { subject.remote_group.should == :asset }
60
+
61
+ it_behaves_like 'class level delegation of remote operations for', :asset
62
+
63
+ end
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+
3
+ describe Eloqua::Builder::Templates do
4
+
5
+ let(:xml) do
6
+ Eloqua::Builder::Xml.new
7
+ end
8
+
9
+ subject do
10
+ klass = Class.new
11
+ klass.send(:include, Eloqua::Builder::Templates)
12
+ klass
13
+ end
14
+
15
+ context "#define_builder_template" do
16
+
17
+ before do
18
+ subject.define_builder_template :iterator do |xml, list|
19
+ end
20
+ end
21
+
22
+ it 'should have saved block in builder_templates' do
23
+ subject.builder_templates.size.should == 1
24
+ end
25
+
26
+ it 'should be able to access block' do
27
+ subject.builder_templates[:iterator].class.should == Proc
28
+ end
29
+
30
+ end
31
+
32
+ context '#builder_template' do
33
+
34
+ context 'passing no arguments to template' do
35
+
36
+ before do
37
+ subject.define_builder_template :bigwow do |xml|
38
+ xml.big_wow("BANG!")
39
+ end
40
+ end
41
+
42
+ it 'should be able to use template to create xml' do
43
+ output = xml.omg(&subject.builder_template(:bigwow))
44
+ output.strip.should == '<omg><big_wow>BANG!</big_wow></omg>'
45
+ end
46
+
47
+ end
48
+
49
+ context 'passing arguments to template' do
50
+
51
+ before do
52
+ subject.define_builder_template :long do |xml, list|
53
+ list.each do |element|
54
+ xml.tag!(element[0], element[1])
55
+ end
56
+ end
57
+ end
58
+
59
+ it 'should take arguments and build output' do
60
+ output = xml.long(&subject.builder_template(:long, [ ['big', 'value'], ['small', 'value'] ]))
61
+ output.strip.should == '<long><big>value</big><small>value</small></long>'
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,254 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eloqua::Builder::Xml do
4
+
5
+ def xml!(&block)
6
+ subject.create(&block)
7
+ end
8
+
9
+ subject { Eloqua::Builder::Xml }
10
+
11
+ let(:xml) do
12
+ subject.new(:namespace => 'wsdl')
13
+ end
14
+
15
+ it "should include Eloqua::Builder::Templates" do
16
+ subject.should include(Eloqua::Builder::Templates)
17
+ end
18
+
19
+ it 'should allow a block during new providing self' do
20
+ subject.new do |xml|
21
+ xml.is_a?(subject)
22
+ end
23
+ end
24
+
25
+ context "when default namespace options is set" do
26
+
27
+ let(:xml) do
28
+ subject.new(:namespace => 'wsdl')
29
+ end
30
+
31
+ it 'should output the default namespace with tag' do
32
+ output = xml.entities {}
33
+ output.strip.should == '<wsdl:entities></wsdl:entities>'
34
+ end
35
+
36
+ it 'should allow us to override the default namespace' do
37
+ output = xml.arr(:int) {}
38
+ output.strip.should == '<arr:int></arr:int>'
39
+ end
40
+
41
+ end
42
+
43
+ # Entity/Asset Helpers
44
+
45
+ context '#dynamic_object!' do
46
+
47
+ let(:expected) { '<DynamicAsset>content</DynamicAsset>' }
48
+
49
+ it 'should return expected xml' do
50
+ xml! {|xml| xml.dynamic_object!(:asset, 'content') }.should == expected
51
+ end
52
+
53
+ end
54
+
55
+ context '#object_type!' do
56
+ let(:expected) { '<AssetType>content</AssetType>' }
57
+
58
+ it 'should return expected xml' do
59
+ xml! {|xml| xml.object_type!(:asset, 'content') }.should == expected
60
+ end
61
+
62
+ end
63
+
64
+ context '#object_type_lower!' do
65
+ let(:expected) { '<assetType>content</assetType>' }
66
+
67
+ it 'should return expected xml' do
68
+ xml! {|xml| xml.object_type_lower!(:asset, 'content') }.should == expected
69
+ end
70
+
71
+ end
72
+
73
+ context '#object_collection!' do
74
+ let(:expected) { "<entities><one>1</one></entities>" }
75
+ it 'should return expected xml' do
76
+ xml! {|xml| xml.object_collection!(:entity) { xml.one('1') } }.should == expected
77
+ end
78
+ end
79
+
80
+ context "#self.create" do
81
+
82
+ let(:klass) do
83
+ Class.new(subject) do
84
+ define_builder_template(:zomg) do |xml|
85
+ xml.wow('zomg')
86
+ end
87
+ end
88
+ end
89
+
90
+ let(:xml_body) do
91
+ '<big>1</big><wow>zomg</wow>'
92
+ end
93
+
94
+ it 'should produce expected output' do
95
+ out = klass.create do |xml|
96
+ xml.big('1')
97
+ xml.template!(:zomg)
98
+ end
99
+ out.should == xml_body
100
+ end
101
+
102
+ end
103
+
104
+ context 'xml templates' do
105
+
106
+ share_examples_for "expected template output" do |template|
107
+
108
+ before do
109
+ @args = []
110
+ if(respond_to?(:args))
111
+ @args = args
112
+ elsif respond_to?(:input)
113
+ @args = [input]
114
+ end
115
+ builder = subject.new
116
+ @output = subject.create(&subject.builder_template(template, *@args))
117
+ end
118
+
119
+ it "should return :expected output from template :#{template}" do
120
+ @output.should == expected.to_s
121
+ end
122
+ end
123
+
124
+ let(:entity) do
125
+ Eloqua::Api.remote_type('Contact')
126
+ end
127
+
128
+ context ':object' do
129
+ let(:args) do
130
+ ['random', Eloqua::Api.remote_type('Contact'), 1]
131
+ end
132
+
133
+ let(:expected) do
134
+ xml! do |xml|
135
+ xml.random do
136
+ xml.RandomType do
137
+ xml.template!(:object_type, Eloqua::Api.remote_type('Contact'))
138
+ end
139
+ xml.Id(1)
140
+ end
141
+ end
142
+ end
143
+
144
+ it_behaves_like 'expected template output', :object
145
+
146
+ end
147
+
148
+ context ':dynamic' do
149
+
150
+ let(:args) do
151
+ ['entity', Eloqua::Api.remote_type('Contact'), 124194, {:C_Company => 'Lights of Apollo LLC'}]
152
+ end
153
+
154
+ let(:expected) do
155
+ subject.create do |xml|
156
+ xml.EntityType do
157
+ xml.template!(:object_type, entity)
158
+ end
159
+ xml.FieldValueCollection do
160
+ xml.template!(:fields, 'entity', args[3])
161
+ end
162
+ xml.Id(args[2])
163
+ end
164
+ end
165
+
166
+ it_behaves_like 'expected template output', :dynamic
167
+
168
+ end
169
+
170
+ context ':fields' do
171
+
172
+ let(:args) do
173
+ ['entity', input]
174
+ end
175
+
176
+ let(:input) do
177
+ list = {}
178
+ list[:C_EmailAddress] = 'james@localhost'
179
+ list
180
+ end
181
+
182
+
183
+ let(:expected) do
184
+ subject.create do |xml|
185
+ xml.EntityFields do
186
+ xml.InternalName('C_EmailAddress')
187
+ xml.Value('james@localhost')
188
+ end
189
+ end
190
+ end
191
+
192
+ it_behaves_like 'expected template output', :fields
193
+
194
+ end
195
+
196
+ context ':entity' do
197
+
198
+ let(:input) do
199
+ Eloqua::Api.remote_type('Contact')
200
+ end
201
+
202
+ let(:expected) do
203
+ subject.create do |xml|
204
+ xml.ID('0')
205
+ xml.Name('Contact')
206
+ xml.Type('Base')
207
+ end
208
+ end
209
+
210
+ it_behaves_like 'expected template output', :object_type
211
+
212
+ end
213
+
214
+ context ":array" do
215
+
216
+ let(:input) do
217
+ [1, 'string', '1', 'string']
218
+ end
219
+ let(:expected) do
220
+ subject.create do |xml|
221
+ xml.arr(:int, '1')
222
+ xml.arr(:string, 'string')
223
+ xml.arr(:string, '1')
224
+ xml.arr(:string, 'string')
225
+ end
226
+ end
227
+
228
+ it_behaves_like 'expected template output', :array
229
+
230
+ end
231
+
232
+ context ":int_array" do
233
+
234
+
235
+ let(:input) do
236
+ [1, 'ouch', 2, 'wow', '3']
237
+ end
238
+
239
+ let(:expected) do
240
+ subject.create do |xml|
241
+ xml.arr(:int, 1)
242
+ xml.arr(:int, 2)
243
+ xml.arr(:int, 3)
244
+ end
245
+ end
246
+
247
+ it_behaves_like 'expected template output', :int_array
248
+
249
+ end
250
+
251
+ end
252
+
253
+
254
+ end