her5 0.8.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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.travis.yml +17 -0
- data/.yardopts +2 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +10 -0
- data/LICENSE +7 -0
- data/README.md +1017 -0
- data/Rakefile +11 -0
- data/UPGRADE.md +101 -0
- data/gemfiles/Gemfile.activemodel-3.2.x +7 -0
- data/gemfiles/Gemfile.activemodel-4.0 +7 -0
- data/gemfiles/Gemfile.activemodel-4.1 +7 -0
- data/gemfiles/Gemfile.activemodel-4.2 +7 -0
- data/gemfiles/Gemfile.activemodel-5.0.x +7 -0
- data/her5.gemspec +30 -0
- data/lib/her.rb +19 -0
- data/lib/her/api.rb +120 -0
- data/lib/her/collection.rb +12 -0
- data/lib/her/errors.rb +104 -0
- data/lib/her/json_api/model.rb +57 -0
- data/lib/her/middleware.rb +12 -0
- data/lib/her/middleware/accept_json.rb +17 -0
- data/lib/her/middleware/first_level_parse_json.rb +36 -0
- data/lib/her/middleware/json_api_parser.rb +68 -0
- data/lib/her/middleware/parse_json.rb +28 -0
- data/lib/her/middleware/second_level_parse_json.rb +36 -0
- data/lib/her/model.rb +75 -0
- data/lib/her/model/associations.rb +141 -0
- data/lib/her/model/associations/association.rb +107 -0
- data/lib/her/model/associations/association_proxy.rb +45 -0
- data/lib/her/model/associations/belongs_to_association.rb +101 -0
- data/lib/her/model/associations/has_many_association.rb +101 -0
- data/lib/her/model/associations/has_one_association.rb +80 -0
- data/lib/her/model/attributes.rb +297 -0
- data/lib/her/model/base.rb +33 -0
- data/lib/her/model/deprecated_methods.rb +61 -0
- data/lib/her/model/http.rb +113 -0
- data/lib/her/model/introspection.rb +65 -0
- data/lib/her/model/nested_attributes.rb +84 -0
- data/lib/her/model/orm.rb +207 -0
- data/lib/her/model/parse.rb +221 -0
- data/lib/her/model/paths.rb +126 -0
- data/lib/her/model/relation.rb +164 -0
- data/lib/her/version.rb +3 -0
- data/spec/api_spec.rb +114 -0
- data/spec/collection_spec.rb +26 -0
- data/spec/json_api/model_spec.rb +305 -0
- data/spec/middleware/accept_json_spec.rb +10 -0
- data/spec/middleware/first_level_parse_json_spec.rb +62 -0
- data/spec/middleware/json_api_parser_spec.rb +32 -0
- data/spec/middleware/second_level_parse_json_spec.rb +35 -0
- data/spec/model/associations/association_proxy_spec.rb +31 -0
- data/spec/model/associations_spec.rb +504 -0
- data/spec/model/attributes_spec.rb +389 -0
- data/spec/model/callbacks_spec.rb +145 -0
- data/spec/model/dirty_spec.rb +91 -0
- data/spec/model/http_spec.rb +158 -0
- data/spec/model/introspection_spec.rb +76 -0
- data/spec/model/nested_attributes_spec.rb +134 -0
- data/spec/model/orm_spec.rb +506 -0
- data/spec/model/parse_spec.rb +345 -0
- data/spec/model/paths_spec.rb +347 -0
- data/spec/model/relation_spec.rb +226 -0
- data/spec/model/validations_spec.rb +42 -0
- data/spec/model_spec.rb +44 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/extensions/array.rb +5 -0
- data/spec/support/extensions/hash.rb +5 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/model_macros.rb +36 -0
- data/spec/support/macros/request_macros.rb +27 -0
- metadata +289 -0
@@ -0,0 +1,506 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
3
|
+
|
4
|
+
describe Her::Model::ORM do
|
5
|
+
context "mapping data to Ruby objects" do
|
6
|
+
before do
|
7
|
+
api = Her::API.new
|
8
|
+
api.setup :url => "https://api.example.com" do |builder|
|
9
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
10
|
+
builder.use Faraday::Request::UrlEncoded
|
11
|
+
builder.adapter :test do |stub|
|
12
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
|
13
|
+
stub.get("/users") { |env| [200, {}, [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }].to_json] }
|
14
|
+
stub.get("/admin_users") { |env| [200, {}, [{ :admin_id => 1, :name => "Tobias Fünke" }, { :admin_id => 2, :name => "Lindsay Fünke" }].to_json] }
|
15
|
+
stub.get("/admin_users/1") { |env| [200, {}, { :admin_id => 1, :name => "Tobias Fünke" }.to_json] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
spawn_model "Foo::User" do
|
20
|
+
uses_api api
|
21
|
+
end
|
22
|
+
|
23
|
+
spawn_model "Foo::AdminUser" do
|
24
|
+
uses_api api
|
25
|
+
primary_key :admin_id
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "maps a single resource to a Ruby object" do
|
30
|
+
@user = Foo::User.find(1)
|
31
|
+
@user.id.should == 1
|
32
|
+
@user.name.should == "Tobias Fünke"
|
33
|
+
|
34
|
+
@admin = Foo::AdminUser.find(1)
|
35
|
+
@admin.id.should == 1
|
36
|
+
@admin.name.should == "Tobias Fünke"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "maps a collection of resources to an array of Ruby objects" do
|
40
|
+
@users = Foo::User.all
|
41
|
+
@users.length.should == 2
|
42
|
+
@users.first.name.should == "Tobias Fünke"
|
43
|
+
|
44
|
+
@users = Foo::AdminUser.all
|
45
|
+
@users.length.should == 2
|
46
|
+
@users.first.name.should == "Tobias Fünke"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "handles new resource" do
|
50
|
+
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
51
|
+
@new_user.new?.should be_truthy
|
52
|
+
@new_user.new_record?.should be_truthy
|
53
|
+
@new_user.fullname.should == "Tobias Fünke"
|
54
|
+
|
55
|
+
@existing_user = Foo::User.find(1)
|
56
|
+
@existing_user.new?.should be_falsey
|
57
|
+
@existing_user.new_record?.should be_falsey
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'handles new resource with custom primary key' do
|
61
|
+
@new_user = Foo::AdminUser.new(:fullname => 'Lindsay Fünke', :id => -1)
|
62
|
+
@new_user.should be_new
|
63
|
+
|
64
|
+
@existing_user = Foo::AdminUser.find(1)
|
65
|
+
@existing_user.should_not be_new
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "mapping data, metadata and error data to Ruby objects" do
|
70
|
+
before do
|
71
|
+
api = Her::API.new
|
72
|
+
api.setup :url => "https://api.example.com" do |builder|
|
73
|
+
builder.use Her::Middleware::SecondLevelParseJSON
|
74
|
+
builder.use Faraday::Request::UrlEncoded
|
75
|
+
builder.adapter :test do |stub|
|
76
|
+
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] }
|
77
|
+
stub.post("/users") { |env| [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
spawn_model :User do
|
82
|
+
uses_api api
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "handles metadata on a collection" do
|
87
|
+
@users = User.all
|
88
|
+
@users.metadata[:total_pages].should == 10
|
89
|
+
end
|
90
|
+
|
91
|
+
it "handles error data on a collection" do
|
92
|
+
@users = User.all
|
93
|
+
@users.errors.length.should == 3
|
94
|
+
end
|
95
|
+
|
96
|
+
it "handles metadata on a resource" do
|
97
|
+
@user = User.create(:name => "George Michael Bluth")
|
98
|
+
@user.metadata[:foo].should == "bar"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "handles error data on a resource" do
|
102
|
+
@user = User.create(:name => "George Michael Bluth")
|
103
|
+
@user.response_errors.should == ["Yes", "Sir"]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "mapping data, metadata and error data in string keys to Ruby objects" do
|
108
|
+
before do
|
109
|
+
api = Her::API.new
|
110
|
+
api.setup :url => "https://api.example.com" do |builder|
|
111
|
+
builder.use Her::Middleware::SecondLevelParseJSON
|
112
|
+
builder.use Faraday::Request::UrlEncoded
|
113
|
+
builder.adapter :test do |stub|
|
114
|
+
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] }
|
115
|
+
stub.post("/users") { |env| [200, {}, { 'data' => { :name => "George Michael Bluth" }, 'metadata' => { :foo => "bar" }, 'errors' => ["Yes", "Sir"] }.to_json] }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
spawn_model :User do
|
120
|
+
uses_api api
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "handles metadata on a collection" do
|
125
|
+
@users = User.all
|
126
|
+
@users.metadata[:total_pages].should == 10
|
127
|
+
end
|
128
|
+
|
129
|
+
it "handles error data on a collection" do
|
130
|
+
@users = User.all
|
131
|
+
@users.errors.length.should == 3
|
132
|
+
end
|
133
|
+
|
134
|
+
it "handles metadata on a resource" do
|
135
|
+
@user = User.create(:name => "George Michael Bluth")
|
136
|
+
@user.metadata[:foo].should == "bar"
|
137
|
+
end
|
138
|
+
|
139
|
+
it "handles error data on a resource" do
|
140
|
+
@user = User.create(:name => "George Michael Bluth")
|
141
|
+
@user.response_errors.should == ["Yes", "Sir"]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "defining custom getters and setters" do
|
146
|
+
before do
|
147
|
+
api = Her::API.new
|
148
|
+
api.setup :url => "https://api.example.com" do |builder|
|
149
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
150
|
+
builder.use Faraday::Request::UrlEncoded
|
151
|
+
builder.adapter :test do |stub|
|
152
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :friends => ["Maeby", "GOB", "Anne"] }.to_json] }
|
153
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 1 }.to_json] }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
spawn_model :User do
|
158
|
+
uses_api api
|
159
|
+
belongs_to :organization
|
160
|
+
|
161
|
+
def friends=(val)
|
162
|
+
val = val.gsub("\r", "").split("\n").map { |friend| friend.gsub(/^\s*\*\s*/, "") } if val and val.is_a?(String)
|
163
|
+
@attributes[:friends] = val
|
164
|
+
end
|
165
|
+
|
166
|
+
def friends
|
167
|
+
@attributes[:friends].map { |friend| "* #{friend}" }.join("\n")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it "handles custom setters" do
|
173
|
+
@user = User.find(1)
|
174
|
+
@user.friends.should == "* Maeby\n* GOB\n* Anne"
|
175
|
+
@user.instance_eval do
|
176
|
+
@attributes[:friends] = ["Maeby", "GOB", "Anne"]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "handles custom getters" do
|
181
|
+
@user = User.new
|
182
|
+
@user.friends = "* George\n* Oscar\n* Lucille"
|
183
|
+
@user.friends.should == "* George\n* Oscar\n* Lucille"
|
184
|
+
@user.instance_eval do
|
185
|
+
@attributes[:friends] = ["George", "Oscar", "Lucille"]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "finding resources" do
|
191
|
+
before do
|
192
|
+
api = Her::API.new
|
193
|
+
api.setup :url => "https://api.example.com" do |builder|
|
194
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
195
|
+
builder.use Faraday::Request::UrlEncoded
|
196
|
+
builder.adapter :test do |stub|
|
197
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
|
198
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 2, :age => 34 }.to_json] }
|
199
|
+
stub.get("/users?id[]=1&id[]=2") { |env| [200, {}, [{ :id => 1, :age => 42 }, { :id => 2, :age => 34 }].to_json] }
|
200
|
+
stub.get("/users?age=42&foo=bar") { |env| [200, {}, [{ :id => 3, :age => 42 }].to_json] }
|
201
|
+
stub.get("/users?age=42") { |env| [200, {}, [{ :id => 1, :age => 42 }].to_json] }
|
202
|
+
stub.get("/users?age=40") { |env| [200, {}, [{ :id => 1, :age => 40 }].to_json] }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
spawn_model :User do
|
207
|
+
uses_api api
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
it "handles finding by a single id" do
|
212
|
+
@user = User.find(1)
|
213
|
+
@user.id.should == 1
|
214
|
+
end
|
215
|
+
|
216
|
+
it "handles finding by multiple ids" do
|
217
|
+
@users = User.find(1, 2)
|
218
|
+
@users.should be_kind_of(Array)
|
219
|
+
@users.length.should == 2
|
220
|
+
@users[0].id.should == 1
|
221
|
+
@users[1].id.should == 2
|
222
|
+
end
|
223
|
+
|
224
|
+
it "handles finding by an array of ids" do
|
225
|
+
@users = User.find([1, 2])
|
226
|
+
@users.should be_kind_of(Array)
|
227
|
+
@users.length.should == 2
|
228
|
+
@users[0].id.should == 1
|
229
|
+
@users[1].id.should == 2
|
230
|
+
end
|
231
|
+
|
232
|
+
it "handles finding by an array of ids of length 1" do
|
233
|
+
@users = User.find([1])
|
234
|
+
@users.should be_kind_of(Array)
|
235
|
+
@users.length.should == 1
|
236
|
+
@users[0].id.should == 1
|
237
|
+
end
|
238
|
+
|
239
|
+
it "handles finding by an array id param of length 2" do
|
240
|
+
@users = User.find(id: [1, 2])
|
241
|
+
@users.should be_kind_of(Array)
|
242
|
+
@users.length.should == 2
|
243
|
+
@users[0].id.should == 1
|
244
|
+
@users[1].id.should == 2
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'handles finding with id parameter as an array' do
|
248
|
+
@users = User.where(id: [1, 2])
|
249
|
+
@users.should be_kind_of(Array)
|
250
|
+
@users.length.should == 2
|
251
|
+
@users[0].id.should == 1
|
252
|
+
@users[1].id.should == 2
|
253
|
+
end
|
254
|
+
|
255
|
+
it "handles finding with other parameters" do
|
256
|
+
@users = User.where(:age => 42, :foo => "bar").all
|
257
|
+
@users.should be_kind_of(Array)
|
258
|
+
@users.first.id.should == 3
|
259
|
+
end
|
260
|
+
|
261
|
+
it "handles finding with other parameters and scoped" do
|
262
|
+
@users = User.scoped
|
263
|
+
@users.where(:age => 42).should be_all { |u| u.age == 42 }
|
264
|
+
@users.where(:age => 40).should be_all { |u| u.age == 40 }
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "building resources" do
|
269
|
+
context "when request_new_object_on_build is not set (default)" do
|
270
|
+
before do
|
271
|
+
spawn_model("Foo::User")
|
272
|
+
end
|
273
|
+
|
274
|
+
it "builds a new resource without requesting it" do
|
275
|
+
Foo::User.should_not_receive(:request)
|
276
|
+
@new_user = Foo::User.build(:fullname => "Tobias Fünke")
|
277
|
+
@new_user.new?.should be_truthy
|
278
|
+
@new_user.fullname.should == "Tobias Fünke"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context "when request_new_object_on_build is set" do
|
283
|
+
before do
|
284
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
285
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
286
|
+
builder.use Faraday::Request::UrlEncoded
|
287
|
+
builder.adapter :test do |stub|
|
288
|
+
stub.get("/users/new") { |env| ok! :id => nil, :fullname => params(env)[:fullname], :email => "tobias@bluthcompany.com" }
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
spawn_model("Foo::User") { request_new_object_on_build true }
|
293
|
+
end
|
294
|
+
|
295
|
+
it "requests a new resource" do
|
296
|
+
Foo::User.should_receive(:request).once.and_call_original
|
297
|
+
@new_user = Foo::User.build(:fullname => "Tobias Fünke")
|
298
|
+
@new_user.new?.should be_truthy
|
299
|
+
@new_user.fullname.should == "Tobias Fünke"
|
300
|
+
@new_user.email.should == "tobias@bluthcompany.com"
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context "creating resources" do
|
306
|
+
before do
|
307
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
308
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
309
|
+
builder.use Faraday::Request::UrlEncoded
|
310
|
+
builder.adapter :test do |stub|
|
311
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :fullname => Faraday::Utils.parse_query(env[:body])['fullname'], :email => Faraday::Utils.parse_query(env[:body])['email'] }.to_json] }
|
312
|
+
stub.post("/companies") { |env| [200, {}, { :errors => ["name is required"] }.to_json] }
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
spawn_model "Foo::User"
|
317
|
+
spawn_model "Foo::Company"
|
318
|
+
end
|
319
|
+
|
320
|
+
it "handle one-line resource creation" do
|
321
|
+
@user = Foo::User.create(:fullname => "Tobias Fünke", :email => "tobias@bluth.com")
|
322
|
+
@user.id.should == 1
|
323
|
+
@user.fullname.should == "Tobias Fünke"
|
324
|
+
@user.email.should == "tobias@bluth.com"
|
325
|
+
end
|
326
|
+
|
327
|
+
it "handle resource creation through Model.new + #save" do
|
328
|
+
@user = Foo::User.new(:fullname => "Tobias Fünke")
|
329
|
+
@user.save.should be_truthy
|
330
|
+
@user.fullname.should == "Tobias Fünke"
|
331
|
+
end
|
332
|
+
|
333
|
+
it "handle resource creation through Model.new + #save!" do
|
334
|
+
@user = Foo::User.new(:fullname => "Tobias Fünke")
|
335
|
+
@user.save!.should be_truthy
|
336
|
+
@user.fullname.should == "Tobias Fünke"
|
337
|
+
end
|
338
|
+
|
339
|
+
it "returns false when #save gets errors" do
|
340
|
+
@company = Foo::Company.new
|
341
|
+
@company.save.should be_falsey
|
342
|
+
end
|
343
|
+
|
344
|
+
it "raises ResourceInvalid when #save! gets errors" do
|
345
|
+
@company = Foo::Company.new
|
346
|
+
expect { @company.save! }.to raise_error Her::Errors::ResourceInvalid, "Remote validation failed: name is required"
|
347
|
+
end
|
348
|
+
|
349
|
+
it "don't overwrite data if response is empty" do
|
350
|
+
@company = Foo::Company.new(:name => 'Company Inc.')
|
351
|
+
@company.save.should be_falsey
|
352
|
+
@company.name.should == "Company Inc."
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context "updating resources" do
|
357
|
+
before do
|
358
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
359
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
360
|
+
builder.use Faraday::Request::UrlEncoded
|
361
|
+
builder.adapter :test do |stub|
|
362
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
363
|
+
stub.put("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
spawn_model "Foo::User"
|
368
|
+
end
|
369
|
+
|
370
|
+
it "handle resource data update without saving it" do
|
371
|
+
@user = Foo::User.find(1)
|
372
|
+
@user.fullname.should == "Tobias Fünke"
|
373
|
+
@user.fullname = "Kittie Sanchez"
|
374
|
+
@user.fullname.should == "Kittie Sanchez"
|
375
|
+
end
|
376
|
+
|
377
|
+
it "handle resource update through the .update class method" do
|
378
|
+
@user = Foo::User.save_existing(1, { :fullname => "Lindsay Fünke" })
|
379
|
+
@user.fullname.should == "Lindsay Fünke"
|
380
|
+
end
|
381
|
+
|
382
|
+
it "handle resource update through #save on an existing resource" do
|
383
|
+
@user = Foo::User.find(1)
|
384
|
+
@user.fullname = "Lindsay Fünke"
|
385
|
+
@user.save
|
386
|
+
@user.fullname.should == "Lindsay Fünke"
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context "deleting resources" do
|
391
|
+
before do
|
392
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
393
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
394
|
+
builder.use Faraday::Request::UrlEncoded
|
395
|
+
builder.adapter :test do |stub|
|
396
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json] }
|
397
|
+
stub.delete("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json] }
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
spawn_model "Foo::User"
|
402
|
+
end
|
403
|
+
|
404
|
+
it "handle resource deletion through the .destroy class method" do
|
405
|
+
@user = Foo::User.destroy_existing(1)
|
406
|
+
@user.active.should be_falsey
|
407
|
+
@user.should be_destroyed
|
408
|
+
end
|
409
|
+
|
410
|
+
it "handle resource deletion through #destroy on an existing resource" do
|
411
|
+
@user = Foo::User.find(1)
|
412
|
+
@user.destroy
|
413
|
+
@user.active.should be_falsey
|
414
|
+
@user.should be_destroyed
|
415
|
+
end
|
416
|
+
|
417
|
+
context "with params" do
|
418
|
+
before do
|
419
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
420
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
421
|
+
builder.use Faraday::Request::UrlEncoded
|
422
|
+
builder.adapter :test do |stub|
|
423
|
+
stub.delete("/users/1?delete_type=soft") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json] }
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
it "handle resource deletion through the .destroy class method" do
|
429
|
+
@user = Foo::User.destroy_existing(1, delete_type: 'soft')
|
430
|
+
@user.active.should be_false
|
431
|
+
@user.should be_destroyed
|
432
|
+
end
|
433
|
+
|
434
|
+
it "handle resource deletion through #destroy on an existing resource" do
|
435
|
+
@user = Foo::User.find(1)
|
436
|
+
@user.destroy(delete_type: 'soft')
|
437
|
+
@user.active.should be_false
|
438
|
+
@user.should be_destroyed
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
context 'customizing HTTP methods' do
|
444
|
+
before do
|
445
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
446
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
447
|
+
builder.use Faraday::Request::UrlEncoded
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
context 'create' do
|
452
|
+
before do
|
453
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
454
|
+
stub.put('/users') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
|
455
|
+
end
|
456
|
+
spawn_model 'Foo::User' do
|
457
|
+
attributes :fullname, :email
|
458
|
+
method_for :create, 'PUT'
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
context 'for top-level class' do
|
463
|
+
it 'uses the custom method (PUT) instead of default method (POST)' do
|
464
|
+
user = Foo::User.new(:fullname => 'Tobias Fünke')
|
465
|
+
user.should be_new
|
466
|
+
user.save.should be_truthy
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context 'for children class' do
|
471
|
+
before do
|
472
|
+
class User < Foo::User; end
|
473
|
+
@spawned_models << :User
|
474
|
+
end
|
475
|
+
|
476
|
+
it 'uses the custom method (PUT) instead of default method (POST)' do
|
477
|
+
user = User.new(:fullname => 'Tobias Fünke')
|
478
|
+
user.should be_new
|
479
|
+
user.save.should be_truthy
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
context 'update' do
|
485
|
+
before do
|
486
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
487
|
+
stub.get('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Lindsay Fünke' }.to_json] }
|
488
|
+
stub.post('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
|
489
|
+
end
|
490
|
+
|
491
|
+
spawn_model 'Foo::User' do
|
492
|
+
attributes :fullname, :email
|
493
|
+
method_for :update, :post
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
it 'uses the custom method (POST) instead of default method (PUT)' do
|
498
|
+
user = Foo::User.find(1)
|
499
|
+
user.fullname.should eq 'Lindsay Fünke'
|
500
|
+
user.fullname = 'Toby Fünke'
|
501
|
+
user.save
|
502
|
+
user.fullname.should eq 'Tobias Fünke'
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|