her 0.3.1 → 0.3.2
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.
- data/README.md +4 -1
- data/Rakefile +2 -2
- data/her.gemspec +2 -2
- data/lib/her/model.rb +2 -4
- data/lib/her/model/hooks.rb +10 -7
- data/lib/her/model/http.rb +14 -2
- data/lib/her/model/introspection.rb +27 -27
- data/lib/her/model/orm.rb +132 -80
- data/lib/her/model/paths.rb +58 -46
- data/lib/her/model/relationships.rb +36 -18
- data/lib/her/version.rb +1 -1
- data/spec/middleware/accept_json_spec.rb +2 -2
- data/spec/middleware/first_level_parse_json_spec.rb +4 -4
- data/spec/middleware/second_level_parse_json_spec.rb +4 -4
- data/spec/model/hooks_spec.rb +43 -32
- data/spec/model/http_spec.rb +82 -34
- data/spec/model/introspection_spec.rb +8 -8
- data/spec/model/orm_spec.rb +172 -0
- data/spec/model/paths_spec.rb +116 -16
- data/spec/model/relationships_spec.rb +28 -3
- data/spec/spec_helper.rb +2 -1
- metadata +8 -8
@@ -21,31 +21,31 @@ describe Her::Model::Introspection do
|
|
21
21
|
describe "#inspect" do
|
22
22
|
it "outputs resource attributs for an existing resource" do # {{{
|
23
23
|
@user = Foo::User.find(1)
|
24
|
-
["#<Foo::User(
|
24
|
+
["#<Foo::User(users/1) name=\"Tobias Funke\" id=1>", "#<Foo::User(users/1) id=1 name=\"Tobias Funke\">"].should include(@user.inspect)
|
25
25
|
end # }}}
|
26
26
|
|
27
27
|
it "outputs resource attributs for an not-saved-yet resource" do # {{{
|
28
28
|
@user = Foo::User.new(:name => "Tobias Funke")
|
29
|
-
@user.inspect.should == "#<Foo::User(
|
29
|
+
@user.inspect.should == "#<Foo::User(users) name=\"Tobias Funke\">"
|
30
30
|
end # }}}
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "#nearby_class" do
|
35
|
-
context "for a class inside of a module" do
|
36
|
-
before do
|
35
|
+
context "for a class inside of a module" do # {{{
|
36
|
+
before do # {{{
|
37
37
|
spawn_model "Foo::User"
|
38
38
|
spawn_model "Foo::AccessRecord"
|
39
39
|
spawn_model "AccessRecord"
|
40
40
|
spawn_model "Log"
|
41
|
-
end
|
41
|
+
end # }}}
|
42
42
|
|
43
|
-
it "returns a sibling class, if found" do
|
43
|
+
it "returns a sibling class, if found" do # {{{
|
44
44
|
Foo::User.nearby_class("AccessRecord").should == Foo::AccessRecord
|
45
45
|
AccessRecord.nearby_class("Log").should == Log
|
46
46
|
Foo::User.nearby_class("Log").should == Log
|
47
47
|
Foo::User.nearby_class("X").should be_nil
|
48
|
-
end
|
49
|
-
end
|
48
|
+
end # }}}
|
49
|
+
end # }}}
|
50
50
|
end
|
51
51
|
end
|
data/spec/model/orm_spec.rb
CHANGED
@@ -59,6 +59,27 @@ describe Her::Model::ORM do
|
|
59
59
|
@new_user = Foo::User.new
|
60
60
|
expect { @new_user.fullname = "Tobias Fünke" }.to_not raise_error(NoMethodError)
|
61
61
|
end# }}}
|
62
|
+
|
63
|
+
it "handles method missing for query" do#{{{
|
64
|
+
@new_user = Foo::User.new
|
65
|
+
expect { @new_user.fullname? }.to_not raise_error(NoMethodError)
|
66
|
+
end# }}}
|
67
|
+
|
68
|
+
it "handles respond_to for getter" do#{{{
|
69
|
+
@new_user = Foo::User.new(:fullname => 'Mayonegg')
|
70
|
+
@new_user.should_not respond_to(:unknown_method_for_a_user)
|
71
|
+
@new_user.should respond_to(:fullname)
|
72
|
+
end#}}}
|
73
|
+
|
74
|
+
it "handles respond_to for setter" do#{{{
|
75
|
+
@new_user = Foo::User.new
|
76
|
+
@new_user.should respond_to(:fullname=)
|
77
|
+
end#}}}
|
78
|
+
|
79
|
+
it "handles respond_to for query" do#{{{
|
80
|
+
@new_user = Foo::User.new
|
81
|
+
@new_user.should respond_to(:fullname?)
|
82
|
+
end#}}}
|
62
83
|
end
|
63
84
|
|
64
85
|
context "mapping data, metadata and error data to Ruby objects" do
|
@@ -155,6 +176,59 @@ describe Her::Model::ORM do
|
|
155
176
|
end # }}}
|
156
177
|
end
|
157
178
|
|
179
|
+
context "finding resources" do
|
180
|
+
before do # {{{
|
181
|
+
api = Her::API.new
|
182
|
+
api.setup :url => "https://api.example.com" do |builder|
|
183
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
184
|
+
builder.use Faraday::Request::UrlEncoded
|
185
|
+
builder.adapter :test do |stub|
|
186
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
|
187
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 2, :age => 34 }.to_json] }
|
188
|
+
stub.get("/users?age=42") { |env| [200, {}, [{ :id => 1, :age => 42 }].to_json] }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
spawn_model :User do
|
193
|
+
uses_api api
|
194
|
+
end
|
195
|
+
end # }}}
|
196
|
+
|
197
|
+
it "handles finding by a single id" do # {{{
|
198
|
+
@user = User.find(1)
|
199
|
+
@user.id.should == 1
|
200
|
+
end # }}}
|
201
|
+
|
202
|
+
it "handles finding by multiple ids" do # {{{
|
203
|
+
@users = User.find(1, 2)
|
204
|
+
@users.should be_kind_of(Array)
|
205
|
+
@users.length.should == 2
|
206
|
+
@users[0].id.should == 1
|
207
|
+
@users[1].id.should == 2
|
208
|
+
end # }}}
|
209
|
+
|
210
|
+
it "handles finding by an array of ids" do
|
211
|
+
@users = User.find([1, 2])
|
212
|
+
@users.should be_kind_of(Array)
|
213
|
+
@users.length.should == 2
|
214
|
+
@users[0].id.should == 1
|
215
|
+
@users[1].id.should == 2
|
216
|
+
end
|
217
|
+
|
218
|
+
it "handles finding by an array of ids of length 1" do
|
219
|
+
@users = User.find([1])
|
220
|
+
@users.should be_kind_of(Array)
|
221
|
+
@users.length.should == 1
|
222
|
+
@users[0].id.should == 1
|
223
|
+
end
|
224
|
+
|
225
|
+
it "handles finding with other parameters" do # {{{
|
226
|
+
@users = User.all(:age => 42)
|
227
|
+
@users.should be_kind_of(Array)
|
228
|
+
@users.should be_all { |u| u.age == 42 }
|
229
|
+
end # }}}
|
230
|
+
end
|
231
|
+
|
158
232
|
context "creating resources" do
|
159
233
|
before do # {{{
|
160
234
|
Her::API.setup :url => "https://api.example.com" do |builder|
|
@@ -240,4 +314,102 @@ describe Her::Model::ORM do
|
|
240
314
|
@user.active.should be_false
|
241
315
|
end # }}}
|
242
316
|
end
|
317
|
+
|
318
|
+
context "saving resources with overridden to_params" do
|
319
|
+
before do # {{{
|
320
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
321
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
322
|
+
builder.use Faraday::Request::UrlEncoded
|
323
|
+
builder.adapter :test do |stub|
|
324
|
+
stub.post("/users") do |env|
|
325
|
+
body = {
|
326
|
+
:id => 1,
|
327
|
+
:fullname => Faraday::Utils.parse_query(env[:body])['fullname']
|
328
|
+
}.to_json
|
329
|
+
[200, {}, body]
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end # }}}
|
333
|
+
|
334
|
+
spawn_model "Foo::User" do
|
335
|
+
def to_params
|
336
|
+
{ :fullname => "Lindsay Fünke" }
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end # }}}
|
340
|
+
|
341
|
+
it "changes the request parameters for one-line resource creation" do # {{{
|
342
|
+
@user = Foo::User.create(:fullname => "Tobias Fünke")
|
343
|
+
@user.fullname.should == "Lindsay Fünke"
|
344
|
+
end # }}}
|
345
|
+
|
346
|
+
it "changes the request parameters for Model.new + #save" do # {{{
|
347
|
+
@user = Foo::User.new(:fullname => "Tobias Fünke")
|
348
|
+
@user.save
|
349
|
+
@user.fullname.should == "Lindsay Fünke"
|
350
|
+
end # }}}
|
351
|
+
end
|
352
|
+
|
353
|
+
context "checking resource equality" do
|
354
|
+
before do # {{{
|
355
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
356
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
357
|
+
builder.use Faraday::Request::UrlEncoded
|
358
|
+
builder.adapter :test do |stub|
|
359
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
360
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
361
|
+
stub.get("/admins/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
spawn_model "Foo::User"
|
366
|
+
spawn_model "Foo::Admin"
|
367
|
+
end # }}}
|
368
|
+
|
369
|
+
let(:user) { Foo::User.find(1) }
|
370
|
+
|
371
|
+
it "returns true for the exact same object" do # {{{
|
372
|
+
user.should == user
|
373
|
+
end # }}}
|
374
|
+
|
375
|
+
it "returns true for the same resource via find" do # {{{
|
376
|
+
user.should == Foo::User.find(1)
|
377
|
+
end # }}}
|
378
|
+
|
379
|
+
it "returns true for the same class with identical data" do # {{{
|
380
|
+
user.should == Foo::User.new(:id => 1, :fullname => "Lindsay Fünke")
|
381
|
+
end # }}}
|
382
|
+
|
383
|
+
it "returns true for a different resource with the same data" do # {{{
|
384
|
+
user.should == Foo::Admin.find(1)
|
385
|
+
end # }}}
|
386
|
+
|
387
|
+
it "returns false for the same class with different data" do # {{{
|
388
|
+
user.should_not == Foo::User.new(:id => 2, :fullname => "Tobias Fünke")
|
389
|
+
end # }}}
|
390
|
+
|
391
|
+
it "returns false for a non-resource with the same data" do # {{{
|
392
|
+
fake_user = stub(:data => { :id => 1, :fullname => "Lindsay Fünke" })
|
393
|
+
user.should_not == fake_user
|
394
|
+
end # }}}
|
395
|
+
|
396
|
+
it "delegates eql? to ==" do # {{{
|
397
|
+
other = Object.new
|
398
|
+
user.expects(:==).with(other).returns(true)
|
399
|
+
user.eql?(other).should be_true
|
400
|
+
end # }}}
|
401
|
+
|
402
|
+
it "treats equal resources as equal for Array#uniq" do # {{{
|
403
|
+
user2 = Foo::User.find(1)
|
404
|
+
[user, user2].uniq.should == [user]
|
405
|
+
end # }}}
|
406
|
+
|
407
|
+
it "treats equal resources as equal for hash keys" do # {{{
|
408
|
+
Foo::User.find(1)
|
409
|
+
hash = { user => true }
|
410
|
+
hash[Foo::User.find(1)] = false
|
411
|
+
hash.size.should == 1
|
412
|
+
hash.should == { user => false }
|
413
|
+
end # }}}
|
414
|
+
end
|
243
415
|
end
|
data/spec/model/paths_spec.rb
CHANGED
@@ -10,8 +10,8 @@ describe Her::Model::Paths do
|
|
10
10
|
|
11
11
|
describe "#build_request_path" do
|
12
12
|
it "builds paths with defaults" do # {{{
|
13
|
-
Foo::User.build_request_path(:id => "foo").should == "
|
14
|
-
Foo::User.build_request_path.should == "
|
13
|
+
Foo::User.build_request_path(:id => "foo").should == "users/foo"
|
14
|
+
Foo::User.build_request_path.should == "users"
|
15
15
|
end # }}}
|
16
16
|
|
17
17
|
it "builds paths with custom collection path" do # {{{
|
@@ -20,16 +20,42 @@ describe Her::Model::Paths do
|
|
20
20
|
Foo::User.build_request_path.should == "/utilisateurs"
|
21
21
|
end # }}}
|
22
22
|
|
23
|
+
it "builds paths with custom relative collection path" do # {{{
|
24
|
+
Foo::User.collection_path "utilisateurs"
|
25
|
+
Foo::User.build_request_path(:id => "foo").should == "utilisateurs/foo"
|
26
|
+
Foo::User.build_request_path.should == "utilisateurs"
|
27
|
+
end # }}}
|
28
|
+
|
23
29
|
it "builds paths with custom collection path with multiple variables" do # {{{
|
24
30
|
Foo::User.collection_path "/organizations/:organization_id/utilisateurs"
|
31
|
+
|
25
32
|
Foo::User.build_request_path(:id => "foo", :_organization_id => "acme").should == "/organizations/acme/utilisateurs/foo"
|
26
33
|
Foo::User.build_request_path(:_organization_id => "acme").should == "/organizations/acme/utilisateurs"
|
34
|
+
|
35
|
+
Foo::User.build_request_path(:id => "foo", :organization_id => "acme").should == "/organizations/acme/utilisateurs/foo"
|
36
|
+
Foo::User.build_request_path(:organization_id => "acme").should == "/organizations/acme/utilisateurs"
|
37
|
+
end # }}}
|
38
|
+
|
39
|
+
it "builds paths with custom relative collection path with multiple variables" do # {{{
|
40
|
+
Foo::User.collection_path "organizations/:organization_id/utilisateurs"
|
41
|
+
|
42
|
+
Foo::User.build_request_path(:id => "foo", :_organization_id => "acme").should == "organizations/acme/utilisateurs/foo"
|
43
|
+
Foo::User.build_request_path(:_organization_id => "acme").should == "organizations/acme/utilisateurs"
|
44
|
+
|
45
|
+
Foo::User.build_request_path(:id => "foo", :organization_id => "acme").should == "organizations/acme/utilisateurs/foo"
|
46
|
+
Foo::User.build_request_path(:organization_id => "acme").should == "organizations/acme/utilisateurs"
|
27
47
|
end # }}}
|
28
48
|
|
29
49
|
it "builds paths with custom item path" do # {{{
|
30
50
|
Foo::User.resource_path "/utilisateurs/:id"
|
31
51
|
Foo::User.build_request_path(:id => "foo").should == "/utilisateurs/foo"
|
32
|
-
Foo::User.build_request_path.should == "
|
52
|
+
Foo::User.build_request_path.should == "users"
|
53
|
+
end # }}}
|
54
|
+
|
55
|
+
it "builds paths with custom relative item path" do # {{{
|
56
|
+
Foo::User.resource_path "utilisateurs/:id"
|
57
|
+
Foo::User.build_request_path(:id => "foo").should == "utilisateurs/foo"
|
58
|
+
Foo::User.build_request_path.should == "users"
|
33
59
|
end # }}}
|
34
60
|
|
35
61
|
it "raises exceptions when building a path without required custom variables" do # {{{
|
@@ -46,8 +72,8 @@ describe Her::Model::Paths do
|
|
46
72
|
|
47
73
|
describe "#build_request_path" do
|
48
74
|
it "builds paths with defaults" do # {{{
|
49
|
-
Foo::AdminUser.build_request_path(:id => "foo").should == "
|
50
|
-
Foo::AdminUser.build_request_path.should == "
|
75
|
+
Foo::AdminUser.build_request_path(:id => "foo").should == "admin_users/foo"
|
76
|
+
Foo::AdminUser.build_request_path.should == "admin_users"
|
51
77
|
end # }}}
|
52
78
|
|
53
79
|
it "builds paths with custom collection path" do # {{{
|
@@ -56,22 +82,45 @@ describe Her::Model::Paths do
|
|
56
82
|
Foo::AdminUser.build_request_path.should == "/users"
|
57
83
|
end # }}}
|
58
84
|
|
85
|
+
it "builds paths with custom relative collection path" do # {{{
|
86
|
+
Foo::AdminUser.collection_path "users"
|
87
|
+
Foo::AdminUser.build_request_path(:id => "foo").should == "users/foo"
|
88
|
+
Foo::AdminUser.build_request_path.should == "users"
|
89
|
+
end # }}}
|
90
|
+
|
59
91
|
it "builds paths with custom collection path with multiple variables" do # {{{
|
60
92
|
Foo::AdminUser.collection_path "/organizations/:organization_id/users"
|
61
93
|
Foo::AdminUser.build_request_path(:id => "foo", :_organization_id => "acme").should == "/organizations/acme/users/foo"
|
62
94
|
Foo::AdminUser.build_request_path(:_organization_id => "acme").should == "/organizations/acme/users"
|
63
95
|
end # }}}
|
64
96
|
|
97
|
+
it "builds paths with custom relative collection path with multiple variables" do # {{{
|
98
|
+
Foo::AdminUser.collection_path "organizations/:organization_id/users"
|
99
|
+
Foo::AdminUser.build_request_path(:id => "foo", :_organization_id => "acme").should == "organizations/acme/users/foo"
|
100
|
+
Foo::AdminUser.build_request_path(:_organization_id => "acme").should == "organizations/acme/users"
|
101
|
+
end # }}}
|
102
|
+
|
65
103
|
it "builds paths with custom item path" do # {{{
|
66
104
|
Foo::AdminUser.resource_path "/users/:id"
|
67
105
|
Foo::AdminUser.build_request_path(:id => "foo").should == "/users/foo"
|
68
|
-
Foo::AdminUser.build_request_path.should == "
|
106
|
+
Foo::AdminUser.build_request_path.should == "admin_users"
|
107
|
+
end # }}}
|
108
|
+
|
109
|
+
it "builds paths with custom relative item path" do # {{{
|
110
|
+
Foo::AdminUser.resource_path "users/:id"
|
111
|
+
Foo::AdminUser.build_request_path(:id => "foo").should == "users/foo"
|
112
|
+
Foo::AdminUser.build_request_path.should == "admin_users"
|
69
113
|
end # }}}
|
70
114
|
|
71
115
|
it "raises exceptions when building a path without required custom variables" do # {{{
|
72
116
|
Foo::AdminUser.collection_path "/organizations/:organization_id/users"
|
73
117
|
expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError)
|
74
118
|
end # }}}
|
119
|
+
|
120
|
+
it "raises exceptions when building a relative path without required custom variables" do # {{{
|
121
|
+
Foo::AdminUser.collection_path "organizations/:organization_id/users"
|
122
|
+
expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError)
|
123
|
+
end # }}}
|
75
124
|
end
|
76
125
|
end
|
77
126
|
|
@@ -82,29 +131,29 @@ describe Her::Model::Paths do
|
|
82
131
|
|
83
132
|
describe "#build_request_path" do
|
84
133
|
it "builds paths with defaults" do # {{{
|
85
|
-
Foo::User.build_request_path(:id => "foo").should == "
|
86
|
-
Foo::User.build_request_path.should == "
|
134
|
+
Foo::User.build_request_path(:id => "foo").should == "users/foo"
|
135
|
+
Foo::User.build_request_path.should == "users"
|
87
136
|
end # }}}
|
88
137
|
end
|
89
138
|
end
|
90
139
|
end
|
91
140
|
|
92
|
-
context "making HTTP requests" do
|
141
|
+
context "making subdomain HTTP requests" do
|
93
142
|
before do # {{{
|
94
|
-
Her::API.setup :url => "https://api.example.com" do |builder|
|
143
|
+
Her::API.setup :url => "https://api.example.com/" do |builder|
|
95
144
|
builder.use Her::Middleware::FirstLevelParseJSON
|
96
145
|
builder.use Faraday::Request::UrlEncoded
|
97
146
|
builder.adapter :test do |stub|
|
98
|
-
stub.get("
|
99
|
-
stub.post("
|
100
|
-
stub.put("
|
101
|
-
stub.get("
|
102
|
-
stub.delete("
|
147
|
+
stub.get("organizations/2/users") { |env| [200, {}, [{ :id => 1, :fullname => "Tobias Fünke", :organization_id => 2 }, { :id => 2, :fullname => "Lindsay Fünke", :organization_id => 2 }].to_json] }
|
148
|
+
stub.post("organizations/2/users") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :organization_id => 2 }.to_json] }
|
149
|
+
stub.put("organizations/2/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :organization_id => 2 }.to_json] }
|
150
|
+
stub.get("organizations/2/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :organization_id => 2, :active => true }.to_json] }
|
151
|
+
stub.delete("organizations/2/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :organization_id => 2, :active => false }.to_json] }
|
103
152
|
end
|
104
153
|
end
|
105
154
|
|
106
155
|
spawn_model "Foo::User" do
|
107
|
-
collection_path "
|
156
|
+
collection_path "organizations/:organization_id/users"
|
108
157
|
end
|
109
158
|
end # }}}
|
110
159
|
|
@@ -182,4 +231,55 @@ describe Her::Model::Paths do
|
|
182
231
|
end # }}}
|
183
232
|
end
|
184
233
|
end
|
234
|
+
|
235
|
+
context "making path HTTP requests" do
|
236
|
+
before do # {{{
|
237
|
+
Her::API.setup :url => "https://example.com/api/" do |builder|
|
238
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
239
|
+
builder.use Faraday::Request::UrlEncoded
|
240
|
+
builder.adapter :test do |stub|
|
241
|
+
stub.get("/api/organizations/2/users") { |env| [200, {}, [{ :id => 1, :fullname => "Tobias Fünke", :organization_id => 2 }, { :id => 2, :fullname => "Lindsay Fünke", :organization_id => 2 }].to_json] }
|
242
|
+
stub.get("/api/organizations/2/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :organization_id => 2, :active => true }.to_json] }
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
spawn_model "Foo::User" do
|
247
|
+
collection_path "organizations/:organization_id/users"
|
248
|
+
end
|
249
|
+
end # }}}
|
250
|
+
|
251
|
+
describe "fetching a resource" do
|
252
|
+
it "maps a single resource to a Ruby object" do # {{{
|
253
|
+
@user = Foo::User.find(1, :_organization_id => 2)
|
254
|
+
@user.id.should == 1
|
255
|
+
@user.fullname.should == "Tobias Fünke"
|
256
|
+
end # }}}
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "fetching a collection" do
|
260
|
+
it "maps a collection of resources to an array of Ruby objects" do # {{{
|
261
|
+
@users = Foo::User.all(:_organization_id => 2)
|
262
|
+
@users.length.should == 2
|
263
|
+
@users.first.fullname.should == "Tobias Fünke"
|
264
|
+
end # }}}
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "fetching a resource with absolute path" do
|
268
|
+
it "maps a single resource to a Ruby object" do # {{{
|
269
|
+
Foo::User.resource_path '/api/' + Foo::User.resource_path
|
270
|
+
@user = Foo::User.find(1, :_organization_id => 2)
|
271
|
+
@user.id.should == 1
|
272
|
+
@user.fullname.should == "Tobias Fünke"
|
273
|
+
end # }}}
|
274
|
+
end
|
275
|
+
|
276
|
+
describe "fetching a collection with absolute path" do
|
277
|
+
it "maps a collection of resources to an array of Ruby objects" do # {{{
|
278
|
+
Foo::User.collection_path '/api/' + Foo::User.collection_path
|
279
|
+
@users = Foo::User.all(:_organization_id => 2)
|
280
|
+
@users.length.should == 2
|
281
|
+
@users.first.fullname.should == "Tobias Fünke"
|
282
|
+
end # }}}
|
283
|
+
end
|
284
|
+
end
|
185
285
|
end
|
@@ -60,6 +60,16 @@ describe Her::Model::Relationships do
|
|
60
60
|
Foo::User.belongs_to :organization, :class_name => "Business", :foreign_key => "org_id"
|
61
61
|
Foo::User.relationships[:belongs_to].should == [{ :name => :organization, :class_name => "Business", :foreign_key => "org_id", :path => "/organizations/:id" }]
|
62
62
|
end # }}}
|
63
|
+
|
64
|
+
context "inheriting relationships from a superclass" do
|
65
|
+
it "copies relationships to the subclass" do # {{{
|
66
|
+
Foo::User.has_many :comments, :class_name => "Post"
|
67
|
+
subclass = Class.new(Foo::User)
|
68
|
+
subclass.relationships.object_id.should_not == Foo::User.relationships.object_id
|
69
|
+
subclass.relationships[:has_many].length.should == 1
|
70
|
+
subclass.relationships[:has_many].first[:class_name].should == "Post"
|
71
|
+
end # }}}
|
72
|
+
end
|
63
73
|
end
|
64
74
|
|
65
75
|
context "handling relationships without details" do
|
@@ -69,10 +79,13 @@ describe Her::Model::Relationships do
|
|
69
79
|
builder.use Faraday::Request::UrlEncoded
|
70
80
|
builder.adapter :test do |stub|
|
71
81
|
stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!" }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak" }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 }.to_json] }
|
72
|
-
stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id =>
|
82
|
+
stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id => 2 }.to_json] }
|
83
|
+
stub.get("/users/1/comments") { |env| [200, {}, [{ :id => 4, :body => "They're having a FIRESALE?" }].to_json] }
|
73
84
|
stub.get("/users/2/comments") { |env| [200, {}, [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }].to_json] }
|
74
85
|
stub.get("/users/2/role") { |env| [200, {}, { :id => 2, :body => "User" }.to_json] }
|
75
|
-
stub.get("/
|
86
|
+
stub.get("/users/1/role") { |env| [200, {}, { :id => 3, :body => "User" }.to_json] }
|
87
|
+
stub.get("/organizations/1") { |env| [200, {}, { :id => 1, :name => "Bluth Company Foo" }.to_json] }
|
88
|
+
stub.get("/organizations/2") { |env| [200, {}, { :id => 2, :name => "Bluth Company" }.to_json] }
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
@@ -104,6 +117,10 @@ describe Her::Model::Relationships do
|
|
104
117
|
@user_without_included_data.comments.first.body.should == "They're having a FIRESALE?"
|
105
118
|
end # }}}
|
106
119
|
|
120
|
+
it "fetches has_many data even if it was included, only if called with parameters" do # {{{
|
121
|
+
@user_with_included_data.comments(:foo_id => 1).length.should == 1
|
122
|
+
end # }}}
|
123
|
+
|
107
124
|
it "maps an array of included data through has_one" do # {{{
|
108
125
|
@user_with_included_data.role.should be_a(Foo::Role)
|
109
126
|
@user_with_included_data.role.id.should == 1
|
@@ -116,6 +133,10 @@ describe Her::Model::Relationships do
|
|
116
133
|
@user_without_included_data.role.body.should == "User"
|
117
134
|
end # }}}
|
118
135
|
|
136
|
+
it "fetches has_one data even if it was included, only if called with parameters" do # {{{
|
137
|
+
@user_with_included_data.role(:foo_id => 2).id.should == 3
|
138
|
+
end # }}}
|
139
|
+
|
119
140
|
it "maps an array of included data through belongs_to" do # {{{
|
120
141
|
@user_with_included_data.organization.should be_a(Foo::Organization)
|
121
142
|
@user_with_included_data.organization.id.should == 1
|
@@ -124,9 +145,13 @@ describe Her::Model::Relationships do
|
|
124
145
|
|
125
146
|
it "fetches data that was not included through belongs_to" do # {{{
|
126
147
|
@user_without_included_data.organization.should be_a(Foo::Organization)
|
127
|
-
@user_without_included_data.organization.id.should ==
|
148
|
+
@user_without_included_data.organization.id.should == 2
|
128
149
|
@user_without_included_data.organization.name.should == "Bluth Company"
|
129
150
|
end # }}}
|
151
|
+
|
152
|
+
it "fetches belongs_to data even if it was included, only if called with parameters" do # {{{
|
153
|
+
@user_with_included_data.organization(:foo_id => 1).name.should == "Bluth Company Foo"
|
154
|
+
end # }}}
|
130
155
|
end
|
131
156
|
|
132
157
|
context "handling relationships with details" do
|