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/attributes_spec.rb
CHANGED
@@ -7,30 +7,25 @@ describe "Attributes" do
|
|
7
7
|
before(:all) do
|
8
8
|
TestResource.reload_class_attributes
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
after(:all) do
|
12
12
|
TestResource.reload_class_attributes
|
13
13
|
end
|
14
14
|
|
15
15
|
context "setters" do
|
16
16
|
|
17
|
-
it "should allow setting of protected attributes individually" do
|
18
|
-
test_resource = TestResource.new
|
19
|
-
test_resource.protected_attr = 100
|
20
|
-
test_resource.protected_attr.should eql(100)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should not allow mass assignment of protected attributes" do
|
17
|
+
it "should not allow setting of protected attributes individually" do
|
24
18
|
test_resource = TestResource.new
|
25
19
|
lambda{
|
26
|
-
test_resource.
|
27
|
-
}.should raise_error
|
28
|
-
end
|
20
|
+
test_resource.protected_attr = 100
|
21
|
+
}.should raise_error NoMethodError
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
lambda {
|
24
|
+
test_resource.attributes = { protected_attr: 100 }
|
25
|
+
}.should_not raise_error ApiResource::AttributeAccessError
|
26
|
+
|
27
|
+
test_resource = TestResource.new(protected_attr: 100)
|
28
|
+
test_resource.protected_attr.should eql(100)
|
34
29
|
end
|
35
30
|
|
36
31
|
end
|
@@ -42,7 +37,7 @@ describe "Attributes" do
|
|
42
37
|
TestResource.attribute?(:attr1).should be_true
|
43
38
|
TestResource.attribute?(:attr2).should be_true
|
44
39
|
end
|
45
|
-
|
40
|
+
|
46
41
|
|
47
42
|
describe "Determining Attributes, Scopes, and Associations from the server" do
|
48
43
|
|
@@ -51,12 +46,12 @@ describe "Attributes" do
|
|
51
46
|
tst.attribute?(:name).should be_true
|
52
47
|
tst.attribute?(:age).should be_true
|
53
48
|
end
|
54
|
-
|
49
|
+
|
55
50
|
it "should typecast data if a format is specified" do
|
56
51
|
tst = TestResource.new(:bday => Date.today.to_s)
|
57
52
|
tst.bday.should be_a Date
|
58
53
|
end
|
59
|
-
|
54
|
+
|
60
55
|
it "should typecast data if a format is specified" do
|
61
56
|
tst = TestResource.new(:roles => [:role1, :role2])
|
62
57
|
tst.roles.should be_a Array
|
@@ -72,7 +67,7 @@ describe "Attributes" do
|
|
72
67
|
tst.association?(:has_many_objects).should be_true
|
73
68
|
tst.association?(:belongs_to_object).should be_true
|
74
69
|
end
|
75
|
-
|
70
|
+
|
76
71
|
it "should be able to determine scopes when the class loads" do
|
77
72
|
tst = TestResource.new
|
78
73
|
tst.scope?(:paginate).should be_true
|
@@ -92,9 +87,9 @@ describe "Attributes" do
|
|
92
87
|
context "Attributes" do
|
93
88
|
before(:all) do
|
94
89
|
TestResource.define_attributes :attr1, :attr2
|
95
|
-
TestResource.
|
90
|
+
TestResource.define_attributes :attr3, access_level: :protected
|
96
91
|
end
|
97
|
-
|
92
|
+
|
98
93
|
it "should set attributes for the data loaded from a hash" do
|
99
94
|
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2"})
|
100
95
|
tst.attr1?.should be_true
|
@@ -102,14 +97,12 @@ describe "Attributes" do
|
|
102
97
|
tst.attr1 = "test"
|
103
98
|
tst.attr1.should eql("test")
|
104
99
|
end
|
105
|
-
|
106
|
-
it "should
|
107
|
-
|
108
|
-
TestResource.connection.stubs(:get => {:attr1 => "attr1", :attr3 => "attr3"})
|
100
|
+
|
101
|
+
it "should allow access to an unknown attribute through method missing" do
|
102
|
+
TestResource.connection.stubs(:get => {:attr1 => "attr1", :attr5 => "attr5"})
|
109
103
|
tst = TestResource.find(1)
|
110
104
|
|
111
|
-
tst.
|
112
|
-
tst.attr3.should eql("attr3")
|
105
|
+
tst.attr5.should eql("attr5")
|
113
106
|
end
|
114
107
|
end
|
115
108
|
|
@@ -120,7 +113,7 @@ describe "Attributes" do
|
|
120
113
|
tst.respond_to?(:attr1=).should be_true
|
121
114
|
tst.respond_to?(:attr1?).should be_true
|
122
115
|
end
|
123
|
-
|
116
|
+
|
124
117
|
it "should be able to set and change attributes" do
|
125
118
|
TestResource.define_attributes :attr1, :attr2
|
126
119
|
tst = TestResource.new
|
@@ -130,20 +123,20 @@ describe "Attributes" do
|
|
130
123
|
tst.attr1.should eql("test")
|
131
124
|
tst.attr1?.should be_true
|
132
125
|
end
|
133
|
-
|
126
|
+
|
134
127
|
it "should be able to set multiple attributes at once" do
|
135
|
-
TestResource.define_attributes :attr1, :attr2, :
|
128
|
+
TestResource.define_attributes :attr1, :attr2, :attr4
|
136
129
|
tst = TestResource.new
|
137
|
-
tst.
|
138
|
-
|
130
|
+
tst.attr4 = "123"
|
131
|
+
|
139
132
|
tst.attributes = {:attr1 => "abc", :attr2 => "test"}
|
140
133
|
tst.attr1.should eql "abc"
|
141
134
|
tst.attr2.should eql "test"
|
142
|
-
tst.
|
135
|
+
tst.attr4.should eql "123"
|
143
136
|
end
|
144
|
-
|
137
|
+
|
145
138
|
end
|
146
|
-
|
139
|
+
|
147
140
|
context "Dirty tracking" do
|
148
141
|
context "Changes to attributes" do
|
149
142
|
it "should implement dirty tracking for attributes" do
|
@@ -153,57 +146,48 @@ describe "Attributes" do
|
|
153
146
|
tst.attr1 = "Hello"
|
154
147
|
tst.changed.include?("attr1").should be_true
|
155
148
|
tst.changes.should_not be_blank
|
156
|
-
|
149
|
+
|
157
150
|
# Set an attribute equal to itself
|
158
151
|
tst.attr2 = tst.attr2
|
159
152
|
tst.changes.include?("attr2").should be_false
|
160
153
|
end
|
161
154
|
|
162
155
|
end
|
163
|
-
|
156
|
+
|
164
157
|
context "Resetting and marking attributes current" do
|
165
|
-
|
158
|
+
|
166
159
|
before(:each) do
|
167
160
|
TestResource.define_attributes :attr1, :attr2
|
168
161
|
end
|
169
|
-
|
170
|
-
it "should be able to mark any list of attributes as current (unchanged)" do
|
171
|
-
tst = TestResource.new
|
172
|
-
tst.attr1 = "Hello"
|
173
|
-
tst.changed.should_not be_blank
|
174
|
-
tst.set_attributes_as_current :attr1, :attr2
|
175
|
-
tst.changed.should be_blank
|
176
|
-
end
|
177
|
-
|
162
|
+
|
178
163
|
it "should be able to mark all the attributes as current if none are given" do
|
179
164
|
tst = TestResource.new
|
180
165
|
tst.attr1 = "attr1"
|
181
166
|
tst.attr2 = "attr2"
|
182
167
|
tst.changed.should_not be_blank
|
183
|
-
tst.
|
168
|
+
tst.clear_changes
|
184
169
|
tst.changed.should be_blank
|
185
170
|
end
|
186
|
-
|
187
|
-
it "should be able to reset any
|
171
|
+
|
172
|
+
it "should be able to reset any attribute" do
|
188
173
|
tst = TestResource.new
|
189
174
|
tst.attr1 = "attr1"
|
190
|
-
tst.
|
175
|
+
tst.reset_attr1!
|
191
176
|
tst.attr1.should be_nil
|
192
177
|
tst.changed.should be_blank
|
193
178
|
end
|
194
|
-
|
179
|
+
|
195
180
|
it "should be able to reset all the attributes if none are given" do
|
196
181
|
tst = TestResource.new
|
197
182
|
tst.attr1 = "attr1"
|
198
183
|
tst.attr2 = "attr2"
|
199
|
-
|
200
|
-
tst.reset_attribute_changes
|
184
|
+
tst.reset_changes
|
201
185
|
tst.attr1.should be_nil
|
202
186
|
tst.attr2.should be_nil
|
203
187
|
tst.changed.should be_blank
|
204
188
|
end
|
205
189
|
end
|
206
|
-
|
190
|
+
|
207
191
|
end
|
208
|
-
|
192
|
+
|
209
193
|
end
|
data/spec/lib/base_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
include ApiResource
|
5
5
|
|
6
6
|
describe "Base" do
|
7
|
-
|
7
|
+
|
8
8
|
before(:each) do
|
9
9
|
TestResource.reload_resource_definition
|
10
10
|
HasOneObject.reload_resource_definition
|
@@ -14,15 +14,15 @@ describe "Base" do
|
|
14
14
|
|
15
15
|
context ".instantiate_record" do
|
16
16
|
|
17
|
-
context "should handle blank associations and not load them
|
17
|
+
context "should handle blank associations and not load them
|
18
18
|
afterwards" do
|
19
19
|
|
20
20
|
it "belongs_to_remote" do
|
21
21
|
tr = TestResource.instantiate_record(
|
22
|
-
:
|
23
|
-
:
|
22
|
+
name: "X",
|
23
|
+
belongs_to_object: nil
|
24
24
|
)
|
25
|
-
# load our resource definition so we can say we never expect a
|
25
|
+
# load our resource definition so we can say we never expect a
|
26
26
|
# get
|
27
27
|
BelongsToObject.reload_resource_definition
|
28
28
|
BelongsToObject.connection.expects(:get).never
|
@@ -32,10 +32,10 @@ describe "Base" do
|
|
32
32
|
|
33
33
|
it "has_one_remote" do
|
34
34
|
tr = TestResource.instantiate_record(
|
35
|
-
:
|
36
|
-
:
|
35
|
+
name: "X",
|
36
|
+
has_one_object: nil
|
37
37
|
)
|
38
|
-
# load our resource definition so we can say we never expect a
|
38
|
+
# load our resource definition so we can say we never expect a
|
39
39
|
# get
|
40
40
|
HasOneObject.reload_resource_definition
|
41
41
|
HasOneObject.connection.expects(:get).never
|
@@ -45,10 +45,10 @@ describe "Base" do
|
|
45
45
|
|
46
46
|
it "has_many_remote" do
|
47
47
|
tr = TestResource.instantiate_record(
|
48
|
-
:
|
49
|
-
:
|
48
|
+
name: "X",
|
49
|
+
has_many_objects: []
|
50
50
|
)
|
51
|
-
# load our resource definition so we can say we never expect a
|
51
|
+
# load our resource definition so we can say we never expect a
|
52
52
|
# get
|
53
53
|
HasManyObject.reload_resource_definition
|
54
54
|
HasManyObject.connection.expects(:get).never
|
@@ -67,7 +67,7 @@ describe "Base" do
|
|
67
67
|
ErrorResource.new
|
68
68
|
orig_public_attr_names = ErrorResource.public_attribute_names
|
69
69
|
orig_protected_attr_names = ErrorResource.protected_attribute_names
|
70
|
-
|
70
|
+
|
71
71
|
TestResource.new
|
72
72
|
|
73
73
|
ErrorResource.public_attribute_names.should eql(
|
@@ -110,30 +110,6 @@ describe "Base" do
|
|
110
110
|
|
111
111
|
end
|
112
112
|
|
113
|
-
context "#method_missing" do
|
114
|
-
|
115
|
-
after(:all) do
|
116
|
-
TestResource.reload_resource_definition
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should attempt to reload the resource definition if a method
|
120
|
-
is not found" do
|
121
|
-
|
122
|
-
TestResource.class_eval do
|
123
|
-
remove_method :bday
|
124
|
-
end
|
125
|
-
|
126
|
-
tr = TestResource.new
|
127
|
-
|
128
|
-
lambda{
|
129
|
-
tr.bday
|
130
|
-
}.should_not raise_error
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
113
|
context "Prefixes" do
|
138
114
|
|
139
115
|
before(:all) do
|
@@ -146,19 +122,20 @@ describe "Base" do
|
|
146
122
|
|
147
123
|
context "#create" do
|
148
124
|
|
149
|
-
it "should place prefix data in the URL and remove it from
|
125
|
+
it "should place prefix data in the URL and remove it from
|
150
126
|
the parameters" do
|
151
127
|
|
152
128
|
TestResource.connection.expects(:post).with(
|
153
|
-
"/belongs_to_objects/22/test_resources.json",
|
154
|
-
|
155
|
-
|
129
|
+
"/belongs_to_objects/22/test_resources.json",
|
130
|
+
{
|
131
|
+
test_resource: {
|
132
|
+
'name' => 'Dan'
|
156
133
|
}
|
157
|
-
|
134
|
+
},
|
158
135
|
TestResource.headers
|
159
136
|
)
|
160
137
|
|
161
|
-
TestResource.create(:
|
138
|
+
TestResource.create(belongs_to_object_id: 22, name: "Dan")
|
162
139
|
|
163
140
|
end
|
164
141
|
|
@@ -174,10 +151,10 @@ describe "Base" do
|
|
174
151
|
it "should allow grouping by resources with the same id" do
|
175
152
|
|
176
153
|
test_resource_1 = TestResource.new
|
177
|
-
test_resource_1.stubs(:
|
154
|
+
test_resource_1.stubs(id: 1)
|
178
155
|
|
179
156
|
test_resource_2 = TestResource.new
|
180
|
-
test_resource_2.stubs(:
|
157
|
+
test_resource_2.stubs(id: 1)
|
181
158
|
|
182
159
|
|
183
160
|
ParentResource = Struct.new(:resource, :name)
|
@@ -195,22 +172,22 @@ describe "Base" do
|
|
195
172
|
|
196
173
|
end
|
197
174
|
|
198
|
-
|
175
|
+
|
199
176
|
describe "Loading data from a hash" do
|
200
|
-
|
177
|
+
|
201
178
|
|
202
179
|
context ".instantiate_record" do
|
203
180
|
|
204
181
|
it "should set boolean values" do
|
205
182
|
|
206
|
-
tr = TestResource.instantiate_record(:
|
183
|
+
tr = TestResource.instantiate_record(is_active: true)
|
207
184
|
tr.is_active.should eql(true)
|
208
185
|
|
209
186
|
end
|
210
187
|
|
211
188
|
it "should set boolean values" do
|
212
189
|
|
213
|
-
tr = TestResource.instantiate_record(:
|
190
|
+
tr = TestResource.instantiate_record(is_active: false)
|
214
191
|
tr.is_active.should eql(false)
|
215
192
|
|
216
193
|
end
|
@@ -242,105 +219,105 @@ describe "Base" do
|
|
242
219
|
TestResource.has_one :has_one_object
|
243
220
|
TestResource.belongs_to :belongs_to_object
|
244
221
|
end
|
245
|
-
|
222
|
+
|
246
223
|
after(:all) do
|
247
224
|
TestResource.related_objects.each do |key,val|
|
248
225
|
val.clear
|
249
226
|
end
|
250
227
|
end
|
251
|
-
|
228
|
+
|
252
229
|
context "MultiObjectProxy" do
|
253
|
-
|
230
|
+
|
254
231
|
it "should create a MultiObjectProxy for has_many associations" do
|
255
|
-
tst = TestResource.new({:
|
232
|
+
tst = TestResource.new({has_many_objects: []})
|
256
233
|
tst.has_many_objects.should be_a(Associations::MultiObjectProxy)
|
257
234
|
end
|
258
|
-
|
235
|
+
|
259
236
|
it "should throw an error if a has many association is not nil or an array or a hash" do
|
260
|
-
TestResource.new({:
|
237
|
+
TestResource.new({has_many_objects: nil})
|
261
238
|
lambda {
|
262
|
-
TestResource.new({:
|
239
|
+
TestResource.new({has_many_objects: "invalid"})
|
263
240
|
}.should raise_error
|
264
241
|
end
|
265
|
-
|
242
|
+
|
266
243
|
it "should properly load the data from the provided array or hash" do
|
267
244
|
tst = TestResource.new({
|
268
|
-
:
|
245
|
+
has_many_objects: [{service_uri: '/path'}]
|
269
246
|
})
|
270
247
|
tst.has_many_objects.remote_path.should eql('/path')
|
271
248
|
|
272
249
|
tst = TestResource.new({
|
273
|
-
:
|
250
|
+
has_many_objects: {service_uri: '/path'}
|
274
251
|
})
|
275
252
|
tst.has_many_objects.remote_path.should eql('/path')
|
276
253
|
end
|
277
|
-
|
254
|
+
|
278
255
|
end
|
279
|
-
|
256
|
+
|
280
257
|
context "SingleObjectProxy" do
|
281
|
-
|
258
|
+
|
282
259
|
it "should create a SingleObjectProxy for belongs to and has_one associations" do
|
283
|
-
tst = TestResource.new(:
|
260
|
+
tst = TestResource.new(belongs_to_object: {}, has_one_object: {})
|
284
261
|
tst.belongs_to_object.should be_a(Associations::SingleObjectProxy)
|
285
262
|
tst.has_one_object.should be_a(Associations::SingleObjectProxy)
|
286
263
|
end
|
287
|
-
|
288
|
-
it "should throw an error if a belongs_to or
|
264
|
+
|
265
|
+
it "should throw an error if a belongs_to or
|
289
266
|
has_many association is not a hash or nil" do
|
290
267
|
lambda {
|
291
|
-
TestResource.new(:
|
268
|
+
TestResource.new(belongs_to_object: [])
|
292
269
|
}.should raise_error
|
293
270
|
lambda {
|
294
|
-
TestResource.new(:
|
271
|
+
TestResource.new(has_one_object: [])
|
295
272
|
}.should raise_error
|
296
273
|
end
|
297
|
-
|
274
|
+
|
298
275
|
it "should properly load data from the provided hash" do
|
299
276
|
tst = TestResource.new(
|
300
|
-
:
|
301
|
-
:
|
277
|
+
has_one_object: {
|
278
|
+
service_uri: "/path"
|
302
279
|
}
|
303
280
|
)
|
304
281
|
tst.has_one_object.remote_path.should eql('/path')
|
305
282
|
end
|
306
|
-
|
283
|
+
|
307
284
|
end
|
308
285
|
end
|
309
286
|
end
|
310
|
-
|
287
|
+
|
311
288
|
describe "Request parameters and paths" do
|
312
|
-
|
289
|
+
|
313
290
|
after(:each) do
|
314
291
|
TestResource.element_name = TestResource.model_name.element
|
315
292
|
TestResource.collection_name = TestResource.element_name.to_s.pluralize
|
316
293
|
end
|
317
|
-
|
294
|
+
|
318
295
|
it "should set the element name and collection name by default" do
|
319
296
|
TestResource.element_name.should eql("test_resource")
|
320
297
|
TestResource.collection_name.should eql("test_resources")
|
321
298
|
end
|
322
|
-
|
299
|
+
|
323
300
|
it "should inherit element name and collection name from its parent class if using SCI" do
|
324
301
|
ChildTestResource.ancestors.should include TestResource
|
325
302
|
ChildTestResource.collection_name.should eql "test_resources"
|
326
303
|
end
|
327
|
-
|
304
|
+
|
328
305
|
it "should be able to set the element and collection names to anything" do
|
329
306
|
TestResource.element_name = "element"
|
330
307
|
TestResource.collection_name = "elements"
|
331
308
|
TestResource.element_name.should eql("element")
|
332
309
|
TestResource.collection_name.should eql("elements")
|
333
310
|
end
|
334
|
-
|
311
|
+
|
335
312
|
it "should propery generate collection paths and element paths with the new names and the default format json" do
|
336
313
|
TestResource.element_name = "element"
|
337
314
|
TestResource.collection_name = "elements"
|
338
315
|
TestResource.new_element_path.should eql("/elements/new.json")
|
339
316
|
TestResource.collection_path.should eql("/elements.json")
|
340
317
|
TestResource.element_path(1).should eql("/elements/1.json")
|
341
|
-
TestResource.element_path(1, :
|
318
|
+
TestResource.element_path(1, active: true).should eql("/elements/1.json?active=true")
|
342
319
|
end
|
343
|
-
|
320
|
+
|
344
321
|
it "should be able to set the format" do
|
345
322
|
TestResource.format.extension.to_sym.should eql(:json)
|
346
323
|
TestResource.format = :xml
|
@@ -350,18 +327,18 @@ describe "Base" do
|
|
350
327
|
|
351
328
|
it "should only allow proper formats to be set" do
|
352
329
|
expect {TestResource.format = :blah}.to raise_error(::ApiResource::Formats::BadFormat)
|
353
|
-
end
|
354
|
-
|
330
|
+
end
|
331
|
+
|
355
332
|
it "should be able to set an http timeout" do
|
356
333
|
TestResource.timeout = 5
|
357
334
|
TestResource.timeout.should eql(5)
|
358
335
|
TestResource.connection.timeout.should eql(5)
|
359
336
|
end
|
360
|
-
|
337
|
+
|
361
338
|
end
|
362
|
-
|
363
|
-
|
364
|
-
|
339
|
+
|
340
|
+
context 'Serialization' do
|
341
|
+
|
365
342
|
before(:each) do
|
366
343
|
TestResource.reload_resource_definition
|
367
344
|
TestResource.has_many :has_many_objects
|
@@ -372,277 +349,206 @@ describe "Base" do
|
|
372
349
|
after(:all) do
|
373
350
|
TestResource.include_root_in_json = true
|
374
351
|
end
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
352
|
+
|
353
|
+
context "#to_json" do
|
354
|
+
|
379
355
|
it "should be able to serialize itself without the root" do
|
356
|
+
|
380
357
|
TestResource.include_root_in_json = false
|
381
|
-
|
358
|
+
|
359
|
+
tst = TestResource.new({attr1: "attr1", attr2: "attr2"})
|
382
360
|
hash = JSON.parse(tst.to_json)
|
361
|
+
|
383
362
|
hash["attr1"].should eql("attr1")
|
384
363
|
hash["attr2"].should eql("attr2")
|
385
364
|
end
|
386
|
-
|
365
|
+
|
387
366
|
it "should be able to serialize itself with the root" do
|
388
367
|
TestResource.include_root_in_json = true
|
389
|
-
tst = TestResource.new({:
|
368
|
+
tst = TestResource.new({attr1: "attr1", attr2: "attr2"})
|
390
369
|
hash = JSON.parse(tst.to_json)
|
391
370
|
hash["test_resource"].should_not be_nil
|
392
371
|
end
|
393
|
-
|
394
|
-
it "should not include associations by default if
|
395
|
-
they have not changed" do
|
396
|
-
tst = TestResource.new({
|
397
|
-
:attr1 => "attr1",
|
398
|
-
:attr2 => "attr2",
|
399
|
-
:has_many_objects => []
|
400
|
-
})
|
401
|
-
hash = JSON.parse(tst.to_json)
|
402
|
-
hash["has_many_objects"].should be_nil
|
403
|
-
end
|
404
|
-
|
405
|
-
it "should include associations passed given in the include_associations array" do
|
406
|
-
tst = TestResource.new({
|
407
|
-
:attr1 => "attr1",
|
408
|
-
:attr2 => "attr2",
|
409
|
-
:has_many_objects => []
|
410
|
-
})
|
411
|
-
hash = JSON.parse(
|
412
|
-
tst.to_json(
|
413
|
-
:include_associations => [:has_many_objects]
|
414
|
-
)
|
415
|
-
)
|
416
|
-
hash["has_many_objects"].should_not be_nil
|
417
|
-
end
|
418
|
-
|
419
|
-
it "should include associations by default if they have changed" do
|
420
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => []})
|
421
|
-
tst.has_many_objects = [{:name => "test"}]
|
422
|
-
hash = JSON.parse(tst.to_json)
|
423
|
-
hash["has_many_objects"].should_not be_nil
|
424
|
-
end
|
425
|
-
|
426
|
-
it "should not include unknown attributes unless they
|
427
|
-
are passed in via the include_extras array" do
|
428
|
-
|
429
|
-
TestResource.class_eval do
|
430
|
-
define_protected_attributes(:attr3)
|
431
|
-
end
|
432
372
|
|
433
|
-
tst = TestResource.instantiate_record({
|
434
|
-
:attr1 => "attr1",
|
435
|
-
:attr2 => "attr2",
|
436
|
-
:attr3 => "attr3"
|
437
|
-
})
|
438
|
-
|
439
|
-
hash = JSON.parse(tst.to_json)
|
440
|
-
hash["attr3"].should be_nil
|
441
|
-
hash = JSON.parse(tst.to_json(:include_extras => [:attr3]))
|
442
|
-
hash["attr3"].should_not be_nil
|
443
|
-
end
|
444
|
-
|
445
|
-
it "should ignore fields set under the except option" do
|
446
|
-
tst = TestResource.instantiate_record({
|
447
|
-
:attr1 => "attr1",
|
448
|
-
:attr2 => "attr2",
|
449
|
-
:attr3 => "attr3"
|
450
|
-
})
|
451
|
-
hash = JSON.parse(tst.to_json(:except => [:attr1]))
|
452
|
-
hash["attr1"].should be_nil
|
453
|
-
end
|
454
|
-
|
455
|
-
context "Nested Objects" do
|
456
|
-
before(:all) do
|
457
|
-
TestResource.has_many(:has_many_objects)
|
458
|
-
end
|
459
|
-
after(:all) do
|
460
|
-
TestResource.reload_resource_definition
|
461
|
-
end
|
462
|
-
|
463
|
-
it "should include the id of nested objects in the serialization" do
|
464
|
-
tst = TestResource.new({
|
465
|
-
:attr1 => "attr1",
|
466
|
-
:attr2 => "attr2",
|
467
|
-
:has_many_objects => [
|
468
|
-
{:name => "123", :id => "1"}
|
469
|
-
]
|
470
|
-
})
|
471
|
-
tst.has_many_objects.first.id
|
472
|
-
hash = JSON.parse(
|
473
|
-
tst.to_json(:include_associations => [:has_many_objects])
|
474
|
-
)
|
475
|
-
hash["has_many_objects"].first["id"].should_not be_nil
|
476
|
-
end
|
477
|
-
|
478
|
-
it "should include the id of nested objects in the serialization" do
|
479
|
-
tst = TestResource.new({
|
480
|
-
:attr1 => "attr1",
|
481
|
-
:attr2 => "attr2",
|
482
|
-
:has_many_objects => [
|
483
|
-
{:name => "123"}
|
484
|
-
]
|
485
|
-
})
|
486
|
-
hash = JSON.parse(tst.to_json(:include_associations => [:has_many_objects]))
|
487
|
-
hash["has_many_objects"].first.keys.should_not include "id"
|
488
|
-
end
|
489
|
-
end
|
490
373
|
end
|
491
|
-
|
492
|
-
context "
|
493
|
-
|
374
|
+
|
375
|
+
context "#to_xml" do
|
494
376
|
it "should only be able to serialize itself with the root" do
|
495
|
-
tst = TestResource.new({:
|
377
|
+
tst = TestResource.new({attr1: "attr1", attr2: "attr2"})
|
496
378
|
hash = Hash.from_xml(tst.to_xml)
|
497
379
|
hash["test_resource"].should_not be_nil
|
498
380
|
end
|
499
|
-
|
381
|
+
|
500
382
|
it "should properly serialize associations if they are included" do
|
501
383
|
tst = TestResource.new({
|
502
|
-
:
|
384
|
+
has_many_objects: []
|
503
385
|
})
|
504
|
-
hash = Hash.from_xml(
|
386
|
+
hash = Hash.from_xml(
|
387
|
+
tst.to_xml(include_associations: [:has_many_objects])
|
388
|
+
)
|
505
389
|
hash["test_resource"]["has_many_objects"].should eql([])
|
506
390
|
end
|
507
391
|
end
|
508
|
-
|
509
392
|
end
|
510
|
-
|
393
|
+
|
511
394
|
describe "Finding Data" do
|
512
|
-
|
395
|
+
|
513
396
|
before(:all) do
|
514
397
|
TestResource.reload_resource_definition
|
515
398
|
end
|
516
|
-
|
399
|
+
|
517
400
|
it "should be able to find all" do
|
518
401
|
resources = TestResource.find(:all)
|
519
402
|
resources.size.should eql(5)
|
520
403
|
resources.each{|r| r.should be_a TestResource}
|
521
404
|
end
|
522
|
-
|
405
|
+
|
523
406
|
it "should be able to find first or last" do
|
524
407
|
res = TestResource.first
|
525
408
|
res.should be_a TestResource
|
526
409
|
res.name.should_not be_blank
|
527
410
|
res.age.should_not be_blank
|
528
|
-
|
411
|
+
|
529
412
|
res = TestResource.last
|
530
413
|
res.should be_a TestResource
|
531
414
|
res.name.should_not be_blank
|
532
415
|
res.age.should_not be_blank
|
533
416
|
end
|
534
|
-
|
417
|
+
|
535
418
|
it "should be able to find by id" do
|
536
419
|
res = TestResource.find(2)
|
537
420
|
res.should be_a TestResource
|
538
421
|
res.id.to_i.should eql(2)
|
539
422
|
end
|
540
|
-
|
423
|
+
|
541
424
|
end
|
542
|
-
|
425
|
+
|
543
426
|
describe "Saving Data" do
|
544
|
-
|
427
|
+
|
545
428
|
before(:all) do
|
546
429
|
TestResource.include_root_in_json = true
|
547
430
|
TestResource.reload_resource_definition
|
548
431
|
end
|
549
|
-
|
432
|
+
|
550
433
|
context "Creating new records" do
|
551
|
-
|
434
|
+
|
552
435
|
before(:all) do
|
553
436
|
TestResource.has_many :has_many_objects
|
554
437
|
end
|
555
|
-
|
438
|
+
|
556
439
|
it "should be able to post new data via the save method" do
|
557
|
-
tr = TestResource.build({:
|
440
|
+
tr = TestResource.build({name: "Ethan", age: 20})
|
558
441
|
tr.save.should be_true
|
559
442
|
tr.id.should_not be_blank
|
560
443
|
end
|
561
|
-
|
444
|
+
|
562
445
|
context("Override create to return the json") do
|
563
|
-
|
564
|
-
before(:all) do
|
565
|
-
RestClient::Payload.stubs(:has_file? => false)
|
566
|
-
end
|
446
|
+
|
567
447
|
|
568
448
|
it "should be able to include associations when saving if they are specified" do
|
569
449
|
ApiResource::Connection.any_instance.expects(:post).with(
|
570
|
-
"/test_resources.json",
|
571
|
-
|
450
|
+
"/test_resources.json",
|
451
|
+
{
|
452
|
+
test_resource: {
|
453
|
+
'name' => 'Ethan',
|
454
|
+
'age' => 20
|
455
|
+
}
|
456
|
+
},
|
572
457
|
TestResource.headers
|
573
458
|
)
|
574
459
|
|
575
|
-
tr = TestResource.build(:
|
460
|
+
tr = TestResource.build(name: "Ethan", age: 20)
|
576
461
|
tr.save
|
577
462
|
end
|
578
|
-
|
463
|
+
|
579
464
|
|
580
465
|
it "should not include nil attributes when creating by default" do
|
581
466
|
ApiResource::Connection.any_instance.expects(:post).with(
|
582
|
-
"/test_resources.json",
|
583
|
-
|
467
|
+
"/test_resources.json",
|
468
|
+
{
|
469
|
+
test_resource: {
|
470
|
+
'name' => 'Ethan'
|
471
|
+
}
|
472
|
+
},
|
584
473
|
TestResource.headers
|
585
474
|
)
|
586
475
|
|
587
|
-
tr = TestResource.build(:
|
476
|
+
tr = TestResource.build(name: "Ethan")
|
588
477
|
tr.save
|
589
478
|
end
|
590
479
|
|
591
480
|
it "should include false attributes when creating by default" do
|
592
481
|
ApiResource::Connection.any_instance.expects(:post).with(
|
593
|
-
"/test_resources.json",
|
594
|
-
|
482
|
+
"/test_resources.json",
|
483
|
+
{
|
484
|
+
test_resource: {
|
485
|
+
'name' => 'Ethan',
|
486
|
+
'is_active' => false
|
487
|
+
}
|
488
|
+
},
|
595
489
|
TestResource.headers
|
596
490
|
)
|
597
491
|
|
598
|
-
tr = TestResource.build(:
|
492
|
+
tr = TestResource.build(name: "Ethan", is_active: false)
|
599
493
|
tr.save
|
600
494
|
end
|
601
495
|
|
602
496
|
|
603
497
|
it "should not include nil attributes for associated objects when creating by default" do
|
604
498
|
ApiResource::Connection.any_instance.expects(:post).with(
|
605
|
-
"/test_resources.json",
|
606
|
-
|
499
|
+
"/test_resources.json",
|
500
|
+
{
|
501
|
+
test_resource: {
|
502
|
+
'name' => 'Ethan',
|
503
|
+
'has_one_object' => {
|
504
|
+
'size' => 'large'
|
505
|
+
}
|
506
|
+
}
|
507
|
+
},
|
607
508
|
TestResource.headers
|
608
509
|
)
|
609
510
|
|
610
|
-
tr = TestResource.build(:
|
611
|
-
tr.has_one_object = HasOneObject.new(:
|
612
|
-
tr.save(:
|
511
|
+
tr = TestResource.build(name: "Ethan")
|
512
|
+
tr.has_one_object = HasOneObject.new(size: "large", color: nil)
|
513
|
+
tr.save(include_associations: [:has_one_object])
|
613
514
|
end
|
614
|
-
|
515
|
+
|
615
516
|
|
616
517
|
it "should include nil attributes if they are passed in through the include_extras" do
|
617
518
|
ApiResource::Connection.any_instance.expects(:post).with(
|
618
|
-
"/test_resources.json",
|
619
|
-
|
519
|
+
"/test_resources.json",
|
520
|
+
{
|
521
|
+
test_resource: {
|
522
|
+
'name' => 'Ethan',
|
523
|
+
'age' => nil
|
524
|
+
}
|
525
|
+
},
|
620
526
|
TestResource.headers
|
621
527
|
)
|
622
528
|
|
623
|
-
tr = TestResource.build(:
|
624
|
-
tr.save(:
|
529
|
+
tr = TestResource.build(name: "Ethan")
|
530
|
+
tr.save(include_extras: [:age])
|
625
531
|
end
|
626
|
-
|
532
|
+
|
627
533
|
|
628
534
|
it "should include nil attributes when creating if include_nil_attributes_on_create is true" do
|
629
535
|
ApiResource::Connection.any_instance.expects(:post).with(
|
630
|
-
"/test_resources.json",
|
631
|
-
:
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
536
|
+
"/test_resources.json", {
|
537
|
+
test_resource: {
|
538
|
+
'name' => "Ethan",
|
539
|
+
'age' => nil,
|
540
|
+
'is_active' => nil,
|
541
|
+
'belongs_to_object_id' => nil,
|
542
|
+
'custom_name_id' => nil,
|
543
|
+
'bday' => nil,
|
544
|
+
'roles' => []
|
639
545
|
}
|
640
|
-
|
546
|
+
},
|
641
547
|
TestResource.headers
|
642
548
|
)
|
643
549
|
|
644
550
|
TestResource.include_nil_attributes_on_create = true
|
645
|
-
tr = TestResource.build(:
|
551
|
+
tr = TestResource.build(name: "Ethan")
|
646
552
|
tr.save
|
647
553
|
|
648
554
|
#hash['test_resource'].key?('age').should be_true
|
@@ -650,13 +556,12 @@ describe "Base" do
|
|
650
556
|
end
|
651
557
|
end
|
652
558
|
end
|
653
|
-
|
559
|
+
|
654
560
|
context "Updating old records" do
|
655
561
|
before(:all) do
|
656
562
|
TestResource.reload_resource_definition
|
657
563
|
HasOneObject.reload_resource_definition
|
658
564
|
TestResource.has_many :has_many_objects
|
659
|
-
RestClient::Payload.stubs(:has_file? => false)
|
660
565
|
end
|
661
566
|
|
662
567
|
it "should be able to put updated data via the update method and
|
@@ -666,67 +571,67 @@ describe "Base" do
|
|
666
571
|
# put request, but name is not present since it has not changed.
|
667
572
|
|
668
573
|
ApiResource::Connection.any_instance.expects(:put).with(
|
669
|
-
"/test_resources/1.json",
|
670
|
-
|
671
|
-
:
|
672
|
-
|
673
|
-
|
574
|
+
"/test_resources/1.json",
|
575
|
+
{
|
576
|
+
test_resource: {
|
577
|
+
'name' => "Ethan",
|
578
|
+
'age' => 6
|
674
579
|
}
|
675
|
-
}
|
580
|
+
},
|
676
581
|
TestResource.headers
|
677
582
|
)
|
678
583
|
|
679
|
-
tr = TestResource.new(:
|
680
|
-
tr.stubs(:
|
584
|
+
tr = TestResource.new(name: "Ethan")
|
585
|
+
tr.stubs(id: 1)
|
681
586
|
tr.should_not be_new
|
682
|
-
|
587
|
+
|
683
588
|
# Thus we know we are calling update
|
684
589
|
tr.age = 6
|
685
590
|
tr.save
|
686
591
|
end
|
687
|
-
|
592
|
+
|
688
593
|
|
689
594
|
it "should include changed associations without specification" do
|
690
595
|
ApiResource::Connection.any_instance.expects(:put).with(
|
691
|
-
"/test_resources/1.json",
|
692
|
-
|
693
|
-
:
|
694
|
-
|
695
|
-
|
596
|
+
"/test_resources/1.json",
|
597
|
+
{
|
598
|
+
test_resource: {
|
599
|
+
'name' => "Ethan",
|
600
|
+
'has_many_objects' => [{'name' => "Test"}]
|
696
601
|
}
|
697
|
-
}
|
602
|
+
},
|
698
603
|
TestResource.headers
|
699
604
|
)
|
700
605
|
|
701
606
|
tr = TestResource.new(
|
702
|
-
:
|
703
|
-
:
|
607
|
+
name: "Ethan",
|
608
|
+
has_many_objects: [{id: 12, name: "Dan"}]
|
704
609
|
)
|
705
|
-
tr.stubs(:
|
610
|
+
tr.stubs(id: 1)
|
706
611
|
|
707
|
-
tr.has_many_objects = [HasManyObject.new(:
|
612
|
+
tr.has_many_objects = [HasManyObject.new(name: "Test")]
|
708
613
|
tr.save
|
709
614
|
end
|
710
|
-
|
615
|
+
|
711
616
|
|
712
617
|
it "should include unchanged associations if they are specified" do
|
713
618
|
ApiResource::Connection.any_instance.expects(:put).with(
|
714
|
-
"/test_resources/1.json",
|
715
|
-
|
716
|
-
:
|
717
|
-
|
718
|
-
|
619
|
+
"/test_resources/1.json",
|
620
|
+
{
|
621
|
+
test_resource: {
|
622
|
+
'name' => "Ethan",
|
623
|
+
'has_many_objects' => []
|
719
624
|
}
|
720
|
-
}
|
625
|
+
},
|
721
626
|
TestResource.headers
|
722
627
|
)
|
723
628
|
|
724
|
-
tr = TestResource.new(:
|
725
|
-
tr.stubs(:
|
629
|
+
tr = TestResource.new(name: "Ethan", has_many_objects: [])
|
630
|
+
tr.stubs(id: 1)
|
726
631
|
|
727
|
-
tr.save(:
|
632
|
+
tr.save(include_associations: [:has_many_objects])
|
728
633
|
end
|
729
|
-
|
634
|
+
|
730
635
|
|
731
636
|
it "should not include nil attributes of associated objects when updating,
|
732
637
|
unless the attributes have changed to nil" do
|
@@ -734,104 +639,108 @@ describe "Base" do
|
|
734
639
|
correct_order = sequence("ordering")
|
735
640
|
|
736
641
|
ApiResource::Connection.any_instance.expects(:put).with(
|
737
|
-
"/test_resources/1.json",
|
738
|
-
|
739
|
-
:
|
740
|
-
|
741
|
-
|
742
|
-
|
642
|
+
"/test_resources/1.json",
|
643
|
+
{
|
644
|
+
test_resource: {
|
645
|
+
'name' => "Ethan",
|
646
|
+
'has_one_object' => {
|
647
|
+
'size' => "large"
|
743
648
|
}
|
744
649
|
}
|
745
|
-
}
|
650
|
+
},
|
746
651
|
TestResource.headers
|
747
652
|
).in_sequence(correct_order)
|
748
653
|
|
749
|
-
tr = TestResource.new(:
|
750
|
-
tr.stubs(:
|
751
|
-
tr.has_one_object = HasOneObject.new(:
|
752
|
-
tr.save(:
|
654
|
+
tr = TestResource.new(name: "Ethan")
|
655
|
+
tr.stubs(id: 1)
|
656
|
+
tr.has_one_object = HasOneObject.new(size: "large", color: nil)
|
657
|
+
tr.save(include_associations: [:has_one_object])
|
753
658
|
|
754
659
|
|
755
660
|
ApiResource::Connection.any_instance.expects(:put).with(
|
756
|
-
"/test_resources/1.json",
|
757
|
-
|
758
|
-
:
|
759
|
-
|
760
|
-
|
661
|
+
"/test_resources/1.json",
|
662
|
+
{
|
663
|
+
test_resource: {
|
664
|
+
'has_one_object' => {
|
665
|
+
'size' => nil
|
761
666
|
}
|
762
667
|
}
|
763
|
-
}
|
668
|
+
},
|
764
669
|
TestResource.headers
|
765
670
|
).in_sequence(correct_order)
|
766
671
|
|
767
672
|
tr.has_one_object.size = nil
|
768
|
-
tr.save(:
|
673
|
+
tr.save(include_associations: [:has_one_object])
|
769
674
|
end
|
770
675
|
|
771
676
|
|
772
|
-
it "should not include nil values for association objects
|
773
|
-
unless the association has changed to nil" do
|
677
|
+
it "should not include nil values for association objects
|
678
|
+
when updating, unless the association has changed to nil" do
|
774
679
|
|
775
680
|
correct_order = sequence("ordering")
|
776
681
|
|
777
682
|
ApiResource::Connection.any_instance.expects(:put).with(
|
778
|
-
"/test_resources/1.json",
|
779
|
-
|
780
|
-
:
|
781
|
-
|
782
|
-
|
783
|
-
|
683
|
+
"/test_resources/1.json",
|
684
|
+
{
|
685
|
+
test_resource: {
|
686
|
+
'name' => "Ethan",
|
687
|
+
'has_one_object' => {
|
688
|
+
'size' => "large"
|
784
689
|
}
|
785
690
|
}
|
786
|
-
}
|
691
|
+
},
|
787
692
|
TestResource.headers
|
788
693
|
).in_sequence(correct_order)
|
789
694
|
|
790
|
-
tr = TestResource.new(:
|
791
|
-
tr.stubs(:
|
792
|
-
tr.has_one_object = HasOneObject.new(:
|
793
|
-
tr.save(:
|
695
|
+
tr = TestResource.new(name: "Ethan")
|
696
|
+
tr.stubs(id: 1)
|
697
|
+
tr.has_one_object = HasOneObject.new(size: "large", color: nil)
|
698
|
+
tr.save(include_associations: [:has_one_object])
|
794
699
|
|
795
700
|
|
796
701
|
ApiResource::Connection.any_instance.expects(:put).with(
|
797
|
-
"/test_resources/1.json",
|
798
|
-
|
702
|
+
"/test_resources/1.json",
|
703
|
+
{
|
704
|
+
test_resource: {
|
705
|
+
'has_one_object' => nil
|
706
|
+
}
|
707
|
+
},
|
799
708
|
TestResource.headers
|
800
709
|
).in_sequence(correct_order)
|
801
710
|
|
802
711
|
tr.has_one_object = nil
|
803
|
-
tr.save(:
|
712
|
+
tr.save(include_associations: [:has_one_object])
|
804
713
|
end
|
805
714
|
|
806
715
|
|
807
|
-
it "should include all attributes if include_all_attributes_on_update is true" do
|
808
|
-
|
716
|
+
it "should include all attributes if include_all_attributes_on_update is true" do
|
717
|
+
|
809
718
|
ApiResource::Connection.any_instance.expects(:put).with(
|
810
|
-
"/test_resources/1.json",
|
811
|
-
:
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
719
|
+
"/test_resources/1.json",{
|
720
|
+
test_resource: {
|
721
|
+
'name' => "Ethan",
|
722
|
+
'age' => nil,
|
723
|
+
'is_active' => nil,
|
724
|
+
'belongs_to_object_id' => nil,
|
725
|
+
'custom_name_id' => nil,
|
726
|
+
'bday' => nil,
|
727
|
+
'roles' => []
|
819
728
|
}
|
820
|
-
|
729
|
+
},
|
821
730
|
TestResource.headers
|
822
731
|
)
|
823
732
|
begin
|
824
733
|
TestResource.include_all_attributes_on_update = true
|
825
|
-
tr = TestResource.new(:
|
826
|
-
tr.stubs(:
|
734
|
+
tr = TestResource.new(name: "Ethan")
|
735
|
+
tr.stubs(id: 1)
|
827
736
|
tr.save
|
828
|
-
ensure
|
737
|
+
ensure
|
829
738
|
TestResource.include_all_attributes_on_update = false
|
830
739
|
end
|
831
740
|
end
|
832
|
-
|
741
|
+
|
833
742
|
it "should provide an update_attributes method to set attrs and save" do
|
834
|
-
|
743
|
+
|
835
744
|
correct_order = sequence("ordering")
|
836
745
|
|
837
746
|
# initial save
|
@@ -840,22 +749,22 @@ describe "Base" do
|
|
840
749
|
|
841
750
|
ApiResource::Connection.any_instance.expects(:put)
|
842
751
|
.with(
|
843
|
-
"/test_resources/1.json",
|
844
|
-
{:
|
752
|
+
"/test_resources/1.json",
|
753
|
+
{test_resource: {'name' => "Dan"}},
|
845
754
|
TestResource.headers
|
846
755
|
).in_sequence(correct_order)
|
847
756
|
|
848
|
-
tr = TestResource.new(:
|
849
|
-
tr.stubs(:
|
757
|
+
tr = TestResource.new(name: "Ethan")
|
758
|
+
tr.stubs(id: 1)
|
850
759
|
tr.save
|
851
760
|
|
852
|
-
tr.update_attributes(:
|
761
|
+
tr.update_attributes(name: "Dan")
|
853
762
|
end
|
854
|
-
|
855
763
|
|
856
|
-
|
764
|
+
|
765
|
+
it "should include nil attributes when updating if they have
|
857
766
|
changed by default" do
|
858
|
-
|
767
|
+
|
859
768
|
correct_order = sequence("ordering")
|
860
769
|
|
861
770
|
# initial save
|
@@ -864,19 +773,19 @@ describe "Base" do
|
|
864
773
|
|
865
774
|
ApiResource::Connection.any_instance.expects(:put)
|
866
775
|
.with(
|
867
|
-
"/test_resources/1.json",
|
868
|
-
{:
|
776
|
+
"/test_resources/1.json",
|
777
|
+
{test_resource: {"is_active" => nil}},
|
869
778
|
TestResource.headers
|
870
779
|
)
|
871
780
|
.in_sequence(correct_order)
|
872
781
|
|
873
782
|
tr = TestResource.new(
|
874
|
-
:
|
783
|
+
name: "Ethan", is_active: false
|
875
784
|
)
|
876
|
-
tr.stubs(:
|
785
|
+
tr.stubs(id: 1)
|
877
786
|
tr.save
|
878
787
|
|
879
|
-
tr.update_attributes(:
|
788
|
+
tr.update_attributes(is_active: nil)
|
880
789
|
end
|
881
790
|
|
882
791
|
it "should include attributes that have changed to false by default" do
|
@@ -889,58 +798,58 @@ describe "Base" do
|
|
889
798
|
# update
|
890
799
|
ApiResource::Connection.any_instance.expects(:put)
|
891
800
|
.with(
|
892
|
-
"/test_resources/1.json",
|
893
|
-
{:
|
801
|
+
"/test_resources/1.json",
|
802
|
+
{test_resource: {"is_active" => false}},
|
894
803
|
TestResource.headers
|
895
804
|
).in_sequence(correct_order)
|
896
805
|
|
897
806
|
tr = TestResource.new(
|
898
|
-
:
|
807
|
+
name: "Ethan", is_active: true
|
899
808
|
)
|
900
|
-
tr.stubs(:
|
809
|
+
tr.stubs(id: 1)
|
901
810
|
tr.save
|
902
811
|
|
903
|
-
tr.update_attributes(:
|
812
|
+
tr.update_attributes(is_active: false)
|
904
813
|
|
905
814
|
end
|
906
|
-
|
815
|
+
|
907
816
|
end
|
908
|
-
|
817
|
+
|
909
818
|
end
|
910
|
-
|
819
|
+
|
911
820
|
describe "Deleting data" do
|
912
821
|
it "should be able to delete an id from the class method" do
|
913
822
|
TestResource.delete(1).should be_true
|
914
823
|
end
|
915
|
-
|
824
|
+
|
916
825
|
it "should be able to destroy itself as an instance" do
|
917
|
-
tr = TestResource.new(:
|
918
|
-
tr.stubs(:
|
826
|
+
tr = TestResource.new(name: "Ethan")
|
827
|
+
tr.stubs(id: 1)
|
919
828
|
|
920
829
|
tr.destroy.should be_true
|
921
830
|
end
|
922
831
|
end
|
923
|
-
|
832
|
+
|
924
833
|
describe "Random methods" do
|
925
834
|
|
926
|
-
before(:
|
835
|
+
before(:each) {
|
836
|
+
TestResource.reload_resource_definition
|
927
837
|
HasOneObject.reload_resource_definition
|
928
|
-
HasManyObject.
|
929
|
-
|
930
|
-
|
838
|
+
HasManyObject.reload_resource_definition
|
839
|
+
}
|
840
|
+
|
931
841
|
it "should know if it is persisted" do
|
932
|
-
tr = TestResource.new(:
|
933
|
-
tr.stubs(:
|
842
|
+
tr = TestResource.new(name: "Ethan")
|
843
|
+
tr.stubs(id: 1)
|
934
844
|
|
935
845
|
tr.persisted?.should be_true
|
936
846
|
|
937
|
-
tr = TestResource.new(:
|
847
|
+
tr = TestResource.new(name: "Ethan")
|
938
848
|
tr.persisted?.should be_false
|
939
849
|
end
|
940
850
|
|
941
851
|
it "should know how to reload attributes" do
|
942
852
|
tr = TestResource.find(1)
|
943
|
-
|
944
853
|
tr.age = 47
|
945
854
|
tr.name = "Ethan"
|
946
855
|
|
@@ -952,7 +861,6 @@ describe "Base" do
|
|
952
861
|
|
953
862
|
it "should know how to reload associations" do
|
954
863
|
tr = TestResource.find(1)
|
955
|
-
|
956
864
|
tr.has_one_object.size = "small"
|
957
865
|
tr.has_many_objects.first.name = "Ethan"
|
958
866
|
|
@@ -964,29 +872,29 @@ describe "Base" do
|
|
964
872
|
tr.has_one_object.size.should eql "large"
|
965
873
|
tr.has_many_objects.first.name.should eql "name"
|
966
874
|
end
|
967
|
-
|
875
|
+
|
968
876
|
end
|
969
|
-
|
877
|
+
|
970
878
|
describe "Inheritable Accessors" do
|
971
|
-
|
879
|
+
|
972
880
|
it "should copy the default values down to any level of subclass" do
|
973
|
-
|
881
|
+
|
974
882
|
class Child < TestResource
|
975
883
|
end
|
976
|
-
|
884
|
+
|
977
885
|
Child.site.should eql(TestResource.site)
|
978
886
|
Child.site.should_not be_blank
|
979
887
|
end
|
980
|
-
|
888
|
+
|
981
889
|
end
|
982
|
-
|
890
|
+
|
983
891
|
describe "Inflections" do
|
984
|
-
|
892
|
+
|
985
893
|
it "should be able to singularize and pluralize words ending in ess" do
|
986
894
|
"address".singularize.should eql("address")
|
987
895
|
"address".pluralize.should eql("addresses")
|
988
896
|
end
|
989
|
-
|
897
|
+
|
990
898
|
end
|
991
899
|
|
992
900
|
context ".get" do
|
@@ -1001,25 +909,25 @@ describe "Base" do
|
|
1001
909
|
Object.send(:remove_const, :Rails)
|
1002
910
|
end
|
1003
911
|
example.run
|
1004
|
-
ensure
|
912
|
+
ensure
|
1005
913
|
ApiResource::Base.ttl = initial
|
1006
914
|
end
|
1007
915
|
|
1008
916
|
end
|
1009
917
|
|
1010
918
|
it "should implement caching using the ttl setting" do
|
1011
|
-
cache = mock(:
|
1012
|
-
ApiResource.stubs(:
|
919
|
+
cache = mock(fetch: {id: 123, name: "Dan"})
|
920
|
+
ApiResource.stubs(cache: cache)
|
1013
921
|
TestResource.find(123)
|
1014
922
|
end
|
1015
|
-
|
923
|
+
|
1016
924
|
it "should find with expires_in and cache" do
|
1017
925
|
ApiResource.cache.expects(:fetch)
|
1018
|
-
.with(anything, :
|
1019
|
-
.returns({:
|
1020
|
-
|
1021
|
-
res = TestResource.find("adfa", :
|
1022
|
-
|
926
|
+
.with(anything, expires_in: 10.0)
|
927
|
+
.returns({id: 2, name: "d"})
|
928
|
+
|
929
|
+
res = TestResource.find("adfa", expires_in: 10)
|
930
|
+
|
1023
931
|
ApiResource::Base.ttl.should eql(1)
|
1024
932
|
res.id.to_i.should eql(2)
|
1025
933
|
end
|
@@ -1046,5 +954,5 @@ describe "Base" do
|
|
1046
954
|
end
|
1047
955
|
|
1048
956
|
|
1049
|
-
|
957
|
+
|
1050
958
|
end
|