ddy_remote_resource 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.