rexpense 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +22 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +24 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +54 -0
  7. data/.travis.yml +9 -0
  8. data/CHANGELOG.md +1 -0
  9. data/Gemfile +4 -0
  10. data/Gemfile.lock +97 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +195 -0
  13. data/Rakefile +6 -0
  14. data/bin/console +14 -0
  15. data/bin/rspec +21 -0
  16. data/bin/setup +7 -0
  17. data/lib/rexpense/client.rb +39 -0
  18. data/lib/rexpense/configuration.rb +13 -0
  19. data/lib/rexpense/entities/activity.rb +11 -0
  20. data/lib/rexpense/entities/activity_collection.rb +14 -0
  21. data/lib/rexpense/entities/advancement.rb +14 -0
  22. data/lib/rexpense/entities/advancement_collection.rb +14 -0
  23. data/lib/rexpense/entities/advancement_devolution.rb +13 -0
  24. data/lib/rexpense/entities/attachment.rb +13 -0
  25. data/lib/rexpense/entities/attachment_collection.rb +14 -0
  26. data/lib/rexpense/entities/base.rb +9 -0
  27. data/lib/rexpense/entities/collection.rb +65 -0
  28. data/lib/rexpense/entities/comment.rb +13 -0
  29. data/lib/rexpense/entities/comment_collection.rb +14 -0
  30. data/lib/rexpense/entities/expense.rb +22 -0
  31. data/lib/rexpense/entities/expense_collection.rb +14 -0
  32. data/lib/rexpense/entities/membership.rb +10 -0
  33. data/lib/rexpense/entities/membership_collection.rb +14 -0
  34. data/lib/rexpense/entities/organization.rb +14 -0
  35. data/lib/rexpense/entities/organization_collection.rb +14 -0
  36. data/lib/rexpense/entities/pre_expense.rb +17 -0
  37. data/lib/rexpense/entities/pre_expense_collection.rb +14 -0
  38. data/lib/rexpense/entities/reimbursement.rb +14 -0
  39. data/lib/rexpense/entities/reimbursement_collection.rb +14 -0
  40. data/lib/rexpense/entities/tag.rb +8 -0
  41. data/lib/rexpense/entities/tag_collection.rb +14 -0
  42. data/lib/rexpense/entities/user.rb +14 -0
  43. data/lib/rexpense/entities/user_collection.rb +14 -0
  44. data/lib/rexpense/entities/webhook.rb +10 -0
  45. data/lib/rexpense/entities/webhook_collection.rb +14 -0
  46. data/lib/rexpense/exception.rb +11 -0
  47. data/lib/rexpense/http.rb +41 -0
  48. data/lib/rexpense/request.rb +56 -0
  49. data/lib/rexpense/resources/activity.rb +24 -0
  50. data/lib/rexpense/resources/advancement.rb +20 -0
  51. data/lib/rexpense/resources/advancement_devolution.rb +36 -0
  52. data/lib/rexpense/resources/base.rb +52 -0
  53. data/lib/rexpense/resources/expense.rb +39 -0
  54. data/lib/rexpense/resources/nested_endpoints/attachment.rb +48 -0
  55. data/lib/rexpense/resources/nested_endpoints/comment.rb +84 -0
  56. data/lib/rexpense/resources/nested_endpoints/membership.rb +74 -0
  57. data/lib/rexpense/resources/nested_endpoints/participant.rb +43 -0
  58. data/lib/rexpense/resources/organization.rb +31 -0
  59. data/lib/rexpense/resources/pre_expense.rb +56 -0
  60. data/lib/rexpense/resources/reimbursement.rb +20 -0
  61. data/lib/rexpense/resources/resource_base.rb +105 -0
  62. data/lib/rexpense/resources/tag.rb +82 -0
  63. data/lib/rexpense/resources/webhook.rb +82 -0
  64. data/lib/rexpense/response.rb +43 -0
  65. data/lib/rexpense/version.rb +3 -0
  66. data/lib/rexpense.rb +19 -0
  67. data/rexpense.gemspec +48 -0
  68. data/spec/lib/rexpense/client_spec.rb +47 -0
  69. data/spec/lib/rexpense/configuration_spec.rb +26 -0
  70. data/spec/lib/rexpense/entities/activity_collection_spec.rb +5 -0
  71. data/spec/lib/rexpense/entities/activity_spec.rb +9 -0
  72. data/spec/lib/rexpense/entities/advancement_collection_spec.rb +5 -0
  73. data/spec/lib/rexpense/entities/advancement_devolution_spec.rb +9 -0
  74. data/spec/lib/rexpense/entities/advancement_spec.rb +10 -0
  75. data/spec/lib/rexpense/entities/base_spec.rb +28 -0
  76. data/spec/lib/rexpense/entities/collection_spec.rb +70 -0
  77. data/spec/lib/rexpense/entities/comment_collection_spec.rb +5 -0
  78. data/spec/lib/rexpense/entities/comment_spec.rb +10 -0
  79. data/spec/lib/rexpense/entities/expense_collection_spec.rb +5 -0
  80. data/spec/lib/rexpense/entities/expense_spec.rb +14 -0
  81. data/spec/lib/rexpense/entities/membership_collection_spec.rb +5 -0
  82. data/spec/lib/rexpense/entities/membership_spec.rb +7 -0
  83. data/spec/lib/rexpense/entities/organization_collection_spec.rb +5 -0
  84. data/spec/lib/rexpense/entities/organization_spec.rb +8 -0
  85. data/spec/lib/rexpense/entities/pre_expense_collection_spec.rb +5 -0
  86. data/spec/lib/rexpense/entities/pre_expense_spec.rb +10 -0
  87. data/spec/lib/rexpense/entities/reimbursement_collection_spec.rb +5 -0
  88. data/spec/lib/rexpense/entities/reimbursement_spec.rb +10 -0
  89. data/spec/lib/rexpense/entities/user_collection_spec.rb +5 -0
  90. data/spec/lib/rexpense/entities/user_spec.rb +10 -0
  91. data/spec/lib/rexpense/entities/webhook_collection_spec.rb +5 -0
  92. data/spec/lib/rexpense/entities/webhook_spec.rb +7 -0
  93. data/spec/lib/rexpense/http_spec.rb +37 -0
  94. data/spec/lib/rexpense/request_spec.rb +29 -0
  95. data/spec/lib/rexpense/resources/activity_spec.rb +16 -0
  96. data/spec/lib/rexpense/resources/advancement_devolution_spec.rb +29 -0
  97. data/spec/lib/rexpense/resources/advancement_spec.rb +207 -0
  98. data/spec/lib/rexpense/resources/expense_spec.rb +227 -0
  99. data/spec/lib/rexpense/resources/organization_spec.rb +162 -0
  100. data/spec/lib/rexpense/resources/pre_expense_spec.rb +83 -0
  101. data/spec/lib/rexpense/resources/reimbursement_spec.rb +207 -0
  102. data/spec/lib/rexpense/resources/tag_specs.rb +77 -0
  103. data/spec/lib/rexpense/resources/webhook_spec.rb +51 -0
  104. data/spec/lib/rexpense/response_spec.rb +91 -0
  105. data/spec/lib/rexpense_spec.rb +34 -0
  106. data/spec/spec_helper.rb +39 -0
  107. data/spec/support/attachments/logo.png +0 -0
  108. data/spec/support/client.rb +3 -0
  109. data/spec/support/matchers/have_attr_accessor.rb +18 -0
  110. data/spec/support/shared_examples/entity_attributes.rb +9 -0
  111. data/spec/support/shared_examples/entity_collection.rb +19 -0
  112. data/spec/support/shared_examples/http_request_methods.rb +35 -0
  113. data/spec/support/vcr.rb +7 -0
  114. 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
@@ -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,3 @@
1
+ def client
2
+ Rexpense.client("8cd049b4afca9213fb2455528394ab2fb0bc34f5c905f33c")
3
+ end
@@ -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,9 @@
1
+ shared_examples "entity_attributes" do |attrs|
2
+ attrs.each do |attr|
3
+ it { is_expected.to have_attr_accessor(attr) }
4
+ end
5
+
6
+ it "expect to cover all attributes" do
7
+ expect(subject.attributes.keys).to match_array(attrs)
8
+ end
9
+ 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
@@ -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