charging-client 0.0.2
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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +191 -0
- data/README.rdoc +228 -0
- data/Rakefile +16 -0
- data/charging-client.gemspec +40 -0
- data/lib/charging.rb +36 -0
- data/lib/charging/base.rb +109 -0
- data/lib/charging/charge_account.rb +169 -0
- data/lib/charging/collection.rb +29 -0
- data/lib/charging/configuration.rb +28 -0
- data/lib/charging/domain.rb +164 -0
- data/lib/charging/helpers.rb +37 -0
- data/lib/charging/http.rb +96 -0
- data/lib/charging/invoice.rb +191 -0
- data/lib/charging/service_account.rb +50 -0
- data/lib/charging/version.rb +4 -0
- data/spec/charging/charge_account_collection_spec.rb +95 -0
- data/spec/charging/charge_account_spec.rb +289 -0
- data/spec/charging/configuration_spec.rb +61 -0
- data/spec/charging/domain_collection_spec.rb +101 -0
- data/spec/charging/domain_spec.rb +386 -0
- data/spec/charging/helpers_spec.rb +59 -0
- data/spec/charging/http_last_response_error_spec.rb +18 -0
- data/spec/charging/http_spec.rb +184 -0
- data/spec/charging/invoice_spec.rb +442 -0
- data/spec/charging/service_account_spec.rb +71 -0
- data/spec/charging_spec.rb +42 -0
- data/spec/fixtures/new_user.json +8 -0
- data/spec/fixtures/recreate_user.json +9 -0
- data/spec/spec_helper.rb +69 -0
- data/spec/support/factory.rb +32 -0
- data/spec/support/faker.rb +56 -0
- metadata +283 -0
@@ -0,0 +1,386 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Charging::Domain, :vcr do
|
6
|
+
let(:national_identifier) { Faker.cnpj_generator }
|
7
|
+
let(:attributes) do
|
8
|
+
{
|
9
|
+
supplier_name: 'Springfield Elemenary School',
|
10
|
+
address: '1608 Florida Avenue',
|
11
|
+
city_state: 'Greenwood/SC',
|
12
|
+
zipcode: '29646',
|
13
|
+
national_identifier: national_identifier,
|
14
|
+
description: 'The mission of Greenwood School District 50 is to educate all students to become responsible and productive citizens.',
|
15
|
+
}
|
16
|
+
end
|
17
|
+
let(:domain) do
|
18
|
+
described_class.new(attributes, current_account).create!
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'for new domain instance' do
|
22
|
+
let(:response_mock) { double(:response, code: 500) }
|
23
|
+
|
24
|
+
subject do
|
25
|
+
VCR.use_cassette('Domain/for new instance') do
|
26
|
+
described_class.new({
|
27
|
+
supplier_name: 'supplier_name data',
|
28
|
+
address: 'address data',
|
29
|
+
city_state: 'city_state data',
|
30
|
+
zipcode: 'zipcode data',
|
31
|
+
national_identifier: 'national_identifier data',
|
32
|
+
description: 'description data',
|
33
|
+
}, current_account, response_mock)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
%w[supplier_name address city_state zipcode national_identifier description].each do |attr|
|
38
|
+
describe attr do
|
39
|
+
subject { super().send(attr) }
|
40
|
+
it { is_expected.to eq "#{attr} data"}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
%w[uri uuid etag token].each do |attr|
|
45
|
+
describe attr do
|
46
|
+
subject { super().send(attr) }
|
47
|
+
it { is_expected.to be_nil }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#last_response' do
|
52
|
+
subject { super().last_response }
|
53
|
+
it { is_expected.to eq response_mock }
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#persisted?' do
|
57
|
+
subject { super().persisted? }
|
58
|
+
it { is_expected.to be_falsey }
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#deleted?' do
|
62
|
+
subject { super().deleted? }
|
63
|
+
it { is_expected.to be_falsey }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#account' do
|
67
|
+
subject { super().account }
|
68
|
+
it { is_expected.to eq current_account }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#attributes' do
|
72
|
+
subject { super().attributes }
|
73
|
+
it { is_expected.to eq({
|
74
|
+
address: 'address data',
|
75
|
+
city_state: 'city_state data',
|
76
|
+
description: 'description data',
|
77
|
+
national_identifier: 'national_identifier data',
|
78
|
+
supplier_name: 'supplier_name data',
|
79
|
+
zipcode: 'zipcode data'
|
80
|
+
}) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#create!' do
|
85
|
+
it 'should require an account and load errors' do
|
86
|
+
invalid_domain = described_class.new(attributes, nil)
|
87
|
+
|
88
|
+
expect(invalid_domain.errors).to be_empty
|
89
|
+
|
90
|
+
expected_error = [StandardError, 'can not create without a service account']
|
91
|
+
expect { invalid_domain.create! }.to raise_error(*expected_error)
|
92
|
+
|
93
|
+
expect(invalid_domain.errors).to eq ['can not create without a service account']
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when API responds with 409 Conflict' do
|
97
|
+
it 'should raise Http::LastResponseError, and load errors and last response' do
|
98
|
+
VCR.use_cassette('Domain/conflict to create a domain') do
|
99
|
+
domain
|
100
|
+
domain = described_class.new(attributes, current_account)
|
101
|
+
|
102
|
+
expect {
|
103
|
+
domain.create!
|
104
|
+
}.to raise_error Charging::Http::LastResponseError
|
105
|
+
|
106
|
+
expect(domain.errors).to_not be_empty
|
107
|
+
expect(domain.last_response.code).to eq 409
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when everything is OK' do
|
113
|
+
before do
|
114
|
+
VCR.use_cassette('Domain/creating a domain') do
|
115
|
+
@domain = described_class.new(attributes, current_account)
|
116
|
+
@domain.create!
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
subject { @domain }
|
121
|
+
|
122
|
+
[:uuid, :uri, :etag, :token].each do |attribute|
|
123
|
+
describe attribute do
|
124
|
+
subject { super().send(attribute) }
|
125
|
+
it { is_expected.not_to be_nil }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should be persisted' do
|
130
|
+
expect(subject).to be_persisted
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#destroy!' do
|
136
|
+
it 'should require an account and load errors' do
|
137
|
+
invalid_domain = described_class.new(attributes, nil)
|
138
|
+
|
139
|
+
expect(invalid_domain.errors).to be_empty
|
140
|
+
|
141
|
+
expected_error = [StandardError, 'can not destroy without a service account']
|
142
|
+
expect { invalid_domain.destroy! }.to raise_error(*expected_error)
|
143
|
+
|
144
|
+
expect(invalid_domain.errors).to eq ['can not destroy without a service account']
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should require a persisted domain' do
|
148
|
+
VCR.use_cassette('Domain/try destroy a new instance') do
|
149
|
+
not_persisted_domain = described_class.new(attributes, current_account)
|
150
|
+
|
151
|
+
expect(not_persisted_domain).to_not be_persisted
|
152
|
+
|
153
|
+
expected_error = [StandardError, 'can not destroy a not persisted domain']
|
154
|
+
|
155
|
+
expect {
|
156
|
+
not_persisted_domain.destroy!
|
157
|
+
}.to raise_error(*expected_error)
|
158
|
+
|
159
|
+
expect(not_persisted_domain.errors).to eq ['can not destroy a not persisted domain']
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should raise Http::LastResponseError for domains already deleted' do
|
164
|
+
VCR.use_cassette('Domain/try delete invalid domain') do
|
165
|
+
expect { domain.destroy! }.to_not raise_error
|
166
|
+
|
167
|
+
domain.instance_variable_set :@deleted, false
|
168
|
+
domain.instance_variable_set :@persisted, true
|
169
|
+
|
170
|
+
expect {
|
171
|
+
domain.destroy!
|
172
|
+
}.to raise_error Charging::Http::LastResponseError
|
173
|
+
end
|
174
|
+
|
175
|
+
expect(domain.last_response.code).to eq 404
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should delete an exist domain' do
|
179
|
+
VCR.use_cassette('Domain/deleting a domain') do
|
180
|
+
expect(domain).to be_persisted
|
181
|
+
expect(domain).to_not be_deleted
|
182
|
+
|
183
|
+
expect(domain.destroy!).to_not raise_error
|
184
|
+
|
185
|
+
expect(domain).to_not be_persisted
|
186
|
+
expect(domain).to be_deleted
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '.find_all' do
|
192
|
+
it 'should require an account' do
|
193
|
+
expected_error = [ArgumentError, 'service account required']
|
194
|
+
expect { described_class.find_all(nil) }.to raise_error(*expected_error)
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'for an account' do
|
198
|
+
before do
|
199
|
+
VCR.use_cassette('Domain/list all available domains') do
|
200
|
+
@domain = domain # loading a domain
|
201
|
+
@result = described_class.find_all(current_account)
|
202
|
+
@first_result = @result.first
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should result be a domain collection instance' do
|
207
|
+
expect(@result).to be_an_instance_of(Charging::Domain::Collection)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should contain only one domain' do
|
211
|
+
expect(@result.size).to_not eq 0
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should contain last response information' do
|
215
|
+
expect(@result.last_response.code).to eq 200
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'on first element result' do
|
219
|
+
it 'should be a persisted domain' do
|
220
|
+
expect(@first_result).to be_persisted
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should contain etag' do
|
224
|
+
expect(@first_result.etag).to_not be_nil
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should contain uuid' do
|
228
|
+
expect(@first_result.uuid).to_not be_nil
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should contain uri' do
|
232
|
+
expect(@first_result.uri).to_not be_nil
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe '.find_by_uuid' do
|
239
|
+
it 'should require an account' do
|
240
|
+
expected_error = [ArgumentError, 'service account required']
|
241
|
+
|
242
|
+
expect { described_class.find_by_uuid(nil, '') }.to raise_error(*expected_error)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should require an uuid' do
|
246
|
+
VCR.use_cassette('Domain/try find a domain by uuid with nil value') do
|
247
|
+
expected_error = [ArgumentError, 'uuid required']
|
248
|
+
|
249
|
+
|
250
|
+
expect { described_class.find_by_uuid(current_account, nil) }.to raise_error(*expected_error)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should raise for invalid uuid' do
|
255
|
+
VCR.use_cassette('Domain/not found a domain by uuid') do
|
256
|
+
expect { described_class.find_by_uuid(current_account, 'invalid-uuid') }.to raise_error Charging::Http::LastResponseError
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should raise if not response to success (200)' do
|
261
|
+
VCR.use_cassette('Domain/find by uuid with response not success') do
|
262
|
+
uuid = domain.uuid
|
263
|
+
|
264
|
+
response_mock = double('AcceptedResponse', code: 202, to_s: 'AcceptedResponse')
|
265
|
+
|
266
|
+
expect(described_class)
|
267
|
+
.to receive(:get_account_domain)
|
268
|
+
.with(current_account, uuid)
|
269
|
+
.and_return(response_mock)
|
270
|
+
|
271
|
+
expect {
|
272
|
+
described_class.find_by_uuid(current_account, uuid)
|
273
|
+
}.to raise_error Charging::Http::LastResponseError, 'AcceptedResponse'
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context 'for a valid uuid' do
|
278
|
+
before do
|
279
|
+
VCR.use_cassette('Domain/finding a domain by uuid via account') do
|
280
|
+
@current_account = current_account
|
281
|
+
@domain = domain
|
282
|
+
@uuid = @domain.uuid
|
283
|
+
|
284
|
+
@finded_domain = described_class.find_by_uuid(@current_account, @uuid)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
subject { @finded_domain }
|
289
|
+
|
290
|
+
it 'should instanciate a domain' do
|
291
|
+
expect(subject).to be_an_instance_of(Charging::Domain)
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should be a persisted instance' do
|
295
|
+
expect(subject).to be_persisted
|
296
|
+
end
|
297
|
+
|
298
|
+
describe '#uri' do
|
299
|
+
subject { super().uri }
|
300
|
+
it { is_expected.to eq "http://sandbox.charging.financeconnect.com.br/account/domains/#{@uuid}/" }
|
301
|
+
end
|
302
|
+
|
303
|
+
describe '#uuid' do
|
304
|
+
subject { super().uuid }
|
305
|
+
it { is_expected.to eq @uuid }
|
306
|
+
end
|
307
|
+
|
308
|
+
describe '#etag' do
|
309
|
+
subject { super().etag }
|
310
|
+
it { is_expected.to eq @domain.etag }
|
311
|
+
end
|
312
|
+
|
313
|
+
describe '#token' do
|
314
|
+
subject { super().token }
|
315
|
+
it { is_expected.to eq @domain.token }
|
316
|
+
end
|
317
|
+
|
318
|
+
describe '#account' do
|
319
|
+
subject { super().account }
|
320
|
+
it { is_expected.to eq @current_account }
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
describe '.find_by_token' do
|
326
|
+
it 'should require a token' do
|
327
|
+
VCR.use_cassette('Domain/try find by token with wil value') do
|
328
|
+
expected_error = [ArgumentError, 'token required']
|
329
|
+
|
330
|
+
expect { described_class.find_by_token(nil) }.to raise_error(*expected_error)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'should raise for invalid uuid' do
|
335
|
+
VCR.use_cassette('Domain/domain by token unauthorized') do
|
336
|
+
expect { described_class.find_by_token('invalid-token') }.to raise_error Charging::Http::LastResponseError
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context 'for a valid domain token' do
|
341
|
+
before do
|
342
|
+
VCR.use_cassette('Domain/finding a domain by token') do
|
343
|
+
@domain = domain
|
344
|
+
@uuid = @domain.uuid
|
345
|
+
@token = @domain.token
|
346
|
+
@finded_domain = described_class.find_by_token(@token)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
subject { @finded_domain }
|
351
|
+
|
352
|
+
it 'should instanciate a domain' do
|
353
|
+
expect(subject).to be_an_instance_of(Charging::Domain)
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'should be a persisted instance' do
|
357
|
+
expect(subject).to be_persisted
|
358
|
+
end
|
359
|
+
|
360
|
+
describe '#uri' do
|
361
|
+
subject { super().uri }
|
362
|
+
it { is_expected.to eq "http://sandbox.charging.financeconnect.com.br/account/domains/#{@uuid}/" }
|
363
|
+
end
|
364
|
+
|
365
|
+
describe '#uuid' do
|
366
|
+
subject { super().uuid }
|
367
|
+
it { is_expected.to eq @uuid }
|
368
|
+
end
|
369
|
+
|
370
|
+
describe '#etag' do
|
371
|
+
subject { super().etag }
|
372
|
+
it { is_expected.to eq @domain.etag }
|
373
|
+
end
|
374
|
+
|
375
|
+
describe '#token' do
|
376
|
+
subject { super().token }
|
377
|
+
it { is_expected.to eq @token }
|
378
|
+
end
|
379
|
+
|
380
|
+
describe '#account' do
|
381
|
+
subject { super().account }
|
382
|
+
it { is_expected.to be_nil }
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Charging::Helpers do
|
6
|
+
attr_reader :name, :address
|
7
|
+
|
8
|
+
describe '.load_variables' do
|
9
|
+
it 'should only load instance variables specified' do
|
10
|
+
object = Object.new
|
11
|
+
|
12
|
+
described_class.load_variables(object, [:name, :address, :phone], {name: 'name', 'address' => 'address', other: 'other'})
|
13
|
+
|
14
|
+
expect(object.instance_variable_get :@name).to eq 'name'
|
15
|
+
expect(object.instance_variable_get :@address).to eq 'address'
|
16
|
+
expect(object.instance_variables).to include(:@name, :@address, :@phone)
|
17
|
+
expect(object.instance_variables).to_not include(:@other)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.required_arguments!' do
|
22
|
+
it 'should raise for nil value' do
|
23
|
+
expect {
|
24
|
+
described_class.required_arguments!(name: nil)
|
25
|
+
}.to raise_error ArgumentError, 'name required'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not raise without nil value' do
|
29
|
+
expect {
|
30
|
+
described_class.required_arguments!(name: 'value')
|
31
|
+
}.to_not raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.hashify' do
|
36
|
+
it 'should results a hash for attributes from a object' do
|
37
|
+
attributes = [:name, :phones, :emails]
|
38
|
+
object = Struct.new(*attributes).new(
|
39
|
+
'John Doe',
|
40
|
+
{home: '+552123456789'},
|
41
|
+
['john.doe@mailinator.com', 'john@doe.com']
|
42
|
+
)
|
43
|
+
|
44
|
+
result = described_class.hashify(object, attributes)
|
45
|
+
|
46
|
+
expect(result).to eq(name: 'John Doe', phones: {home: '+552123456789'}, emails: ['john.doe@mailinator.com', 'john@doe.com'])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.extract_uuid' do
|
51
|
+
it 'should return an empty string if invalid data' do
|
52
|
+
expect(described_class.extract_uuid(nil)).to eq ''
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should extract uuid from charing url' do
|
56
|
+
expect(described_class.extract_uuid('/charging-accounts/any-uuid')).to eq 'any-uuid'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Charging::Http::LastResponseError do
|
5
|
+
let(:mock_response) { double(:some_http_response, to_s: 'called to_s from mock response') }
|
6
|
+
|
7
|
+
subject { described_class.new(mock_response) }
|
8
|
+
|
9
|
+
describe '#last_response' do
|
10
|
+
subject { super().last_response }
|
11
|
+
it { is_expected.to eq mock_response }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#message' do
|
15
|
+
subject { super().message }
|
16
|
+
it { is_expected.to eq 'called to_s from mock response'}
|
17
|
+
end
|
18
|
+
end
|