her 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmJlNGEzMjNhZjMyOTYyZWVkYmM2NjhhNGEwZDAwZmY0ODk4MWRkNQ==
4
+ OWFlMWJkMGQ3ODVkOTdhZGVmNDM3MDE3OTJiYTIxMThjNDZkZDVhYw==
5
5
  data.tar.gz: !binary |-
6
- OGVjNGUzNDY5YTQxZmQzMzgxMDJmMWM4OGUxNmRhMjE1NWY2YzQ3Mw==
6
+ ODljYTk3MjhiNjhmYWM1MjQ1NDczZmJmNjIxYmMxNDA0NDk0ZDU0MQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YmQ0Y2VkYTM2YTg1ZmRkNzBmODkxMGVhMDI3NTI2YzRkZmYwZTJjMzE5OTI3
10
- Nzg0ZjRiMzU3ZTEzMTY5YTBiMjk4YjYzYzYzMWMwNjFlMmU2MzI3MTdhZDQ5
11
- OGUyODNhMTc4YTA3ZDYzYjVlOTc5ZGY1Y2UzZTk4MzJlM2U0YzI=
9
+ NjlmZmY0MzUxZmZlZjY0MzRkODg3YmM0MzQ1YzI4MDdjOTE5NTM1YTc0NTcw
10
+ OGZiYjgyMzA3YTlmMGRmMzAyNjRiMzQwZjQ3YjM1ODFmYTQzMDNkZmRmMzBk
11
+ ZTRkNWUxZWM2Mzk4NmJlNTQ2YmU1YWQwZmRmNzIxZDFkYjk0NTM=
12
12
  data.tar.gz: !binary |-
13
- NzVmNzU1OWVlNjQ0NzNlNWM2MmVjZDc2NjU5OWQ5NWJlN2I0ZWRkZmY3Y2Q4
14
- MTI1YzkyMDJhNDM2ZDBmN2ZmNmE4MzQxODc5MzhmZDEwNGFjOTE4MzFmYzA4
15
- OTY3OGZlNjM5MDMxZGFhMzExZDRjZTRmOTNkMjZkYWFkOTA4Nzc=
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; end;
4
- class AssociationUnknownError < StandardError; end;
5
- class ParseError < StandardError; end;
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
@@ -4,7 +4,7 @@ module Her
4
4
  module Attributes
5
5
  extend ActiveSupport::Concern
6
6
 
7
- attr_accessor :attributes, :metadata, :response_errors
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
@@ -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
- send(method, path, attrs.first || Hash.new)
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
- "#<#{self.class}(#{request_path}) #{attributes.keys.map { |k| "#{k}=#{attribute_for_inspect(send(k))}" }.join(" ")}>"
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
@@ -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
- return @include_root_in_json if value.nil?
33
- @include_root_in_json = value
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
- return @parse_root_in_json if value.nil?
45
- @parse_root_in_json = value
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
- return @root_element if value.nil?
61
- @root_element = value
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
- @parse_root_in_json
77
+ parse_root_in_json
67
78
  end
68
79
 
69
80
  # @private
70
81
  def include_root_in_json?
71
- @include_root_in_json
82
+ include_root_in_json
72
83
  end
73
84
 
74
85
  # @private
@@ -28,10 +28,14 @@ module Her
28
28
  # primary_key 'UserId'
29
29
  # end
30
30
  #
31
- # @param [Symbol] field
32
- def primary_key(field = nil)
33
- return @her_primary_key if field.nil?
34
- @her_primary_key = field.to_sym
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
- @_her_collection_path ||= begin
46
- superclass.collection_path.dup if superclass.respond_to?(:collection_path)
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
- @_her_resource_path ||= begin
79
- superclass.resource_path.dup if superclass.respond_to?(:resource_path)
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, "Missing :_#{$1} parameter to build the request path. Path is `#{path}`. Parameters are `#{parameters.inspect}`.")
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
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.5.4"
2
+ VERSION = "0.5.5"
3
3
  end
@@ -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
@@ -161,13 +161,15 @@ describe Her::Model::HTTP do
161
161
  subject { Foo::User }
162
162
 
163
163
  describe :custom_get do
164
- before { Foo::User.custom_get :popular, :recent }
165
- it { should respond_to(:popular) }
166
- it { should respond_to(:recent) }
167
-
168
- context "making the HTTP request" do
169
- subject { Foo::User.popular }
170
- its(:length) { should == 2 }
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
@@ -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
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-08 00:00:00.000000000 Z
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