api_resource 0.6.18 → 0.6.19
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 +4 -4
- data/Gemfile.lock +4 -8
- data/Guardfile +5 -17
- data/api_resource.gemspec +4 -7
- data/lib/api_resource.rb +20 -19
- data/lib/api_resource/associations.rb +39 -23
- data/lib/api_resource/associations/association_proxy.rb +14 -13
- data/lib/api_resource/attributes.rb +555 -156
- data/lib/api_resource/base.rb +376 -305
- data/lib/api_resource/connection.rb +22 -12
- data/lib/api_resource/finders.rb +17 -18
- data/lib/api_resource/finders/single_finder.rb +1 -1
- data/lib/api_resource/mocks.rb +37 -31
- data/lib/api_resource/scopes.rb +70 -12
- data/lib/api_resource/serializer.rb +264 -0
- data/lib/api_resource/typecast.rb +13 -2
- data/lib/api_resource/typecasters/unknown_typecaster.rb +33 -0
- data/lib/api_resource/version.rb +1 -1
- data/spec/lib/associations/has_many_remote_object_proxy_spec.rb +3 -3
- data/spec/lib/associations_spec.rb +49 -94
- data/spec/lib/attributes_spec.rb +40 -56
- data/spec/lib/base_spec.rb +290 -382
- data/spec/lib/callbacks_spec.rb +6 -6
- data/spec/lib/connection_spec.rb +20 -20
- data/spec/lib/finders_spec.rb +14 -0
- data/spec/lib/mocks_spec.rb +9 -9
- data/spec/lib/prefixes_spec.rb +4 -5
- data/spec/lib/scopes_spec.rb +98 -0
- data/spec/lib/serializer_spec.rb +156 -0
- data/spec/spec_helper.rb +1 -4
- data/spec/support/test_resource.rb +1 -1
- metadata +14 -38
- data/spec/tmp/DIR +0 -0
data/spec/lib/callbacks_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe "Should put callbacks around save, create, update, and destroy by defau
|
|
15
15
|
before_create :bc_cb; after_create :ac_cb
|
16
16
|
before_update :bu_cb; after_update :au_cb
|
17
17
|
before_destroy :bd_cb; after_destroy :ad_cb
|
18
|
-
|
18
|
+
|
19
19
|
def bs_cb
|
20
20
|
@s_val = 1
|
21
21
|
end
|
@@ -42,7 +42,7 @@ describe "Should put callbacks around save, create, update, and destroy by defau
|
|
42
42
|
end
|
43
43
|
EOE
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "should fire save and create callbacks when saving a new record" do
|
47
47
|
tr = TestResource.new(:name => "Ethan", :age => 20)
|
48
48
|
tr.save.should be_true
|
@@ -50,7 +50,7 @@ describe "Should put callbacks around save, create, update, and destroy by defau
|
|
50
50
|
tr.c_val.should eql(2)
|
51
51
|
tr.u_val.should be_nil
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it "should fire save and update callbacks when updating a record" do
|
55
55
|
tr = TestResource.new(:name => "Ethan", :age => 20)
|
56
56
|
tr.stubs(:id => 1)
|
@@ -61,13 +61,13 @@ describe "Should put callbacks around save, create, update, and destroy by defau
|
|
61
61
|
tr.c_val.should be_nil
|
62
62
|
tr.u_val.should eql(2)
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
it "should only fire destroy callbacks when destroying a record" do
|
66
66
|
tr = TestResource.new(:name => "Ethan", :age => 20)
|
67
67
|
tr.stubs(:id => 1)
|
68
68
|
tr.destroy.should be_true
|
69
69
|
tr.d_val.should eql(2)
|
70
|
-
tr.s_val.should be_nil
|
70
|
+
tr.s_val.should be_nil
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
end
|
data/spec/lib/connection_spec.rb
CHANGED
@@ -3,21 +3,21 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
include ApiResource
|
4
4
|
|
5
5
|
describe Connection do
|
6
|
-
|
6
|
+
|
7
7
|
it "should be able to set the token directly on ApiResource" do
|
8
8
|
ApiResource.token = "123"
|
9
9
|
ApiResource::Base.token.should eql "123"
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "should be able to set a default token value, which is passed through each request" do
|
13
|
-
ApiResource::Mocks::Connection.expects(:get).with("/test_resources/1.json", {"Accept"=>"application/json", "Lifebooker-Token" => "abc"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
13
|
+
ApiResource::Mocks::Connection.expects(:get).with("/test_resources/1.json", {}, {"Accept"=>"application/json", "Lifebooker-Token" => "abc"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
14
14
|
ApiResource::Base.token = "abc"
|
15
15
|
TestResource.find(1)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should set the Lifebooker-Token if one is present for GET requests" do
|
19
19
|
token = Kernel.rand(100000).to_s
|
20
|
-
ApiResource::Mocks::Connection.expects(:get).with("/test_resources/1.json", {"Accept"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
20
|
+
ApiResource::Mocks::Connection.expects(:get).with("/test_resources/1.json", {}, {"Accept"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
21
21
|
|
22
22
|
ApiResource::Base.token = token
|
23
23
|
|
@@ -44,7 +44,7 @@ describe Connection do
|
|
44
44
|
|
45
45
|
it "should set the Lifebooker-Token if one is present for POST requests" do
|
46
46
|
token = Kernel.rand(100000).to_s
|
47
|
-
ApiResource::Mocks::Connection.expects(:post).with("/test_resources/1.json", {}, {"Content-Type"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
47
|
+
ApiResource::Mocks::Connection.expects(:post).with("/test_resources/1.json", '{}', {"Content-Type"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
48
48
|
|
49
49
|
ApiResource::Base.token = token
|
50
50
|
|
@@ -53,7 +53,7 @@ describe Connection do
|
|
53
53
|
|
54
54
|
it "should set the Lifebooker-Token if one is present for PUT requests" do
|
55
55
|
token = Kernel.rand(100000).to_s
|
56
|
-
ApiResource::Mocks::Connection.expects(:put).with("/test_resources/1.json", {}, {"Content-Type"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
56
|
+
ApiResource::Mocks::Connection.expects(:put).with("/test_resources/1.json", '{}', {"Content-Type"=>"application/json", 'Lifebooker-Token' => "#{token}"}).returns(ApiResource::Mocks::MockResponse.new({}))
|
57
57
|
|
58
58
|
ApiResource::Base.token = token
|
59
59
|
|
@@ -75,7 +75,7 @@ describe Connection do
|
|
75
75
|
TestResource.connection.headers.include?("Lifebooker-Token").should eql true
|
76
76
|
TestResource.connection.headers["Lifebooker-Token"] = token
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it "should be able to set a token for a given block" do
|
80
80
|
ApiResource::Base.token = "123456"
|
81
81
|
begin
|
@@ -88,14 +88,14 @@ describe Connection do
|
|
88
88
|
end
|
89
89
|
ApiResource::Base.token.should eql "123456"
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
it "should provider a method to regenerate its connection" do
|
93
93
|
conn = ApiResource::Base.connection
|
94
94
|
conn.should be ApiResource::Base.connection
|
95
95
|
ApiResource.reset_connection
|
96
96
|
conn.should_not be ApiResource::Base.connection
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
context "No Mocks" do
|
100
100
|
before(:all) do
|
101
101
|
ApiResource::Mocks.remove
|
@@ -111,25 +111,25 @@ describe Connection do
|
|
111
111
|
ApiResource.open_timeout = 1
|
112
112
|
ApiResource.open_timeout.should eql 1
|
113
113
|
|
114
|
-
ApiResource::Base.connection.send(:http
|
115
|
-
ApiResource::Base.connection.send(:http
|
116
|
-
|
114
|
+
ApiResource::Base.connection.send(:http).receive_timeout.should eql 1
|
115
|
+
ApiResource::Base.connection.send(:http).connect_timeout.should eql 1
|
116
|
+
|
117
117
|
ApiResource.timeout = 100
|
118
|
-
ApiResource::Base.connection.send(:http
|
118
|
+
ApiResource::Base.connection.send(:http).receive_timeout.should eql 100
|
119
119
|
|
120
120
|
end
|
121
|
-
|
122
|
-
it "should time out if
|
123
|
-
|
121
|
+
|
122
|
+
it "should time out if HttpClient takes too long" do
|
123
|
+
|
124
124
|
# hopefully google won't actually respond this fast :)
|
125
125
|
ApiResource.timeout = 0.001
|
126
126
|
ApiResource::Base.site = "http://www.google.com"
|
127
127
|
lambda{
|
128
128
|
ApiResource::Base.connection.get("/")
|
129
129
|
}.should raise_error(ApiResource::RequestTimeout)
|
130
|
-
|
130
|
+
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
end
|
134
134
|
|
135
135
|
context "headers" do
|
@@ -150,7 +150,7 @@ describe Connection do
|
|
150
150
|
end
|
151
151
|
|
152
152
|
end
|
153
|
-
|
154
153
|
|
155
|
-
|
154
|
+
|
155
|
+
|
156
156
|
end
|
data/spec/lib/finders_spec.rb
CHANGED
@@ -79,6 +79,20 @@ describe ApiResource::Finders do
|
|
79
79
|
TestResource.includes(:has_many_objects).find(1)
|
80
80
|
end
|
81
81
|
|
82
|
+
it "should be able to chain find on top of an includes call and a scope" do
|
83
|
+
TestResource.connection.expects(:get).with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns({"id" => 1, "has_many_object_ids" => [1,2]})
|
84
|
+
HasManyObject.connection.expects(:get).with("/has_many_objects.json?ids%5B%5D=1&ids%5B%5D=2").returns([])
|
85
|
+
|
86
|
+
TestResource.includes(:has_many_objects).birthday(5).find(1)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should disregard condition order" do
|
90
|
+
TestResource.connection.expects(:get).with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns({"id" => 1, "has_many_object_ids" => [1,2]})
|
91
|
+
HasManyObject.connection.expects(:get).with("/has_many_objects.json?ids%5B%5D=1&ids%5B%5D=2").returns([])
|
92
|
+
|
93
|
+
TestResource.birthday(5).includes(:has_many_objects).find(1)
|
94
|
+
end
|
95
|
+
|
82
96
|
it "should be able to use a scope with arguments" do
|
83
97
|
TestResource.connection.expects(:get)
|
84
98
|
.with("/test_resources.json?active=true&birthday%5Bdate%5D=5").returns([{"id" => 10}])
|
data/spec/lib/mocks_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
include ApiResource
|
5
5
|
|
6
6
|
describe Mocks do
|
7
|
-
|
7
|
+
|
8
8
|
# we set up the mocks in spec helper, so we can just assert this
|
9
9
|
it "should hijack the connection" do
|
10
10
|
ApiResource::Mocks::Interface.any_instance.expects(:get).once.returns(
|
@@ -12,29 +12,29 @@ describe Mocks do
|
|
12
12
|
)
|
13
13
|
TestResource.reload_class_attributes
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "should allow the user to raise errors for invalid responsed" do
|
17
|
-
old_err_status = ApiResource.raise_missing_definition_error
|
17
|
+
old_err_status = ApiResource.raise_missing_definition_error
|
18
18
|
ApiResource::Base.raise_missing_definition_error = true
|
19
|
-
|
19
|
+
|
20
20
|
lambda {
|
21
21
|
class MyNewInvalidResource < ApiResource::Base; end
|
22
|
-
MyNewInvalidResource.new
|
22
|
+
MyNewInvalidResource.new
|
23
23
|
}.should raise_error(ApiResource::ResourceNotFound)
|
24
|
-
|
24
|
+
|
25
25
|
ApiResource.raise_missing_definition_error = old_err_status
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should merge params for a request" do
|
29
29
|
resp = ApiResource::Base.connection.get(
|
30
|
-
"/mock_with_block/1?#{{:test => "abc"}.to_query}"
|
30
|
+
"/mock_with_block/1.json?#{{:test => "abc"}.to_query}"
|
31
31
|
)
|
32
32
|
resp["id"].should eql "1"
|
33
33
|
resp["test"].should eql "abc"
|
34
34
|
end
|
35
35
|
|
36
36
|
context "Mock Request" do
|
37
|
-
context "Initialize" do
|
37
|
+
context "Initialize" do
|
38
38
|
it "should correctly assign blank params" do
|
39
39
|
request = ApiResource::Mocks::MockRequest.new(:get, "/authenticate.json?token=")
|
40
40
|
request.params.should eql({"token" => ""})
|
@@ -70,5 +70,5 @@ describe Mocks do
|
|
70
70
|
|
71
71
|
end
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
end
|
data/spec/lib/prefixes_spec.rb
CHANGED
@@ -36,8 +36,8 @@ describe "With Prefixes" do
|
|
36
36
|
it "should use the prefix to create a new record" do
|
37
37
|
prefix_model.send(:connection).expects(:post)
|
38
38
|
.with(
|
39
|
-
"/foreign/123/prefix_models.json",
|
40
|
-
|
39
|
+
"/foreign/123/prefix_models.json",
|
40
|
+
has_entry(:prefix_model, has_entry('name', 'test')),
|
41
41
|
instance_of(Hash)
|
42
42
|
)
|
43
43
|
prefix_model.save
|
@@ -90,9 +90,8 @@ describe "With Prefixes" do
|
|
90
90
|
prefix_model.name = "changed name"
|
91
91
|
prefix_model.send(:connection).expects(:put)
|
92
92
|
.with(
|
93
|
-
|
94
|
-
|
95
|
-
{"prefix_model" => {"name" => "changed name"}}.to_json,
|
93
|
+
"/foreign/123/prefix_models/456.json",
|
94
|
+
has_entry(:prefix_model, has_entry('name', 'changed name')),
|
96
95
|
instance_of(Hash)
|
97
96
|
)
|
98
97
|
prefix_model.save
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApiResource::Scopes do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
ScopeResource.class_eval do
|
7
|
+
scope :no_arg, {}
|
8
|
+
scope :one_arg, {id: :req}
|
9
|
+
scope :one_array_arg, {ids: :req}
|
10
|
+
scope :two_args, {page: :req, per_page: :req}
|
11
|
+
scope :opt_args, {arg1: :opt}
|
12
|
+
scope :req_and_opt_args, {arg1: :req, arg2: :opt}
|
13
|
+
scope :var_args, {ids: :rest}
|
14
|
+
scope :mix_args, {id: :req, vararg: :rest}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "Constructing arguments" do
|
19
|
+
|
20
|
+
it "should be able to query scopes on the current model" do
|
21
|
+
ScopeResource.no_arg.to_query.should eql(
|
22
|
+
"no_arg=true"
|
23
|
+
)
|
24
|
+
ScopeResource.one_arg(5).to_query.should eql(
|
25
|
+
"one_arg[id]=5"
|
26
|
+
)
|
27
|
+
ScopeResource.one_array_arg([3, 5]).to_query.should eql(
|
28
|
+
"one_array_arg[ids][]=3&one_array_arg[ids][]=5"
|
29
|
+
)
|
30
|
+
ScopeResource.two_args(1, 20).to_query.should eql(
|
31
|
+
"two_args[page]=1&two_args[per_page]=20"
|
32
|
+
)
|
33
|
+
$DEB = true
|
34
|
+
ScopeResource.opt_args.to_query.should eql(
|
35
|
+
"opt_args=true"
|
36
|
+
)
|
37
|
+
ScopeResource.opt_args(3).to_query.should eql(
|
38
|
+
"opt_args[arg1]=3"
|
39
|
+
)
|
40
|
+
ScopeResource.var_args(1, 2).to_query.should eql(
|
41
|
+
"var_args[ids][]=1&var_args[ids][]=2"
|
42
|
+
)
|
43
|
+
args = ["a", {opt1: 1}, {opt2: 2}]
|
44
|
+
ScopeResource.mix_args(*args).to_query.should eql(
|
45
|
+
"mix_args[id]=a&mix_args[vararg][][opt1]=1&mix_args[vararg][][opt2]=2"
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#add_scopes' do
|
51
|
+
|
52
|
+
it 'applies static scopes' do
|
53
|
+
ScopeResource.expects(:no_arg).returns(ScopeResource)
|
54
|
+
ScopeResource.add_scopes(no_arg: 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'applies scopes with one argument' do
|
58
|
+
ScopeResource.expects(:one_arg).with(5).returns(ScopeResource)
|
59
|
+
ScopeResource.add_scopes(one_arg: {id: 5})
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'applies scopes with an array argument' do
|
63
|
+
ScopeResource.expects(:one_array_arg).with([5]).returns(ScopeResource)
|
64
|
+
ScopeResource.add_scopes(one_array_arg: {ids: [5]})
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'applies scopes with two arguments' do
|
68
|
+
ScopeResource.expects(:two_args).with(7,9).returns(ScopeResource)
|
69
|
+
ScopeResource.add_scopes(two_args: {page: 7, per_page: 9})
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'applies scopes with optional arguments when those arguments are supplied' do
|
73
|
+
ScopeResource.expects(:opt_args).with(5).returns(ScopeResource)
|
74
|
+
ScopeResource.add_scopes(opt_args: {arg1: 5})
|
75
|
+
end
|
76
|
+
|
77
|
+
it "doesn't apply scopes with only optional arguments when there are no supplied args" do
|
78
|
+
ScopeResource.expects(:opt_args).never
|
79
|
+
ScopeResource.add_scopes(opt_args: {})
|
80
|
+
end
|
81
|
+
|
82
|
+
it "applies scopes that have both optional and required args with only the required args if the optional args are not passed in" do
|
83
|
+
ScopeResource.expects(:req_and_opt_args).with(5).returns(ScopeResource)
|
84
|
+
ScopeResource.add_scopes(req_and_opt_args: {arg1: 5})
|
85
|
+
end
|
86
|
+
|
87
|
+
it "applies scopes with variable arg lists" do
|
88
|
+
ScopeResource.expects(:var_args).with([5,6,7]).returns(ScopeResource)
|
89
|
+
ScopeResource.add_scopes(var_args: {ids: [5,6,7]})
|
90
|
+
end
|
91
|
+
|
92
|
+
it "applies scopes with mixed arg lists" do
|
93
|
+
ScopeResource.expects(:mix_args).with(4,[5,6,7]).returns(ScopeResource)
|
94
|
+
ScopeResource.add_scopes(mix_args: {id: 4, vararg: [5,6,7]})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ApiResource
|
4
|
+
|
5
|
+
describe Serializer do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
TestResource.reload_resource_definition
|
9
|
+
TestResource.has_many :has_many_objects
|
10
|
+
TestResource.define_attributes :attr1, :attr2
|
11
|
+
TestResource.include_root_in_json = false
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
TestResource.include_root_in_json = true
|
16
|
+
end
|
17
|
+
|
18
|
+
subject {
|
19
|
+
Serializer.new(instance)
|
20
|
+
}
|
21
|
+
|
22
|
+
let(:instance){
|
23
|
+
TestResource.new({
|
24
|
+
attr1: "attr1",
|
25
|
+
attr2: "attr2",
|
26
|
+
has_many_objects: []
|
27
|
+
})
|
28
|
+
}
|
29
|
+
|
30
|
+
context "#to_hash" do
|
31
|
+
|
32
|
+
it 'includes attributes' do
|
33
|
+
|
34
|
+
subject.to_hash["attr1"].should_not be_nil
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not include associations by default if
|
39
|
+
they have not changed" do
|
40
|
+
|
41
|
+
subject.to_hash["has_many_objects"].should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should include associations passed given in the include_associations array" do
|
45
|
+
|
46
|
+
subject = Serializer.new(
|
47
|
+
instance,
|
48
|
+
include_associations: [:has_many_objects]
|
49
|
+
)
|
50
|
+
|
51
|
+
subject.to_hash["has_many_objects"].should_not be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should include associations by default if they have changed" do
|
55
|
+
instance.has_many_objects = [{name: "test"}]
|
56
|
+
hash = subject.to_hash
|
57
|
+
hash["has_many_objects"].should_not be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not include unknown attributes unless they
|
61
|
+
are passed in via the include_extras array" do
|
62
|
+
|
63
|
+
TestResource.class_eval do
|
64
|
+
define_attributes :attr3, access_level: :protected
|
65
|
+
end
|
66
|
+
|
67
|
+
instance = TestResource.instantiate_record({
|
68
|
+
attr1: "attr1",
|
69
|
+
attr2: "attr2",
|
70
|
+
attr3: "attr3"
|
71
|
+
})
|
72
|
+
|
73
|
+
subject = Serializer.new(instance)
|
74
|
+
subject.to_hash["attr3"].should be_nil
|
75
|
+
|
76
|
+
subject = Serializer.new(instance, include_extras: [:attr3])
|
77
|
+
subject.to_hash["attr3"].should_not be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should ignore fields set under the except option" do
|
81
|
+
tst = TestResource.new({
|
82
|
+
attr1: "attr1",
|
83
|
+
attr2: "attr2"
|
84
|
+
})
|
85
|
+
hash = JSON.parse(tst.to_json(except: [:attr1]))
|
86
|
+
hash["attr1"].should be_nil
|
87
|
+
hash["attr2"].should be_present
|
88
|
+
end
|
89
|
+
|
90
|
+
context "Nested Objects" do
|
91
|
+
|
92
|
+
before(:all) do
|
93
|
+
TestResource.has_many(:has_many_objects)
|
94
|
+
end
|
95
|
+
|
96
|
+
after(:all) do
|
97
|
+
TestResource.reload_resource_definition
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should include the id of nested objects in the serialization" do
|
101
|
+
instance.has_many_objects = [
|
102
|
+
{name: "123", id: "1"}
|
103
|
+
]
|
104
|
+
subject = Serializer.new(
|
105
|
+
instance,
|
106
|
+
include_associations: [:has_many_objects]
|
107
|
+
)
|
108
|
+
subject.to_hash["has_many_objects"].first["id"].should_not be_nil
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should exclude include the id of new nested objects in the
|
112
|
+
serialization" do
|
113
|
+
instance.has_many_objects = [
|
114
|
+
{name: "123"}
|
115
|
+
]
|
116
|
+
subject = Serializer.new(
|
117
|
+
instance,
|
118
|
+
include_associations: [:has_many_objects]
|
119
|
+
)
|
120
|
+
object_hash = subject.to_hash["has_many_objects"].first
|
121
|
+
object_hash.keys.should_not include "id"
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'Foreign keys' do
|
127
|
+
|
128
|
+
context 'Prefixed' do
|
129
|
+
|
130
|
+
before(:all) do
|
131
|
+
TestResource.prefix =
|
132
|
+
"/belongs_to_objects/:belongs_to_object_id/"
|
133
|
+
end
|
134
|
+
|
135
|
+
after(:all) do
|
136
|
+
TestResource.prefix = "/"
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'excludes the foreign key when it is nested in the prefix' do
|
140
|
+
instance.belongs_to_object_id = 123
|
141
|
+
subject.to_hash["belongs_to_object_id"].should be_blank
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should include the foreign_key_id when saving" do
|
147
|
+
instance.stubs(:id => 123)
|
148
|
+
instance.has_many_object_ids = [4]
|
149
|
+
subject.to_hash[:has_many_object_ids].should eql([4])
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|