flexirest 1.3.22 → 1.3.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +12 -0
- data/README.md +44 -1
- data/flexirest.gemspec +12 -1
- data/lib/flexirest/attribute_parsing.rb +2 -2
- data/lib/flexirest/caching.rb +25 -4
- data/lib/flexirest/result_iterator.rb +6 -2
- data/lib/flexirest/version.rb +1 -1
- data/spec/lib/attribute_parsing_spec.rb +8 -0
- data/spec/lib/base_spec.rb +20 -1
- data/spec/lib/caching_spec.rb +3 -3
- data/spec/lib/connection_spec.rb +0 -1
- data/spec/lib/logger_spec.rb +3 -1
- data/spec/lib/result_iterator_spec.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14a35d637cc44c2743283d3c63c3072b5d46b43c
|
4
|
+
data.tar.gz: a5b9fa6ad5756255d0f7d7033fe7f82ff85927bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e4b418eb542330bcc6223c05ed6335d0727d12a654facf6977e21c639082a066c3e48ffab1bd806a49a1d910a8752799ca351ac9df82dab0cc4331a9bed55b
|
7
|
+
data.tar.gz: 174b86be52593db6abd70544225a2775029c648e03eb4c971e52973a356a31fa304accd0281e7c14f4a167056b369f75843dda5c46fcd38755204360ed11a53b
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.3.24
|
4
|
+
|
5
|
+
Bugfix:
|
6
|
+
|
7
|
+
- Calling class methods on an instance where the instance is cacheable should work (thanks to johnmckinght for the bug report)
|
8
|
+
|
9
|
+
## 1.3.23
|
10
|
+
|
11
|
+
Bugfix:
|
12
|
+
|
13
|
+
- Should not parse multiline strings as `DateTime` when using the automatica parsing (thanks to execjosh for the PR)
|
14
|
+
|
3
15
|
## 1.3.22
|
4
16
|
|
5
17
|
Bugfix:
|
data/README.md
CHANGED
@@ -9,6 +9,49 @@
|
|
9
9
|
|
10
10
|
This gem is for accessing REST services in an ActiveRecord style. ActiveResource already exists for this, but it doesn't work where the resource naming doesn't follow Rails conventions, it doesn't have in-built caching and it's not as flexible in general.
|
11
11
|
|
12
|
+
If you are a previous user of ActiveRestClient, there's some more information on [why I created this fork and how to upgrade](https://github.com/flexirest/flexirest/blob/master/Migrating-from-ActiveRestClient.md).
|
13
|
+
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Basic Usage](#usage)
|
16
|
+
- [Create a new person](#create-a-new-person)
|
17
|
+
- [Find a person](#find-a-person-not-needed-after-creating)
|
18
|
+
- [Update a person](#update-a-person)
|
19
|
+
- [Get all people](#get-all-people)
|
20
|
+
- [Ruby on Rails Integration](#ruby-on-rails-integration)
|
21
|
+
- [Advanced Features](#advanced-features)
|
22
|
+
- [Faraday Configuration](#faraday-configuration)
|
23
|
+
- [Associations](#associations)
|
24
|
+
- [Association Type 1 - Loading Other Classes](#association-type-1-loading-other-classes)
|
25
|
+
- [Association Type 2 - Lazy Loading From Other URLs](#association-type-2-lazy-loading-from-other-urls)
|
26
|
+
- [Association Type 3 - HAL Auto-loaded Resources](#association-type-3-hal-auto-loaded-resources)
|
27
|
+
- [Association Type 4 - Nested Resources](#association-type-4-nested-resources)
|
28
|
+
- [Caching](#caching)
|
29
|
+
- [Using callbacks](#using-callbacks)
|
30
|
+
- [Lazy Loading](#lazy-loading)
|
31
|
+
- [Authentication](#authentication)
|
32
|
+
- [Basic](#basic)
|
33
|
+
- [Api-Auth](#api-auth)
|
34
|
+
- [Body Types](#body-types)
|
35
|
+
- [Parallel Requests](#parallel-requests)
|
36
|
+
- [Faking Calls](#faking-calls)
|
37
|
+
- [Per-request Timeouts](#per-request-timeouts)
|
38
|
+
- [Per-request Params Encoding](#per-request-params-encoding)
|
39
|
+
- [Automatic Conversion of Fields to Date/DateTime](#automatic-conversion-of-fields-to-datedatetime)
|
40
|
+
- [Raw Requests](#raw-requests)
|
41
|
+
- [Plain Requests](#plain-requests)
|
42
|
+
- [Proxying APIs](#proxying-apis)
|
43
|
+
- [Translating APIs](#translating-apis)
|
44
|
+
- [Default Parameters](#default-parameters)
|
45
|
+
- [Root element removal](#root-element-removal)
|
46
|
+
- [Required Parameters](#required-parameters)
|
47
|
+
- [HTTP/Parse Error Handling](#httpparse-error-handling)
|
48
|
+
- [Validation](#validation)
|
49
|
+
- [Permitting nil values](#permitting-nil-values)
|
50
|
+
- [Debugging](#debugging)
|
51
|
+
- [XML Responses](#xml-responses)
|
52
|
+
- [Contributing](#contributing)
|
53
|
+
|
54
|
+
|
12
55
|
## Installation
|
13
56
|
|
14
57
|
Add this line to your application's Gemfile:
|
@@ -400,7 +443,7 @@ Flexirest::Base.cache_store = Redis::Store.new("redis://localhost:6379/0/cache")
|
|
400
443
|
|
401
444
|
You can use callbacks to alter get/post parameters, the URL or set the post body (doing so overrides normal parameter insertion in to the body) before a request or to adjust the response after a request. This can either be a block or a named method (like ActionController's `before_callback`/`before_action` methods).
|
402
445
|
|
403
|
-
The callback is passed the name of the method (e.g. `:save`) and an object (a request object for `before_request` and a response object for `after_request`). The request object has four public attributes `post_params` (a Hash of the POST parameters), `get_params` (a Hash of the GET parameters), headers and `url` (a String containing the full URL without GET parameters appended)
|
446
|
+
The callback is passed the name of the method (e.g. `:save`) and an object (a request object for `before_request` and a response object for `after_request`). The request object has four public attributes `post_params` (a Hash of the POST parameters), `get_params` (a Hash of the GET parameters), `headers` and `url` (a `String` containing the full URL without GET parameters appended).
|
404
447
|
|
405
448
|
```ruby
|
406
449
|
require 'secure_random'
|
data/flexirest.gemspec
CHANGED
@@ -32,6 +32,17 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_runtime_dependency "multi_json"
|
34
34
|
spec.add_runtime_dependency "crack"
|
35
|
-
spec.add_runtime_dependency "activesupport"
|
36
35
|
spec.add_runtime_dependency "faraday"
|
36
|
+
|
37
|
+
# Use Gem::Version to parse the Ruby version for reliable comparison
|
38
|
+
# ActiveSupport 5+ requires Ruby 2.2.2
|
39
|
+
if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('2.2.2')
|
40
|
+
spec.add_runtime_dependency "activesupport"
|
41
|
+
else
|
42
|
+
spec.add_runtime_dependency "activesupport", "< 5.0.0"
|
43
|
+
end
|
44
|
+
# JSON is an implicit dependency of something, but JSON v2+ requires Ruby 2+
|
45
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0')
|
46
|
+
spec.add_runtime_dependency "json", "< 2.0.0"
|
47
|
+
end
|
37
48
|
end
|
@@ -3,9 +3,9 @@ module Flexirest
|
|
3
3
|
private
|
4
4
|
|
5
5
|
def parse_attribute_value(v)
|
6
|
-
if v.to_s[(
|
6
|
+
if v.to_s[(/\A(((19|20)\d\d[- \/.](0[1-9]|1[012]|[1-9])[- \/.](0[1-9]|[12][0-9]|3[01]|[1-9]))|((0[1-9]|1[012]|[1-9])[- \/.](0[1-9]|[12][0-9]|3[01]|[1-9])[- \/.](19|20)\d\d))\Z/)]
|
7
7
|
Date.parse(v)
|
8
|
-
elsif v.to_s[
|
8
|
+
elsif v.to_s[/\A([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?))\Z/]
|
9
9
|
DateTime.parse(v)
|
10
10
|
else
|
11
11
|
v
|
data/lib/flexirest/caching.rb
CHANGED
@@ -68,9 +68,11 @@ module Flexirest
|
|
68
68
|
key = "#{request.class_name}:#{request.original_url}"
|
69
69
|
Flexirest::Logger.debug " \033[1;4;32m#{Flexirest.name}\033[0m #{key} - Writing to cache"
|
70
70
|
cached_response = CachedResponse.new(status:response.status, result:result)
|
71
|
-
cached_response.etag = headers[:etag] if headers[:etag]
|
71
|
+
cached_response.etag = "#{headers[:etag]}" if headers[:etag]
|
72
72
|
cached_response.expires = Time.parse(headers[:expires]) rescue nil if headers[:expires]
|
73
|
-
|
73
|
+
if cached_response.etag.present? || cached_response.expires
|
74
|
+
cache_store.write(key, Marshal.dump(cached_response), {})
|
75
|
+
end
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
@@ -82,13 +84,32 @@ module Flexirest
|
|
82
84
|
end
|
83
85
|
|
84
86
|
class CachedResponse
|
85
|
-
attr_accessor :
|
87
|
+
attr_accessor :class_name, :status, :etag, :expires
|
86
88
|
|
87
89
|
def initialize(options)
|
88
90
|
@status = options[:status]
|
89
|
-
@result = options[:result]
|
90
91
|
@etag = options[:etag]
|
91
92
|
@expires = options[:expires]
|
93
|
+
|
94
|
+
@class_name = options[:result].class.name
|
95
|
+
if options[:result].is_a?(ResultIterator)
|
96
|
+
@class_name = options[:result][0].class.name
|
97
|
+
@result = options[:result].map{|i| {}.merge(i._attributes)}
|
98
|
+
else
|
99
|
+
@result = {}.merge(options[:result].try(:_attributes) || {})
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def result
|
104
|
+
return @result if @class_name.nil? # Old cached instance
|
105
|
+
|
106
|
+
if @result.is_a?(Array)
|
107
|
+
ri = ResultIterator.new(self)
|
108
|
+
ri.items = @result.map{|i| @class_name.constantize.new(i)}
|
109
|
+
ri
|
110
|
+
else
|
111
|
+
@class_name.constantize.new(@result)
|
112
|
+
end
|
92
113
|
end
|
93
114
|
end
|
94
115
|
end
|
@@ -2,8 +2,8 @@ module Flexirest
|
|
2
2
|
class ResultIterator
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
-
attr_accessor :_status
|
6
|
-
attr_reader :
|
5
|
+
attr_accessor :_status, :items
|
6
|
+
attr_reader :_headers
|
7
7
|
|
8
8
|
def initialize(response = nil)
|
9
9
|
@_status = response.try :status
|
@@ -19,6 +19,10 @@ module Flexirest
|
|
19
19
|
@items.size
|
20
20
|
end
|
21
21
|
|
22
|
+
def to_a
|
23
|
+
@items
|
24
|
+
end
|
25
|
+
|
22
26
|
def index(value)
|
23
27
|
@items.index(value)
|
24
28
|
end
|
data/lib/flexirest/version.rb
CHANGED
@@ -16,10 +16,18 @@ describe Flexirest::AttributeParsing do
|
|
16
16
|
expect(subject.test("1980-12-24T00:00:00.000Z")).to be_a(DateTime)
|
17
17
|
end
|
18
18
|
|
19
|
+
it "should not parse a multiline string as a datetime" do
|
20
|
+
expect(subject.test("not a datetime\n1980-12-24T00:00:00.000Z")).to be_a(String)
|
21
|
+
end
|
22
|
+
|
19
23
|
it "should parse dates" do
|
20
24
|
expect(subject.test("1980-12-24")).to be_a(Date)
|
21
25
|
end
|
22
26
|
|
27
|
+
it "should not parse a multiline string as a datetime" do
|
28
|
+
expect(subject.test("not a date\n1980-12-24")).to be_a(String)
|
29
|
+
end
|
30
|
+
|
23
31
|
it "should return strings for string values" do
|
24
32
|
expect(subject.test("1980-12")).to eq("1980-12")
|
25
33
|
end
|
data/spec/lib/base_spec.rb
CHANGED
@@ -37,6 +37,11 @@ class NonHostnameBaseUrlExample < Flexirest::Base
|
|
37
37
|
get :all, "/all"
|
38
38
|
end
|
39
39
|
|
40
|
+
class InstanceMethodExample < Flexirest::Base
|
41
|
+
base_url "http://www.example.com/v1/"
|
42
|
+
get :all, "/all"
|
43
|
+
end
|
44
|
+
|
40
45
|
describe Flexirest::Base do
|
41
46
|
it 'should instantiate a new descendant' do
|
42
47
|
expect{EmptyExample.new}.to_not raise_error
|
@@ -345,6 +350,21 @@ describe Flexirest::Base do
|
|
345
350
|
end
|
346
351
|
end
|
347
352
|
|
353
|
+
it "should work with caching if instance methods are used" do
|
354
|
+
perform_caching = InstanceMethodExample.perform_caching
|
355
|
+
cache_store = InstanceMethodExample.cache_store
|
356
|
+
begin
|
357
|
+
response = "{\"id\": 1, \"name\":\"test\"}"
|
358
|
+
allow_any_instance_of(Flexirest::Connection).to receive(:get).and_return( ::FaradayResponseMock.new(OpenStruct.new(status:200, response_headers:{"Etag" => "12345678", "Content-type" => "application/json"}, body:response)))
|
359
|
+
e = InstanceMethodExample.new
|
360
|
+
e.all(1)
|
361
|
+
expect(e.id).to eq(1)
|
362
|
+
ensure
|
363
|
+
InstanceMethodExample.perform_caching = perform_caching
|
364
|
+
InstanceMethodExample.cache_store = cache_store
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
348
368
|
it "should be able to lazy load a direct URL request" do
|
349
369
|
expect_any_instance_of(Flexirest::Request).to receive(:do_request).with(any_args).and_return(::FaradayResponseMock.new(OpenStruct.new(status:200, response_headers:{}, body:"{\"first_name\":\"Billy\"}")))
|
350
370
|
example = EmptyExample._lazy_request("http://api.example.com/")
|
@@ -409,7 +429,6 @@ describe Flexirest::Base do
|
|
409
429
|
expect(json_parsed_object["students"].first["age"]).to eq(student1.age)
|
410
430
|
expect(json_parsed_object["students"].second["age"]).to eq(student2.age)
|
411
431
|
end
|
412
|
-
|
413
432
|
end
|
414
433
|
|
415
434
|
end
|
data/spec/lib/caching_spec.rb
CHANGED
@@ -82,9 +82,9 @@ describe Flexirest::Caching do
|
|
82
82
|
def write(key, value, options={}) ; end
|
83
83
|
end
|
84
84
|
|
85
|
-
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore2.new }.to raise_error
|
86
|
-
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore3.new }.to raise_error
|
87
|
-
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore4.new }.to raise_error
|
85
|
+
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore2.new }.to raise_error(Flexirest::InvalidCacheStoreException)
|
86
|
+
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore3.new }.to raise_error(Flexirest::InvalidCacheStoreException)
|
87
|
+
expect{ Flexirest::Base.cache_store = CachingExampleCacheStore4.new }.to raise_error(Flexirest::InvalidCacheStoreException)
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should allow you to remove the custom cache store" do
|
data/spec/lib/connection_spec.rb
CHANGED
@@ -149,7 +149,6 @@ describe Flexirest::Connection do
|
|
149
149
|
|
150
150
|
if Gem.loaded_specs["api-auth"].present? && Gem.loaded_specs["api-auth"].version.to_s >= "2.0.0"
|
151
151
|
it 'should have an Authorization header with a custom digest method' do
|
152
|
-
puts Gem.loaded_specs["api-auth"].version
|
153
152
|
@options[:api_auth][:api_auth_options] = {
|
154
153
|
digest: "sha256"
|
155
154
|
}
|
data/spec/lib/logger_spec.rb
CHANGED
@@ -45,9 +45,10 @@ describe Flexirest::Instrumentation do
|
|
45
45
|
expect(File).to receive(:open).with("/dev/null", "a").and_yield(file)
|
46
46
|
expect(file).to receive(:<<).with("Hello warn\n")
|
47
47
|
Flexirest::Logger.warn("Hello warn")
|
48
|
+
Flexirest::Logger.logfile = nil
|
48
49
|
end
|
49
50
|
|
50
|
-
it "should write to
|
51
|
+
it "should write to STODOUT if one has been specified" do
|
51
52
|
Flexirest::Logger.logfile = STDOUT
|
52
53
|
expect(STDOUT).to receive(:<<).with("Hello world\n")
|
53
54
|
Flexirest::Logger.debug("Hello world")
|
@@ -60,6 +61,7 @@ describe Flexirest::Instrumentation do
|
|
60
61
|
|
61
62
|
expect(STDOUT).to receive(:<<).with("Hello warn\n")
|
62
63
|
Flexirest::Logger.warn("Hello warn")
|
64
|
+
Flexirest::Logger.logfile = nil
|
63
65
|
end
|
64
66
|
|
65
67
|
it "should append to its own messages list if neither Rails nor a logfile has been specified" do
|
@@ -120,7 +120,7 @@ describe Flexirest::ResultIterator do
|
|
120
120
|
it "raises an error if you call paginate without WillPaginate installed" do
|
121
121
|
result = Flexirest::ResultIterator.new
|
122
122
|
result << 3
|
123
|
-
expect{result.paginate}.to raise_error
|
123
|
+
expect{result.paginate}.to raise_error(Flexirest::WillPaginateNotAvailableException)
|
124
124
|
end
|
125
125
|
|
126
126
|
it "returns a WillPaginate::Collection if you call paginate with WillPaginate installed" do
|
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.3.
|
4
|
+
version: 1.3.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jeffries
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -179,7 +179,7 @@ dependencies:
|
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
182
|
+
name: faraday
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
185
|
- - ">="
|
@@ -193,7 +193,7 @@ dependencies:
|
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
196
|
+
name: activesupport
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
198
198
|
requirements:
|
199
199
|
- - ">="
|