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,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
|