eloqua 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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