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