ddy_remote_resource 0.4.11 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Guardfile +3 -0
  4. data/lib/remote_resource.rb +77 -34
  5. data/lib/remote_resource/base.rb +20 -8
  6. data/lib/remote_resource/connection.rb +26 -5
  7. data/lib/remote_resource/connection_options.rb +5 -3
  8. data/lib/remote_resource/querying/finder_methods.rb +3 -3
  9. data/lib/remote_resource/querying/persistence_methods.rb +17 -12
  10. data/lib/remote_resource/request.rb +96 -62
  11. data/lib/remote_resource/response.rb +5 -1
  12. data/lib/remote_resource/rest.rb +13 -17
  13. data/lib/remote_resource/url_naming.rb +4 -10
  14. data/lib/remote_resource/url_naming_determination.rb +1 -3
  15. data/lib/remote_resource/util.rb +64 -0
  16. data/lib/remote_resource/version.rb +1 -1
  17. data/remote_resource.gemspec +2 -2
  18. data/spec/fixtures/text_file.txt +1 -0
  19. data/spec/integration/all_spec.rb +166 -0
  20. data/spec/integration/collection_prefix_spec.rb +99 -0
  21. data/spec/integration/create_spec.rb +181 -0
  22. data/spec/integration/destroy_spec.rb +252 -0
  23. data/spec/integration/find_by_spec.rb +168 -0
  24. data/spec/integration/find_spec.rb +139 -0
  25. data/spec/integration/headers_spec.rb +222 -0
  26. data/spec/integration/naming_spec.rb +138 -0
  27. data/spec/integration/save_spec.rb +320 -0
  28. data/spec/integration/update_attributes_spec.rb +221 -0
  29. data/spec/integration/where_spec.rb +152 -0
  30. data/spec/lib/extensions/ethon/easy/queryable_spec.rb +4 -4
  31. data/spec/lib/remote_resource/base_spec.rb +54 -110
  32. data/spec/lib/remote_resource/builder_spec.rb +1 -1
  33. data/spec/lib/remote_resource/collection_spec.rb +1 -1
  34. data/spec/lib/remote_resource/connection_options_spec.rb +20 -17
  35. data/spec/lib/remote_resource/connection_spec.rb +36 -27
  36. data/spec/lib/remote_resource/querying/finder_methods_spec.rb +199 -72
  37. data/spec/lib/remote_resource/querying/persistence_methods_spec.rb +228 -220
  38. data/spec/lib/remote_resource/request_spec.rb +313 -342
  39. data/spec/lib/remote_resource/response_spec.rb +9 -3
  40. data/spec/lib/remote_resource/rest_spec.rb +11 -11
  41. data/spec/lib/remote_resource/url_naming_determination_spec.rb +1 -1
  42. data/spec/lib/remote_resource/url_naming_spec.rb +7 -22
  43. data/spec/lib/remote_resource/util_spec.rb +56 -0
  44. data/spec/lib/remote_resource/version_spec.rb +2 -3
  45. data/spec/spec_helper.rb +37 -0
  46. metadata +33 -22
  47. data/lib/remote_resource/http_errors.rb +0 -33
  48. data/lib/remote_resource/response_handeling.rb +0 -48
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe '.create' do
4
+
5
+ class Post
6
+ include RemoteResource::Base
7
+
8
+ self.site = 'https://www.example.com'
9
+ self.collection = true
10
+ self.root_element = :data
11
+
12
+ attribute :title, String
13
+ attribute :body, String
14
+ attribute :featured, Boolean
15
+ attribute :created_at, Time
16
+ end
17
+
18
+ let(:response_body) do
19
+ {
20
+ data: {
21
+ id: 12,
22
+ title: 'Lorem Ipsum',
23
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
24
+ featured: true,
25
+ created_at: Time.new(2015, 10, 4, 9, 30, 0),
26
+ }
27
+ }
28
+ end
29
+
30
+ let(:expected_default_headers) do
31
+ { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'User-Agent' => "RemoteResource #{RemoteResource::VERSION}" }
32
+ end
33
+
34
+ describe 'default behaviour' do
35
+ let(:expected_request_body) do
36
+ {
37
+ data: {
38
+ title: 'Lorem Ipsum',
39
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
40
+ featured: true
41
+ }
42
+ }
43
+ end
44
+
45
+ let!(:expected_request) do
46
+ mock_request = stub_request(:post, 'https://www.example.com/posts.json')
47
+ mock_request.with(query: nil, body: JSON.generate(expected_request_body), headers: expected_default_headers)
48
+ mock_request.to_return(status: 201, body: JSON.generate(response_body))
49
+ mock_request
50
+ end
51
+
52
+ it 'performs the correct HTTP POST request' do
53
+ Post.create(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true)
54
+ expect(expected_request).to have_been_requested
55
+ end
56
+
57
+ it 'builds the correct resource' do
58
+ post = Post.create(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true)
59
+
60
+ aggregate_failures do
61
+ expect(post.persisted?).to eql true
62
+ expect(post.id).to eql 12
63
+ expect(post.title).to eql 'Lorem Ipsum'
64
+ expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
65
+ expect(post.featured).to eql true
66
+ expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'with connection_options[:headers]' do
72
+ let(:expected_request_body) do
73
+ {
74
+ data: {
75
+ title: 'Lorem Ipsum',
76
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
77
+ featured: true
78
+ }
79
+ }
80
+ end
81
+
82
+ let!(:expected_request) do
83
+ mock_request = stub_request(:post, 'https://www.example.com/posts.json')
84
+ mock_request.with(query: nil, body: JSON.generate(expected_request_body), headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
85
+ mock_request.to_return(status: 201, body: JSON.generate(response_body))
86
+ mock_request
87
+ end
88
+
89
+ it 'performs the correct HTTP POST request' do
90
+ Post.create({ title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true }, { headers: { 'X-Pseudonym' => 'pseudonym' } })
91
+ expect(expected_request).to have_been_requested
92
+ end
93
+ end
94
+
95
+ describe 'with a 422 response' do
96
+ let(:response_body) do
97
+ {
98
+ errors: {
99
+ title: ['Please use a title which is more than 5 characters'],
100
+ body: ['Please fill in a body'],
101
+ virtual_attribute: ['You already posted today', 'Please refrain from using curse words']
102
+ }
103
+ }
104
+ end
105
+
106
+ let(:expected_request_body) do
107
+ {
108
+ data: {
109
+ title: 'Lore',
110
+ featured: true
111
+ }
112
+ }
113
+ end
114
+
115
+ let!(:expected_request) do
116
+ mock_request = stub_request(:post, 'https://www.example.com/posts.json')
117
+ mock_request.with(query: nil, body: JSON.generate(expected_request_body), headers: expected_default_headers)
118
+ mock_request.to_return(status: 422, body: JSON.generate(response_body))
119
+ mock_request
120
+ end
121
+
122
+ it 'performs the correct HTTP POST request' do
123
+ Post.create(title: 'Lore', featured: true)
124
+ expect(expected_request).to have_been_requested
125
+ end
126
+
127
+ it 'builds the correct resource with validation errors' do
128
+ post = Post.create(title: 'Lore', featured: true)
129
+
130
+ aggregate_failures do
131
+ expect(post.persisted?).to eql false
132
+ expect(post.id).to be_nil
133
+ expect(post.title).to eql 'Lore'
134
+ expect(post.body).to be_nil
135
+ expect(post.featured).to eql true
136
+ expect(post.created_at).to be_blank
137
+ expect(post.errors.messages[:title]).to eql ['Please use a title which is more than 5 characters']
138
+ expect(post.errors.messages[:body]).to eql ['Please fill in a body']
139
+ expect(post.errors.messages[:base]).to eql ['You already posted today', 'Please refrain from using curse words']
140
+ end
141
+ end
142
+ end
143
+
144
+ describe 'with a 500 response' do
145
+ let(:expected_request_body) do
146
+ {
147
+ data: {
148
+ title: 'Lorem Ipsum',
149
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
150
+ featured: true
151
+ }
152
+ }
153
+ end
154
+
155
+ let!(:expected_request) do
156
+ mock_request = stub_request(:post, 'https://www.example.com/posts.json')
157
+ mock_request.with(query: nil, body: JSON.generate(expected_request_body), headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
158
+ mock_request.to_return(status: 500)
159
+ mock_request
160
+ end
161
+
162
+ it 'raises the server error' do
163
+ expect { Post.create({ title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true }, { headers: { 'X-Pseudonym' => 'pseudonym' } }) }.to raise_error RemoteResource::HTTPServerError
164
+ end
165
+
166
+ it 'adds metadata to the raised error' do
167
+ begin
168
+ Post.create({ title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true }, { headers: { 'X-Pseudonym' => 'pseudonym' } })
169
+ rescue RemoteResource::HTTPServerError => error
170
+ aggregate_failures do
171
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=500 with http_action=post with request_url=https://www.example.com/posts.json'
172
+ expect(error.request_url).to eql 'https://www.example.com/posts.json'
173
+ expect(error.response_code).to eql 500
174
+ expect(error.request_query).to be_nil
175
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe '.destroy and #destroy' do
4
+
5
+ class Post
6
+ include RemoteResource::Base
7
+
8
+ self.site = 'https://www.example.com'
9
+ self.collection = true
10
+ self.root_element = :data
11
+
12
+ attribute :title, String
13
+ attribute :body, String
14
+ attribute :featured, Boolean
15
+ attribute :created_at, Time
16
+ end
17
+
18
+ describe '.destroy' do
19
+ let(:response_body) do
20
+ {}
21
+ end
22
+
23
+ let(:expected_default_headers) do
24
+ { 'Accept' => 'application/json', 'User-Agent' => "RemoteResource #{RemoteResource::VERSION}" }
25
+ end
26
+
27
+ describe 'default behaviour' do
28
+ let!(:expected_request) do
29
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
30
+ mock_request.with(query: nil, body: nil, headers: expected_default_headers)
31
+ mock_request.to_return(status: 204, body: response_body.to_json)
32
+ mock_request
33
+ end
34
+
35
+ it 'performs the correct HTTP DELETE request' do
36
+ Post.destroy(12)
37
+ expect(expected_request).to have_been_requested
38
+ end
39
+
40
+ it 'builds the correct non-persistent resource' do
41
+ post = Post.destroy(12)
42
+
43
+ aggregate_failures do
44
+ expect(post.id).to eql 12
45
+ expect(post.persisted?).to eql false
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'with connection_options[:params]' do
51
+ let!(:expected_request) do
52
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
53
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers)
54
+ mock_request.to_return(status: 204, body: response_body.to_json)
55
+ mock_request
56
+ end
57
+
58
+ it 'performs the correct HTTP DELETE request' do
59
+ Post.destroy(12, params: { pseudonym: 'pseudonym' })
60
+ expect(expected_request).to have_been_requested
61
+ end
62
+ end
63
+
64
+ describe 'with connection_options[:headers]' do
65
+ let!(:expected_request) do
66
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
67
+ mock_request.with(query: nil, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
68
+ mock_request.to_return(status: 204, body: response_body.to_json)
69
+ mock_request
70
+ end
71
+
72
+ it 'performs the correct HTTP DELETE request' do
73
+ Post.destroy(12, headers: { 'X-Pseudonym' => 'pseudonym' })
74
+ expect(expected_request).to have_been_requested
75
+ end
76
+ end
77
+
78
+ describe 'with a 404 response' do
79
+ let!(:expected_request) do
80
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
81
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
82
+ mock_request.to_return(status: 404)
83
+ mock_request
84
+ end
85
+
86
+ it 'raises the not found error' do
87
+ expect { Post.destroy(12, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }) }.to raise_error RemoteResource::HTTPNotFound
88
+ end
89
+
90
+ it 'adds metadata to the raised error' do
91
+ begin
92
+ Post.destroy(12, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' })
93
+ rescue RemoteResource::HTTPNotFound => error
94
+ aggregate_failures do
95
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=404 with http_action=delete with request_url=https://www.example.com/posts/12.json'
96
+ expect(error.request_url).to eql 'https://www.example.com/posts/12.json'
97
+ expect(error.response_code).to eql 404
98
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym' }))
99
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ describe 'with a 500 response' do
106
+ let!(:expected_request) do
107
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
108
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
109
+ mock_request.to_return(status: 500)
110
+ mock_request
111
+ end
112
+
113
+ it 'raises the server error' do
114
+ expect { Post.destroy(12, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }) }.to raise_error RemoteResource::HTTPServerError
115
+ end
116
+
117
+ it 'adds metadata to the raised error' do
118
+ begin
119
+ Post.destroy(12, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' })
120
+ rescue RemoteResource::HTTPServerError => error
121
+ aggregate_failures do
122
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=500 with http_action=delete with request_url=https://www.example.com/posts/12.json'
123
+ expect(error.request_url).to eql 'https://www.example.com/posts/12.json'
124
+ expect(error.response_code).to eql 500
125
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym' }))
126
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ describe '#destroy' do
134
+ let(:resource) { Post.new(id: 12) }
135
+
136
+ let(:response_body) do
137
+ {}
138
+ end
139
+
140
+ let(:expected_default_headers) do
141
+ { 'Accept' => 'application/json', 'User-Agent' => "RemoteResource #{RemoteResource::VERSION}" }
142
+ end
143
+
144
+ describe 'default behaviour' do
145
+ let!(:expected_request) do
146
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
147
+ mock_request.with(query: nil, body: nil, headers: expected_default_headers)
148
+ mock_request.to_return(status: 204, body: response_body.to_json)
149
+ mock_request
150
+ end
151
+
152
+ it 'performs the correct HTTP DELETE request' do
153
+ resource.destroy
154
+ expect(expected_request).to have_been_requested
155
+ end
156
+
157
+ it 'builds the correct non-persistent resource' do
158
+ resource.destroy
159
+
160
+ post = resource
161
+
162
+ aggregate_failures do
163
+ expect(post.id).to eql 12
164
+ expect(post.persisted?).to eql false
165
+ end
166
+ end
167
+ end
168
+
169
+ describe 'with connection_options[:params]' do
170
+ let!(:expected_request) do
171
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
172
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers)
173
+ mock_request.to_return(status: 204, body: response_body.to_json)
174
+ mock_request
175
+ end
176
+
177
+ it 'performs the correct HTTP DELETE request' do
178
+ resource.destroy(params: { pseudonym: 'pseudonym' })
179
+ expect(expected_request).to have_been_requested
180
+ end
181
+ end
182
+
183
+ describe 'with connection_options[:headers]' do
184
+ let!(:expected_request) do
185
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
186
+ mock_request.with(query: nil, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
187
+ mock_request.to_return(status: 204, body: response_body.to_json)
188
+ mock_request
189
+ end
190
+
191
+ it 'performs the correct HTTP DELETE request' do
192
+ resource.destroy(headers: { 'X-Pseudonym' => 'pseudonym' })
193
+ expect(expected_request).to have_been_requested
194
+ end
195
+ end
196
+
197
+ describe 'with a 404 response' do
198
+ let!(:expected_request) do
199
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
200
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
201
+ mock_request.to_return(status: 404)
202
+ mock_request
203
+ end
204
+
205
+ it 'raises the not found error' do
206
+ expect { resource.destroy(params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }) }.to raise_error RemoteResource::HTTPNotFound
207
+ end
208
+
209
+ it 'adds metadata to the raised error' do
210
+ begin
211
+ resource.destroy(params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' })
212
+ rescue RemoteResource::HTTPNotFound => error
213
+ aggregate_failures do
214
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=404 with http_action=delete with request_url=https://www.example.com/posts/12.json'
215
+ expect(error.request_url).to eql 'https://www.example.com/posts/12.json'
216
+ expect(error.response_code).to eql 404
217
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym' }))
218
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ describe 'with a 500 response' do
225
+ let!(:expected_request) do
226
+ mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
227
+ mock_request.with(query: { pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
228
+ mock_request.to_return(status: 500)
229
+ mock_request
230
+ end
231
+
232
+ it 'raises the server error' do
233
+ expect { resource.destroy(params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }) }.to raise_error RemoteResource::HTTPServerError
234
+ end
235
+
236
+ it 'adds metadata to the raised error' do
237
+ begin
238
+ resource.destroy(params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' })
239
+ rescue RemoteResource::HTTPServerError => error
240
+ aggregate_failures do
241
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=500 with http_action=delete with request_url=https://www.example.com/posts/12.json'
242
+ expect(error.request_url).to eql 'https://www.example.com/posts/12.json'
243
+ expect(error.response_code).to eql 500
244
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym' }))
245
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe '.find_by' do
4
+
5
+ class Post
6
+ include RemoteResource::Base
7
+
8
+ self.site = 'https://www.example.com'
9
+ self.collection = true
10
+ self.root_element = :data
11
+
12
+ attribute :title, String
13
+ attribute :body, String
14
+ attribute :featured, Boolean
15
+ attribute :created_at, Time
16
+ end
17
+
18
+ let(:response_body) do
19
+ {
20
+ data: {
21
+ id: 12,
22
+ title: 'Lorem Ipsum',
23
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
24
+ featured: true,
25
+ created_at: Time.new(2015, 10, 4, 9, 30, 0),
26
+ }
27
+ }
28
+ end
29
+
30
+ let(:expected_default_headers) do
31
+ { 'Accept' => 'application/json', 'User-Agent' => "RemoteResource #{RemoteResource::VERSION}" }
32
+ end
33
+
34
+ describe 'default behaviour' do
35
+ let!(:expected_request) do
36
+ mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
37
+ mock_request.with(query: { title: 'Lorem Ipsum', featured: true }, body: nil, headers: expected_default_headers)
38
+ mock_request.to_return(status: 200, body: response_body.to_json)
39
+ mock_request
40
+ end
41
+
42
+ it 'performs the correct HTTP GET request' do
43
+ Post.find_by({ title: 'Lorem Ipsum', featured: true }, path_postfix: '/current')
44
+ expect(expected_request).to have_been_requested
45
+ end
46
+
47
+ it 'builds the correct resource' do
48
+ post = Post.find_by({ title: 'Lorem Ipsum', featured: true }, path_postfix: '/current')
49
+
50
+ aggregate_failures do
51
+ expect(post.id).to eql 12
52
+ expect(post.title).to eql 'Lorem Ipsum'
53
+ expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
54
+ expect(post.featured).to eql true
55
+ expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe 'with params[:id]' do
61
+ let!(:expected_request) do
62
+ mock_request = stub_request(:get, 'https://www.example.com/posts/12.json')
63
+ mock_request.with(query: { title: 'Lorem Ipsum', featured: true }, body: nil, headers: expected_default_headers)
64
+ mock_request.to_return(status: 200, body: response_body.to_json)
65
+ mock_request
66
+ end
67
+
68
+ it 'performs the correct HTTP GET request' do
69
+ Post.find_by({ id: 12, title: 'Lorem Ipsum', featured: true })
70
+ expect(expected_request).to have_been_requested
71
+ end
72
+
73
+ it 'builds the correct resource' do
74
+ post = Post.find_by({ id: 12, title: 'Lorem Ipsum', featured: true })
75
+
76
+ aggregate_failures do
77
+ expect(post.id).to eql 12
78
+ expect(post.title).to eql 'Lorem Ipsum'
79
+ expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
80
+ expect(post.featured).to eql true
81
+ expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe 'with connection_options[:params]' do
87
+ let!(:expected_request) do
88
+ mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
89
+ mock_request.with(query: { title: 'Lorem Ipsum', featured: true, pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers)
90
+ mock_request.to_return(status: 200, body: response_body.to_json)
91
+ mock_request
92
+ end
93
+
94
+ it 'performs the correct HTTP GET request' do
95
+ Post.find_by({ title: 'Lorem Ipsum', featured: true }, params: { pseudonym: 'pseudonym' }, path_postfix: '/current')
96
+ expect(expected_request).to have_been_requested
97
+ end
98
+ end
99
+
100
+ describe 'with connection_options[:headers]' do
101
+ let!(:expected_request) do
102
+ mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
103
+ mock_request.with(query: { title: 'Lorem Ipsum', featured: true }, body: nil, headers: { 'X-Pseudonym' => 'pseudonym' })
104
+ mock_request.to_return(status: 200, body: response_body.to_json)
105
+ mock_request
106
+ end
107
+
108
+ it 'performs the correct HTTP GET request' do
109
+ Post.find_by({ title: 'Lorem Ipsum', featured: true }, headers: { 'X-Pseudonym' => 'pseudonym' }, path_postfix: '/current')
110
+ expect(expected_request).to have_been_requested
111
+ end
112
+ end
113
+
114
+ describe 'with a 404 response' do
115
+ let!(:expected_request) do
116
+ mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
117
+ mock_request.with(query: { featured: false, pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
118
+ mock_request.to_return(status: 404)
119
+ mock_request
120
+ end
121
+
122
+ it 'raises the not found error' do
123
+ expect { Post.find_by({ featured: false }, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }, path_postfix: '/current') }.to raise_error RemoteResource::HTTPNotFound
124
+ end
125
+
126
+ it 'adds metadata to the raised error' do
127
+ begin
128
+ Post.find_by({ featured: false }, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }, path_postfix: '/current')
129
+ rescue RemoteResource::HTTPNotFound => error
130
+ aggregate_failures do
131
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=404 with http_action=get with request_url=https://www.example.com/posts/current.json'
132
+ expect(error.request_url).to eql 'https://www.example.com/posts/current.json'
133
+ expect(error.response_code).to eql 404
134
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym', featured: false }))
135
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ describe 'with a 500 response' do
142
+ let!(:expected_request) do
143
+ mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
144
+ mock_request.with(query: { featured: false, pseudonym: 'pseudonym' }, body: nil, headers: expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
145
+ mock_request.to_return(status: 500)
146
+ mock_request
147
+ end
148
+
149
+ it 'raises the server error' do
150
+ expect { Post.find_by({ featured: false }, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }, path_postfix: '/current') }.to raise_error RemoteResource::HTTPServerError
151
+ end
152
+
153
+ it 'adds metadata to the raised error' do
154
+ begin
155
+ Post.find_by({ featured: false }, params: { pseudonym: 'pseudonym' }, headers: { 'X-Pseudonym' => 'pseudonym' }, path_postfix: '/current')
156
+ rescue RemoteResource::HTTPServerError => error
157
+ aggregate_failures do
158
+ expect(error.message).to eql 'HTTP request failed for Post with response_code=500 with http_action=get with request_url=https://www.example.com/posts/current.json'
159
+ expect(error.request_url).to eql 'https://www.example.com/posts/current.json'
160
+ expect(error.response_code).to eql 500
161
+ expect(error.request_query).to eql(RemoteResource::Util.encode_params_to_query({ pseudonym: 'pseudonym', featured: false }))
162
+ expect(error.request_headers).to eql(expected_default_headers.merge({ 'X-Pseudonym' => 'pseudonym' }))
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ end