castle-her 1.0.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 +6 -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 +110 -0
- data/castle-her.gemspec +30 -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/lib/castle-her.rb +20 -0
- data/lib/castle-her/api.rb +113 -0
- data/lib/castle-her/collection.rb +12 -0
- data/lib/castle-her/errors.rb +27 -0
- data/lib/castle-her/json_api/model.rb +46 -0
- data/lib/castle-her/middleware.rb +12 -0
- data/lib/castle-her/middleware/accept_json.rb +17 -0
- data/lib/castle-her/middleware/first_level_parse_json.rb +36 -0
- data/lib/castle-her/middleware/json_api_parser.rb +36 -0
- data/lib/castle-her/middleware/parse_json.rb +21 -0
- data/lib/castle-her/middleware/second_level_parse_json.rb +36 -0
- data/lib/castle-her/model.rb +75 -0
- data/lib/castle-her/model/associations.rb +141 -0
- data/lib/castle-her/model/associations/association.rb +103 -0
- data/lib/castle-her/model/associations/association_proxy.rb +45 -0
- data/lib/castle-her/model/associations/belongs_to_association.rb +96 -0
- data/lib/castle-her/model/associations/has_many_association.rb +100 -0
- data/lib/castle-her/model/associations/has_one_association.rb +79 -0
- data/lib/castle-her/model/attributes.rb +284 -0
- data/lib/castle-her/model/base.rb +33 -0
- data/lib/castle-her/model/deprecated_methods.rb +61 -0
- data/lib/castle-her/model/http.rb +114 -0
- data/lib/castle-her/model/introspection.rb +65 -0
- data/lib/castle-her/model/nested_attributes.rb +45 -0
- data/lib/castle-her/model/orm.rb +207 -0
- data/lib/castle-her/model/parse.rb +216 -0
- data/lib/castle-her/model/paths.rb +126 -0
- data/lib/castle-her/model/relation.rb +164 -0
- data/lib/castle-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 +166 -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 +290 -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
|
+
expect(@user.id).to eq(1)
|
32
|
+
expect(@user.name).to eq("Tobias Fünke")
|
33
|
+
|
34
|
+
@admin = Foo::AdminUser.find(1)
|
35
|
+
expect(@admin.id).to eq(1)
|
36
|
+
expect(@admin.name).to eq("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
|
+
expect(@users.length).to eq(2)
|
42
|
+
expect(@users.first.name).to eq("Tobias Fünke")
|
43
|
+
|
44
|
+
@users = Foo::AdminUser.all
|
45
|
+
expect(@users.length).to eq(2)
|
46
|
+
expect(@users.first.name).to eq("Tobias Fünke")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "handles new resource" do
|
50
|
+
@new_user = Foo::User.new(:fullname => "Tobias Fünke")
|
51
|
+
expect(@new_user.new?).to be_truthy
|
52
|
+
expect(@new_user.new_record?).to be_truthy
|
53
|
+
expect(@new_user.fullname).to eq("Tobias Fünke")
|
54
|
+
|
55
|
+
@existing_user = Foo::User.find(1)
|
56
|
+
expect(@existing_user.new?).to be_falsey
|
57
|
+
expect(@existing_user.new_record?).to 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
|
+
expect(@new_user).to be_new
|
63
|
+
|
64
|
+
@existing_user = Foo::AdminUser.find(1)
|
65
|
+
expect(@existing_user).not_to 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
|
+
expect(@users.metadata[:total_pages]).to eq(10)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "handles error data on a collection" do
|
92
|
+
@users = User.all
|
93
|
+
expect(@users.errors.length).to eq(3)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "handles metadata on a resource" do
|
97
|
+
@user = User.create(:name => "George Michael Bluth")
|
98
|
+
expect(@user.metadata[:foo]).to eq("bar")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "handles error data on a resource" do
|
102
|
+
@user = User.create(:name => "George Michael Bluth")
|
103
|
+
expect(@user.response_errors).to eq(["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
|
+
expect(@users.metadata[:total_pages]).to eq(10)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "handles error data on a collection" do
|
130
|
+
@users = User.all
|
131
|
+
expect(@users.errors.length).to eq(3)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "handles metadata on a resource" do
|
135
|
+
@user = User.create(:name => "George Michael Bluth")
|
136
|
+
expect(@user.metadata[:foo]).to eq("bar")
|
137
|
+
end
|
138
|
+
|
139
|
+
it "handles error data on a resource" do
|
140
|
+
@user = User.create(:name => "George Michael Bluth")
|
141
|
+
expect(@user.response_errors).to eq(["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
|
+
expect(@user.friends).to eq("* 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
|
+
expect(@user.friends).to eq("* 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
|
+
expect(@user.id).to eq(1)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "handles finding by multiple ids" do
|
217
|
+
@users = User.find(1, 2)
|
218
|
+
expect(@users).to be_kind_of(Array)
|
219
|
+
expect(@users.length).to eq(2)
|
220
|
+
expect(@users[0].id).to eq(1)
|
221
|
+
expect(@users[1].id).to eq(2)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "handles finding by an array of ids" do
|
225
|
+
@users = User.find([1, 2])
|
226
|
+
expect(@users).to be_kind_of(Array)
|
227
|
+
expect(@users.length).to eq(2)
|
228
|
+
expect(@users[0].id).to eq(1)
|
229
|
+
expect(@users[1].id).to eq(2)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "handles finding by an array of ids of length 1" do
|
233
|
+
@users = User.find([1])
|
234
|
+
expect(@users).to be_kind_of(Array)
|
235
|
+
expect(@users.length).to eq(1)
|
236
|
+
expect(@users[0].id).to eq(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
|
+
expect(@users).to be_kind_of(Array)
|
242
|
+
expect(@users.length).to eq(2)
|
243
|
+
expect(@users[0].id).to eq(1)
|
244
|
+
expect(@users[1].id).to eq(2)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'handles finding with id parameter as an array' do
|
248
|
+
@users = User.where(id: [1, 2])
|
249
|
+
expect(@users).to be_kind_of(Array)
|
250
|
+
expect(@users.length).to eq(2)
|
251
|
+
expect(@users[0].id).to eq(1)
|
252
|
+
expect(@users[1].id).to eq(2)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "handles finding with other parameters" do
|
256
|
+
@users = User.where(:age => 42, :foo => "bar").all
|
257
|
+
expect(@users).to be_kind_of(Array)
|
258
|
+
expect(@users.first.id).to eq(3)
|
259
|
+
end
|
260
|
+
|
261
|
+
it "handles finding with other parameters and scoped" do
|
262
|
+
@users = User.scoped
|
263
|
+
expect(@users.where(:age => 42)).to be_all { |u| u.age == 42 }
|
264
|
+
expect(@users.where(:age => 40)).to 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
|
+
expect(Foo::User).not_to receive(:request)
|
276
|
+
@new_user = Foo::User.build(:fullname => "Tobias Fünke")
|
277
|
+
expect(@new_user.new?).to be_truthy
|
278
|
+
expect(@new_user.fullname).to eq("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
|
+
expect(Foo::User).to receive(:request).once.and_call_original
|
297
|
+
@new_user = Foo::User.build(:fullname => "Tobias Fünke")
|
298
|
+
expect(@new_user.new?).to be_truthy
|
299
|
+
expect(@new_user.fullname).to eq("Tobias Fünke")
|
300
|
+
expect(@new_user.email).to eq("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
|
+
expect(@user.id).to eq(1)
|
323
|
+
expect(@user.fullname).to eq("Tobias Fünke")
|
324
|
+
expect(@user.email).to eq("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
|
+
expect(@user.save).to be_truthy
|
330
|
+
expect(@user.fullname).to eq("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
|
+
expect(@user.save!).to be_truthy
|
336
|
+
expect(@user.fullname).to eq("Tobias Fünke")
|
337
|
+
end
|
338
|
+
|
339
|
+
it "returns false when #save gets errors" do
|
340
|
+
@company = Foo::Company.new
|
341
|
+
expect(@company.save).to 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
|
+
expect(@company.save).to be_falsey
|
352
|
+
expect(@company.name).to eq("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
|
+
expect(@user.fullname).to eq("Tobias Fünke")
|
373
|
+
@user.fullname = "Kittie Sanchez"
|
374
|
+
expect(@user.fullname).to eq("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
|
+
expect(@user.fullname).to eq("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
|
+
expect(@user.fullname).to eq("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
|
+
expect(@user.active).to be_falsey
|
407
|
+
expect(@user).to 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
|
+
expect(@user.active).to be_falsey
|
414
|
+
expect(@user).to 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
|
+
expect(@user.active).to eq(false)
|
431
|
+
expect(@user).to 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
|
+
expect(@user.active).to eq(false)
|
438
|
+
expect(@user).to 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
|
+
expect(user).to be_new
|
466
|
+
expect(user.save).to 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
|
+
expect(user).to be_new
|
479
|
+
expect(user.save).to 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
|
+
expect(user.fullname).to eq('Lindsay Fünke')
|
500
|
+
user.fullname = 'Toby Fünke'
|
501
|
+
user.save
|
502
|
+
expect(user.fullname).to eq('Tobias Fünke')
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|