flexirest 1.12.3 → 1.12.5

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: 61eaaa77dfcbab57b714007844456fe903c759cbb981761a43b7eb4910da3463
4
- data.tar.gz: 10e7bbe8cc3b35887eb34c32562af637ed8cd4aae34df0547c2e2cd52a730a7e
3
+ metadata.gz: 44aa9166918c27766f3d696c23cc78b08e1f956edb6ae8a7413c9e88f01c48e7
4
+ data.tar.gz: 1068bcb89fb8da7af5505177f989997794615703df092d8d27fa55479987565c
5
5
  SHA512:
6
- metadata.gz: 251b2a247480a4f7b3c46a70cd469c3ad24cbdb6c245703ec60658ae3429107a7a364eb12e8794c2e28729ebb58e7a17bc1d2fbeebf59a035d5f277032ba7d82
7
- data.tar.gz: e4fb534d1775963465155761cd4e6b8a7f14e7c66b0f0406d48d39abe4810906c588a9f00fea1b9325b1ed6d1682c9224f47b07c0f75e51b48986d2be43f5e0c
6
+ metadata.gz: 9cddabff55c7531fdb3856c863fc9888fa3731c82135f9a02c4e3d5026514c479815ecaa499fc38b6f50c6579bff7703bcbaef688d76ea067a43f7a26dc8efc5
7
+ data.tar.gz: 204f29f4a0baa07661ea497d88799f137ed55114fdea808f5a1ea905a21f9ff51f2d0ce1c9a82d985c140c6e6f4fc29ae26e394a34a63cc51b87907dbef81139
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.12.5
4
+
5
+ Feature:
6
+
7
+ - Some broken APIs require a GET body, even though this is against HTTP spec. Added a `send_get_body` parameter like we already have for DELETE requests (thanks to Jan Schroeder for the request)
8
+
9
+ ## 1.12.4
10
+
11
+ Bugfix:
12
+
13
+ - 204 responses could not be read from Cache (thanks to rgisiger for the PR)
14
+
3
15
  ## 1.12.3
4
16
 
5
17
  Bugfix:
data/docs/basic-usage.md CHANGED
@@ -52,6 +52,12 @@ For `delete` requests whether an API can handle a body or not is undefined. The
52
52
  delete :remove, "/people/:id", send_delete_body: true
53
53
  ```
54
54
 
55
+ In a similar way, although it's against the HTTP specification, you can force a GET request to send a request body if your API requires that:
56
+
57
+ ```
58
+ get :people_search, "/people/search", send_get_body: true
59
+ ```
60
+
55
61
  If an API returns an array of results and you have [will_paginate](https://rubygems.org/gems/will_paginate) installed then you can call the paginate method to return a particular page of the results (note: this doesn't reduce the load on the server, but it can help with pagination if you have a cached response).
56
62
 
57
63
  ```ruby
@@ -68,9 +68,10 @@ module Flexirest
68
68
  end
69
69
 
70
70
  if cache_store && (headers[:etag] || headers[:expires])
71
- key = "#{request.class_name}:#{request.original_url}"
71
+ class_name = request.class_name
72
+ key = "#{class_name}:#{request.original_url}"
72
73
  Flexirest::Logger.debug " \033[1;4;32m#{Flexirest.name}\033[0m #{key} - Writing to cache" unless quiet
73
- cached_response = CachedResponse.new(status:response.status, result:result, response_headers: headers)
74
+ cached_response = CachedResponse.new(status:response.status, result:result, response_headers: headers, class_name:class_name)
74
75
  cached_response.etag = "#{headers[:etag]}" if headers[:etag]
75
76
  cached_response.expires = Time.parse(headers[:expires]) rescue nil if headers[:expires]
76
77
  if cached_response.etag.present? || cached_response.expires
@@ -101,18 +102,19 @@ module Flexirest
101
102
  @etag = options[:etag]
102
103
  @expires = options[:expires]
103
104
  @response_headers = options[:response_headers]
105
+ @old_cached_instance = options[:result].class.name.nil?
104
106
 
105
- @class_name = options[:result].class.name
106
107
  if options[:result].is_a?(ResultIterator)
107
108
  @class_name = options[:result][0].class.name
108
109
  @result = options[:result].map{|i| {}.merge(i._attributes)}
109
110
  else
111
+ @class_name = options[:class_name]
110
112
  @result = {}.merge(options[:result].try(:_attributes) || {})
111
113
  end
112
114
  end
113
115
 
114
116
  def result
115
- return @result if @class_name.nil? # Old cached instance
117
+ return @result if @old_cached_instance
116
118
 
117
119
  if @result.is_a?(Array)
118
120
  ri = ResultIterator.new(self)
@@ -361,10 +361,10 @@ module Flexirest
361
361
  if @explicit_parameters
362
362
  params = @explicit_parameters
363
363
  end
364
- if http_method == :get || (http_method == :delete && !@method[:options][:send_delete_body] && proxy != :json_api)
364
+ if (http_method == :get && !@method[:options][:send_get_body]) || (http_method == :delete && !@method[:options][:send_delete_body] && proxy != :json_api)
365
365
  @get_params = default_params.merge(params || {})
366
366
  @post_params = nil
367
- elsif http_method == :delete && @method[:options][:send_delete_body]
367
+ elsif (http_method == :get && @method[:options][:send_get_body]) || (http_method == :delete && @method[:options][:send_delete_body])
368
368
  @post_params = default_params.merge(params || {})
369
369
  @get_params = {}
370
370
  elsif params.is_a? String
@@ -476,7 +476,7 @@ module Flexirest
476
476
 
477
477
  headers["Accept"] ||= "application/vnd.api+json"
478
478
  JsonAPIProxy::Headers.save(headers)
479
- elsif http_method == :get || (http_method == :delete && !@method[:options][:send_delete_body])
479
+ elsif (http_method == :get && !@method[:options][:send_get_body]) || (http_method == :delete && !@method[:options][:send_delete_body])
480
480
  if request_body_type == :form_encoded
481
481
  headers["Content-Type"] ||= "application/x-www-form-urlencoded; charset=utf-8"
482
482
  elsif request_body_type == :form_multipart
@@ -607,16 +607,17 @@ module Flexirest
607
607
  request_options[:timeout] = @method[:options][:timeout]
608
608
  end
609
609
 
610
- case http_method
611
- when :get
610
+ if http_method == :get && !@method[:options][:send_get_body]
612
611
  response = connection.get(@url, request_options)
613
- when :put
612
+ elsif http_method == :get
613
+ response = connection.get(@url, @body, request_options)
614
+ elsif http_method == :put
614
615
  response = connection.put(@url, @body, request_options)
615
- when :post
616
+ elsif http_method == :post
616
617
  response = connection.post(@url, @body, request_options)
617
- when :patch
618
+ elsif http_method == :patch
618
619
  response = connection.patch(@url, @body, request_options)
619
- when :delete
620
+ elsif http_method == :delete
620
621
  response = connection.delete(@url, @body, request_options)
621
622
  else
622
623
  raise InvalidRequestException.new("Invalid method #{http_method}")
@@ -1,3 +1,3 @@
1
1
  module Flexirest
2
- VERSION = "1.12.3"
2
+ VERSION = "1.12.5"
3
3
  end
@@ -109,6 +109,7 @@ describe Flexirest::Caching do
109
109
  base_url "http://www.example.com"
110
110
  get :all, "/"
111
111
  put :save_all, "/"
112
+ get :plain, "/plain/:id", plain: true
112
113
  end
113
114
 
114
115
  Person.cache_store = CachingExampleCacheStore5.new({ expires_in: 1.day.to_i }) # default cache expiration
@@ -121,7 +122,8 @@ describe Flexirest::Caching do
121
122
  cached_response = Flexirest::CachedResponse.new(
122
123
  status:200,
123
124
  result:@cached_object,
124
- etag:@etag)
125
+ etag:@etag,
126
+ class_name:Person.name)
125
127
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
126
128
  expect_any_instance_of(Flexirest::Connection).to receive(:get){ |connection, path, options|
127
129
  expect(path).to eq('/')
@@ -131,11 +133,23 @@ describe Flexirest::Caching do
131
133
  expect(ret.first_name).to eq("Johnny")
132
134
  end
133
135
 
136
+ it "should read the response to the cache store if response is a 204 with empty bodies and cache is wanted" do
137
+ cached_response = Flexirest::CachedResponse.new(
138
+ status:204,
139
+ result:true,
140
+ expires:Time.now + 30,
141
+ class_name:Person.name)
142
+ expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
143
+ expect_any_instance_of(Flexirest::Connection).not_to receive(:get)
144
+ Person.all
145
+ end
146
+
134
147
  it "should not read from the cache store to check for an etag unless it's a GET request" do
135
148
  cached_response = Flexirest::CachedResponse.new(
136
149
  status:200,
137
150
  result:@cached_object,
138
- etag:@etag)
151
+ etag:@etag,
152
+ class_name:Person.name)
139
153
  expect_any_instance_of(CachingExampleCacheStore5).to_not receive(:read)
140
154
  expect_any_instance_of(Flexirest::Connection).to receive(:put).and_return(::FaradayResponseMock.new(OpenStruct.new(status:200, body: {result: "foo"}.to_json, response_headers:{})))
141
155
  ret = Person.save_all
@@ -145,7 +159,8 @@ describe Flexirest::Caching do
145
159
  cached_response = Flexirest::CachedResponse.new(
146
160
  status: 200,
147
161
  result: @cached_object,
148
- etag: @etag
162
+ etag: @etag,
163
+ class_name:Person.name
149
164
  )
150
165
  allow_any_instance_of(CachingExampleCacheStore5).to receive(:read).and_return(Marshal.dump(cached_response))
151
166
  new_name = 'Pete'
@@ -166,7 +181,8 @@ describe Flexirest::Caching do
166
181
  cached_response = Flexirest::CachedResponse.new(
167
182
  status:200,
168
183
  result:@cached_object,
169
- expires:Time.now + 30)
184
+ expires:Time.now + 30,
185
+ class_name:Person.name)
170
186
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
171
187
  expect_any_instance_of(Flexirest::Connection).not_to receive(:get)
172
188
  ret = Person.all
@@ -177,7 +193,8 @@ describe Flexirest::Caching do
177
193
  cached_response = Flexirest::CachedResponse.new(
178
194
  status:200,
179
195
  result:@cached_object,
180
- expires:Time.now + 30)
196
+ expires:Time.now + 30,
197
+ class_name:Person.name)
181
198
  Timecop.travel(Time.now + 60)
182
199
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(nil)
183
200
  expect_any_instance_of(Flexirest::Connection).to receive(:get).with("/", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(status:200, body:"{\"result\":true}", response_headers:{})))
@@ -189,7 +206,8 @@ describe Flexirest::Caching do
189
206
  cached_response = Flexirest::CachedResponse.new(
190
207
  status:200,
191
208
  result:@cached_object,
192
- expires:Time.now + 30)
209
+ expires:Time.now + 30,
210
+ class_name:Person.name)
193
211
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
194
212
  expect_any_instance_of(Flexirest::Connection).not_to receive(:get)
195
213
  ret = Person.all
@@ -201,7 +219,8 @@ describe Flexirest::Caching do
201
219
  cached_response = Flexirest::CachedResponse.new(
202
220
  status:200,
203
221
  result:@cached_object,
204
- expires:Time.now + 30)
222
+ expires:Time.now + 30,
223
+ class_name:Person.name)
205
224
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
206
225
  expect_any_instance_of(Flexirest::Connection).not_to receive(:get)
207
226
  p = Person.new(first_name:"Billy")
@@ -219,7 +238,8 @@ describe Flexirest::Caching do
219
238
  status:200,
220
239
  result:object,
221
240
  etag:etag,
222
- expires:Time.now + 30)
241
+ expires:Time.now + 30,
242
+ class_name:Person.name)
223
243
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(Marshal.dump(cached_response))
224
244
  expect_any_instance_of(Flexirest::Connection).not_to receive(:get)
225
245
  ret = Person.all
@@ -237,7 +257,8 @@ describe Flexirest::Caching do
237
257
  status:200,
238
258
  result:object,
239
259
  etag:etag,
240
- expires:Time.now + 30)
260
+ expires:Time.now + 30,
261
+ class_name:Person.name)
241
262
  Timecop.travel(Time.now + 60)
242
263
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(nil)
243
264
  expect_any_instance_of(Flexirest::Connection).to receive(:get).with("/", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(status:200, body:"[{\"first_name\":\"Billy\"}]", response_headers:{})))
@@ -247,6 +268,21 @@ describe Flexirest::Caching do
247
268
  Timecop.return
248
269
  end
249
270
 
271
+ it "should not write the response to the cache if it is a plain request" do
272
+ response_body = "This is another non-JSON string"
273
+ expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/plain/1234").and_return(nil)
274
+ expect_any_instance_of(CachingExampleCacheStore5).to receive(:write).once.with("Person:/plain/1234", an_instance_of(String), hash_excluding(:etag))
275
+ expect_any_instance_of(Flexirest::Connection).to receive(:get).with(any_args).and_return(::FaradayResponseMock.new(OpenStruct.new(status:200, response_headers:{expires:(Time.now + 30).rfc822}, body:response_body)))
276
+ Person.plain(id:1234)
277
+ end
278
+
279
+ it "should write the response to the cache if response is a 204 with empty bodies and with expires set (or an etag)" do
280
+ expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(nil)
281
+ expect_any_instance_of(CachingExampleCacheStore5).to receive(:write).once.with("Person:/", an_instance_of(String), hash_excluding(:etag))
282
+ expect_any_instance_of(Flexirest::Connection).to receive(:get).with(any_args).and_return(::FaradayResponseMock.new(OpenStruct.new(status:204, response_headers:{expires:(Time.now + 30).rfc822}, body: nil)))
283
+ Person.all
284
+ end
285
+
250
286
  it "should not write the response to the cache unless it has caching headers" do
251
287
  expect_any_instance_of(CachingExampleCacheStore5).to receive(:read).once.with("Person:/").and_return(nil)
252
288
  expect_any_instance_of(CachingExampleCacheStore5).not_to receive(:write)
@@ -54,6 +54,7 @@ describe Flexirest::Request do
54
54
  put :conversion_child, "/put/:id", parse_fields: [:converted_child]
55
55
  delete :remove, "/remove/:id"
56
56
  delete :remove_body, "/remove/:id", send_delete_body: true
57
+ get :get_body, "/get-body", send_get_body: true
57
58
  get :hal, "/hal", fake:"{\"_links\":{\"child\": {\"href\": \"/child/1\"}, \"other\": {\"href\": \"/other/1\"}, \"cars\":[{\"href\": \"/car/1\", \"name\":\"car1\"}, {\"href\": \"/car/2\", \"name\":\"car2\"}, {\"href\": \"/car/not-embed\", \"name\":\"car_not_embed\"} ], \"lazy\": {\"href\": \"/lazy/load\"}, \"invalid\": [{\"href\": \"/invalid/1\"}]}, \"_embedded\":{\"other\":{\"name\":\"Jane\"},\"child\":{\"name\":\"Billy\"}, \"cars\":[{\"_links\": {\"self\": {\"href\": \"/car/1\"} }, \"make\": \"Bugatti\", \"model\": \"Veyron\"}, {\"_links\": {\"self\": {\"href\": \"/car/2\"} }, \"make\": \"Ferrari\", \"model\": \"F458 Italia\"} ], \"invalid\": [{\"present\":true, \"_links\": {} } ] } }", has_many:{other:ExampleOtherClient}
58
59
  get :fake_object, "/fake", fake:"{\"result\":true, \"list\":[1,2,3,{\"test\":true}], \"child\":{\"grandchild\":{\"test\":true}}}"
59
60
  get :fake_proc_object, "/fake", fake:->(request) { "{\"result\":#{request.get_params[:id]}}" }
@@ -451,6 +452,11 @@ describe Flexirest::Request do
451
452
  ExampleClient.all
452
453
  end
453
454
 
455
+ it "should get an HTTP connection when called and call get with a body if send_get_body is specified" do
456
+ expect_any_instance_of(Flexirest::Connection).to receive(:get).with("/get-body", "something=else", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{})))
457
+ ExampleClient.get_body(something: "else")
458
+ end
459
+
454
460
  it "should get an HTTP connection when called and call delete on it" do
455
461
  expect_any_instance_of(Flexirest::Connection).to receive(:delete).with("/remove/1", "", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:'{"result":true}', response_headers:{})))
456
462
  ExampleClient.remove(id:1)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flexirest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.3
4
+ version: 1.12.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jeffries
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
11
+ date: 2025-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -407,7 +407,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
407
407
  - !ruby/object:Gem::Version
408
408
  version: '0'
409
409
  requirements: []
410
- rubygems_version: 3.5.6
410
+ rubygems_version: 3.5.21
411
411
  signing_key:
412
412
  specification_version: 4
413
413
  summary: This gem is for accessing REST services in a flexible way. ActiveResource