api_resource 0.6.18 → 0.6.19
Sign up to get free protection for your applications and to get access to all the features.
- 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
|