her 0.5.4 → 0.5.5
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 +8 -8
- data/README.md +35 -0
- data/UPGRADE.md +11 -0
- data/lib/her/errors.rb +14 -3
- data/lib/her/model.rb +4 -7
- data/lib/her/model/attributes.rb +35 -1
- data/lib/her/model/http.rb +4 -1
- data/lib/her/model/introspection.rb +7 -1
- data/lib/her/model/parse.rb +23 -12
- data/lib/her/model/paths.rb +20 -18
- data/lib/her/version.rb +1 -1
- data/spec/model/attributes_spec.rb +27 -0
- data/spec/model/http_spec.rb +9 -7
- data/spec/model/introspection_spec.rb +12 -0
- data/spec/model/orm_spec.rb +0 -86
- data/spec/model/parse_spec.rb +125 -0
- data/spec/model/validations_spec.rb +20 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OWFlMWJkMGQ3ODVkOTdhZGVmNDM3MDE3OTJiYTIxMThjNDZkZDVhYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODljYTk3MjhiNjhmYWM1MjQ1NDczZmJmNjIxYmMxNDA0NDk0ZDU0MQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NjlmZmY0MzUxZmZlZjY0MzRkODg3YmM0MzQ1YzI4MDdjOTE5NTM1YTc0NTcw
|
10
|
+
OGZiYjgyMzA3YTlmMGRmMzAyNjRiMzQwZjQ3YjM1ODFmYTQzMDNkZmRmMzBk
|
11
|
+
ZTRkNWUxZWM2Mzk4NmJlNTQ2YmU1YWQwZmRmNzIxZDFkYjk0NTM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZmExYTE0MzIyODFjN2JiYzAxOGUxM2ZhMzIzNjRiYjc4MjVlYjQxMTBlMWU2
|
14
|
+
ZmE4ZjE2ZDU2YzI0YmIyNjIxZGQ5M2I1MzJlMDU1NzkwNWFiMDk0NmRlN2Vh
|
15
|
+
NDZkMWYxOTNiZDRkNmE0NThjOWFlZjNhZDc4OGMxZjE5NjY2NmI=
|
data/README.md
CHANGED
@@ -593,6 +593,41 @@ end
|
|
593
593
|
# POST /organizations/2/users
|
594
594
|
```
|
595
595
|
|
596
|
+
### Custom primary keys
|
597
|
+
|
598
|
+
If your record uses an attribute other than `:id` to identify itself, specify it using the `primary_key` method:
|
599
|
+
|
600
|
+
```ruby
|
601
|
+
class User
|
602
|
+
include Her::Model
|
603
|
+
primary_key :_id
|
604
|
+
end
|
605
|
+
|
606
|
+
user = User.find(1) # GET /users/1 returns { "_id": 1, "name": "Tobias" }
|
607
|
+
user.save # PUT /users/1
|
608
|
+
```
|
609
|
+
|
610
|
+
### Inheritance
|
611
|
+
|
612
|
+
If all your models share the same settings, you might want to make them children of a class and only include `Her::Model` in that class.
|
613
|
+
|
614
|
+
```ruby
|
615
|
+
module MyAPI
|
616
|
+
class Model
|
617
|
+
include Her::Model
|
618
|
+
|
619
|
+
parse_root_in_json true
|
620
|
+
include_root_in_json true
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
class User < MyAPI::Model
|
625
|
+
end
|
626
|
+
|
627
|
+
User.find(1)
|
628
|
+
# GET /users/1
|
629
|
+
```
|
630
|
+
|
596
631
|
### Multiple APIs
|
597
632
|
|
598
633
|
It is possible to use different APIs for different models. Instead of calling `Her::API.setup`, you can create instances of `Her::API`:
|
data/UPGRADE.md
CHANGED
@@ -12,6 +12,17 @@ Here is a list of backward-incompatible changes that were introduced while Her i
|
|
12
12
|
|
13
13
|
Before 0.5, the `errors` method on an object would return an error list received from the server (the `:errors` key defined by the parsing middleware). But now, `errors` returns the error list generated after calling the `valid?` method (or any other similar validation method from `ActiveModel::Validations`). The error list returned from the server is now accessible from the `response_errors` method.
|
14
14
|
|
15
|
+
Since 0.5.5, Her provides a `store_response_errors` method, which allows you to choose the method which will return the response errors. You can use it to revert Her back to its original behavior (ie. `errors` returning the response errors):
|
16
|
+
|
17
|
+
class User
|
18
|
+
include Her::Model
|
19
|
+
|
20
|
+
store_response_errors :errors
|
21
|
+
end
|
22
|
+
|
23
|
+
user = User.create(:email => "foo") # POST /users returns { :errors => ["Email is invalid"] }
|
24
|
+
user.errors # => ["Email is invalid"]
|
25
|
+
|
15
26
|
## 0.2.4
|
16
27
|
|
17
28
|
* Her no longer includes default middleware when making HTTP requests. The user has now to define all the needed middleware. Before:
|
data/lib/her/errors.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
module Her
|
2
2
|
module Errors
|
3
|
-
class PathError < StandardError
|
4
|
-
|
5
|
-
|
3
|
+
class PathError < StandardError
|
4
|
+
attr_reader :missing_parameter
|
5
|
+
|
6
|
+
def initialize(message, missing_parameter=nil)
|
7
|
+
super(message)
|
8
|
+
@missing_parameter = missing_parameter
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class AssociationUnknownError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
class ParseError < StandardError
|
16
|
+
end
|
6
17
|
end
|
7
18
|
end
|
data/lib/her/model.rb
CHANGED
@@ -43,19 +43,16 @@ module Her
|
|
43
43
|
|
44
44
|
# Class methods
|
45
45
|
included do
|
46
|
-
# Define the root element name, used when `parse_root_in_json` is set to `true`
|
47
|
-
root_element self.name.split("::").last.underscore.to_sym
|
48
|
-
|
49
|
-
# Define resource and collection paths
|
50
|
-
collection_path "#{root_element.to_s.pluralize}"
|
51
|
-
resource_path "#{root_element.to_s.pluralize}/:id"
|
52
|
-
|
53
46
|
# Assign the default API
|
54
47
|
uses_api Her::API.default_api
|
55
48
|
|
56
49
|
# Define the default primary key
|
57
50
|
primary_key :id
|
58
51
|
|
52
|
+
# Define default storage variables for errors and metadata
|
53
|
+
store_response_errors :response_errors
|
54
|
+
store_metadata :metadata
|
55
|
+
|
59
56
|
# Configure ActiveModel callbacks
|
60
57
|
extend ActiveModel::Callbacks
|
61
58
|
define_model_callbacks :create, :update, :save, :find, :destroy
|
data/lib/her/model/attributes.rb
CHANGED
@@ -4,7 +4,7 @@ module Her
|
|
4
4
|
module Attributes
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
attr_accessor :attributes
|
7
|
+
attr_accessor :attributes
|
8
8
|
alias :data :attributes
|
9
9
|
alias :data= :attributes=
|
10
10
|
|
@@ -167,6 +167,40 @@ module Her
|
|
167
167
|
memo
|
168
168
|
end
|
169
169
|
end
|
170
|
+
|
171
|
+
def store_response_errors(value = nil)
|
172
|
+
if @_her_store_response_errors
|
173
|
+
remove_method @_her_store_response_errors
|
174
|
+
remove_method "#{@_her_store_response_errors}="
|
175
|
+
end
|
176
|
+
|
177
|
+
@_her_store_response_errors ||= begin
|
178
|
+
superclass.store_response_errors if superclass.respond_to?(:store_response_errors)
|
179
|
+
end
|
180
|
+
|
181
|
+
return @_her_store_response_errors unless value
|
182
|
+
@_her_store_response_errors = value
|
183
|
+
|
184
|
+
define_method(@_her_store_response_errors) { @response_errors }
|
185
|
+
define_method("#{@_her_store_response_errors}=") { |value| @response_errors = value }
|
186
|
+
end
|
187
|
+
|
188
|
+
def store_metadata(value = nil)
|
189
|
+
if @_her_store_metadata
|
190
|
+
remove_method @_her_store_metadata
|
191
|
+
remove_method "#{@_her_store_metadata}="
|
192
|
+
end
|
193
|
+
|
194
|
+
@_her_store_metadata ||= begin
|
195
|
+
superclass.store_metadata if superclass.respond_to?(:store_metadata)
|
196
|
+
end
|
197
|
+
|
198
|
+
return @_her_store_metadata unless value
|
199
|
+
@_her_store_metadata = value
|
200
|
+
|
201
|
+
define_method(@_her_store_metadata) { @metadata }
|
202
|
+
define_method("#{@_her_store_metadata}=") { |value| @metadata = value }
|
203
|
+
end
|
170
204
|
end
|
171
205
|
end
|
172
206
|
end
|
data/lib/her/model/http.rb
CHANGED
@@ -73,9 +73,12 @@ module Her
|
|
73
73
|
|
74
74
|
define_method "custom_#{method}".to_sym do |*paths|
|
75
75
|
metaclass = (class << self; self; end)
|
76
|
+
opts = paths.last.is_a?(Hash) ? paths.pop : Hash.new
|
77
|
+
|
76
78
|
paths.each do |path|
|
77
79
|
metaclass.send(:define_method, path.to_sym) do |*attrs|
|
78
|
-
|
80
|
+
attrs = attrs.first || Hash.new
|
81
|
+
send(method, path, attrs)
|
79
82
|
end
|
80
83
|
end
|
81
84
|
end
|
@@ -12,7 +12,13 @@ module Her
|
|
12
12
|
# @user = User.find(1)
|
13
13
|
# p @user # => #<User(/users/1) id=1 name="Tobias Fünke">
|
14
14
|
def inspect
|
15
|
-
|
15
|
+
resource_path = begin
|
16
|
+
request_path
|
17
|
+
rescue Her::Errors::PathError => e
|
18
|
+
"<unknown path, missing `#{e.missing_parameter}`>"
|
19
|
+
end
|
20
|
+
|
21
|
+
"#<#{self.class}(#{resource_path}) #{attributes.keys.map { |k| "#{k}=#{attribute_for_inspect(send(k))}" }.join(" ")}>"
|
16
22
|
end
|
17
23
|
|
18
24
|
private
|
data/lib/her/model/parse.rb
CHANGED
@@ -28,9 +28,13 @@ module Her
|
|
28
28
|
# include Her::Model
|
29
29
|
# include_root_in_json true
|
30
30
|
# end
|
31
|
-
def include_root_in_json(value=nil)
|
32
|
-
|
33
|
-
|
31
|
+
def include_root_in_json(value = nil)
|
32
|
+
@_her_include_root_in_json ||= begin
|
33
|
+
superclass.include_root_in_json if superclass.respond_to?(:include_root_in_json)
|
34
|
+
end
|
35
|
+
|
36
|
+
return @_her_include_root_in_json unless value
|
37
|
+
@_her_include_root_in_json = value
|
34
38
|
end
|
35
39
|
|
36
40
|
# Return or change the value of `parse_root_in`
|
@@ -40,12 +44,16 @@ module Her
|
|
40
44
|
# include Her::Model
|
41
45
|
# parse_root_in_json true
|
42
46
|
# end
|
43
|
-
def parse_root_in_json(value=nil)
|
44
|
-
|
45
|
-
|
47
|
+
def parse_root_in_json(value = nil)
|
48
|
+
@_her_parse_root_in_json ||= begin
|
49
|
+
superclass.parse_root_in_json if superclass.respond_to?(:parse_root_in_json)
|
50
|
+
end
|
51
|
+
|
52
|
+
return @_her_parse_root_in_json unless value
|
53
|
+
@_her_parse_root_in_json = value
|
46
54
|
end
|
47
55
|
|
48
|
-
# Return or change the value of `root_element
|
56
|
+
# Return or change the value of `root_element`. Always defaults to the base name of the class.
|
49
57
|
#
|
50
58
|
# @example
|
51
59
|
# class User
|
@@ -56,19 +64,22 @@ module Her
|
|
56
64
|
#
|
57
65
|
# user = User.find(1) # { :huh => { :id => 1, :name => "Tobias" } }
|
58
66
|
# user.name # => "Tobias"
|
59
|
-
def root_element(value=nil)
|
60
|
-
|
61
|
-
|
67
|
+
def root_element(value = nil)
|
68
|
+
if value.nil?
|
69
|
+
@_her_root_element ||= self.name.split("::").last.underscore.to_sym
|
70
|
+
else
|
71
|
+
@_her_root_element = value.to_sym
|
72
|
+
end
|
62
73
|
end
|
63
74
|
|
64
75
|
# @private
|
65
76
|
def parse_root_in_json?
|
66
|
-
|
77
|
+
parse_root_in_json
|
67
78
|
end
|
68
79
|
|
69
80
|
# @private
|
70
81
|
def include_root_in_json?
|
71
|
-
|
82
|
+
include_root_in_json
|
72
83
|
end
|
73
84
|
|
74
85
|
# @private
|
data/lib/her/model/paths.rb
CHANGED
@@ -28,10 +28,14 @@ module Her
|
|
28
28
|
# primary_key 'UserId'
|
29
29
|
# end
|
30
30
|
#
|
31
|
-
# @param [Symbol]
|
32
|
-
def primary_key(
|
33
|
-
|
34
|
-
|
31
|
+
# @param [Symbol] value
|
32
|
+
def primary_key(value = nil)
|
33
|
+
@_her_primary_key ||= begin
|
34
|
+
superclass.primary_key.to_sym if superclass.respond_to?(:primary_key)
|
35
|
+
end
|
36
|
+
|
37
|
+
return @_her_primary_key unless value
|
38
|
+
@_her_primary_key = value.to_sym
|
35
39
|
end
|
36
40
|
|
37
41
|
# Defines a custom collection path for the resource
|
@@ -41,14 +45,13 @@ module Her
|
|
41
45
|
# include Her::Model
|
42
46
|
# collection_path "/users"
|
43
47
|
# end
|
44
|
-
def collection_path(path=nil)
|
45
|
-
|
46
|
-
|
48
|
+
def collection_path(path = nil)
|
49
|
+
if path.nil?
|
50
|
+
@_her_collection_path ||= "#{root_element.to_s.pluralize}"
|
51
|
+
else
|
52
|
+
@_her_collection_path = path
|
53
|
+
@_her_resource_path = "#{path}/:id"
|
47
54
|
end
|
48
|
-
|
49
|
-
return @_her_collection_path unless path
|
50
|
-
@_her_resource_path = "#{path}/:id"
|
51
|
-
@_her_collection_path = path
|
52
55
|
end
|
53
56
|
|
54
57
|
# Defines a custom resource path for the resource
|
@@ -74,13 +77,12 @@ module Her
|
|
74
77
|
# resource_path '/users/:id'
|
75
78
|
# end
|
76
79
|
#
|
77
|
-
def resource_path(path=nil)
|
78
|
-
|
79
|
-
|
80
|
+
def resource_path(path = nil)
|
81
|
+
if path.nil?
|
82
|
+
@_her_resource_path ||= "#{root_element.to_s.pluralize}/:id"
|
83
|
+
else
|
84
|
+
@_her_resource_path = path
|
80
85
|
end
|
81
|
-
|
82
|
-
return @_her_resource_path unless path
|
83
|
-
@_her_resource_path = path
|
84
86
|
end
|
85
87
|
|
86
88
|
# Return a custom path based on the collection path and variable parameters
|
@@ -108,7 +110,7 @@ module Her
|
|
108
110
|
|
109
111
|
path.gsub(/:([\w_]+)/) do
|
110
112
|
# Look for :key or :_key, otherwise raise an exception
|
111
|
-
parameters.delete($1.to_sym) || parameters.delete("_#{$1}".to_sym) || raise(Her::Errors::PathError
|
113
|
+
parameters.delete($1.to_sym) || parameters.delete("_#{$1}".to_sym) || raise(Her::Errors::PathError.new("Missing :_#{$1} parameter to build the request path. Path is `#{path}`. Parameters are `#{parameters.inspect}`.", $1))
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
data/lib/her/version.rb
CHANGED
@@ -136,4 +136,31 @@ describe Her::Model::Attributes do
|
|
136
136
|
hash.should == { user => false }
|
137
137
|
end
|
138
138
|
end
|
139
|
+
|
140
|
+
context "handling metadata and errors" do
|
141
|
+
before do
|
142
|
+
spawn_model 'Foo::User' do
|
143
|
+
store_response_errors :errors
|
144
|
+
store_metadata :my_data
|
145
|
+
end
|
146
|
+
|
147
|
+
@user = Foo::User.new(:_errors => ["Foo", "Bar"], :_metadata => { :secret => true })
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should return response_errors stored in the method provided by `store_response_errors`" do
|
151
|
+
@user.errors.should == ["Foo", "Bar"]
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should remove the default method for errors" do
|
155
|
+
expect { @user.response_errors }.to raise_error(NoMethodError)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return metadata stored in the method provided by `store_metadata`" do
|
159
|
+
@user.my_data.should == { :secret => true }
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should remove the default method for metadata" do
|
163
|
+
expect { @user.metadata }.to raise_error(NoMethodError)
|
164
|
+
end
|
165
|
+
end
|
139
166
|
end
|
data/spec/model/http_spec.rb
CHANGED
@@ -161,13 +161,15 @@ describe Her::Model::HTTP do
|
|
161
161
|
subject { Foo::User }
|
162
162
|
|
163
163
|
describe :custom_get do
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
164
|
+
context "without cache" do
|
165
|
+
before { Foo::User.custom_get :popular, :recent }
|
166
|
+
it { should respond_to(:popular) }
|
167
|
+
it { should respond_to(:recent) }
|
168
|
+
|
169
|
+
context "making the HTTP request" do
|
170
|
+
subject { Foo::User.popular }
|
171
|
+
its(:length) { should == 2 }
|
172
|
+
end
|
171
173
|
end
|
172
174
|
end
|
173
175
|
|
@@ -12,10 +12,14 @@ describe Her::Model::Introspection do
|
|
12
12
|
stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Funke" }.to_json] }
|
13
13
|
stub.put("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Funke" }.to_json] }
|
14
14
|
stub.delete("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Funke" }.to_json] }
|
15
|
+
stub.get("/projects/1/comments") { |env| [200, {}, [{ :id => 1, :body => "Hello!" }].to_json] }
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
spawn_model "Foo::User"
|
20
|
+
spawn_model "Foo::Comment" do
|
21
|
+
collection_path "projects/:project_id/comments"
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
describe "#inspect" do
|
@@ -37,6 +41,14 @@ describe Her::Model::Introspection do
|
|
37
41
|
@user.inspect.should_not include("password=\"Funke\"")
|
38
42
|
end
|
39
43
|
end
|
44
|
+
|
45
|
+
describe "#inspect with errors in resource path" do
|
46
|
+
it "prints the resource path as “unknown”" do
|
47
|
+
@comment = Foo::Comment.all(:project_id => 1).first
|
48
|
+
path = '<unknown path, missing `project_id`>'
|
49
|
+
["#<Foo::Comment(#{path}) body=\"Hello!\" id=1>", "#<Foo::Comment(#{path}) id=1 body=\"Hello!\">"].should include(@comment.inspect)
|
50
|
+
end
|
51
|
+
end
|
40
52
|
end
|
41
53
|
|
42
54
|
describe "#her_nearby_class" do
|
data/spec/model/orm_spec.rb
CHANGED
@@ -399,90 +399,4 @@ describe Her::Model::ORM do
|
|
399
399
|
end
|
400
400
|
end
|
401
401
|
|
402
|
-
context "when include_root_in_json is true" do
|
403
|
-
context "when include_root_in_json is true" do
|
404
|
-
before do
|
405
|
-
spawn_model "Foo::User" do
|
406
|
-
include_root_in_json true
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
it "wraps params in the element name" do
|
411
|
-
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
412
|
-
@new_user.to_params.should == { :user => { :fullname => "Tobias Fünke" } }
|
413
|
-
end
|
414
|
-
end
|
415
|
-
|
416
|
-
context "when include_root_in_json is set to another value" do
|
417
|
-
before do
|
418
|
-
spawn_model "Foo::User" do
|
419
|
-
include_root_in_json :person
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
it "wraps params in the specified value" do
|
424
|
-
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
425
|
-
@new_user.to_params.should == { :person => { :fullname => "Tobias Fünke" } }
|
426
|
-
end
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
context "when parse_root_in_json is set" do
|
431
|
-
before do
|
432
|
-
Her::API.setup :url => "https://api.example.com" do |builder|
|
433
|
-
builder.use Her::Middleware::FirstLevelParseJSON
|
434
|
-
builder.use Faraday::Request::UrlEncoded
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
context "when parse_root_in_json is true" do
|
439
|
-
before do
|
440
|
-
Her::API.default_api.connection.adapter :test do |stub|
|
441
|
-
stub.post("/users") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
442
|
-
stub.get("/users") { |env| [200, {}, [{ :user => { :id => 1, :fullname => "Lindsay Fünke" } }].to_json] }
|
443
|
-
stub.get("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
444
|
-
stub.put("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Tobias Fünke Jr." } }.to_json] }
|
445
|
-
end
|
446
|
-
|
447
|
-
spawn_model("Foo::User") { parse_root_in_json true }
|
448
|
-
end
|
449
|
-
|
450
|
-
it "parse the data from the JSON root element after .create" do
|
451
|
-
@new_user = Foo::User.create(:fullname => "Lindsay Fünke")
|
452
|
-
@new_user.fullname.should == "Lindsay Fünke"
|
453
|
-
end
|
454
|
-
|
455
|
-
it "parse the data from the JSON root element after .all" do
|
456
|
-
@users = Foo::User.all
|
457
|
-
@users.first.fullname.should == "Lindsay Fünke"
|
458
|
-
end
|
459
|
-
|
460
|
-
it "parse the data from the JSON root element after .find" do
|
461
|
-
@user = Foo::User.find(1)
|
462
|
-
@user.fullname.should == "Lindsay Fünke"
|
463
|
-
end
|
464
|
-
|
465
|
-
it "parse the data from the JSON root element after .save" do
|
466
|
-
@user = Foo::User.find(1)
|
467
|
-
@user.fullname = "Tobias Fünke"
|
468
|
-
@user.save
|
469
|
-
@user.fullname.should == "Tobias Fünke Jr."
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
context "when parse_root_in_json is set to a symbol" do
|
474
|
-
before do
|
475
|
-
Her::API.default_api.connection.adapter :test do |stub|
|
476
|
-
stub.post("/users") { |env| [200, {}, { :person => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
477
|
-
end
|
478
|
-
|
479
|
-
spawn_model("Foo::User") { parse_root_in_json :person }
|
480
|
-
end
|
481
|
-
|
482
|
-
it "parse the data with the symbol" do
|
483
|
-
@new_user = Foo::User.create(:fullname => "Lindsay Fünke")
|
484
|
-
@new_user.fullname.should == "Lindsay Fünke"
|
485
|
-
end
|
486
|
-
end
|
487
|
-
end
|
488
402
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe Her::Model::Parse do
|
5
|
+
context "when include_root_in_json is true" do
|
6
|
+
context "when include_root_in_json is true" do
|
7
|
+
before do
|
8
|
+
spawn_model "Foo::User" do
|
9
|
+
include_root_in_json true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it "wraps params in the element name" do
|
14
|
+
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
15
|
+
@new_user.to_params.should == { :user => { :fullname => "Tobias Fünke" } }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when include_root_in_json is set to another value" do
|
20
|
+
before do
|
21
|
+
spawn_model "Foo::User" do
|
22
|
+
include_root_in_json :person
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "wraps params in the specified value" do
|
27
|
+
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
28
|
+
@new_user.to_params.should == { :person => { :fullname => "Tobias Fünke" } }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when include_root_in_json is set in the parent class" do
|
33
|
+
before do
|
34
|
+
spawn_model("Foo::Model") { include_root_in_json true }
|
35
|
+
|
36
|
+
class User < Foo::Model; end
|
37
|
+
@spawned_models << :User
|
38
|
+
end
|
39
|
+
|
40
|
+
it "wraps params with the class name" do
|
41
|
+
@new_user = User.new(:fullname => "Tobias Fünke")
|
42
|
+
@new_user.to_params.should == { :user => { :fullname => "Tobias Fünke" } }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when parse_root_in_json is set" do
|
48
|
+
before do
|
49
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
50
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
51
|
+
builder.use Faraday::Request::UrlEncoded
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when parse_root_in_json is true" do
|
56
|
+
before do
|
57
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
58
|
+
stub.post("/users") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
59
|
+
stub.get("/users") { |env| [200, {}, [{ :user => { :id => 1, :fullname => "Lindsay Fünke" } }].to_json] }
|
60
|
+
stub.get("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
61
|
+
stub.put("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Tobias Fünke Jr." } }.to_json] }
|
62
|
+
end
|
63
|
+
|
64
|
+
spawn_model("Foo::User") { parse_root_in_json true }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "parse the data from the JSON root element after .create" do
|
68
|
+
@new_user = Foo::User.create(:fullname => "Lindsay Fünke")
|
69
|
+
@new_user.fullname.should == "Lindsay Fünke"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "parse the data from the JSON root element after .all" do
|
73
|
+
@users = Foo::User.all
|
74
|
+
@users.first.fullname.should == "Lindsay Fünke"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "parse the data from the JSON root element after .find" do
|
78
|
+
@user = Foo::User.find(1)
|
79
|
+
@user.fullname.should == "Lindsay Fünke"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "parse the data from the JSON root element after .save" do
|
83
|
+
@user = Foo::User.find(1)
|
84
|
+
@user.fullname = "Tobias Fünke"
|
85
|
+
@user.save
|
86
|
+
@user.fullname.should == "Tobias Fünke Jr."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when parse_root_in_json is set to a symbol" do
|
91
|
+
before do
|
92
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
93
|
+
stub.post("/users") { |env| [200, {}, { :person => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
94
|
+
end
|
95
|
+
|
96
|
+
spawn_model("Foo::User") { parse_root_in_json :person }
|
97
|
+
end
|
98
|
+
|
99
|
+
it "parse the data with the symbol" do
|
100
|
+
@new_user = Foo::User.create(:fullname => "Lindsay Fünke")
|
101
|
+
@new_user.fullname.should == "Lindsay Fünke"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when parse_root_in_json is set from the parent class" do
|
106
|
+
before do
|
107
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
108
|
+
stub.post("/users") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
109
|
+
end
|
110
|
+
|
111
|
+
spawn_model("Foo::Model") { parse_root_in_json true }
|
112
|
+
class User < Foo::Model
|
113
|
+
collection_path "/users"
|
114
|
+
end
|
115
|
+
|
116
|
+
@spawned_models << :User
|
117
|
+
end
|
118
|
+
|
119
|
+
it "parse the data with the symbol" do
|
120
|
+
@new_user = User.create(:fullname => "Lindsay Fünke")
|
121
|
+
@new_user.fullname.should == "Lindsay Fünke"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -14,9 +14,29 @@ describe "Her::Model and ActiveModel::Validations" do
|
|
14
14
|
it "validates attributes when calling #valid?" do
|
15
15
|
user = Foo::User.new
|
16
16
|
user.should_not be_valid
|
17
|
+
user.errors.full_messages.should include("Fullname can't be blank")
|
18
|
+
user.errors.full_messages.should include("Email can't be blank")
|
17
19
|
user.fullname = "Tobias Fünke"
|
18
20
|
user.email = "tobias@bluthcompany.com"
|
19
21
|
user.should be_valid
|
20
22
|
end
|
21
23
|
end
|
24
|
+
|
25
|
+
context "handling server errors" do
|
26
|
+
before do
|
27
|
+
spawn_model("Foo::Model") do
|
28
|
+
def errors
|
29
|
+
@response_errors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class User < Foo::Model; end
|
34
|
+
@spawned_models << :User
|
35
|
+
end
|
36
|
+
|
37
|
+
it "validates attributes when calling #valid?" do
|
38
|
+
user = User.new(:_errors => ["Email cannot be blank"])
|
39
|
+
user.errors.should include("Email cannot be blank")
|
40
|
+
end
|
41
|
+
end
|
22
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: her
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Prévost
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -193,6 +193,7 @@ files:
|
|
193
193
|
- spec/model/introspection_spec.rb
|
194
194
|
- spec/model/nested_attributes_spec.rb
|
195
195
|
- spec/model/orm_spec.rb
|
196
|
+
- spec/model/parse_spec.rb
|
196
197
|
- spec/model/paths_spec.rb
|
197
198
|
- spec/model/validations_spec.rb
|
198
199
|
- spec/model_spec.rb
|
@@ -239,6 +240,7 @@ test_files:
|
|
239
240
|
- spec/model/introspection_spec.rb
|
240
241
|
- spec/model/nested_attributes_spec.rb
|
241
242
|
- spec/model/orm_spec.rb
|
243
|
+
- spec/model/parse_spec.rb
|
242
244
|
- spec/model/paths_spec.rb
|
243
245
|
- spec/model/validations_spec.rb
|
244
246
|
- spec/model_spec.rb
|