sfdc 3.0.0 → 3.0.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +96 -0
- data/Gemfile +11 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.md +88 -98
- data/Rakefile +10 -0
- data/lib/sfdc.rb +1 -0
- data/lib/sfdc/abstract_client.rb +1 -1
- data/lib/sfdc/attachment.rb +0 -2
- data/lib/sfdc/concerns/api.rb +1 -2
- data/lib/sfdc/concerns/authentication.rb +1 -2
- data/lib/sfdc/concerns/base.rb +5 -7
- data/lib/sfdc/concerns/caching.rb +1 -3
- data/lib/sfdc/concerns/canvas.rb +0 -2
- data/lib/sfdc/concerns/connection.rb +2 -3
- data/lib/sfdc/concerns/picklists.rb +1 -4
- data/lib/sfdc/concerns/streaming.rb +2 -2
- data/lib/sfdc/concerns/verbs.rb +0 -2
- data/lib/sfdc/config.rb +1 -0
- data/lib/sfdc/middleware/authentication.rb +4 -2
- data/lib/sfdc/middleware/authentication/password.rb +2 -5
- data/lib/sfdc/middleware/authorization.rb +1 -5
- data/lib/sfdc/middleware/caching.rb +0 -2
- data/lib/sfdc/middleware/instance_url.rb +0 -4
- data/lib/sfdc/middleware/mashify.rb +1 -3
- data/lib/sfdc/middleware/multipart.rb +6 -4
- data/lib/sfdc/signed_request.rb +1 -1
- data/lib/sfdc/tooling/client.rb +4 -6
- data/lib/sfdc/version.rb +2 -2
- data/sfdc.gemspec +27 -0
- data/spec/fixtures/auth_error_response.json +4 -0
- data/spec/fixtures/auth_success_response.json +7 -0
- data/spec/fixtures/blob.jpg +0 -0
- data/spec/fixtures/expired_session_response.json +6 -0
- data/spec/fixtures/reauth_success_response.json +7 -0
- data/spec/fixtures/refresh_error_response.json +4 -0
- data/spec/fixtures/refresh_success_response.json +7 -0
- data/spec/fixtures/services_data_success_response.json +12 -0
- data/spec/fixtures/sobject/create_success_response.json +5 -0
- data/spec/fixtures/sobject/delete_error_response.json +1 -0
- data/spec/fixtures/sobject/describe_sobjects_success_response.json +31 -0
- data/spec/fixtures/sobject/list_sobjects_success_response.json +31 -0
- data/spec/fixtures/sobject/org_query_response.json +11 -0
- data/spec/fixtures/sobject/query_aggregate_success_response.json +23 -0
- data/spec/fixtures/sobject/query_empty_response.json +5 -0
- data/spec/fixtures/sobject/query_error_response.json +6 -0
- data/spec/fixtures/sobject/query_paginated_first_page_response.json +14 -0
- data/spec/fixtures/sobject/query_paginated_last_page_response.json +13 -0
- data/spec/fixtures/sobject/query_success_response.json +38 -0
- data/spec/fixtures/sobject/recent_success_response.json +18 -0
- data/spec/fixtures/sobject/search_error_response.json +6 -0
- data/spec/fixtures/sobject/search_success_response.json +16 -0
- data/spec/fixtures/sobject/sobject_describe_error_response.json +6 -0
- data/spec/fixtures/sobject/sobject_describe_success_response.json +1429 -0
- data/spec/fixtures/sobject/sobject_find_error_response.json +6 -0
- data/spec/fixtures/sobject/sobject_find_success_response.json +29 -0
- data/spec/fixtures/sobject/upsert_created_success_response.json +5 -0
- data/spec/fixtures/sobject/upsert_error_response.json +6 -0
- data/spec/fixtures/sobject/upsert_multiple_error_response.json +4 -0
- data/spec/fixtures/sobject/upsert_updated_success_response.json +0 -0
- data/spec/fixtures/sobject/write_error_response.json +6 -0
- data/spec/integration/abstract_client_spec.rb +306 -0
- data/spec/integration/data/client_spec.rb +90 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/client_integration.rb +45 -0
- data/spec/support/concerns.rb +18 -0
- data/spec/support/event_machine.rb +14 -0
- data/spec/support/fixture_helpers.rb +45 -0
- data/spec/support/matchers.rb +11 -0
- data/spec/support/middleware.rb +76 -0
- data/spec/support/mock_cache.rb +13 -0
- data/spec/unit/abstract_client_spec.rb +11 -0
- data/spec/unit/attachment_spec.rb +15 -0
- data/spec/unit/collection_spec.rb +52 -0
- data/spec/unit/concerns/api_spec.rb +244 -0
- data/spec/unit/concerns/authentication_spec.rb +98 -0
- data/spec/unit/concerns/base_spec.rb +42 -0
- data/spec/unit/concerns/caching_spec.rb +29 -0
- data/spec/unit/concerns/canvas_spec.rb +30 -0
- data/spec/unit/concerns/connection_spec.rb +22 -0
- data/spec/unit/config_spec.rb +99 -0
- data/spec/unit/data/client_spec.rb +10 -0
- data/spec/unit/mash_spec.rb +36 -0
- data/spec/unit/middleware/authentication/password_spec.rb +31 -0
- data/spec/unit/middleware/authentication/token_spec.rb +24 -0
- data/spec/unit/middleware/authentication_spec.rb +67 -0
- data/spec/unit/middleware/authorization_spec.rb +11 -0
- data/spec/unit/middleware/gzip_spec.rb +66 -0
- data/spec/unit/middleware/instance_url_spec.rb +24 -0
- data/spec/unit/middleware/logger_spec.rb +19 -0
- data/spec/unit/middleware/mashify_spec.rb +11 -0
- data/spec/unit/middleware/raise_error_spec.rb +32 -0
- data/spec/unit/signed_request_spec.rb +24 -0
- data/spec/unit/sobject_spec.rb +86 -0
- data/spec/unit/tooling/client_spec.rb +7 -0
- metadata +225 -65
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"attributes": {
|
3
|
+
"type": "Whizbang",
|
4
|
+
"url": "/services/data/v20.0/sobjects/Whizbang/23foo"
|
5
|
+
},
|
6
|
+
"Id": "23foo",
|
7
|
+
"OwnerId": "owner_id",
|
8
|
+
"IsDeleted": false,
|
9
|
+
"Name": "My First Whizbang",
|
10
|
+
"CreatedById": "created_by_id",
|
11
|
+
"LastModifiedById": "last_modified_by_id",
|
12
|
+
"Auto_Number": "A-1",
|
13
|
+
"Checkbox_Label": true,
|
14
|
+
"Currency_Label": 23.0,
|
15
|
+
"Date_Label": "2010-01-01",
|
16
|
+
"DateTime_Label": "2011-07-07T00:37:00.000+0000",
|
17
|
+
"OtherDateTime_Label": null,
|
18
|
+
"Email_Label": "danny@example.com",
|
19
|
+
"Number_Label": 23.0,
|
20
|
+
"Percent_Label": 33.0,
|
21
|
+
"Phone_Label": "(415) 555-1212",
|
22
|
+
"Picklist_Label": "one",
|
23
|
+
"Picklist_Multiselect_Label": "four;six",
|
24
|
+
"Text_Label": "some text",
|
25
|
+
"TextArea_Label": "a text area",
|
26
|
+
"TextAreaLong_Label": "a loooooooooooooong text area",
|
27
|
+
"TextAreaRich_Label": "Rich <strong>text</strong>",
|
28
|
+
"URL_Label": "http://pivotallabs.com"
|
29
|
+
}
|
File without changes
|
@@ -0,0 +1,306 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for Sfdc::AbstractClient do
|
4
|
+
describe '.list_sobjects' do
|
5
|
+
requests :sobjects, :fixture => 'sobject/describe_sobjects_success_response'
|
6
|
+
|
7
|
+
subject { client.list_sobjects }
|
8
|
+
it { should be_an Array }
|
9
|
+
it { should eq ['Account'] }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.describe' do
|
13
|
+
context 'with no arguments' do
|
14
|
+
requests :sobjects, :fixture => 'sobject/describe_sobjects_success_response'
|
15
|
+
|
16
|
+
subject { client.describe }
|
17
|
+
it { should be_an Array }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with an argument' do
|
21
|
+
requests 'sobjects/Whizbang/describe', :fixture => 'sobject/sobject_describe_success_response'
|
22
|
+
|
23
|
+
subject { client.describe('Whizbang') }
|
24
|
+
its(['name']) { should eq 'Whizbang' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.query' do
|
29
|
+
requests 'query\?q=SELECT%20some,%20fields%20FROM%20object', :fixture => 'sobject/query_success_response'
|
30
|
+
|
31
|
+
subject { client.query('SELECT some, fields FROM object') }
|
32
|
+
it { should be_an Enumerable }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.search' do
|
36
|
+
requests 'search\?q=FIND%20%7Bbar%7D', :fixture => 'sobject/search_success_response'
|
37
|
+
|
38
|
+
subject { client.search('FIND {bar}') }
|
39
|
+
it { should be_an Array }
|
40
|
+
its(:size) { should eq 2 }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.org_id' do
|
44
|
+
requests 'query\?q=select%20id%20from%20Organization', :fixture => 'sobject/org_query_response'
|
45
|
+
|
46
|
+
subject { client.org_id }
|
47
|
+
it { should eq '00Dx0000000BV7z' }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.create' do
|
51
|
+
context 'without multipart' do
|
52
|
+
requests 'sobjects/Account',
|
53
|
+
:method => :post,
|
54
|
+
:with_body => "{\"Name\":\"Foobar\"}",
|
55
|
+
:fixture => 'sobject/create_success_response'
|
56
|
+
|
57
|
+
subject { client.create('Account', :Name => 'Foobar') }
|
58
|
+
it { should eq 'some_id' }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with multipart' do
|
62
|
+
requests 'sobjects/Account',
|
63
|
+
:method => :post,
|
64
|
+
:with_body => %r(----boundary_string\r\nContent-Disposition: form-data; name=\"entity_content\";\r\nContent-Type: application/json\r\n\r\n{\"Name\":\"Foobar\"}\r\n----boundary_string\r\nContent-Disposition: form-data; name=\"Blob\"; filename=\"blob.jpg\"\r\nContent-Length: 42171\r\nContent-Type: image/jpeg\r\nContent-Transfer-Encoding: binary),
|
65
|
+
:fixture => 'sobject/create_success_response'
|
66
|
+
|
67
|
+
subject { client.create('Account', :Name => 'Foobar', :Blob => Sfdc::UploadIO.new(File.expand_path('../../fixtures/blob.jpg', __FILE__), 'image/jpeg')) }
|
68
|
+
it { should eq 'some_id' }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '.update!' do
|
73
|
+
context 'with invalid Id' do
|
74
|
+
requests 'sobjects/Account/001D000000INjVe',
|
75
|
+
:method => :patch,
|
76
|
+
:with_body => "{\"Name\":\"Foobar\"}",
|
77
|
+
:status => 404,
|
78
|
+
:fixture => 'sobject/delete_error_response'
|
79
|
+
|
80
|
+
subject { lambda { client.update!('Account', :Id => '001D000000INjVe', :Name => 'Foobar') } }
|
81
|
+
it { should raise_error Faraday::Error::ResourceNotFound }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '.update' do
|
86
|
+
context 'with missing Id' do
|
87
|
+
subject { lambda { client.update('Account', :Name => 'Foobar') } }
|
88
|
+
it { should raise_error ArgumentError, 'Id field missing from attrs.' }
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'with invalid Id' do
|
92
|
+
requests 'sobjects/Account/001D000000INjVe',
|
93
|
+
:method => :patch,
|
94
|
+
:with_body => "{\"Name\":\"Foobar\"}",
|
95
|
+
:status => 404,
|
96
|
+
:fixture => 'sobject/delete_error_response'
|
97
|
+
|
98
|
+
subject { client.update('Account', :Id => '001D000000INjVe', :Name => 'Foobar') }
|
99
|
+
it { should be_false }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with success' do
|
103
|
+
requests 'sobjects/Account/001D000000INjVe',
|
104
|
+
:method => :patch,
|
105
|
+
:with_body => "{\"Name\":\"Foobar\"}"
|
106
|
+
|
107
|
+
[:Id, :id, 'Id', 'id'].each do |key|
|
108
|
+
context "with #{key.inspect} as the key" do
|
109
|
+
subject { client.update('Account', key => '001D000000INjVe', :Name => 'Foobar') }
|
110
|
+
it { should be_true }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '.upsert!' do
|
117
|
+
context 'when updated' do
|
118
|
+
requests 'sobjects/Account/External__c/foobar',
|
119
|
+
:method => :patch,
|
120
|
+
:with_body => "{\"Name\":\"Foobar\"}"
|
121
|
+
|
122
|
+
context 'with symbol external Id key' do
|
123
|
+
subject { client.upsert!('Account', 'External__c', :External__c => 'foobar', :Name => 'Foobar') }
|
124
|
+
it { should be_true }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with string external Id key' do
|
128
|
+
subject { client.upsert!('Account', 'External__c', 'External__c' => 'foobar', 'Name' => 'Foobar') }
|
129
|
+
it { should be_true }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when created' do
|
134
|
+
requests 'sobjects/Account/External__c/foobar',
|
135
|
+
:method => :patch,
|
136
|
+
:with_body => "{\"Name\":\"Foobar\"}",
|
137
|
+
:fixture => 'sobject/upsert_created_success_response'
|
138
|
+
|
139
|
+
[:External__c, 'External__c', :external__c, 'external__c'].each do |key|
|
140
|
+
context "with #{key.inspect} as the external id" do
|
141
|
+
subject { client.upsert!('Account', 'External__c', key => 'foobar', :Name => 'Foobar') }
|
142
|
+
it { should eq 'foo' }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '.destroy!' do
|
149
|
+
subject(:destroy!) { client.destroy!('Account', '001D000000INjVe') }
|
150
|
+
|
151
|
+
context 'with invalid Id' do
|
152
|
+
requests 'sobjects/Account/001D000000INjVe',
|
153
|
+
:fixture => 'sobject/delete_error_response',
|
154
|
+
:method => :delete,
|
155
|
+
:status => 404
|
156
|
+
|
157
|
+
subject { lambda { destroy! } }
|
158
|
+
it { should raise_error Faraday::Error::ResourceNotFound }
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'with success' do
|
162
|
+
requests 'sobjects/Account/001D000000INjVe', :method => :delete
|
163
|
+
|
164
|
+
it { should be_true }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '.destroy' do
|
169
|
+
subject { client.destroy('Account', '001D000000INjVe') }
|
170
|
+
|
171
|
+
context 'with invalid Id' do
|
172
|
+
requests 'sobjects/Account/001D000000INjVe',
|
173
|
+
:fixture => 'sobject/delete_error_response',
|
174
|
+
:method => :delete,
|
175
|
+
:status => 404
|
176
|
+
|
177
|
+
it { should be_false }
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'with success' do
|
181
|
+
requests 'sobjects/Account/001D000000INjVe', :method => :delete
|
182
|
+
|
183
|
+
it { should be_true }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe '.find' do
|
188
|
+
context 'with no external id passed' do
|
189
|
+
requests 'sobjects/Account/001D000000INjVe',
|
190
|
+
:fixture => 'sobject/sobject_find_success_response'
|
191
|
+
|
192
|
+
subject { client.find('Account', '001D000000INjVe') }
|
193
|
+
it { should be_a Hash }
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'when an external id is passed' do
|
197
|
+
requests 'sobjects/Account/External_Field__c/1234',
|
198
|
+
:fixture => 'sobject/sobject_find_success_response'
|
199
|
+
|
200
|
+
subject { client.find('Account', '1234', 'External_Field__c') }
|
201
|
+
it { should be_a Hash }
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe '.authenticate!' do
|
206
|
+
subject(:authenticate!) { client.authenticate! }
|
207
|
+
|
208
|
+
context 'when successful' do
|
209
|
+
before do
|
210
|
+
@request = stub_login_request(:with_body => "grant_type=password&client_id=client_id&client_secret=" \
|
211
|
+
"client_secret&username=foo&password=barsecurity_token").
|
212
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
213
|
+
end
|
214
|
+
|
215
|
+
after do
|
216
|
+
expect(@request).to have_been_requested
|
217
|
+
end
|
218
|
+
|
219
|
+
it { should be_a Hash }
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'when no authentication middleware is present' do
|
223
|
+
before do
|
224
|
+
client.stub(:authentication_middleware).and_return(nil)
|
225
|
+
end
|
226
|
+
|
227
|
+
subject { lambda { authenticate! } }
|
228
|
+
it { should raise_error Sfdc::AuthenticationError, 'No authentication middleware present'}
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe '.without_caching' do
|
233
|
+
requests 'query\?q=SELECT%20some,%20fields%20FROM%20object',
|
234
|
+
:fixture => 'sobject/query_success_response'
|
235
|
+
|
236
|
+
before do
|
237
|
+
cache.should_receive(:delete).and_call_original
|
238
|
+
cache.should_receive(:fetch).and_call_original
|
239
|
+
end
|
240
|
+
|
241
|
+
let(:cache) { MockCache.new }
|
242
|
+
subject { client.without_caching { client.query('SELECT some, fields FROM object') } }
|
243
|
+
it { should be_an Enumerable }
|
244
|
+
end
|
245
|
+
|
246
|
+
describe 'authentication retries' do
|
247
|
+
context 'when retries reaches 0' do
|
248
|
+
before do
|
249
|
+
@auth_request = stub_api_request('query\?q=SELECT%20some,%20fields%20FROM%20object',
|
250
|
+
:status => 401,
|
251
|
+
:fixture => 'expired_session_response')
|
252
|
+
@query_request = stub_login_request(:with_body => "grant_type=password&client_id=client_id&client_secret=" \
|
253
|
+
"client_secret&username=foo&password=barsecurity_token").
|
254
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
255
|
+
end
|
256
|
+
|
257
|
+
subject { lambda { client.query('SELECT some, fields FROM object') } }
|
258
|
+
it { should raise_error Sfdc::UnauthorizedError }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe '.query with caching' do
|
263
|
+
let(:cache) { MockCache.new }
|
264
|
+
|
265
|
+
before do
|
266
|
+
@query = stub_api_request('query\?q=SELECT%20some,%20fields%20FROM%20object').
|
267
|
+
with(:headers => { 'Authorization' => "OAuth #{oauth_token}" }).
|
268
|
+
to_return(:status => 401, :body => fixture('expired_session_response'), :headers => { 'Content-Type' => 'application/json' }).then.
|
269
|
+
to_return(:status => 200, :body => fixture('sobject/query_success_response'), :headers => { 'Content-Type' => 'application/json' })
|
270
|
+
|
271
|
+
@login = stub_login_request(:with_body => "grant_type=password&client_id=client_id&client_secret=" \
|
272
|
+
"client_secret&username=foo&password=barsecurity_token").
|
273
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
274
|
+
end
|
275
|
+
|
276
|
+
after do
|
277
|
+
expect(@query).to have_been_made.times(2)
|
278
|
+
expect(@login).to have_been_made
|
279
|
+
end
|
280
|
+
|
281
|
+
subject { client.query('SELECT some, fields FROM object') }
|
282
|
+
it { should be_an Enumerable }
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe Sfdc::AbstractClient do
|
287
|
+
describe 'with mashify' do
|
288
|
+
it_behaves_like Sfdc::AbstractClient
|
289
|
+
|
290
|
+
describe '.query' do
|
291
|
+
context 'with pagination' do
|
292
|
+
subject { client.query('SELECT some, fields FROM object').next_page }
|
293
|
+
|
294
|
+
requests 'query\?q', :fixture => 'sobject/query_paginated_first_page_response'
|
295
|
+
requests 'query/01gD', :fixture => 'sobject/query_paginated_last_page_response'
|
296
|
+
|
297
|
+
it { should be_a Sfdc::Collection }
|
298
|
+
its('first.Text_Label') { should eq 'Last Page'}
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
describe 'without mashify', :mashify => false do
|
304
|
+
it_behaves_like Sfdc::AbstractClient
|
305
|
+
end
|
306
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for Sfdc::Data::Client do
|
4
|
+
describe '.picklist_values' do
|
5
|
+
requests 'sobjects/Account/describe',
|
6
|
+
:fixture => 'sobject/sobject_describe_success_response'
|
7
|
+
|
8
|
+
context 'when given a picklist field' do
|
9
|
+
subject { client.picklist_values('Account', 'Picklist_Field') }
|
10
|
+
it { should be_an Array }
|
11
|
+
its(:length) { should eq 3 }
|
12
|
+
it { should include_picklist_values ['one', 'two', 'three'] }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when given a multipicklist field' do
|
16
|
+
subject { client.picklist_values('Account', 'Picklist_Multiselect_Field') }
|
17
|
+
it { should be_an Array }
|
18
|
+
its(:length) { should eq 3 }
|
19
|
+
it { should include_picklist_values ['four', 'five', 'six'] }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'dependent picklists' do
|
23
|
+
context 'when given a picklist field that has a dependency' do
|
24
|
+
subject { client.picklist_values('Account', 'Dependent_Picklist_Field', :valid_for => 'one') }
|
25
|
+
it { should be_an Array }
|
26
|
+
its(:length) { should eq 2 }
|
27
|
+
it { should include_picklist_values ['seven', 'eight'] }
|
28
|
+
it { should_not include_picklist_values ['nine'] }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when given a picklist field that does not have a dependency' do
|
32
|
+
subject { client.picklist_values('Account', 'Picklist_Field', :valid_for => 'one') }
|
33
|
+
it 'raises an exception' do
|
34
|
+
expect { subject }.to raise_error(/Picklist_Field is not a dependent picklist/)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '.faye', :event_machine => true do
|
41
|
+
subject { client.faye }
|
42
|
+
|
43
|
+
context 'with missing instance url' do
|
44
|
+
let(:instance_url) { nil }
|
45
|
+
specify { expect { subject }.to raise_error RuntimeError, 'Instance URL missing. Call .authenticate! first.' }
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with oauth token and instance url' do
|
49
|
+
let(:instance_url) { 'http://google.com' }
|
50
|
+
let(:oauth_token) { 'bar' }
|
51
|
+
specify { expect { subject }.to_not raise_error }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when the connection goes down' do
|
55
|
+
it 'should reauthenticate' do
|
56
|
+
access_token = double('access token')
|
57
|
+
access_token.stub(:access_token).and_return('token')
|
58
|
+
client.should_receive(:authenticate!).and_return(access_token)
|
59
|
+
client.faye.should_receive(:set_header).with('Authorization', "OAuth token")
|
60
|
+
client.faye.trigger('transport:down')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '.subcribe', :event_machine => true do
|
66
|
+
context 'when given a single pushtopic' do
|
67
|
+
it 'subscribes to the pushtopic' do
|
68
|
+
client.faye.should_receive(:subscribe).with(['/topic/PushTopic'])
|
69
|
+
client.subscribe('PushTopic')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when given an array of pushtopics' do
|
74
|
+
it 'subscribes to each pushtopic' do
|
75
|
+
client.faye.should_receive(:subscribe).with(['/topic/PushTopic1', '/topic/PushTopic2'])
|
76
|
+
client.subscribe(['PushTopic1', 'PushTopic2'])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Sfdc::Data::Client do
|
83
|
+
describe 'with mashify' do
|
84
|
+
it_behaves_like Sfdc::Client
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'without mashify', :mashify => false do
|
88
|
+
it_behaves_like Sfdc::Client
|
89
|
+
end
|
90
|
+
end
|