charging-client 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,184 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Charging::Http do
|
5
|
+
let(:mock_response) { double('restclient http response') }
|
6
|
+
let(:configuration) { Charging.configuration }
|
7
|
+
|
8
|
+
describe '.basic_credential_for' do
|
9
|
+
it 'should accept only user' do
|
10
|
+
expect(described_class.basic_credential_for('user')).to eql 'Basic dXNlcg=='
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should accept user and password' do
|
14
|
+
expect(described_class.basic_credential_for('user', 'pass')).to eql 'Basic dXNlcjpwYXNz'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.request_to_api' do
|
19
|
+
%w[post put patch].each do |method|
|
20
|
+
context 'with body as json' do
|
21
|
+
it "should use RestClient.#{method} with the supplied params and common options" do
|
22
|
+
expect(RestClient).to receive(method).with(
|
23
|
+
"#{configuration.url}/foo",
|
24
|
+
'{"hello":"world"}',
|
25
|
+
params: {},
|
26
|
+
authorization: 'Basic OnNvbWUtYXBwLXRva2Vu',
|
27
|
+
content_type: :json,
|
28
|
+
accept: :json,
|
29
|
+
user_agent: configuration.user_agent
|
30
|
+
).and_return(mock_response)
|
31
|
+
|
32
|
+
described_class.request_to_api(method, '/foo', {}, 'some-app-token', {hello: 'world'})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with body as string' do
|
37
|
+
it 'should use RestClient.post with the supplied params and common options' do
|
38
|
+
expect(RestClient).to receive(method).with(
|
39
|
+
"#{configuration.url}/foo",
|
40
|
+
'{"hello":"world"}',
|
41
|
+
params: {},
|
42
|
+
authorization: 'Basic OnNvbWUtYXBwLXRva2Vu',
|
43
|
+
content_type: :json,
|
44
|
+
accept: :json,
|
45
|
+
user_agent: configuration.user_agent
|
46
|
+
).and_return(mock_response)
|
47
|
+
|
48
|
+
described_class.request_to_api(method, '/foo', {}, 'some-app-token', '{"hello":"world"}')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe ".delete" do
|
55
|
+
it 'should delegate to request_to_api' do
|
56
|
+
expect(Charging::Http).to receive(:request_to_api).with(
|
57
|
+
:delete,
|
58
|
+
'/foo',
|
59
|
+
{etag: 'etag'},
|
60
|
+
'some-app-token'
|
61
|
+
)
|
62
|
+
|
63
|
+
described_class.delete('/foo', 'some-app-token', 'etag')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe ".get" do
|
68
|
+
it 'should delegate to request_to_api' do
|
69
|
+
expect(Charging::Http).to receive(:request_to_api).with(
|
70
|
+
:get,
|
71
|
+
'/foo',
|
72
|
+
{},
|
73
|
+
'some-app-token'
|
74
|
+
)
|
75
|
+
|
76
|
+
described_class.get('/foo', 'some-app-token')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
%w[post].each do |method|
|
81
|
+
describe ".#{method}" do
|
82
|
+
it 'should delegate to request_to_api' do
|
83
|
+
expect(Charging::Http).to receive(:request_to_api).with(
|
84
|
+
method.to_sym,
|
85
|
+
'/foo',
|
86
|
+
{spam: 'eggs'},
|
87
|
+
'some-app-token',
|
88
|
+
'body'
|
89
|
+
)
|
90
|
+
|
91
|
+
described_class.send(method, '/foo', 'some-app-token', 'body', spam: 'eggs')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
%w[put patch].each do |method|
|
97
|
+
describe ".#{method}" do
|
98
|
+
it 'should delegate to request_to_api' do
|
99
|
+
expect(Charging::Http).to receive(:request_to_api).with(
|
100
|
+
method.to_sym,
|
101
|
+
'/foo',
|
102
|
+
{etag: 'etag'},
|
103
|
+
'some-app-token',
|
104
|
+
'body'
|
105
|
+
)
|
106
|
+
|
107
|
+
described_class.send(method, '/foo', 'some-app-token', 'etag', 'body')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
specify('.charging_path') do
|
113
|
+
expect(described_class.charging_path('/path')).to eql "#{configuration.url}/path"
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '.common_params' do
|
117
|
+
context 'without etag' do
|
118
|
+
it 'should to return a hash with request headers' do
|
119
|
+
expect(described_class.common_params('token', nil)).to eql({
|
120
|
+
accept: :json,
|
121
|
+
authorization: 'Basic OnRva2Vu',
|
122
|
+
content_type: :json,
|
123
|
+
user_agent: configuration.user_agent
|
124
|
+
})
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'with etag' do
|
129
|
+
it 'should to return a hash with request headers' do
|
130
|
+
expect(described_class.common_params('token', 'etag')).to eql({
|
131
|
+
accept: :json,
|
132
|
+
authorization: 'Basic OnRva2Vu',
|
133
|
+
content_type: :json,
|
134
|
+
user_agent: configuration.user_agent,
|
135
|
+
'If-Match' => 'etag'
|
136
|
+
})
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '.encoded_body' do
|
142
|
+
context 'with hash body' do
|
143
|
+
it 'should convert to string in json format' do
|
144
|
+
expect(described_class.encoded_body({some: 'value'})).to eql('{"some":"value"}')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with string body' do
|
149
|
+
it 'should repass the original body' do
|
150
|
+
expect(described_class.encoded_body('some text')).to eql('some text')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '.should_follow_redirect' do
|
156
|
+
context 'on success response code (200)' do
|
157
|
+
it 'should call return on response' do
|
158
|
+
response = double(code: 200).tap do |mock|
|
159
|
+
expect(mock).not_to receive(:follow_redirection)
|
160
|
+
expect(mock).to receive(:return!)
|
161
|
+
end
|
162
|
+
|
163
|
+
described_class.should_follow_redirect.call(response, nil, nil)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
{
|
168
|
+
301 => 'moved permanently',
|
169
|
+
302 => 'found',
|
170
|
+
307 => 'temporary redirect'
|
171
|
+
}.each do |status_code, status_message|
|
172
|
+
context "on #{status_message} response code (#{status_code})" do
|
173
|
+
it 'should call follow redirection on response' do
|
174
|
+
response = double(code: status_code).tap do |mock|
|
175
|
+
expect(mock).to receive(:follow_redirection)
|
176
|
+
expect(mock).not_to receive(:return!)
|
177
|
+
end
|
178
|
+
|
179
|
+
described_class.should_follow_redirect.call(response, nil, nil)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,442 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Charging::Invoice, :vcr do
|
6
|
+
let(:national_identifier) { Faker.cnpj_generator }
|
7
|
+
let(:domain) { create_domain(current_account, national_identifier) }
|
8
|
+
let(:charge_account) { create_charge_account(domain) }
|
9
|
+
let(:attributes) do
|
10
|
+
{
|
11
|
+
kind: 2,
|
12
|
+
amount: 123.45,
|
13
|
+
document_number: '000000000000001',
|
14
|
+
drawee: {
|
15
|
+
name: 'Nome do Sacado',
|
16
|
+
address: 'Rua do Carmo, 43',
|
17
|
+
city_state: 'Rio de Janeiro/RJ',
|
18
|
+
zipcode: '21345-999',
|
19
|
+
national_identifier: '37.818.380/0001-86'
|
20
|
+
},
|
21
|
+
due_date: '2020-12-31'
|
22
|
+
}
|
23
|
+
end
|
24
|
+
let(:invoice) { described_class.new(attributes, domain, charge_account).create! }
|
25
|
+
|
26
|
+
context 'for new instance' do
|
27
|
+
INVOICE_ATTRIBUTES = [
|
28
|
+
:kind, :amount, :document_number, :drawee, :due_date, :portfolio_code,
|
29
|
+
:charging_features, :supplier_name, :discount, :interest, :rebate,
|
30
|
+
:ticket, :protest_code, :protest_days, :instructions, :demonstrative,
|
31
|
+
:our_number
|
32
|
+
]
|
33
|
+
|
34
|
+
let(:response) { double(:response, code: 500) }
|
35
|
+
|
36
|
+
before do
|
37
|
+
VCR.use_cassette('Invoice/for new instance') do
|
38
|
+
attributes = Hash[*INVOICE_ATTRIBUTES.map {|attr| [attr, "#{attr} value"] }.flatten]
|
39
|
+
@domain = domain
|
40
|
+
@charge_account = charge_account
|
41
|
+
|
42
|
+
@new_invoice = described_class.new(attributes, @domain, @charge_account, response)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
subject { @new_invoice }
|
47
|
+
|
48
|
+
INVOICE_ATTRIBUTES.each do |attribute|
|
49
|
+
describe attribute do
|
50
|
+
subject { super().send(attribute) }
|
51
|
+
it { is_expected.to eq "#{attribute} value"}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
[:uuid, :uri, :etag, :document_date, :paid].each do |attribute|
|
56
|
+
describe attribute do
|
57
|
+
subject { super().send(attribute) }
|
58
|
+
it { is_expected.to be_nil }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#domain' do
|
63
|
+
subject { super().domain }
|
64
|
+
it { is_expected.to eq @domain }
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#charge_account' do
|
68
|
+
subject { super().charge_account }
|
69
|
+
it { is_expected.to eq @charge_account }
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#last_response' do
|
73
|
+
subject { super().last_response }
|
74
|
+
it { is_expected.to eq response }
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#errors' do
|
78
|
+
subject { super().errors }
|
79
|
+
it { is_expected.to eq [] }
|
80
|
+
end
|
81
|
+
|
82
|
+
specify('#persisted?') { expect(subject).to_not be_persisted }
|
83
|
+
specify('#deleted?') { expect(subject).to_not be_deleted }
|
84
|
+
|
85
|
+
describe '#attributes' do
|
86
|
+
subject { super().attributes }
|
87
|
+
it do
|
88
|
+
is_expected.to eq({
|
89
|
+
amount: 'amount value',
|
90
|
+
kind: 'kind value',
|
91
|
+
document_number: 'document_number value',
|
92
|
+
drawee: 'drawee value',
|
93
|
+
due_date: 'due_date value',
|
94
|
+
charging_features: 'charging_features value',
|
95
|
+
supplier_name: 'supplier_name value',
|
96
|
+
discount: 'discount value',
|
97
|
+
interest: 'interest value',
|
98
|
+
rebate: 'rebate value',
|
99
|
+
ticket: 'ticket value',
|
100
|
+
protest_code: 'protest_code value',
|
101
|
+
protest_days: 'protest_days value',
|
102
|
+
instructions: 'instructions value',
|
103
|
+
demonstrative: 'demonstrative value',
|
104
|
+
our_number: 'our_number value',
|
105
|
+
portfolio_code: 'portfolio_code value'
|
106
|
+
})
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#create!' do
|
112
|
+
it 'should require a domain and load errors' do
|
113
|
+
VCR.use_cassette('Invoice/try create an invoice with invalid domain') do
|
114
|
+
invoice = described_class.new(attributes, nil, charge_account)
|
115
|
+
|
116
|
+
expect(invoice.errors).to be_empty
|
117
|
+
|
118
|
+
expected_error = [StandardError, 'can not create without a domain']
|
119
|
+
expect { invoice.create! }.to raise_error(*expected_error)
|
120
|
+
|
121
|
+
expect(invoice.errors).to eq ['can not create without a domain']
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should require a charge account and load errors' do
|
126
|
+
VCR.use_cassette('Invoice/try create an invoice with invalid charge account') do
|
127
|
+
invoice = described_class.new(attributes, domain, nil)
|
128
|
+
|
129
|
+
expect(invoice.errors).to be_empty
|
130
|
+
|
131
|
+
expected_error = [StandardError, 'can not create wihtout a charge account']
|
132
|
+
expect { invoice.create! }.to raise_error(*expected_error)
|
133
|
+
|
134
|
+
expect(invoice.errors).to eq ['can not create wihtout a charge account']
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when everything is OK' do
|
139
|
+
before do
|
140
|
+
VCR.use_cassette('Invoice/creating an invoice') do
|
141
|
+
@charge_account = charge_account
|
142
|
+
@domain = @charge_account.domain
|
143
|
+
|
144
|
+
@invoice = described_class.new(attributes, domain, charge_account).create!
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
subject { @invoice }
|
149
|
+
|
150
|
+
[:uuid, :uri, :etag].each do |attribute|
|
151
|
+
describe attribute do
|
152
|
+
subject { super().send(attribute) }
|
153
|
+
it { is_expected.not_to be_nil }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should be persisted' do
|
158
|
+
expect(subject).to be_persisted
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#billet_url' do
|
164
|
+
context 'for not persisted invoice' do
|
165
|
+
subject {
|
166
|
+
VCR.use_cassette('Invoice/check billet url for new invoice instance') do
|
167
|
+
described_class.new({}, domain, charge_account, nil)
|
168
|
+
end
|
169
|
+
}
|
170
|
+
|
171
|
+
describe '#billet_url' do
|
172
|
+
subject { super().billet_url }
|
173
|
+
it { is_expected.to be_nil }
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'for a persisted invoice' do
|
178
|
+
it 'should be nil if something wrong' do
|
179
|
+
VCR.use_cassette('Invoice/try get billet url when something is wrong') do
|
180
|
+
@invoice = invoice
|
181
|
+
|
182
|
+
expect(Charging::Http)
|
183
|
+
.to receive(:get).with("/invoices/#{@invoice.uuid}/billet/", domain.token)
|
184
|
+
.and_return(double(:server_error, code: 500, body: 'generic error message'))
|
185
|
+
|
186
|
+
expect(@invoice.billet_url).to be_nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should get current billet url' do
|
191
|
+
VCR.use_cassette('Invoice/finding current billet url for invoice') do
|
192
|
+
@invoice = invoice
|
193
|
+
expected_url = %r{http://sandbox.charging.financeconnect.com.br/billets/#{@invoice.uuid}/\w+/}
|
194
|
+
expect(@invoice.billet_url).to match expected_url
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe '#pay!' do
|
201
|
+
context 'when something went wrong' do
|
202
|
+
it 'should load raise error' do
|
203
|
+
VCR.use_cassette('Invoice/paying an invoice and something is wrong') do
|
204
|
+
body = MultiJson.encode({
|
205
|
+
amount: invoice.amount,
|
206
|
+
date: Time.now.strftime('%Y-%m-%d')
|
207
|
+
})
|
208
|
+
|
209
|
+
expect(Charging::Http)
|
210
|
+
.to receive(:post).with("/invoices/#{invoice.uuid}/pay/", domain.token, body, etag: invoice.etag)
|
211
|
+
.and_return(double(:response, code: 500))
|
212
|
+
|
213
|
+
expected_error = [Charging::Http::LastResponseError]
|
214
|
+
|
215
|
+
expect { invoice.pay! }.to raise_error(*expected_error)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'when success payment' do
|
221
|
+
it 'should update paid value' do
|
222
|
+
VCR.use_cassette('Invoice/paying an invoice') do
|
223
|
+
invoice.pay!
|
224
|
+
|
225
|
+
expect(invoice.paid).to eq("123.45")
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should pass a new amount' do
|
231
|
+
VCR.use_cassette('Invoice/paying an invoice with another amount') do
|
232
|
+
body = MultiJson.encode({
|
233
|
+
amount: 100,
|
234
|
+
date: Time.now.strftime('%Y-%m-%d')
|
235
|
+
})
|
236
|
+
|
237
|
+
@invoice = invoice
|
238
|
+
@domain = domain
|
239
|
+
|
240
|
+
expect(Charging::Http)
|
241
|
+
.to receive(:post)
|
242
|
+
.with("/invoices/#{@invoice.uuid}/pay/", @domain.token, body, etag: @invoice.etag)
|
243
|
+
.and_return(double(:response, code: 201))
|
244
|
+
|
245
|
+
expect(invoice).to receive(:reload_attributes!)
|
246
|
+
|
247
|
+
invoice.pay!(amount: 100)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should pass a payment date' do
|
252
|
+
VCR.use_cassette('Invoice/paying an invoice with another date') do
|
253
|
+
today = Time.now.strftime('%Y-%m-%d')
|
254
|
+
|
255
|
+
@invoice = invoice
|
256
|
+
@domain = domain
|
257
|
+
|
258
|
+
body = MultiJson.encode({
|
259
|
+
amount: @invoice.amount,
|
260
|
+
date: today
|
261
|
+
})
|
262
|
+
|
263
|
+
expect(Charging::Http)
|
264
|
+
.to receive(:post).with("/invoices/#{@invoice.uuid}/pay/", @domain.token, body, etag: @invoice.etag)
|
265
|
+
.and_return(double(:response, code: 201))
|
266
|
+
|
267
|
+
expect(invoice).to receive(:reload_attributes!)
|
268
|
+
|
269
|
+
invoice.pay!(date: today)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should pass a note' do
|
274
|
+
VCR.use_cassette('Invoice/paying an invoice and adding a note') do
|
275
|
+
@invoice = invoice
|
276
|
+
|
277
|
+
body = MultiJson.encode({
|
278
|
+
amount: @invoice.amount,
|
279
|
+
date: Time.now.strftime('%Y-%m-%d'),
|
280
|
+
note: 'some note for payment'
|
281
|
+
})
|
282
|
+
|
283
|
+
expect(Charging::Http)
|
284
|
+
.to receive(:post).with("/invoices/#{@invoice.uuid}/pay/", domain.token, body, etag: @invoice.etag)
|
285
|
+
.and_return(double(:response, code: 201))
|
286
|
+
|
287
|
+
expect(invoice).to receive(:reload_attributes!)
|
288
|
+
|
289
|
+
invoice.pay!(note: "some note for payment")
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe '#payments' do
|
295
|
+
context 'invoice without payments' do
|
296
|
+
it 'should return an empty array' do
|
297
|
+
VCR.use_cassette('Invoice/invoice without payments') do
|
298
|
+
expect(invoice.payments).to eq []
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context 'invoice with payments' do
|
304
|
+
it 'should return an empty array' do
|
305
|
+
VCR.use_cassette('Invoice/invoice with payments') do
|
306
|
+
invoice.pay!
|
307
|
+
|
308
|
+
expect(invoice.payments).to_not be_empty
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe '#destroy!' do
|
315
|
+
it 'should raise delete an invoice at API' do
|
316
|
+
VCR.use_cassette('Invoice/try delete an invoice with payments') do
|
317
|
+
invoice.pay!
|
318
|
+
|
319
|
+
expect(invoice.payments).to_not be_empty
|
320
|
+
|
321
|
+
expect { invoice.destroy! }.to raise_error Charging::Http::LastResponseError
|
322
|
+
|
323
|
+
expect(invoice).to_not be_deleted
|
324
|
+
expect(invoice).to be_persisted
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'should delete an invoice without payments' do
|
329
|
+
VCR.use_cassette('Invoice/deleting an invoice without payments') do
|
330
|
+
expect(invoice).to be_persisted
|
331
|
+
|
332
|
+
expect { invoice.destroy! }.to_not raise_error
|
333
|
+
|
334
|
+
expect(invoice).to be_deleted
|
335
|
+
expect(invoice).to_not be_persisted
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
describe '.find_by_uuid' do
|
341
|
+
it 'should require an account' do
|
342
|
+
expected_error = [ArgumentError, 'domain required']
|
343
|
+
|
344
|
+
expect { described_class.find_by_uuid(nil, '') }.to raise_error(*expected_error)
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'should require an uuid' do
|
348
|
+
VCR.use_cassette('Invoice/try find by uuid an invoice with nil value') do
|
349
|
+
expected_error = [ArgumentError, 'uuid required']
|
350
|
+
|
351
|
+
expect { described_class.find_by_uuid(domain, nil) }.to raise_error(*expected_error)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'should raise for invalid uuid' do
|
356
|
+
VCR.use_cassette('Invoice/try find by uuid an invoice with invalid uuid') do
|
357
|
+
expect { described_class.find_by_uuid(domain, 'invalid-uuid') }.to raise_error Charging::Http::LastResponseError
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'should raise if not response to success (200)' do
|
362
|
+
VCR.use_cassette('Invoice/try find by uuid an invoice when response not success') do
|
363
|
+
response_mock = double('AcceptedResponse', code: 202, to_s: 'AcceptedResponse')
|
364
|
+
|
365
|
+
expect(described_class)
|
366
|
+
.to receive(:get_invoice)
|
367
|
+
.with(domain, 'uuid')
|
368
|
+
.and_return(response_mock)
|
369
|
+
|
370
|
+
expect {
|
371
|
+
described_class.find_by_uuid(domain, 'uuid')
|
372
|
+
}.to raise_error Charging::Http::LastResponseError, 'AcceptedResponse'
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
context 'for a valid uuid' do
|
377
|
+
before do
|
378
|
+
VCR.use_cassette('Invoice/find by uuid an invoice') do
|
379
|
+
@invoice = invoice
|
380
|
+
@find_result = described_class.find_by_uuid(domain, @invoice.uuid)
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
subject { @find_result }
|
385
|
+
|
386
|
+
it 'should instantiate a charge account' do
|
387
|
+
expect(subject).to be_an_instance_of(Charging::Invoice)
|
388
|
+
end
|
389
|
+
|
390
|
+
describe '#uri' do
|
391
|
+
subject { super().uri }
|
392
|
+
it { is_expected.to eq "http://sandbox.charging.financeconnect.com.br/invoices/#{@invoice.uuid}/" }
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
describe '.kinds' do
|
398
|
+
it 'should require a domain' do
|
399
|
+
expected_error = [ArgumentError, 'domain required']
|
400
|
+
|
401
|
+
expect { described_class.kinds(nil) }.to raise_error(*expected_error)
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'should raise for invalid domain' do
|
405
|
+
VCR.use_cassette('Invoice/try get invoice kinds with invalid domain token') do
|
406
|
+
expected_error = [Charging::Http::LastResponseError]
|
407
|
+
|
408
|
+
expect { described_class.kinds(double(token: 'invalid')) }.to raise_error(*expected_error)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should return an array with first page' do
|
413
|
+
VCR.use_cassette('Invoice/get first page of invoice kinds') do
|
414
|
+
default_result = described_class.kinds(domain)
|
415
|
+
first_page_result = described_class.kinds(domain, 1)
|
416
|
+
|
417
|
+
expect(default_result).to eq first_page_result
|
418
|
+
|
419
|
+
expect(default_result).to include({"acronym"=>"DM", "itau_code"=>1, "code"=>2, "name"=>"Duplicata Mercantil"})
|
420
|
+
expect(default_result.size).to eq 10
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should return an array with second page' do
|
425
|
+
VCR.use_cassette('Invoice/get second page of invoice kinds') do
|
426
|
+
result = described_class.kinds(domain, 2)
|
427
|
+
|
428
|
+
expect(result).to_not include({"acronym"=>"DM", "itau_code"=>1, "code"=>2, "name"=>"Duplicata Mercantil"})
|
429
|
+
expect(result.size).to eq 10
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'should return an array of kinds passing new limit per page' do
|
434
|
+
VCR.use_cassette('Invoice/get first page of invoice kinds with 12 items per page') do
|
435
|
+
result = described_class.kinds(domain, 1, 12)
|
436
|
+
|
437
|
+
expect(result).to include({"acronym"=>"DM", "itau_code"=>1, "code"=>2, "name"=>"Duplicata Mercantil"})
|
438
|
+
expect(result.size).to eq 12
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|