her 1.0.0 → 1.1.1

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.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +19 -1279
  3. data/.rubocop_todo.yml +232 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +16 -4
  6. data/README.md +25 -1
  7. data/gemfiles/Gemfile.faraday-1.0 +6 -0
  8. data/her.gemspec +4 -3
  9. data/lib/her/api.rb +8 -7
  10. data/lib/her/collection.rb +2 -1
  11. data/lib/her/errors.rb +3 -1
  12. data/lib/her/json_api/model.rb +8 -12
  13. data/lib/her/middleware.rb +1 -1
  14. data/lib/her/middleware/accept_json.rb +1 -0
  15. data/lib/her/middleware/first_level_parse_json.rb +6 -5
  16. data/lib/her/middleware/json_api_parser.rb +6 -5
  17. data/lib/her/middleware/parse_json.rb +2 -1
  18. data/lib/her/middleware/second_level_parse_json.rb +6 -5
  19. data/lib/her/model/associations.rb +7 -7
  20. data/lib/her/model/associations/association.rb +7 -9
  21. data/lib/her/model/associations/association_proxy.rb +2 -3
  22. data/lib/her/model/associations/belongs_to_association.rb +2 -3
  23. data/lib/her/model/attributes.rb +14 -6
  24. data/lib/her/model/base.rb +2 -2
  25. data/lib/her/model/http.rb +7 -2
  26. data/lib/her/model/introspection.rb +5 -3
  27. data/lib/her/model/nested_attributes.rb +1 -1
  28. data/lib/her/model/orm.rb +27 -9
  29. data/lib/her/model/parse.rb +10 -12
  30. data/lib/her/model/paths.rb +3 -4
  31. data/lib/her/model/relation.rb +5 -4
  32. data/lib/her/version.rb +1 -1
  33. data/spec/api_spec.rb +3 -0
  34. data/spec/middleware/accept_json_spec.rb +1 -0
  35. data/spec/middleware/first_level_parse_json_spec.rb +2 -1
  36. data/spec/middleware/json_api_parser_spec.rb +1 -0
  37. data/spec/middleware/second_level_parse_json_spec.rb +1 -0
  38. data/spec/model/associations/association_proxy_spec.rb +1 -0
  39. data/spec/model/associations_spec.rb +98 -14
  40. data/spec/model/attributes_spec.rb +9 -3
  41. data/spec/model/callbacks_spec.rb +14 -15
  42. data/spec/model/dirty_spec.rb +1 -0
  43. data/spec/model/http_spec.rb +29 -18
  44. data/spec/model/introspection_spec.rb +3 -2
  45. data/spec/model/nested_attributes_spec.rb +1 -0
  46. data/spec/model/orm_spec.rb +39 -16
  47. data/spec/model/parse_spec.rb +24 -0
  48. data/spec/model/paths_spec.rb +1 -0
  49. data/spec/model/relation_spec.rb +3 -2
  50. data/spec/model/validations_spec.rb +1 -0
  51. data/spec/model_spec.rb +1 -0
  52. data/spec/support/extensions/array.rb +1 -0
  53. data/spec/support/extensions/hash.rb +1 -0
  54. metadata +15 -19
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::Attributes do
@@ -85,6 +86,10 @@ describe Her::Model::Attributes do
85
86
  @user.assign_attributes active: true
86
87
  expect(@user).to be_active
87
88
  end
89
+
90
+ it "expects to receive hash" do
91
+ expect { @user.assign_attributes(1) }.to raise_error(ArgumentError, 'When assigning attributes, you must pass a hash as an argument.')
92
+ end
88
93
  end
89
94
 
90
95
  context "checking resource equality" do
@@ -164,11 +169,11 @@ describe Her::Model::Attributes do
164
169
  store_metadata :my_data
165
170
  end
166
171
 
167
- @user = Foo::User.new(_errors: %w(Foo Bar), _metadata: { secret: true })
172
+ @user = Foo::User.new(_errors: %w[Foo Bar], _metadata: { secret: true })
168
173
  end
169
174
 
170
175
  it "should return response_errors stored in the method provided by `store_response_errors`" do
171
- expect(@user.errors).to eq(%w(Foo Bar))
176
+ expect(@user.errors).to eq(%w[Foo Bar])
172
177
  end
173
178
 
174
179
  it "should remove the default method for errors" do
@@ -204,7 +209,7 @@ describe Her::Model::Attributes do
204
209
 
205
210
  spawn_model "Foo::User" do
206
211
  def document
207
- self.attributes[:document][:url]
212
+ attributes[:document][:url]
208
213
  end
209
214
  end
210
215
  end
@@ -310,6 +315,7 @@ describe Her::Model::Attributes do
310
315
  context "when attribute methods are already defined" do
311
316
  before do
312
317
  class AbstractUser
318
+
313
319
  def fullname
314
320
  raise NotImplementedError
315
321
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe "Her::Model and ActiveModel::Callbacks" do
@@ -6,12 +7,10 @@ describe "Her::Model and ActiveModel::Callbacks" do
6
7
  Her::API.setup url: "https://api.example.com" do |builder|
7
8
  builder.use Her::Middleware::FirstLevelParseJSON
8
9
  end
9
-
10
- spawn_model "Foo::User"
11
10
  end
12
11
 
13
12
  context :before_save do
14
- subject { Foo::User.create(name: "Tobias Funke") }
13
+ subject { User.create(name: "Tobias Funke") }
15
14
  before do
16
15
  Her::API.default_api.connection.adapter :test do |stub|
17
16
  stub.post("/users") { |env| [200, {}, { id: 1, name: env[:body][:name] }.to_json] }
@@ -21,7 +20,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
21
20
 
22
21
  context "when using a symbol callback" do
23
22
  before do
24
- class Foo::User
23
+ spawn_model "User" do
25
24
  before_save :alter_name
26
25
  def alter_name
27
26
  name.upcase!
@@ -37,7 +36,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
37
36
 
38
37
  context "when using a block callback" do
39
38
  before do
40
- class Foo::User
39
+ spawn_model "User" do
41
40
  before_save -> { name.upcase! }
42
41
  end
43
42
  end
@@ -50,7 +49,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
50
49
 
51
50
  context "when changing a value of an existing resource in a callback" do
52
51
  before do
53
- class Foo::User
52
+ spawn_model "User" do
54
53
  before_save :alter_name
55
54
  def alter_name
56
55
  self.name = "Lumberjack" if persisted?
@@ -67,7 +66,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
67
66
  end
68
67
 
69
68
  context :before_create do
70
- subject { Foo::User.create(name: "Tobias Funke") }
69
+ subject { User.create(name: "Tobias Funke") }
71
70
  before do
72
71
  Her::API.default_api.connection.adapter :test do |stub|
73
72
  stub.post("/users") { |env| [200, {}, { id: 1, name: env[:body][:name] }.to_json] }
@@ -76,7 +75,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
76
75
 
77
76
  context "when using a symbol callback" do
78
77
  before do
79
- class Foo::User
78
+ spawn_model "User" do
80
79
  before_create :alter_name
81
80
  def alter_name
82
81
  name.upcase!
@@ -92,7 +91,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
92
91
 
93
92
  context "when using a block callback" do
94
93
  before do
95
- class Foo::User
94
+ spawn_model "User" do
96
95
  before_create -> { name.upcase! }
97
96
  end
98
97
  end
@@ -105,7 +104,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
105
104
  end
106
105
 
107
106
  context :after_find do
108
- subject { Foo::User.find(1) }
107
+ subject { User.find(1) }
109
108
  before do
110
109
  Her::API.default_api.connection.adapter :test do |stub|
111
110
  stub.get("/users/1") { [200, {}, { id: 1, name: "Tobias Funke" }.to_json] }
@@ -114,7 +113,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
114
113
 
115
114
  context "when using a symbol callback" do
116
115
  before do
117
- class Foo::User
116
+ spawn_model "User" do
118
117
  after_find :alter_name
119
118
  def alter_name
120
119
  name.upcase!
@@ -130,7 +129,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
130
129
 
131
130
  context "when using a block callback" do
132
131
  before do
133
- class Foo::User
132
+ spawn_model "User" do
134
133
  after_find -> { name.upcase! }
135
134
  end
136
135
  end
@@ -143,11 +142,11 @@ describe "Her::Model and ActiveModel::Callbacks" do
143
142
  end
144
143
 
145
144
  context :after_initialize do
146
- subject { Foo::User.new(name: "Tobias Funke") }
145
+ subject { User.new(name: "Tobias Funke") }
147
146
 
148
147
  context "when using a symbol callback" do
149
148
  before do
150
- class Foo::User
149
+ spawn_model "User" do
151
150
  after_initialize :alter_name
152
151
  def alter_name
153
152
  name.upcase!
@@ -163,7 +162,7 @@ describe "Her::Model and ActiveModel::Callbacks" do
163
162
 
164
163
  context "when using a block callback" do
165
164
  before do
166
- class Foo::User
165
+ spawn_model "User" do
167
166
  after_initialize -> { name.upcase! }
168
167
  end
169
168
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe "Her::Model and ActiveModel::Dirty" do
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::HTTP do
@@ -157,33 +158,43 @@ describe Her::Model::HTTP do
157
158
  subject { Foo::User }
158
159
 
159
160
  describe :custom_get do
160
- context "without cache" do
161
- before { Foo::User.custom_get :popular, :recent }
162
- it { is_expected.to respond_to(:popular) }
163
- it { is_expected.to respond_to(:recent) }
161
+ before do
162
+ Foo::User.custom_get :popular, :recent
163
+ end
164
164
 
165
- context "making the HTTP request" do
166
- subject { Foo::User.popular }
165
+ it { is_expected.to respond_to(:popular) }
166
+ it { is_expected.to respond_to(:recent) }
167
167
 
168
- describe "#length" do
169
- subject { super().length }
170
- it { is_expected.to eq(2) }
171
- end
172
- end
168
+ it "makes HTTP request" do
169
+ expect(Foo::User.popular.length).to be 2
173
170
  end
174
171
  end
175
172
 
176
173
  describe :custom_post do
177
- before { Foo::User.custom_post :from_default }
174
+ before do
175
+ Foo::User.custom_post :from_default
176
+ end
177
+
178
178
  it { is_expected.to respond_to(:from_default) }
179
179
 
180
- context "making the HTTP request" do
181
- subject { Foo::User.from_default(name: "Tobias Fünke") }
180
+ it "makes HTTP request" do
181
+ user = Foo::User.from_default(name: "Tobias Fünke")
182
+ expect(user.id).to be 4
183
+ end
184
+ end
185
+
186
+ context "with options" do
187
+ before do
188
+ allow(Foo::User).to receive(:warn)
189
+ Foo::User.custom_get :popular, foo: "bar"
190
+ end
182
191
 
183
- describe "#id" do
184
- subject { super().id }
185
- it { is_expected.to eq(4) }
186
- end
192
+ it "issues DEPRECATION warning" do
193
+ expect(Foo::User).to have_received(:warn).with("[DEPRECATION] options for custom request methods are deprecated and will be removed on or after January 2020.")
194
+ end
195
+
196
+ it "makes HTTP request" do
197
+ expect(Foo::User.popular.length).to be 2
187
198
  end
188
199
  end
189
200
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::Introspection do
@@ -38,7 +39,7 @@ describe Her::Model::Introspection do
38
39
  @user.instance_eval do
39
40
  def password
40
41
  "filtered"
41
- end
42
+ end
42
43
  end
43
44
  expect(@user.inspect).to include("name=\"Tobias Funke\"")
44
45
  expect(@user.inspect).to include("password=\"filtered\"")
@@ -73,7 +74,7 @@ describe Her::Model::Introspection do
73
74
  expect(Foo::User.her_nearby_class("AccessRecord")).to eq(Foo::AccessRecord)
74
75
  expect(AccessRecord.her_nearby_class("Log")).to eq(Log)
75
76
  expect(Foo::User.her_nearby_class("Log")).to eq(Log)
76
- expect{Foo::User.her_nearby_class("X")}.to raise_error(NameError)
77
+ expect { Foo::User.her_nearby_class("X") }.to raise_error(NameError)
77
78
  end
78
79
  end
79
80
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::NestedAttributes do
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::ORM do
@@ -73,10 +74,10 @@ describe Her::Model::ORM do
73
74
  builder.use Her::Middleware::SecondLevelParseJSON
74
75
  builder.use Faraday::Request::UrlEncoded
75
76
  builder.adapter :test do |stub|
76
- stub.get("/users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w(Oh My God) }.to_json] }
77
- stub.get("/users") { |env| [200, {}, { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], :metadata => { :total_pages => 10, :next_page => 2 }, :errors => ["Oh", "My", "God"] }.to_json] }
78
- stub.post("/users") { |env| [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
79
- stub.delete("/users/1") { |env| [200, {}, { :data => { :id => 1 }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
77
+ stub.get("/users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w[Oh My God] }.to_json] }
78
+ stub.get("/users") { [200, {}, { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], :metadata => { :total_pages => 10, :next_page => 2 }, :errors => ["Oh", "My", "God"] }.to_json] }
79
+ stub.post("/users") { [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
80
+ stub.delete("/users/1") { [200, {}, { :data => { :id => 1 }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
80
81
  end
81
82
  end
82
83
 
@@ -102,7 +103,7 @@ describe Her::Model::ORM do
102
103
 
103
104
  it "handles error data on a resource" do
104
105
  @user = User.create(name: "George Michael Bluth")
105
- expect(@user.response_errors).to eq(%w(Yes Sir))
106
+ expect(@user.response_errors).to eq(%w[Yes Sir])
106
107
  end
107
108
 
108
109
  it "handles metadata on a destroyed resource" do
@@ -112,7 +113,7 @@ describe Her::Model::ORM do
112
113
 
113
114
  it "handles error data on a destroyed resource" do
114
115
  @user = User.destroy_existing(1)
115
- expect(@user.response_errors).to eq(%w(Yes Sir))
116
+ expect(@user.response_errors).to eq(%w[Yes Sir])
116
117
  end
117
118
  end
118
119
 
@@ -123,8 +124,8 @@ describe Her::Model::ORM do
123
124
  builder.use Her::Middleware::SecondLevelParseJSON
124
125
  builder.use Faraday::Request::UrlEncoded
125
126
  builder.adapter :test do |stub|
126
- stub.get("/users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w(Oh My God) }.to_json] }
127
- stub.post("/users") { [200, {}, { data: { name: "George Michael Bluth" }, metadata: { foo: "bar" }, errors: %w(Yes Sir) }.to_json] }
127
+ stub.get("/users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w[Oh My God] }.to_json] }
128
+ stub.post("/users") { [200, {}, { data: { name: "George Michael Bluth" }, metadata: { foo: "bar" }, errors: %w[Yes Sir] }.to_json] }
128
129
  end
129
130
  end
130
131
 
@@ -150,7 +151,7 @@ describe Her::Model::ORM do
150
151
 
151
152
  it "handles error data on a resource" do
152
153
  @user = User.create(name: "George Michael Bluth")
153
- expect(@user.response_errors).to eq(%w(Yes Sir))
154
+ expect(@user.response_errors).to eq(%w[Yes Sir])
154
155
  end
155
156
  end
156
157
 
@@ -161,7 +162,7 @@ describe Her::Model::ORM do
161
162
  builder.use Her::Middleware::FirstLevelParseJSON
162
163
  builder.use Faraday::Request::UrlEncoded
163
164
  builder.adapter :test do |stub|
164
- stub.get("/users/1") { [200, {}, { id: 1, friends: %w(Maeby GOB Anne) }.to_json] }
165
+ stub.get("/users/1") { [200, {}, { id: 1, friends: %w[Maeby GOB Anne] }.to_json] }
165
166
  stub.get("/users/2") { [200, {}, { id: 1 }.to_json] }
166
167
  end
167
168
  end
@@ -185,7 +186,7 @@ describe Her::Model::ORM do
185
186
  @user = User.find(1)
186
187
  expect(@user.friends).to eq("* Maeby\n* GOB\n* Anne")
187
188
  @user.instance_eval do
188
- @_her_attributes[:friends] = %w(Maeby GOB Anne)
189
+ @_her_attributes[:friends] = %w[Maeby GOB Anne]
189
190
  end
190
191
  end
191
192
 
@@ -194,7 +195,7 @@ describe Her::Model::ORM do
194
195
  @user.friends = "* George\n* Oscar\n* Lucille"
195
196
  expect(@user.friends).to eq("* George\n* Oscar\n* Lucille")
196
197
  @user.instance_eval do
197
- @_her_attributes[:friends] = %w(George Oscar Lucille)
198
+ @_her_attributes[:friends] = %w[George Oscar Lucille]
198
199
  end
199
200
  end
200
201
  end
@@ -401,6 +402,7 @@ describe Her::Model::ORM do
401
402
  builder.adapter :test do |stub|
402
403
  stub.get("/users/1") { [200, {}, { id: 1, fullname: "Tobias Fünke", admin: false }.to_json] }
403
404
  stub.put("/users/1") { [200, {}, { id: 1, fullname: "Lindsay Fünke", admin: true }.to_json] }
405
+ stub.put("/users/2") { [200, {}, { id: 2, errors: ["fullname has already been taken"] }.to_json] }
404
406
  stub.get("/pages/1") { [200, {}, { id: 1, views: 1, unique_visitors: 4 }.to_json] }
405
407
  stub.put("/pages/1") { [200, {}, { id: 1, views: 2, unique_visitors: 3 }.to_json] }
406
408
  end
@@ -422,6 +424,15 @@ describe Her::Model::ORM do
422
424
  expect(@user.fullname).to eq("Lindsay Fünke")
423
425
  end
424
426
 
427
+ it "handle resource update through .save_existing!" do
428
+ @user = Foo::User.save_existing!(1, fullname: "Lindsay Fünke")
429
+ expect(@user.fullname).to eq("Lindsay Fünke")
430
+ end
431
+
432
+ it "raises ResourceInvalid when .save_existing! has errors" do
433
+ expect { Foo::User.save_existing!(2, fullname: "Lindsay Fünke") }.to raise_error(Her::Errors::ResourceInvalid)
434
+ end
435
+
425
436
  it "handle resource update through #save on an existing resource" do
426
437
  @user = Foo::User.find(1)
427
438
  @user.fullname = "Lindsay Fünke"
@@ -429,6 +440,13 @@ describe Her::Model::ORM do
429
440
  expect(@user.fullname).to eq("Lindsay Fünke")
430
441
  end
431
442
 
443
+ it "handle resource update through #update_attributes" do
444
+ @user = Foo::User.find(1)
445
+ expect(@user).to receive(:save).and_return(true)
446
+ @user.update_attributes(fullname: "Lindsay Fünke")
447
+ expect(@user.fullname).to eq("Lindsay Fünke")
448
+ end
449
+
432
450
  it "handles resource update through #toggle without saving it" do
433
451
  @user = Foo::User.find(1)
434
452
  expect(@user.admin).to be_falsey
@@ -492,10 +510,10 @@ describe Her::Model::ORM do
492
510
  stub.get("/users/1") { [200, {}, { id: 1, fullname: "Tobias Fünke", active: true }.to_json] }
493
511
  stub.delete("/users/1") { [status, {}, { id: 1, fullname: "Lindsay Fünke", active: false }.to_json] }
494
512
 
495
- stub.get("/child_users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w(Oh My God) }.to_json] }
496
- stub.get("/child_users") { |env| [200, {}, { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], :metadata => { :total_pages => 10, :next_page => 2 }, :errors => ["Oh", "My", "God"] }.to_json] }
497
- stub.post("/child_users") { |env| [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
498
- stub.delete("/child_users/1") { |env| [200, {}, { :data => { :id => 1 }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
513
+ stub.get("/child_users") { [200, {}, { data: [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }], metadata: { total_pages: 10, next_page: 2 }, errors: %w[Oh My God] }.to_json] }
514
+ stub.get("/child_users") { [200, {}, { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], :metadata => { :total_pages => 10, :next_page => 2 }, :errors => ["Oh", "My", "God"] }.to_json] }
515
+ stub.post("/child_users") { [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
516
+ stub.delete("/child_users/1") { [200, {}, { :data => { :id => 1 }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
499
517
  end
500
518
  end
501
519
 
@@ -652,10 +670,15 @@ describe Her::Model::ORM do
652
670
  after_create :after_create_callback
653
671
  after_save :after_save_callback
654
672
  def before_save_callback; end
673
+
655
674
  def before_create_callback; end
675
+
656
676
  def before_update_callback; end
677
+
657
678
  def after_update_callback; end
679
+
658
680
  def after_create_callback; end
681
+
659
682
  def after_save_callback; end
660
683
  end
661
684
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
4
 
4
5
  describe Her::Model::Parse do
@@ -251,6 +252,7 @@ describe Her::Model::Parse do
251
252
 
252
253
  it "parse the data with the symbol" do
253
254
  @new_user = Foo::User.create(fullname: "Lindsay Fünke")
255
+ expect(@new_user.id).to eq(1)
254
256
  expect(@new_user.fullname).to eq("Lindsay Fünke")
255
257
  end
256
258
  end
@@ -264,6 +266,7 @@ describe Her::Model::Parse do
264
266
 
265
267
  spawn_model("Foo::Model") { parse_root_in_json true, format: :active_model_serializers }
266
268
  class User < Foo::Model
269
+
267
270
  collection_path "/users"
268
271
  end
269
272
 
@@ -493,4 +496,25 @@ describe Her::Model::Parse do
493
496
  expect(user.to_params).to eq(model: { name: 'foo' })
494
497
  end
495
498
  end
499
+
500
+ context "when attribute uses the same name as root element" do
501
+ before do
502
+ Her::API.setup url: "https://api.example.com" do |builder|
503
+ builder.use Her::Middleware::FirstLevelParseJSON
504
+ builder.use Faraday::Request::UrlEncoded
505
+ end
506
+
507
+ Her::API.default_api.connection.adapter :test do |stub|
508
+ stub.post("/users") { |env| [200, {}, { user: "foobar", id: 1, fullname: params(env)[:fullname] }.to_json] }
509
+ end
510
+
511
+ spawn_model "Foo::User"
512
+ end
513
+
514
+ it "parses as attribute instead of root element" do
515
+ user = Foo::User.create(fullname: "barfoo")
516
+ expect(user.fullname).to eq "barfoo"
517
+ expect(user.user).to eq "foobar"
518
+ end
519
+ end
496
520
  end