rexpense 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +22 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.rubocop.yml +54 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +97 -0
- data/LICENSE.txt +21 -0
- data/README.md +195 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/rspec +21 -0
- data/bin/setup +7 -0
- data/lib/rexpense/client.rb +39 -0
- data/lib/rexpense/configuration.rb +13 -0
- data/lib/rexpense/entities/activity.rb +11 -0
- data/lib/rexpense/entities/activity_collection.rb +14 -0
- data/lib/rexpense/entities/advancement.rb +14 -0
- data/lib/rexpense/entities/advancement_collection.rb +14 -0
- data/lib/rexpense/entities/advancement_devolution.rb +13 -0
- data/lib/rexpense/entities/attachment.rb +13 -0
- data/lib/rexpense/entities/attachment_collection.rb +14 -0
- data/lib/rexpense/entities/base.rb +9 -0
- data/lib/rexpense/entities/collection.rb +65 -0
- data/lib/rexpense/entities/comment.rb +13 -0
- data/lib/rexpense/entities/comment_collection.rb +14 -0
- data/lib/rexpense/entities/expense.rb +22 -0
- data/lib/rexpense/entities/expense_collection.rb +14 -0
- data/lib/rexpense/entities/membership.rb +10 -0
- data/lib/rexpense/entities/membership_collection.rb +14 -0
- data/lib/rexpense/entities/organization.rb +14 -0
- data/lib/rexpense/entities/organization_collection.rb +14 -0
- data/lib/rexpense/entities/pre_expense.rb +17 -0
- data/lib/rexpense/entities/pre_expense_collection.rb +14 -0
- data/lib/rexpense/entities/reimbursement.rb +14 -0
- data/lib/rexpense/entities/reimbursement_collection.rb +14 -0
- data/lib/rexpense/entities/tag.rb +8 -0
- data/lib/rexpense/entities/tag_collection.rb +14 -0
- data/lib/rexpense/entities/user.rb +14 -0
- data/lib/rexpense/entities/user_collection.rb +14 -0
- data/lib/rexpense/entities/webhook.rb +10 -0
- data/lib/rexpense/entities/webhook_collection.rb +14 -0
- data/lib/rexpense/exception.rb +11 -0
- data/lib/rexpense/http.rb +41 -0
- data/lib/rexpense/request.rb +56 -0
- data/lib/rexpense/resources/activity.rb +24 -0
- data/lib/rexpense/resources/advancement.rb +20 -0
- data/lib/rexpense/resources/advancement_devolution.rb +36 -0
- data/lib/rexpense/resources/base.rb +52 -0
- data/lib/rexpense/resources/expense.rb +39 -0
- data/lib/rexpense/resources/nested_endpoints/attachment.rb +48 -0
- data/lib/rexpense/resources/nested_endpoints/comment.rb +84 -0
- data/lib/rexpense/resources/nested_endpoints/membership.rb +74 -0
- data/lib/rexpense/resources/nested_endpoints/participant.rb +43 -0
- data/lib/rexpense/resources/organization.rb +31 -0
- data/lib/rexpense/resources/pre_expense.rb +56 -0
- data/lib/rexpense/resources/reimbursement.rb +20 -0
- data/lib/rexpense/resources/resource_base.rb +105 -0
- data/lib/rexpense/resources/tag.rb +82 -0
- data/lib/rexpense/resources/webhook.rb +82 -0
- data/lib/rexpense/response.rb +43 -0
- data/lib/rexpense/version.rb +3 -0
- data/lib/rexpense.rb +19 -0
- data/rexpense.gemspec +48 -0
- data/spec/lib/rexpense/client_spec.rb +47 -0
- data/spec/lib/rexpense/configuration_spec.rb +26 -0
- data/spec/lib/rexpense/entities/activity_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/activity_spec.rb +9 -0
- data/spec/lib/rexpense/entities/advancement_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/advancement_devolution_spec.rb +9 -0
- data/spec/lib/rexpense/entities/advancement_spec.rb +10 -0
- data/spec/lib/rexpense/entities/base_spec.rb +28 -0
- data/spec/lib/rexpense/entities/collection_spec.rb +70 -0
- data/spec/lib/rexpense/entities/comment_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/comment_spec.rb +10 -0
- data/spec/lib/rexpense/entities/expense_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/expense_spec.rb +14 -0
- data/spec/lib/rexpense/entities/membership_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/membership_spec.rb +7 -0
- data/spec/lib/rexpense/entities/organization_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/organization_spec.rb +8 -0
- data/spec/lib/rexpense/entities/pre_expense_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/pre_expense_spec.rb +10 -0
- data/spec/lib/rexpense/entities/reimbursement_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/reimbursement_spec.rb +10 -0
- data/spec/lib/rexpense/entities/user_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/user_spec.rb +10 -0
- data/spec/lib/rexpense/entities/webhook_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/webhook_spec.rb +7 -0
- data/spec/lib/rexpense/http_spec.rb +37 -0
- data/spec/lib/rexpense/request_spec.rb +29 -0
- data/spec/lib/rexpense/resources/activity_spec.rb +16 -0
- data/spec/lib/rexpense/resources/advancement_devolution_spec.rb +29 -0
- data/spec/lib/rexpense/resources/advancement_spec.rb +207 -0
- data/spec/lib/rexpense/resources/expense_spec.rb +227 -0
- data/spec/lib/rexpense/resources/organization_spec.rb +162 -0
- data/spec/lib/rexpense/resources/pre_expense_spec.rb +83 -0
- data/spec/lib/rexpense/resources/reimbursement_spec.rb +207 -0
- data/spec/lib/rexpense/resources/tag_specs.rb +77 -0
- data/spec/lib/rexpense/resources/webhook_spec.rb +51 -0
- data/spec/lib/rexpense/response_spec.rb +91 -0
- data/spec/lib/rexpense_spec.rb +34 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/attachments/logo.png +0 -0
- data/spec/support/client.rb +3 -0
- data/spec/support/matchers/have_attr_accessor.rb +18 -0
- data/spec/support/shared_examples/entity_attributes.rb +9 -0
- data/spec/support/shared_examples/entity_collection.rb +19 -0
- data/spec/support/shared_examples/http_request_methods.rb +35 -0
- data/spec/support/vcr.rb +7 -0
- metadata +390 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rexpense::Resources::Reimbursement, vcr: true do
|
4
|
+
let(:reimbursement_klass) { Rexpense::Entities::Reimbursement }
|
5
|
+
|
6
|
+
describe "#find_all" do
|
7
|
+
context "with success" do
|
8
|
+
subject { client.reimbursements.find_all }
|
9
|
+
|
10
|
+
it "show all reimbursements successfully" do
|
11
|
+
expect(subject.class).to eq(Rexpense::Entities::ReimbursementCollection)
|
12
|
+
expect(subject.collection.first.class).to eq(reimbursement_klass)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "find reimbursements by attributes" do
|
17
|
+
params = { currency_in: ["USD"] }
|
18
|
+
result = client.reimbursements.find_all(params)
|
19
|
+
|
20
|
+
expect(result).to be_a(Rexpense::Entities::ReimbursementCollection)
|
21
|
+
expect(result.collection[0]).to be_a(reimbursement_klass)
|
22
|
+
expect(result.collection[0].currency).to eq("USD")
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when error" do
|
26
|
+
let(:client) { Rexpense.client("") }
|
27
|
+
|
28
|
+
it "raises Rexpense::RequestError with 401 status code" do
|
29
|
+
expect { client.reimbursements.find_all({}) }.to raise_error(Rexpense::RequestError) do |error|
|
30
|
+
expect(error.code).to eq(401)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#find" do
|
37
|
+
context "with success" do
|
38
|
+
subject { client.reimbursements.find(51) }
|
39
|
+
|
40
|
+
it "returns a category successfully" do
|
41
|
+
expect(subject.class).to eq(reimbursement_klass)
|
42
|
+
expect(subject.id).to eq(51)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with error" do
|
47
|
+
it "raises Rexpense::RequestError with 404 status code" do
|
48
|
+
expect { client.reimbursements.find(000000) }.to raise_error(Rexpense::RequestError) do |error|
|
49
|
+
expect(error.code).to eq(404)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#create" do
|
56
|
+
let(:params) do
|
57
|
+
{
|
58
|
+
amount: 10.0,
|
59
|
+
expense_ids: [241],
|
60
|
+
currency: 'BRL',
|
61
|
+
date: '2014-10-16',
|
62
|
+
payer: {
|
63
|
+
id: 16,
|
64
|
+
type: 'Organization'
|
65
|
+
},
|
66
|
+
receiver: {
|
67
|
+
id: 2,
|
68
|
+
type: 'User'
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with success" do
|
74
|
+
it "creates a category successfully" do
|
75
|
+
result = client.reimbursements.create(params)
|
76
|
+
expect(result).to be_a(reimbursement_klass)
|
77
|
+
expect(result.amount).to eq(10.0)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with error" do
|
82
|
+
it "raises Rexpense::RequestError with 422 status code" do
|
83
|
+
expect { client.reimbursements.create({}) }.to raise_error(Rexpense::RequestError) do |error|
|
84
|
+
expect(error.code).to eq(422)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#update" do
|
91
|
+
context "with success" do
|
92
|
+
it "updates a category successfully" do
|
93
|
+
expect(client.reimbursements.update(78, { description: 'something from nothing' })).to be_a(reimbursement_klass)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with error" do
|
98
|
+
it "raises Rexpense::RequestError with 404 status code" do
|
99
|
+
expect { client.reimbursements.update(88888888, {}) }.to raise_error(Rexpense::RequestError) do |error|
|
100
|
+
expect(error.code).to eq(404)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "raises Rexpense::RequestError with 422 status core" do
|
105
|
+
expect { client.reimbursements.update(78, { payer_id: nil }) }.to raise_error(Rexpense::RequestError) do |error|
|
106
|
+
expect(error.code).to eq(422)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#destroy" do
|
113
|
+
context "with success" do
|
114
|
+
it "destroy a category successfully" do
|
115
|
+
expect(client.reimbursements.destroy(78)).to be_truthy
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with error" do
|
120
|
+
it "raises Rexpense::RequestError with 404 status code" do
|
121
|
+
expect { client.reimbursements.destroy(88888888) }.to raise_error(Rexpense::RequestError) do |error|
|
122
|
+
expect(error.code).to eq(404)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'Comments' do
|
129
|
+
let(:comment_klass) { Rexpense::Entities::Comment }
|
130
|
+
|
131
|
+
describe '#comments' do
|
132
|
+
context "with success" do
|
133
|
+
subject { client.reimbursements.comments(11) }
|
134
|
+
|
135
|
+
it "show all reimbursement successfully" do
|
136
|
+
expect(subject.class).to eq(Rexpense::Entities::CommentCollection)
|
137
|
+
expect(subject.collection.first.class).to eq(comment_klass)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe '#find_comment' do
|
143
|
+
context "with success" do
|
144
|
+
subject { client.reimbursements.find_comment(11, 287) }
|
145
|
+
|
146
|
+
it "show a reimbursement comment successfully" do
|
147
|
+
expect(subject.class).to eq(comment_klass)
|
148
|
+
expect(subject.id).to eq(287)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#create_comment' do
|
154
|
+
context "with success" do
|
155
|
+
subject { client.reimbursements.create_comment(72, { content: 'Loren ipsun dollor' }) }
|
156
|
+
|
157
|
+
it "create a comment" do
|
158
|
+
expect(subject.class).to eq(comment_klass)
|
159
|
+
expect(subject.id).to eq(678)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#update_comment' do
|
165
|
+
context "with success" do
|
166
|
+
subject { client.reimbursements.update_comment(72, 678, { content: 'Foo bar' }) }
|
167
|
+
|
168
|
+
it "update comment" do
|
169
|
+
expect(subject.class).to eq(comment_klass)
|
170
|
+
expect(subject.id).to eq(678)
|
171
|
+
expect(subject.content).to eq('Foo bar')
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '#destroy_comment' do
|
177
|
+
subject { client.reimbursements.destroy_comment(72, 678) }
|
178
|
+
|
179
|
+
it "destroy comment" do
|
180
|
+
expect(subject).to be_truthy
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'Participants' do
|
186
|
+
let(:user_klass) { Rexpense::Entities::User }
|
187
|
+
|
188
|
+
describe "#participants" do
|
189
|
+
context "with success" do
|
190
|
+
subject { client.reimbursements.participants(70) }
|
191
|
+
|
192
|
+
it "show all reimbursements successfully" do
|
193
|
+
expect(subject.class).to eq(Rexpense::Entities::UserCollection)
|
194
|
+
expect(subject.collection.first.class).to eq(user_klass)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#leave_participant' do
|
200
|
+
subject { client.reimbursements.leave_participant(51) }
|
201
|
+
|
202
|
+
it "show all reimbursements successfully" do
|
203
|
+
expect(subject).to be_truthy
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rexpense::Resources::Tag, vcr: true do
|
4
|
+
let(:tag_klass) { Rexpense::Entities::Tag }
|
5
|
+
|
6
|
+
describe '#find_all' do
|
7
|
+
subject { client.tags.find_all(35) }
|
8
|
+
|
9
|
+
it "show all tags successfully" do
|
10
|
+
expect(subject.class).to eq(Rexpense::Entities::TagCollection)
|
11
|
+
expect(subject.collection.first.class).to eq(tag_klass)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when error" do
|
15
|
+
let(:client) { Rexpense.client("") }
|
16
|
+
|
17
|
+
it "raises Rexpense::RequestError with 401 status code" do
|
18
|
+
expect { client.tags.find_all(35) }.to raise_error(Rexpense::RequestError) do |error|
|
19
|
+
expect(error.code).to eq(401)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#find' do
|
26
|
+
subject { client.tags.find(35, 64) }
|
27
|
+
|
28
|
+
it "returns a category successfully" do
|
29
|
+
expect(subject.class).to eq(tag_klass)
|
30
|
+
expect(subject.id).to eq(64)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#create' do
|
35
|
+
subject { client.tags.create(35, { name: 'teste gem 2' }) }
|
36
|
+
|
37
|
+
it "returns a category successfully" do
|
38
|
+
expect(subject.class).to eq(tag_klass)
|
39
|
+
expect(subject.name).to eq('teste gem 2')
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with error" do
|
43
|
+
it "raises Rexpense::RequestError with 422 status core" do
|
44
|
+
expect { client.tags.create(35, { name: '' }) }.to raise_error(Rexpense::RequestError) do |error|
|
45
|
+
expect(error.code).to eq(422)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#update' do
|
52
|
+
subject { client.tags.update(35, 64, { name: 'updated tag' }) }
|
53
|
+
|
54
|
+
it "returns a category successfully" do
|
55
|
+
expect(subject.class).to eq(tag_klass)
|
56
|
+
expect(subject.name).to eq('updated tag')
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with error" do
|
60
|
+
it "raises Rexpense::RequestError with 422 status core" do
|
61
|
+
expect { client.tags.update(35, 64, { name: '' }) }.to raise_error(Rexpense::RequestError) do |error|
|
62
|
+
expect(error.code).to eq(422)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#destroy' do
|
69
|
+
subject { client.tags.destroy(35, 90) }
|
70
|
+
|
71
|
+
context "with success" do
|
72
|
+
it "destroy a category successfully" do
|
73
|
+
expect(subject).to be_truthy
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rexpense::Resources::Webhook, vcr: true do
|
4
|
+
let(:webhook_klass) { Rexpense::Entities::Webhook }
|
5
|
+
|
6
|
+
describe "#find_all" do
|
7
|
+
context "with success" do
|
8
|
+
subject { client.webhooks.find_all(35) }
|
9
|
+
|
10
|
+
it "show all webhooks successfully" do
|
11
|
+
expect(subject.class).to eq(Rexpense::Entities::WebhookCollection)
|
12
|
+
expect(subject.collection.first.class).to eq(webhook_klass)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#find" do
|
18
|
+
subject { client.webhooks.find(35, 2) }
|
19
|
+
|
20
|
+
it "returns a category successfully" do
|
21
|
+
expect(subject.class).to eq(webhook_klass)
|
22
|
+
expect(subject.id).to eq(2)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#create" do
|
27
|
+
subject { client.webhooks.create(35, { url: 'https://requestb.in/uxd48yux' }) }
|
28
|
+
|
29
|
+
it "returns a category successfully" do
|
30
|
+
expect(subject.class).to eq(webhook_klass)
|
31
|
+
expect(subject.url).to eq('https://requestb.in/uxd48yux')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#update" do
|
36
|
+
subject { client.webhooks.update(35, 4, { description: 'foobar' }) }
|
37
|
+
|
38
|
+
it "returns a category successfully" do
|
39
|
+
expect(subject.class).to eq(webhook_klass)
|
40
|
+
expect(subject.description).to eq('foobar')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#destroy" do
|
45
|
+
subject { client.webhooks.destroy(35, 2) }
|
46
|
+
|
47
|
+
it "destroy a webhook successfully" do
|
48
|
+
expect(subject).to be_truthy
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Rexpense::Response do
|
4
|
+
subject { described_class.new(response) }
|
5
|
+
|
6
|
+
describe "#resolve!" do
|
7
|
+
context 'when success' do
|
8
|
+
let(:response) { double(success?: true) }
|
9
|
+
|
10
|
+
it 'returns self' do
|
11
|
+
expect(subject.resolve!).to eq(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when block given' do
|
15
|
+
let(:response) { double(success?: true) }
|
16
|
+
|
17
|
+
it 'returns block' do
|
18
|
+
expect(subject.resolve!{ response }).to eq(response)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when timeout' do
|
24
|
+
let(:response) { double(success?: false, timed_out?: true) }
|
25
|
+
|
26
|
+
it 'raises RequestTimeout' do
|
27
|
+
expect { subject.resolve! }.to raise_error(Rexpense::RequestTimeout)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when not success neither timeout' do
|
32
|
+
let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: 'Moved Permanently', body: '') }
|
33
|
+
|
34
|
+
it 'raises RequestError' do
|
35
|
+
expect { subject.resolve! }.to raise_error do |error|
|
36
|
+
expect(error).to be_a(Rexpense::RequestError)
|
37
|
+
expect(error.code).to eq(301)
|
38
|
+
expect(error.message).to eq("Moved Permanently")
|
39
|
+
expect(error.body).to eq({})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when status_message is empty" do
|
44
|
+
context "when body has an 'error' key" do
|
45
|
+
let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: '', body: '{"error": "My custom error message"}') }
|
46
|
+
|
47
|
+
it "raises RequestError with custom message" do
|
48
|
+
expect { subject.resolve! }.to raise_error do |error|
|
49
|
+
expect(error).to be_a(Rexpense::RequestError)
|
50
|
+
expect(error.code).to eq(301)
|
51
|
+
expect(error.message).to eq("My custom error message")
|
52
|
+
expect(error.body).to eq({ "error" => "My custom error message" })
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when body has an 'error' key" do
|
58
|
+
let(:response) { double(success?: false, timed_out?: false, code: 301, status_message: '', body: '') }
|
59
|
+
|
60
|
+
it "raises RequestError with empty message" do
|
61
|
+
expect { subject.resolve! }.to raise_error do |error|
|
62
|
+
expect(error).to be_a(Rexpense::RequestError)
|
63
|
+
expect(error.code).to eq(301)
|
64
|
+
expect(error.message).to eq("")
|
65
|
+
expect(error.body).to eq({})
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#body" do
|
74
|
+
let(:response) { double(success?: true) }
|
75
|
+
|
76
|
+
context "when JSON is invalid" do
|
77
|
+
it "returns empty hash" do
|
78
|
+
allow(subject).to receive(:body).and_return("{\"key\": ")
|
79
|
+
expect(subject.parsed_body).to eq({})
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when JSON is valid" do
|
84
|
+
it "returns empty hash" do
|
85
|
+
allow(subject).to receive(:body).and_return("{\"key\": \"value\"}")
|
86
|
+
expect(JSON).to receive(:parse).with("{\"key\": \"value\"}").and_call_original
|
87
|
+
expect(subject.parsed_body).to eq({ "key" => "value" })
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Rexpense do
|
4
|
+
it "has a version number" do
|
5
|
+
expect(Rexpense::VERSION).to_not be_nil
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "configuration" do
|
9
|
+
it "should be done via block initialization" do
|
10
|
+
Rexpense.configure do |c|
|
11
|
+
c.user_agent = "My App v1.0"
|
12
|
+
c.api_mode = "sandbox"
|
13
|
+
c.version = 'v1'
|
14
|
+
end
|
15
|
+
|
16
|
+
expect(Rexpense.configuration.user_agent).to eq("My App v1.0")
|
17
|
+
expect(Rexpense.configuration.api_mode).to eq("sandbox")
|
18
|
+
expect(Rexpense.configuration.version).to eq("v1")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "uses a singleton object for the configuration values" do
|
22
|
+
config1 = Rexpense.configuration
|
23
|
+
config2 = Rexpense.configuration
|
24
|
+
expect(config1).to eq(config2)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".client" do
|
29
|
+
it "instantiates a new client" do
|
30
|
+
expect(Rexpense::Client).to receive(:new).with("abc").and_call_original
|
31
|
+
Rexpense.client("abc")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
require "simplecov"
|
3
|
+
|
4
|
+
CodeClimate::TestReporter.start
|
5
|
+
|
6
|
+
SimpleCov.start do
|
7
|
+
SimpleCov.maximum_coverage_drop 0.2
|
8
|
+
|
9
|
+
SimpleCov.start do
|
10
|
+
add_group "Resources", "lib/rexpense/resources"
|
11
|
+
add_group "Entities", "lib/rexpense/entities"
|
12
|
+
add_filter "vendor"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
18
|
+
require "rexpense"
|
19
|
+
require "pry"
|
20
|
+
require "vcr"
|
21
|
+
|
22
|
+
|
23
|
+
Dir["spec/support/**/*.rb"].each { |f| load f }
|
24
|
+
|
25
|
+
VCR.configure do |config|
|
26
|
+
config.cassette_library_dir = "spec/vcr_cassettes"
|
27
|
+
config.hook_into :typhoeus
|
28
|
+
config.ignore_hosts "codeclimate.com"
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.configure do |config|
|
32
|
+
config.mock_with :rspec
|
33
|
+
|
34
|
+
config.before(:each) do
|
35
|
+
Rexpense.configuration.api_mode = "sandbox"
|
36
|
+
Typhoeus::Expectation.clear
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec::Matchers.define :have_attr_accessor do |field|
|
2
|
+
match do |object_instance|
|
3
|
+
object_instance.respond_to?(field) &&
|
4
|
+
object_instance.respond_to?("#{field}=")
|
5
|
+
end
|
6
|
+
|
7
|
+
failure_message do |object_instance|
|
8
|
+
"expected attr_accessor for #{field} on #{object_instance}"
|
9
|
+
end
|
10
|
+
|
11
|
+
failure_message_when_negated do |object_instance|
|
12
|
+
"expected attr_accessor for #{field} not to be defined on #{object_instance}"
|
13
|
+
end
|
14
|
+
|
15
|
+
description do
|
16
|
+
"checks to see if there is an attr accessor on the supplied object"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
shared_examples :entity_collection do |entity_type, key|
|
2
|
+
let(:params) { double(headers: {}, parsed_body: { key => [] }) }
|
3
|
+
|
4
|
+
subject { described_class.new(params) }
|
5
|
+
|
6
|
+
context "#build" do
|
7
|
+
it "returns a collection(#{described_class})" do
|
8
|
+
expect(subject.build).to be_a(described_class)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#collection" do
|
13
|
+
before { subject.build }
|
14
|
+
|
15
|
+
it "returns items(#{entity_type})" do
|
16
|
+
expect(subject.collection).to all(be_a(entity_type))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
shared_examples "available http request methods" do
|
2
|
+
it "instantiates a new Request object" do
|
3
|
+
VCR.use_cassette("client/#{http_method}/request") do
|
4
|
+
expect(Rexpense::Request).to receive(:new).with(
|
5
|
+
body: params,
|
6
|
+
method: http_method,
|
7
|
+
token: "8cd049b4afca9213fb2455528394ab2fb0bc34f5c905f33c",
|
8
|
+
url: "https://sandbox.rexpense.com/api/v1#{url}",
|
9
|
+
user_agent: "Rexpense Ruby Client v#{Rexpense::VERSION}"
|
10
|
+
).and_call_original
|
11
|
+
subject.send(http_method, url, body: params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "runs the request" do
|
16
|
+
VCR.use_cassette("client/#{http_method}/request") do
|
17
|
+
expect_any_instance_of(Rexpense::Request).to receive(:run).and_call_original
|
18
|
+
subject.send(http_method, url, body: params)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "instantiates a new Response object" do
|
23
|
+
VCR.use_cassette("client/#{http_method}/request") do
|
24
|
+
expect(Rexpense::Response).to receive(:new).and_call_original
|
25
|
+
subject.send(http_method, url, body: params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "resolves the response of the request a new Response object" do
|
30
|
+
VCR.use_cassette("client/#{http_method}/request") do
|
31
|
+
expect_any_instance_of(Rexpense::Response).to receive(:resolve!).and_call_original
|
32
|
+
subject.send(http_method, url, body: params)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/support/vcr.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
# pass `vcr: true` to an example to run it using VCR
|
3
|
+
config.around(:each, vcr: true) do |example|
|
4
|
+
name = example.metadata[:full_description].gsub(/\W+/, "_").split("_", 2).join("/").gsub('::', '_')[0, 94]
|
5
|
+
VCR.use_cassette(name, record: :once) { example.call }
|
6
|
+
end
|
7
|
+
end
|