flexirest 1.3.33 → 1.3.34
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 +10 -0
- data/README.md +42 -1
- data/flexirest.gemspec +5 -1
- data/lib/flexirest/base.rb +48 -10
- data/lib/flexirest/caching.rb +1 -1
- data/lib/flexirest/connection.rb +11 -4
- data/lib/flexirest/request.rb +37 -1
- data/lib/flexirest/version.rb +1 -1
- data/spec/lib/base_spec.rb +31 -2
- data/spec/lib/caching_spec.rb +14 -0
- data/spec/lib/connection_spec.rb +2 -2
- data/spec/lib/request_spec.rb +80 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0aefbb07885064fa794f6680446e48a678682a6a
|
4
|
+
data.tar.gz: dae31dfd7a9522ac6e5f21b72037b1d4be9ed47c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39aa00c5bc3ff7bce1ef08cfa646bf371dbeff2f13464c750cf462d2ee93cedbe90be9c4b3fa77788240c7a186568de55df382a7c287287fcd044dcc2dbfd49a
|
7
|
+
data.tar.gz: 56f5bdabdfb819ea43a2ea209700d330d05548e174ef3343c5e7cc15a00b69fd6b0ba6c705502263609d03481b72812204632f141bd6f1a90a72ac120fdc2cf4
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.3.34
|
4
|
+
|
5
|
+
Feature:
|
6
|
+
|
7
|
+
- Added ActiveRecord/Mongoid style dirty/changed tracking methods (thanks to eshork for the PR)
|
8
|
+
|
9
|
+
Bugfix:
|
10
|
+
|
11
|
+
- Now can disable caching on subclasses after being enabled on a parent (thanks to yujideveloper for the PR)
|
12
|
+
|
3
13
|
## 1.3.33
|
4
14
|
|
5
15
|
Feature:
|
data/README.md
CHANGED
@@ -44,6 +44,7 @@ If you are a previous user of ActiveRestClient, there's some more information on
|
|
44
44
|
- [Default Parameters](#default-parameters)
|
45
45
|
- [Root element removal](#root-element-removal)
|
46
46
|
- [Required Parameters](#required-parameters)
|
47
|
+
- [Updating Only Changed/Dirty](#updating-only-changed-dirty)
|
47
48
|
- [HTTP/Parse Error Handling](#httpparse-error-handling)
|
48
49
|
- [Validation](#validation)
|
49
50
|
- [Permitting nil values](#permitting-nil-values)
|
@@ -937,6 +938,38 @@ end
|
|
937
938
|
@people = Person.all(active:false)
|
938
939
|
```
|
939
940
|
|
941
|
+
### Updating Only Changed/Dirty
|
942
|
+
|
943
|
+
The most common RESTful usage of the PATCH http-method is to only send fields that have changed. The default action for all calls is to send all known object attributes for POST/PUT/PATCH calls, but this can be altered by setting the `only_changed` option on your call declaration.
|
944
|
+
|
945
|
+
```ruby
|
946
|
+
class Person < Flexirest::Base
|
947
|
+
get :all, '/people'
|
948
|
+
patch :update, '/people/:id', :only_changed => true # only send attributes that are changed/dirty
|
949
|
+
end
|
950
|
+
|
951
|
+
person = Person.all.first
|
952
|
+
person.first_name = 'Billy'
|
953
|
+
person.update # performs a PATCH request, sending only the now changed 'first_name' attribute
|
954
|
+
```
|
955
|
+
|
956
|
+
This functionality is per-call, and there is some additional flexibility to control which attributes are sent and when.
|
957
|
+
|
958
|
+
```ruby
|
959
|
+
class Person < Flexirest::Base
|
960
|
+
get :all, '/people'
|
961
|
+
patch :update_1, '/people/:id', :only_changed => true # only send attributes that are changed/dirty (all known attributes on this object are subject to evaluation)
|
962
|
+
patch :update_2, "/people/:id", :only_changed => [:first_name, :last_name, :dob] # only send these listed attributes, and only if they are changed/dirty
|
963
|
+
patch :update_3, "/people/:id", :only_changed => {first_name: true, last_name: true, dob: false} # include the listed attributes marked 'true' only when changed; attributes marked 'false' are always included (changed or not, and if not present will be sent as nil); unspecified attributes are never sent
|
964
|
+
end
|
965
|
+
```
|
966
|
+
|
967
|
+
#### Additional Notes:
|
968
|
+
|
969
|
+
* The above examples specifically showed PATCH methods, but this is also available for POST and PUT methods for flexibility purposes (even though they break typical REST methodology).
|
970
|
+
* This logic is currently evaluated before Required Parameters, so it is possible to ensure that requirements are met by some clever usage.
|
971
|
+
- This means that if a method is `:requires => [:active], :only_changed => {active: false}` then `active` will always have a value and would always pass the `:requires` directive (so you need to be very careful because the answer may end up being `nil` if you didn't specifically set it).
|
972
|
+
|
940
973
|
### HTTP/Parse Error Handling
|
941
974
|
|
942
975
|
Sometimes the backend server may respond with a non-200/304 header, in which case the code will raise an `Flexirest::HTTPClientException` for 4xx errors or an `Flexirest::HTTPServerException` for 5xx errors. These both have a `status` accessor and a `result` accessor (for getting access to the parsed body):
|
@@ -977,7 +1010,15 @@ Note: the block based validation is responsible for adding errors to `object._er
|
|
977
1010
|
|
978
1011
|
Validations are run when calling `valid?` or when calling any API on an instance (and then only if it is `valid?` will the API go on to be called).
|
979
1012
|
|
980
|
-
`full_error_messages` returns an array of attributes with their associated error messages, i.e. `["age must be at least 18"]`. Custom messages can be specified by passing a `:message` option to `validates`. This differs slightly from ActiveRecord in that it's an option to `validates` itself, not a part of a final hash.
|
1013
|
+
`full_error_messages` returns an array of attributes with their associated error messages, i.e. `["age must be at least 18"]`. Custom messages can be specified by passing a `:message` option to `validates`. This differs slightly from ActiveRecord in that it's an option to `validates` itself, not a part of a final hash of other options. This is because the author doesn't like the ActiveRecord format (but will accept pull requests that make both syntaxes valid). To make this clearer, an example may help:
|
1014
|
+
|
1015
|
+
```ruby
|
1016
|
+
# ActiveRecord
|
1017
|
+
validates :name, presence: { message: "must be given please" }
|
1018
|
+
|
1019
|
+
# Flexirest
|
1020
|
+
validates :name, :presence, message: "must be given please"
|
1021
|
+
```
|
981
1022
|
|
982
1023
|
#### Permitting nil values
|
983
1024
|
The default behavior for `:length`, `:numericality` and `:inclusion` validators is to fail when a `nil` value is encountered. You can prevent `nil` attribute values from triggering validation errors for attributes that may permit `nil` by adding the `:allow_nil => true` option. Adding this option with a `true` value to `:length`, `:numericality` and `:inclusion` validators will permit `nil` values and not trigger errors. Some examples are:
|
data/flexirest.gemspec
CHANGED
@@ -22,7 +22,11 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
23
|
spec.add_development_dependency "rake"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3"
|
25
|
-
|
25
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.1.0')
|
26
|
+
spec.add_development_dependency "webmock", "~> 2.1.0"
|
27
|
+
else
|
28
|
+
spec.add_development_dependency "webmock"
|
29
|
+
end
|
26
30
|
spec.add_development_dependency "rspec_junit_formatter"
|
27
31
|
spec.add_development_dependency "simplecov"
|
28
32
|
spec.add_development_dependency "simplecov-rcov"
|
data/lib/flexirest/base.rb
CHANGED
@@ -20,19 +20,19 @@ module Flexirest
|
|
20
20
|
|
21
21
|
def initialize(attrs={})
|
22
22
|
@attributes = {}
|
23
|
-
@dirty_attributes =
|
23
|
+
@dirty_attributes = Hash.new
|
24
24
|
|
25
25
|
raise Exception.new("Cannot instantiate Base class") if self.class.name == "Flexirest::Base"
|
26
26
|
|
27
27
|
attrs.each do |attribute_name, attribute_value|
|
28
28
|
attribute_name = attribute_name.to_sym
|
29
29
|
@attributes[attribute_name] = parse_date?(attribute_name) ? parse_attribute_value(attribute_value) : attribute_value
|
30
|
-
@dirty_attributes
|
30
|
+
@dirty_attributes[attribute_name] = [nil, attribute_value]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
def _clean!
|
35
|
-
@dirty_attributes =
|
35
|
+
@dirty_attributes = Hash.new
|
36
36
|
end
|
37
37
|
|
38
38
|
def _attributes
|
@@ -48,6 +48,20 @@ module Flexirest
|
|
48
48
|
@dirty_attributes.size > 0
|
49
49
|
end
|
50
50
|
|
51
|
+
def changed?
|
52
|
+
dirty?
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns an array of changed fields
|
56
|
+
def changed
|
57
|
+
@dirty_attributes.keys
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns hash of old and new vaules for each changed field
|
61
|
+
def changes
|
62
|
+
@dirty_attributes
|
63
|
+
end
|
64
|
+
|
51
65
|
def errors
|
52
66
|
@attributes[:errors] || (_errors != {} ? _errors : nil)
|
53
67
|
end
|
@@ -87,8 +101,7 @@ module Flexirest
|
|
87
101
|
end
|
88
102
|
|
89
103
|
def []=(key, value)
|
90
|
-
|
91
|
-
@dirty_attributes << key
|
104
|
+
_set_attribute(key, value)
|
92
105
|
end
|
93
106
|
|
94
107
|
def each
|
@@ -107,15 +120,14 @@ module Flexirest
|
|
107
120
|
end
|
108
121
|
inspection += "#{"," if @attributes.any?} ETag: #{@_etag}" unless @_etag.nil?
|
109
122
|
inspection += "#{"," if @attributes.any?} Status: #{@_status}" unless @_status.nil?
|
110
|
-
inspection += " (unsaved: #{@dirty_attributes.map(&:to_s).join(", ")})" if @dirty_attributes.any?
|
123
|
+
inspection += " (unsaved: #{@dirty_attributes.keys.map(&:to_s).join(", ")})" if @dirty_attributes.any?
|
111
124
|
"#<#{self.class} #{inspection}>"
|
112
125
|
end
|
113
126
|
|
114
127
|
def method_missing(name, *args)
|
115
128
|
if name.to_s[-1,1] == "="
|
116
129
|
name = name.to_s.chop.to_sym
|
117
|
-
|
118
|
-
@dirty_attributes << name
|
130
|
+
_set_attribute(name, args.first)
|
119
131
|
else
|
120
132
|
name_sym = name.to_sym
|
121
133
|
name = name.to_s
|
@@ -124,13 +136,25 @@ module Flexirest
|
|
124
136
|
@attributes[name_sym]
|
125
137
|
else
|
126
138
|
if name[/^lazy_/] && mapped = self.class._mapped_method(name_sym)
|
127
|
-
|
139
|
+
if mapped[:method] != :delete
|
140
|
+
raise ValidationFailedException.new unless valid?
|
141
|
+
end
|
142
|
+
|
128
143
|
request = Request.new(mapped, self, args.first)
|
129
144
|
Flexirest::LazyLoader.new(request)
|
130
145
|
elsif mapped = self.class._mapped_method(name_sym)
|
131
|
-
|
146
|
+
if mapped[:method] != :delete
|
147
|
+
raise ValidationFailedException.new unless valid?
|
148
|
+
end
|
149
|
+
|
132
150
|
request = Request.new(mapped, self, args.first)
|
133
151
|
request.call
|
152
|
+
elsif name[/_was$/] and @attributes.has_key? (name.sub(/_was$/,'').to_sym)
|
153
|
+
k = (name.sub(/_was$/,'').to_sym)
|
154
|
+
@dirty_attributes[k][0]
|
155
|
+
elsif name[/^reset_.*!$/] and @attributes.has_key? (name.sub(/^reset_/,'').sub(/!$/,'').to_sym)
|
156
|
+
k = (name.sub(/^reset_/,'').sub(/!$/,'').to_sym)
|
157
|
+
_reset_attribute(k)
|
134
158
|
elsif self.class.whiny_missing
|
135
159
|
raise NoAttributeException.new("Missing attribute #{name_sym}")
|
136
160
|
else
|
@@ -165,6 +189,20 @@ module Flexirest
|
|
165
189
|
|
166
190
|
private
|
167
191
|
|
192
|
+
def _set_attribute(key, value)
|
193
|
+
old_value = @dirty_attributes[key.to_sym]
|
194
|
+
old_value = @attributes[key.to_sym] unless old_value
|
195
|
+
old_value = old_value[0] if old_value and old_value.is_a? Array
|
196
|
+
@dirty_attributes[key.to_sym] = [old_value, value]
|
197
|
+
@attributes[key.to_sym] = value
|
198
|
+
end
|
199
|
+
|
200
|
+
def _reset_attribute(key)
|
201
|
+
old_value = @dirty_attributes[key.to_sym]
|
202
|
+
@attributes[key.to_sym] = old_value[0] if old_value and old_value.is_a? Array
|
203
|
+
@dirty_attributes.delete(key.to_sym)
|
204
|
+
end
|
205
|
+
|
168
206
|
def value_for_inspect(value)
|
169
207
|
if value.is_a?(String) && value.length > 50
|
170
208
|
"#{value[0..50]}...".inspect
|
data/lib/flexirest/caching.rb
CHANGED
data/lib/flexirest/connection.rb
CHANGED
@@ -2,8 +2,9 @@ require 'faraday'
|
|
2
2
|
|
3
3
|
module Flexirest
|
4
4
|
|
5
|
-
class
|
6
|
-
class
|
5
|
+
class BaseException < StandardError ; end
|
6
|
+
class TimeoutException < BaseException ; end
|
7
|
+
class ConnectionFailedException < BaseException ; end
|
7
8
|
|
8
9
|
class Connection
|
9
10
|
attr_accessor :session, :base_url
|
@@ -25,11 +26,17 @@ module Flexirest
|
|
25
26
|
block.call
|
26
27
|
rescue Faraday::Error::TimeoutError
|
27
28
|
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
|
28
|
-
rescue Faraday::Error::ConnectionFailed
|
29
|
+
rescue Faraday::Error::ConnectionFailed => e1
|
30
|
+
if e1.respond_to?(:cause) && e1.cause.is_a?(Net::OpenTimeout)
|
31
|
+
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
|
32
|
+
end
|
29
33
|
begin
|
30
34
|
reconnect
|
31
35
|
block.call
|
32
|
-
rescue Faraday::Error::ConnectionFailed
|
36
|
+
rescue Faraday::Error::ConnectionFailed => e2
|
37
|
+
if e2.respond_to?(:cause) && e2.cause.is_a?(Net::OpenTimeout)
|
38
|
+
raise Flexirest::TimeoutException.new("Timed out getting #{full_url(path)}")
|
39
|
+
end
|
33
40
|
raise Flexirest::ConnectionFailedException.new("Unable to connect to #{full_url(path)}")
|
34
41
|
end
|
35
42
|
end
|
data/lib/flexirest/request.rb
CHANGED
@@ -224,7 +224,7 @@ module Flexirest
|
|
224
224
|
|
225
225
|
def prepare_params
|
226
226
|
params = @params || @object._attributes rescue {}
|
227
|
-
if params.is_a?(String) || params.is_a?(
|
227
|
+
if params.is_a?(String) || params.is_a?(Integer)
|
228
228
|
params = {id:params}
|
229
229
|
end
|
230
230
|
|
@@ -245,6 +245,39 @@ module Flexirest
|
|
245
245
|
@get_params = {}
|
246
246
|
end
|
247
247
|
|
248
|
+
# Evaluate :only_changed
|
249
|
+
if @method[:options][:only_changed]
|
250
|
+
if http_method == :post or http_method == :put or http_method == :patch
|
251
|
+
# we only ever mess with @post_params in here, because @get_params will/should never match our method criteria
|
252
|
+
if @method[:options][:only_changed].is_a? Hash
|
253
|
+
# only include the listed attributes marked 'true' when they are changed; attributed marked false are always included
|
254
|
+
newPostHash = {}
|
255
|
+
@method[:options][:only_changed].each_pair do |changed_attr_k,changed_attr_v|
|
256
|
+
if changed_attr_v == false or @object.changes.has_key? changed_attr_k.to_sym
|
257
|
+
newPostHash[changed_attr_k.to_sym] = @object[changed_attr_k.to_sym]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
@post_params = newPostHash
|
261
|
+
elsif @method[:options][:only_changed].is_a? Array
|
262
|
+
# only send these listed attributes, and only if they are changed
|
263
|
+
newPostHash = {}
|
264
|
+
@method[:options][:only_changed].each do |changed_attr|
|
265
|
+
if @object.changes.has_key? changed_attr.to_sym
|
266
|
+
newPostHash[changed_attr.to_sym] = @object[changed_attr.to_sym]
|
267
|
+
end
|
268
|
+
end
|
269
|
+
@post_params = newPostHash
|
270
|
+
else
|
271
|
+
# only send attributes if they are changed, drop the rest
|
272
|
+
newPostHash = {}
|
273
|
+
@object.changed.each do |k|
|
274
|
+
newPostHash[k] = @object[k]
|
275
|
+
end
|
276
|
+
@post_params = newPostHash
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
248
281
|
if @method[:options][:requires]
|
249
282
|
requires = @method[:options][:requires].dup
|
250
283
|
merged_params = @get_params.merge(@post_params || {})
|
@@ -270,7 +303,10 @@ module Flexirest
|
|
270
303
|
@post_params ||= {}
|
271
304
|
matches.each do |token|
|
272
305
|
token = token.first[1,999]
|
306
|
+
# pull URL path variables out of @get_params/@post_params
|
273
307
|
target = @get_params.delete(token.to_sym) || @post_params.delete(token.to_sym) || @get_params.delete(token.to_s) || @post_params.delete(token.to_s) || ""
|
308
|
+
# it's possible the URL path variable may not be part of the request, in that case, try to resolve it from the object attributes
|
309
|
+
target = @object._attributes[token.to_sym] || "" if target == ""
|
274
310
|
@url.gsub!(":#{token}", URI.escape(target.to_s))
|
275
311
|
end
|
276
312
|
end
|
data/lib/flexirest/version.rb
CHANGED
data/spec/lib/base_spec.rb
CHANGED
@@ -133,6 +133,35 @@ describe Flexirest::Base do
|
|
133
133
|
expect(client).to be_dirty
|
134
134
|
end
|
135
135
|
|
136
|
+
it "should track changed attributes and provide access to previous values (similar to ActiveRecord/Mongoid)" do
|
137
|
+
client = EmptyExample.new()
|
138
|
+
client["test"] = "Something"
|
139
|
+
|
140
|
+
client._clean! # force a clean state so we can proceed with tests
|
141
|
+
|
142
|
+
expect(client).to_not be_dirty # clean state should have set in (dirty?)
|
143
|
+
expect(client).to_not be_changed # clean state should have set in (changed?)
|
144
|
+
expect(client["test"].to_s).to eq("Something") # verify attribute value persists
|
145
|
+
|
146
|
+
client["test"] = "SomethingElse" # change the attribute value
|
147
|
+
expect(client["test"].to_s).to eq("SomethingElse") # most current set value should be returned
|
148
|
+
expect(client).to be_dirty # an attribute was changed, so the entire object is dirty
|
149
|
+
expect(client).to be_changed # an attribute was changed, so the entire object is changed
|
150
|
+
expect(client.changed).to be_a(Array) # the list of changed attributes should be an Array
|
151
|
+
expect(client.changed).to eq([:test]) # the list of changed attributes should provide the name of the changed attribute
|
152
|
+
expect(client.changes).to be_a(Hash) # changes are returned as a hash
|
153
|
+
expect(client.changes).to eq({test: ["Something", "SomethingElse"]}) # changes include [saved,unsaved] values, keyed by attribute name
|
154
|
+
expect(client.test_was).to eq("Something") # dynamic *_was notation provides original value
|
155
|
+
|
156
|
+
client["test"] = "SomethingElseAgain" # change the attribute value again
|
157
|
+
expect(client.test_was).to eq("Something") # dynamic *_was notation provides original value (from most recent save/load, not most recent change)
|
158
|
+
expect(client.changes).to eq({test: ["Something", "SomethingElseAgain"]}) # changes include [saved,unsaved] values, keyed by attribute name
|
159
|
+
|
160
|
+
# resets the test attribute back to the original value
|
161
|
+
expect( client.reset_test! ).to eq(["Something", "SomethingElseAgain"]) # reseting an attribute returns the previous pending changeset
|
162
|
+
expect(client).to_not be_dirty # reseting an attribute should makeit not dirty again
|
163
|
+
end
|
164
|
+
|
136
165
|
it "should overwrite attributes already set and mark them as dirty" do
|
137
166
|
client = EmptyExample.new(:hello => "World")
|
138
167
|
client._clean!
|
@@ -177,10 +206,10 @@ describe Flexirest::Base do
|
|
177
206
|
expect(client).to_not be_dirty
|
178
207
|
end
|
179
208
|
|
180
|
-
it "should not overly pollute the instance method namespace to reduce chances of clashing (<
|
209
|
+
it "should not overly pollute the instance method namespace to reduce chances of clashing (<13 instance methods)" do
|
181
210
|
instance_methods = EmptyExample.instance_methods - Object.methods
|
182
211
|
instance_methods = instance_methods - instance_methods.grep(/^_/)
|
183
|
-
expect(instance_methods.size).to be <
|
212
|
+
expect(instance_methods.size).to be < 13
|
184
213
|
end
|
185
214
|
|
186
215
|
it "should raise an exception for missing attributes if whiny_missing is enabled" do
|
data/spec/lib/caching_spec.rb
CHANGED
@@ -35,6 +35,20 @@ describe Flexirest::Caching do
|
|
35
35
|
Flexirest::Base._reset_caching!
|
36
36
|
end
|
37
37
|
|
38
|
+
it "should be possible to disable caching for each objects" do
|
39
|
+
Flexirest::Base.perform_caching = true
|
40
|
+
|
41
|
+
class CachingExample4 < Flexirest::Base; end
|
42
|
+
class CachingExample5 < Flexirest::Base
|
43
|
+
perform_caching false
|
44
|
+
end
|
45
|
+
expect(Flexirest::Base.perform_caching).to be_truthy
|
46
|
+
expect(CachingExample4.perform_caching).to be_truthy
|
47
|
+
expect(CachingExample5.perform_caching).to be_falsey
|
48
|
+
|
49
|
+
Flexirest::Base._reset_caching!
|
50
|
+
end
|
51
|
+
|
38
52
|
it "should use Rails.cache if available" do
|
39
53
|
begin
|
40
54
|
class Rails
|
data/spec/lib/connection_spec.rb
CHANGED
@@ -187,12 +187,12 @@ describe Flexirest::Connection do
|
|
187
187
|
|
188
188
|
it "should retry once in the event of a connection failed" do
|
189
189
|
stub_request(:get, "www.example.com/foo").to_raise(Faraday::Error::ConnectionFailed.new("Foo"))
|
190
|
-
expect { @connection.get("/foo") }.to raise_error(Flexirest::
|
190
|
+
expect { @connection.get("/foo") }.to raise_error(Flexirest::BaseException)
|
191
191
|
end
|
192
192
|
|
193
193
|
it "should raise an exception on timeout" do
|
194
194
|
stub_request(:get, "www.example.com/foo").to_timeout
|
195
|
-
expect { @connection.get("/foo") }.to raise_error(Flexirest::
|
195
|
+
expect { @connection.get("/foo") }.to raise_error(Flexirest::BaseException)
|
196
196
|
end
|
197
197
|
|
198
198
|
it "should raise an exception on timeout" do
|
data/spec/lib/request_spec.rb
CHANGED
@@ -42,6 +42,9 @@ describe Flexirest::Request do
|
|
42
42
|
get :fake_proc, "/fake", fake:->(request) { "{\"result\":#{request.get_params[:id]}}" }
|
43
43
|
get :defaults, "/defaults", defaults:{overwrite:"no", persist:"yes"}
|
44
44
|
get :requires, "/requires", requires:[:name, :age]
|
45
|
+
patch :only_changed_1, "/changed1", only_changed: true
|
46
|
+
patch :only_changed_2, "/changed2", only_changed: [:debug1, :debug2]
|
47
|
+
patch :only_changed_3, "/changed3", only_changed: { :debug1 => false, :debug2 => true }
|
45
48
|
end
|
46
49
|
|
47
50
|
class ExampleLoadBalancedClient < Flexirest::Base
|
@@ -390,6 +393,46 @@ describe Flexirest::Request do
|
|
390
393
|
#TODO
|
391
394
|
end
|
392
395
|
|
396
|
+
it "should only send changed attributes if only_changed:true" do
|
397
|
+
expect_any_instance_of(Flexirest::Connection).to receive(:patch).with("/changed1", "debug=true", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:"[{\"first_name\":\"Johnny\"}, {\"first_name\":\"Billy\"}, {\"debug\":\"true\"}]", status:200, response_headers:{})))
|
398
|
+
object = ExampleClient.new
|
399
|
+
object.bad_debug = true
|
400
|
+
object._clean!
|
401
|
+
object.debug = true
|
402
|
+
object.only_changed_1
|
403
|
+
end
|
404
|
+
it "should only send changed attributes within the :only_changed array if :only_changed is an array" do
|
405
|
+
expect_any_instance_of(Flexirest::Connection).to receive(:patch).with("/changed2", "debug2=true", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:"[{\"first_name\":\"Johnny\"}, {\"first_name\":\"Billy\"}, {\"debug\":\"true\"}]", status:200, response_headers:{})))
|
406
|
+
object = ExampleClient.new
|
407
|
+
object.bad_debug1 = true
|
408
|
+
object.debug1 = true
|
409
|
+
object._clean!
|
410
|
+
object.bad_debug2 = true
|
411
|
+
object.debug2 = true
|
412
|
+
object.only_changed_2
|
413
|
+
end
|
414
|
+
it "should only send changed attributes marked true within the :only_changed hash when :only_changed is a hash" do
|
415
|
+
expect_any_instance_of(Flexirest::Connection).to receive(:patch).with("/changed3", "debug1=false&debug2=true", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:"[{\"first_name\":\"Johnny\"}, {\"first_name\":\"Billy\"}, {\"debug\":\"true\"}]", status:200, response_headers:{})))
|
416
|
+
object = ExampleClient.new
|
417
|
+
object.bad_debug1 = true
|
418
|
+
object.debug1 = true
|
419
|
+
object._clean!
|
420
|
+
object.bad_debug2 = true
|
421
|
+
object.debug1 = false
|
422
|
+
object.debug2 = true
|
423
|
+
object.only_changed_3
|
424
|
+
end
|
425
|
+
it "should always send changed attributes marked false within the :only_changed hash when :only_changed is an hash" do
|
426
|
+
expect_any_instance_of(Flexirest::Connection).to receive(:patch).with("/changed3", "debug1=true", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:"[{\"first_name\":\"Johnny\"}, {\"first_name\":\"Billy\"}, {\"debug\":\"true\"}]", status:200, response_headers:{})))
|
427
|
+
object = ExampleClient.new
|
428
|
+
object.bad_debug1 = true
|
429
|
+
object.debug1 = true
|
430
|
+
object._clean!
|
431
|
+
object.bad_debug2 = true
|
432
|
+
object.only_changed_3
|
433
|
+
end
|
434
|
+
|
435
|
+
|
393
436
|
it "should instantiate other classes using has_many when required to do so" do
|
394
437
|
expect_any_instance_of(Flexirest::Connection).to receive(:get).with("/", an_instance_of(Hash)).and_return(::FaradayResponseMock.new(OpenStruct.new(body:"{\"first_name\":\"Johnny\", \"expenses\":[{\"amount\":1}, {\"amount\":2}]}", status:200, response_headers:{})))
|
395
438
|
object = ExampleClient.all
|
@@ -890,4 +933,41 @@ describe Flexirest::Request do
|
|
890
933
|
it "should ignore a specified root element" do
|
891
934
|
expect(IgnoredRootExampleClient.root.title).to eq("Example Feed")
|
892
935
|
end
|
936
|
+
|
937
|
+
context "Parameter preparation" do
|
938
|
+
method = {url: "http://www.example.com", method: :get}
|
939
|
+
object = nil
|
940
|
+
|
941
|
+
it "should properly handle Hash params" do
|
942
|
+
req = Flexirest::Request.new method, object, {hello: {}}
|
943
|
+
req.prepare_params
|
944
|
+
|
945
|
+
expect(req.get_params.is_a?(Hash)).to be_truthy
|
946
|
+
expect(req.get_params[:hello]).to eq({})
|
947
|
+
end
|
948
|
+
|
949
|
+
it "should properly handle String params" do
|
950
|
+
req = Flexirest::Request.new method, object, String.new
|
951
|
+
req.prepare_params
|
952
|
+
|
953
|
+
expect(req.get_params.is_a?(Hash)).to be_truthy
|
954
|
+
expect(req.get_params[:id].is_a?(String)).to be_truthy
|
955
|
+
end
|
956
|
+
|
957
|
+
it "should properly handle Integer (Fixnum) params" do
|
958
|
+
req = Flexirest::Request.new method, object, 1234
|
959
|
+
req.prepare_params
|
960
|
+
|
961
|
+
expect(req.get_params.is_a?(Hash)).to be_truthy
|
962
|
+
expect(req.get_params[:id].is_a?(Integer)).to be_truthy
|
963
|
+
end
|
964
|
+
|
965
|
+
it "should properly handle Integer (Bignum) params" do
|
966
|
+
req = Flexirest::Request.new method, object, 12345678901234567890
|
967
|
+
req.prepare_params
|
968
|
+
|
969
|
+
expect(req.get_params.is_a?(Hash)).to be_truthy
|
970
|
+
expect(req.get_params[:id].is_a?(Integer)).to be_truthy
|
971
|
+
end
|
972
|
+
end
|
893
973
|
end
|
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.34
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jeffries
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|