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/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
|