ddy_remote_resource 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe4c10288f80776d4eca63eb7f5f7db427b470d549e2050cef173a1719432e10
4
- data.tar.gz: c6d661086f88ec0f9efd0b2c185f46824cfc9bbad46ae98a04db990907457a3c
3
+ metadata.gz: 9834a14e5c56cb3573cd70a5b29f928895baf53116926b219cf843f10a9c22df
4
+ data.tar.gz: bc8106a2ae149bcc1e185265d4cd49631a221f98aff93676c5c3fcec9e1833ba
5
5
  SHA512:
6
- metadata.gz: 74d865281d9c94853ceff853318242bd412f34bacd33cb35c1aec4dbb3d02c55cee46a0cd412dd2fa9b6b903efaae7a339cd988a803436f6ba765510d0649022
7
- data.tar.gz: cb9220f100cb61250b34f64c9368966aa300bf364a402d754b83b00f10ec78b95295b3274ce1e235bd37fbdebc3b959f0e311478aed153e7b9528308f8053006
6
+ metadata.gz: adb751faffb267b13f17b7645ab2690c262f7c3c9b7df8f46374afcf455f2f7beacb80b45bcff50489446e786df01ac1416b3d4816d7f4e0c67721079da52de6
7
+ data.tar.gz: d9e331a8342b281aebb2d07c087192dad0415c1aeab60d19966f9ae5c6eefd0880dce73002d757f57d004a8d9dbbb0ac381e612618333105645a3aa95937f1d4
@@ -23,6 +23,7 @@ module RemoteResource
23
23
  attr_writer :destroyed, :persisted, :success
24
24
 
25
25
  class_attribute :root_element, instance_accessor: false
26
+ class_attribute :json_spec, instance_accessor: false
26
27
 
27
28
  attribute :id
28
29
  end
@@ -1,7 +1,7 @@
1
1
  module RemoteResource
2
2
  class ConnectionOptions
3
3
 
4
- AVAILABLE_OPTIONS = [:site, :headers, :default_headers, :version, :path_prefix, :path_postfix, :collection_prefix, :extension, :collection, :collection_name, :root_element].freeze
4
+ AVAILABLE_OPTIONS = [:site, :headers, :default_headers, :version, :path_prefix, :path_postfix, :collection_prefix, :extension, :collection, :collection_name, :root_element, :json_spec].freeze
5
5
 
6
6
  attr_reader :base_class
7
7
 
@@ -84,12 +84,20 @@ module RemoteResource
84
84
  end
85
85
 
86
86
  def attributes
87
- root_element = connection_options[:root_element]
88
-
89
- if root_element.present?
90
- { root_element => @attributes }
87
+ if connection_options[:json_spec] == :json_api
88
+ if @attributes
89
+ { data: { id: @attributes[:id], type: resource_klass.name.demodulize, attributes: @attributes.except(:id) } }
90
+ else
91
+ { data: {} }
92
+ end
91
93
  else
92
- @attributes || {}
94
+ root_element = connection_options[:root_element]
95
+
96
+ if root_element.present?
97
+ { root_element => @attributes }
98
+ else
99
+ @attributes || {}
100
+ end
93
101
  end
94
102
  end
95
103
 
@@ -114,25 +122,44 @@ module RemoteResource
114
122
 
115
123
  def raise_http_error(request, response)
116
124
  case response.try(:response_code)
117
- when 301, 302, 303, 307 then raise RemoteResource::HTTPRedirectionError.new(request, response)
118
- when 400 then raise RemoteResource::HTTPBadRequest.new(request, response)
119
- when 401 then raise RemoteResource::HTTPUnauthorized.new(request, response)
120
- when 403 then raise RemoteResource::HTTPForbidden.new(request, response)
121
- when 404 then raise RemoteResource::HTTPNotFound.new(request, response)
122
- when 405 then raise RemoteResource::HTTPMethodNotAllowed.new(request, response)
123
- when 406 then raise RemoteResource::HTTPNotAcceptable.new(request, response)
124
- when 408 then raise RemoteResource::HTTPRequestTimeout.new(request, response)
125
- when 409 then raise RemoteResource::HTTPConflict.new(request, response)
126
- when 410 then raise RemoteResource::HTTPGone.new(request, response)
127
- when 418 then raise RemoteResource::HTTPTeapot.new(request, response)
128
- when 444 then raise RemoteResource::HTTPNoResponse.new(request, response)
129
- when 494 then raise RemoteResource::HTTPRequestHeaderTooLarge.new(request, response)
130
- when 495 then raise RemoteResource::HTTPCertError.new(request, response)
131
- when 496 then raise RemoteResource::HTTPNoCert.new(request, response)
132
- when 497 then raise RemoteResource::HTTPToHTTPS.new(request, response)
133
- when 499 then raise RemoteResource::HTTPClientClosedRequest.new(request, response)
134
- when 400..499 then raise RemoteResource::HTTPClientError.new(request, response)
135
- when 500..599 then raise RemoteResource::HTTPServerError.new(request, response)
125
+ when 301, 302, 303, 307 then
126
+ raise RemoteResource::HTTPRedirectionError.new(request, response)
127
+ when 400 then
128
+ raise RemoteResource::HTTPBadRequest.new(request, response)
129
+ when 401 then
130
+ raise RemoteResource::HTTPUnauthorized.new(request, response)
131
+ when 403 then
132
+ raise RemoteResource::HTTPForbidden.new(request, response)
133
+ when 404 then
134
+ raise RemoteResource::HTTPNotFound.new(request, response)
135
+ when 405 then
136
+ raise RemoteResource::HTTPMethodNotAllowed.new(request, response)
137
+ when 406 then
138
+ raise RemoteResource::HTTPNotAcceptable.new(request, response)
139
+ when 408 then
140
+ raise RemoteResource::HTTPRequestTimeout.new(request, response)
141
+ when 409 then
142
+ raise RemoteResource::HTTPConflict.new(request, response)
143
+ when 410 then
144
+ raise RemoteResource::HTTPGone.new(request, response)
145
+ when 418 then
146
+ raise RemoteResource::HTTPTeapot.new(request, response)
147
+ when 444 then
148
+ raise RemoteResource::HTTPNoResponse.new(request, response)
149
+ when 494 then
150
+ raise RemoteResource::HTTPRequestHeaderTooLarge.new(request, response)
151
+ when 495 then
152
+ raise RemoteResource::HTTPCertError.new(request, response)
153
+ when 496 then
154
+ raise RemoteResource::HTTPNoCert.new(request, response)
155
+ when 497 then
156
+ raise RemoteResource::HTTPToHTTPS.new(request, response)
157
+ when 499 then
158
+ raise RemoteResource::HTTPClientClosedRequest.new(request, response)
159
+ when 400..499 then
160
+ raise RemoteResource::HTTPClientError.new(request, response)
161
+ when 500..599 then
162
+ raise RemoteResource::HTTPServerError.new(request, response)
136
163
  else
137
164
  raise RemoteResource::HTTPError.new(request, response)
138
165
  end
@@ -44,19 +44,29 @@ module RemoteResource
44
44
 
45
45
  def attributes
46
46
  @attributes ||= begin
47
- root_element = @connection_options[:root_element].to_s
48
- data = nil
49
-
50
- if root_element.present?
51
- data = parsed_body.try(:key?, root_element) && parsed_body[root_element]
47
+ if @connection_options[:json_spec] == :json_api
48
+ data = parsed_body.fetch("data", {})
49
+ if data.is_a?(Array)
50
+ data.map { |row| row["attributes"].merge({ "id" => row["id"] }) }
51
+ elsif data.key?("attributes")
52
+ data["attributes"].merge({ "id" => data["id"] })
53
+ else
54
+ data
55
+ end
52
56
  else
53
- data = parsed_body
54
- end
57
+ root_element = @connection_options[:root_element].to_s
55
58
 
56
- if data.is_a?(Array)
57
- data
58
- else
59
- data.presence || {}
59
+ if root_element.present?
60
+ data = parsed_body.try(:key?, root_element) && parsed_body[root_element]
61
+ else
62
+ data = parsed_body
63
+ end
64
+
65
+ if data.is_a?(Array)
66
+ data
67
+ else
68
+ data.presence || {}
69
+ end
60
70
  end
61
71
  end
62
72
  end
@@ -1,3 +1,3 @@
1
1
  module RemoteResource
2
- VERSION = '1.0.5'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -24,7 +24,7 @@ RSpec.describe RemoteResource::ConnectionOptions do
24
24
  end
25
25
 
26
26
  let(:dummy_class) { RemoteResource::ConnectionOptionsDummy }
27
- let(:dummy) { dummy_class.new }
27
+ let(:dummy) { dummy_class.new }
28
28
 
29
29
  let(:connection_options) { described_class.new dummy_class }
30
30
 
@@ -59,8 +59,8 @@ RSpec.describe RemoteResource::ConnectionOptions do
59
59
  describe '#merge' do
60
60
  let(:custom_connection_options) do
61
61
  {
62
- site: 'https://dummy.foobar.com',
63
- version: '/api/v2',
62
+ site: 'https://dummy.foobar.com',
63
+ version: '/api/v2',
64
64
  root_element: :test_dummy_api
65
65
  }
66
66
  end
@@ -91,7 +91,8 @@ RSpec.describe RemoteResource::ConnectionOptions do
91
91
  collection_prefix: '/parent/:parent_id',
92
92
  collection: true,
93
93
  collection_name: nil,
94
- root_element: :test_dummy
94
+ root_element: :test_dummy,
95
+ json_spec: nil
95
96
  }
96
97
  end
97
98
 
@@ -18,10 +18,10 @@ RSpec.describe RemoteResource::Request do
18
18
  end
19
19
 
20
20
  let(:dummy_class) { RemoteResource::RequestDummy }
21
- let(:dummy) { dummy_class.new id: '12' }
21
+ let(:dummy) { dummy_class.new id: '12' }
22
22
 
23
- let(:resource) { dummy_class }
24
- let(:http_action) { :get }
23
+ let(:resource) { dummy_class }
24
+ let(:http_action) { :get }
25
25
  let(:connection_options) { {} }
26
26
  let(:attributes) do
27
27
  { name: 'Mies' }
@@ -68,6 +68,7 @@ RSpec.describe RemoteResource::Request do
68
68
 
69
69
  let(:block_connection_options) do
70
70
  {
71
+ json_spec: 'From .with_connection_options',
71
72
  root_element: 'From .with_connection_options',
72
73
  version: 'From .with_connection_options',
73
74
  path_prefix: 'From .with_connection_options'
@@ -85,6 +86,7 @@ RSpec.describe RemoteResource::Request do
85
86
  {
86
87
  site: 'From Klass.site',
87
88
  root_element: 'From connection_options[]',
89
+ json_spec: 'From .with_connection_options',
88
90
  version: 'From .with_connection_options',
89
91
  path_prefix: 'From .with_connection_options',
90
92
  path_postfix: 'From connection_options[]',
@@ -270,7 +272,7 @@ RSpec.describe RemoteResource::Request do
270
272
  let(:expected_request_url) { '' }
271
273
 
272
274
  it 'raises the RemoteResource::HTTPMethodUnsupported error' do
273
- expect{ request.perform }.to raise_error RemoteResource::HTTPMethodUnsupported, 'Requested HTTP method=foo is NOT supported, the HTTP action MUST be a supported HTTP action=get, put, patch, post, delete'
275
+ expect { request.perform }.to raise_error RemoteResource::HTTPMethodUnsupported, 'Requested HTTP method=foo is NOT supported, the HTTP action MUST be a supported HTTP action=get, put, patch, post, delete'
274
276
  end
275
277
  end
276
278
  end
@@ -367,7 +369,7 @@ RSpec.describe RemoteResource::Request do
367
369
 
368
370
  context 'when connection_options does NOT include collection_options' do
369
371
  it 'raises error' do
370
- expect{ request.request_url }.to raise_error(RemoteResource::CollectionOptionKeyError)
372
+ expect { request.request_url }.to raise_error(RemoteResource::CollectionOptionKeyError)
371
373
  end
372
374
  end
373
375
  end
@@ -473,6 +475,30 @@ RSpec.describe RemoteResource::Request do
473
475
  end
474
476
  end
475
477
  end
478
+
479
+ context 'when connection_options[:json_spec] == :json_api' do
480
+ let(:connection_options) do
481
+ { json_spec: :json_api }
482
+ end
483
+
484
+ let(:attributes) do
485
+ { id: 1, name: 'Mies', featured: true, labels: [1, '2', 'three'] }
486
+ end
487
+
488
+ it 'returns the given attributes wrapped in the json api spec' do
489
+ expect(request.attributes).to eql({ data: { id: 1, type: "RequestDummy", attributes: { name: 'Mies', featured: true, labels: [1, '2', 'three'] } } })
490
+ end
491
+
492
+ context 'and there are NO given attributes' do
493
+ let(:attributes) do
494
+ nil
495
+ end
496
+
497
+ it 'returns nil wrapped in the connection_options[:root_element]' do
498
+ expect(request.attributes).to eql({ data: {} })
499
+ end
500
+ end
501
+ end
476
502
  end
477
503
 
478
504
  describe '#headers' do
@@ -506,7 +532,7 @@ RSpec.describe RemoteResource::Request do
506
532
  end
507
533
 
508
534
  before { RemoteResource::Base.global_headers = { 'User-Agent' => 'From RemoteResource::Base.global_headers', 'X-Locale' => 'From RemoteResource::Base.global_headers' } }
509
- after { RemoteResource::Base.global_headers = nil }
535
+ after { RemoteResource::Base.global_headers = nil }
510
536
 
511
537
  it 'returns the default headers while overwriting the headers according to the correct precedence' do
512
538
  expect(request.headers).to eql expected_headers
@@ -562,7 +588,7 @@ RSpec.describe RemoteResource::Request do
562
588
 
563
589
  describe '#raise_http_error' do
564
590
  let(:connection_response) { instance_double(Typhoeus::Response, request: instance_double(Typhoeus::Request)) }
565
- let(:response) { RemoteResource::Response.new(connection_response, connection_options) }
591
+ let(:response) { RemoteResource::Response.new(connection_response, connection_options) }
566
592
 
567
593
  context 'when the response code is 301, 302, 303 or 307' do
568
594
  response_codes = [301, 302, 303, 307]
@@ -14,14 +14,14 @@ RSpec.describe RemoteResource::Response do
14
14
  end
15
15
 
16
16
  let(:dummy_class) { RemoteResource::ResponseDummy }
17
- let(:dummy) { dummy_class.new(id: '12') }
17
+ let(:dummy) { dummy_class.new(id: '12') }
18
18
 
19
19
  let(:connection_options) do
20
20
  { collection: true }
21
21
  end
22
- let(:request) { RemoteResource::Request.new(dummy_class, :post, { name: 'Mies' }, connection_options) }
22
+ let(:request) { RemoteResource::Request.new(dummy_class, :post, { name: 'Mies' }, connection_options) }
23
23
  let(:connection_response) { Typhoeus::Response.new(mock: true, code: 201, body: { id: 12, name: 'Mies' }.to_json, headers: { 'Content-Type' => 'application/json', 'Server' => 'nginx/1.4.6 (Ubuntu)' }) }
24
- let(:connection_request) { Typhoeus::Request.new('http://www.foobar.com/response_dummies.json', method: :post, body: { name: 'Mies' }.to_json, headers: { 'Content-Type' => 'application/json' }) }
24
+ let(:connection_request) { Typhoeus::Request.new('http://www.foobar.com/response_dummies.json', method: :post, body: { name: 'Mies' }.to_json, headers: { 'Content-Type' => 'application/json' }) }
25
25
 
26
26
  let(:response) { described_class.new(connection_response, connection_options.merge(request: request, connection_request: connection_request)) }
27
27
 
@@ -156,6 +156,36 @@ RSpec.describe RemoteResource::Response do
156
156
  expect(response.attributes).to eql({})
157
157
  end
158
158
  end
159
+
160
+ context 'with the json_api spec' do
161
+ let(:connection_options) do
162
+ { root_element: :data, json_spec: :json_api }
163
+ end
164
+
165
+ context "single response" do
166
+ let(:connection_response) { Typhoeus::Response.new(mock: true, code: 201, body: { data: { id: 12, attributes: { name: 'Mies' } } }.to_json, headers: { 'Content-Type' => 'application/json', 'Server' => 'nginx/1.4.6 (Ubuntu)' }) }
167
+
168
+ it 'parses the attributes from the nested hash' do
169
+ expect(response.attributes).to eql({ 'id' => 12, 'name' => 'Mies' })
170
+ end
171
+ end
172
+
173
+ context "empty response" do
174
+ let(:connection_response) { Typhoeus::Response.new(mock: true, code: 204, body: {}.to_json, headers: { 'Content-Type' => 'application/json', 'Server' => 'nginx/1.4.6 (Ubuntu)' }) }
175
+
176
+ it 'parses the attributes from the nested hash' do
177
+ expect(response.attributes).to eql({})
178
+ end
179
+ end
180
+
181
+ context "collection response" do
182
+ let(:connection_response) { Typhoeus::Response.new(mock: true, code: 201, body: { data: [{ id: 12, attributes: { name: 'Mies' } }] }.to_json, headers: { 'Content-Type' => 'application/json', 'Server' => 'nginx/1.4.6 (Ubuntu)' }) }
183
+
184
+ it 'parses the attributes from the nested hash' do
185
+ expect(response.attributes).to eql(['id' => 12, 'name' => 'Mies'])
186
+ end
187
+ end
188
+ end
159
189
  end
160
190
 
161
191
  describe '#errors' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddy_remote_resource
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan van der Pas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-13 00:00:00.000000000 Z
11
+ date: 2019-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -206,22 +206,22 @@ dependencies:
206
206
  name: typhoeus
207
207
  requirement: !ruby/object:Gem::Requirement
208
208
  requirements:
209
- - - "~>"
210
- - !ruby/object:Gem::Version
211
- version: '0.7'
212
209
  - - ">="
213
210
  - !ruby/object:Gem::Version
214
211
  version: 0.7.0
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '0.7'
215
215
  type: :runtime
216
216
  prerelease: false
217
217
  version_requirements: !ruby/object:Gem::Requirement
218
218
  requirements:
219
- - - "~>"
220
- - !ruby/object:Gem::Version
221
- version: '0.7'
222
219
  - - ">="
223
220
  - !ruby/object:Gem::Version
224
221
  version: 0.7.0
222
+ - - "~>"
223
+ - !ruby/object:Gem::Version
224
+ version: '0.7'
225
225
  - !ruby/object:Gem::Dependency
226
226
  name: request_store
227
227
  requirement: !ruby/object:Gem::Requirement
@@ -319,8 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
319
  - !ruby/object:Gem::Version
320
320
  version: '0'
321
321
  requirements: []
322
- rubyforge_project:
323
- rubygems_version: 2.7.7
322
+ rubygems_version: 3.0.2
324
323
  signing_key:
325
324
  specification_version: 4
326
325
  summary: RemoteResource, a gem to use resources with REST services.