api_resource 0.4.0 → 0.4.1
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.
- metadata +179 -123
- data/.document +0 -5
- data/.rspec +0 -5
- data/.travis.yml +0 -4
- data/Gemfile +0 -37
- data/Gemfile.lock +0 -190
- data/Guardfile +0 -27
- data/Rakefile +0 -49
- data/VERSION +0 -1
- data/api_resource.gemspec +0 -180
- data/lib/api_resource.rb +0 -130
- data/lib/api_resource/association_activation.rb +0 -19
- data/lib/api_resource/associations.rb +0 -218
- data/lib/api_resource/associations/association_proxy.rb +0 -116
- data/lib/api_resource/associations/belongs_to_remote_object_proxy.rb +0 -16
- data/lib/api_resource/associations/dynamic_resource_scope.rb +0 -23
- data/lib/api_resource/associations/generic_scope.rb +0 -68
- data/lib/api_resource/associations/has_many_remote_object_proxy.rb +0 -16
- data/lib/api_resource/associations/has_many_through_remote_object_proxy.rb +0 -13
- data/lib/api_resource/associations/has_one_remote_object_proxy.rb +0 -24
- data/lib/api_resource/associations/multi_argument_resource_scope.rb +0 -15
- data/lib/api_resource/associations/multi_object_proxy.rb +0 -84
- data/lib/api_resource/associations/related_object_hash.rb +0 -12
- data/lib/api_resource/associations/relation_scope.rb +0 -25
- data/lib/api_resource/associations/resource_scope.rb +0 -32
- data/lib/api_resource/associations/scope.rb +0 -132
- data/lib/api_resource/associations/single_object_proxy.rb +0 -82
- data/lib/api_resource/attributes.rb +0 -243
- data/lib/api_resource/base.rb +0 -717
- data/lib/api_resource/callbacks.rb +0 -45
- data/lib/api_resource/connection.rb +0 -195
- data/lib/api_resource/core_extensions.rb +0 -7
- data/lib/api_resource/custom_methods.rb +0 -117
- data/lib/api_resource/decorators.rb +0 -6
- data/lib/api_resource/decorators/caching_decorator.rb +0 -20
- data/lib/api_resource/exceptions.rb +0 -99
- data/lib/api_resource/formats.rb +0 -22
- data/lib/api_resource/formats/json_format.rb +0 -25
- data/lib/api_resource/formats/xml_format.rb +0 -36
- data/lib/api_resource/local.rb +0 -12
- data/lib/api_resource/log_subscriber.rb +0 -15
- data/lib/api_resource/mocks.rb +0 -277
- data/lib/api_resource/model_errors.rb +0 -82
- data/lib/api_resource/observing.rb +0 -27
- data/lib/api_resource/railtie.rb +0 -24
- data/lib/api_resource/scopes.rb +0 -48
- data/nohup.out +0 -63
- data/spec/lib/api_resource_spec.rb +0 -43
- data/spec/lib/associations_spec.rb +0 -751
- data/spec/lib/attributes_spec.rb +0 -191
- data/spec/lib/base_spec.rb +0 -655
- data/spec/lib/callbacks_spec.rb +0 -68
- data/spec/lib/connection_spec.rb +0 -137
- data/spec/lib/local_spec.rb +0 -20
- data/spec/lib/mocks_spec.rb +0 -45
- data/spec/lib/model_errors_spec.rb +0 -29
- data/spec/lib/prefixes_spec.rb +0 -107
- data/spec/spec_helper.rb +0 -82
- data/spec/support/mocks/association_mocks.rb +0 -63
- data/spec/support/mocks/error_resource_mocks.rb +0 -21
- data/spec/support/mocks/prefix_model_mocks.rb +0 -5
- data/spec/support/mocks/test_resource_mocks.rb +0 -44
- data/spec/support/requests/association_requests.rb +0 -31
- data/spec/support/requests/error_resource_requests.rb +0 -25
- data/spec/support/requests/prefix_model_requests.rb +0 -7
- data/spec/support/requests/test_resource_requests.rb +0 -38
- data/spec/support/test_resource.rb +0 -72
- data/spec/tmp/DIR +0 -0
data/spec/lib/attributes_spec.rb
DELETED
@@ -1,191 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
include ApiResource
|
4
|
-
|
5
|
-
describe "Attributes" do
|
6
|
-
|
7
|
-
after(:all) do
|
8
|
-
TestResource.reload_class_attributes
|
9
|
-
end
|
10
|
-
|
11
|
-
context "Defining, getting, and setting attributes" do
|
12
|
-
it "should be able to define known attributes" do
|
13
|
-
TestResource.define_attributes :attr1, :attr2
|
14
|
-
TestResource.attribute?(:attr1).should be_true
|
15
|
-
TestResource.attribute?(:attr2).should be_true
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
describe "Determining Attributes, Scopes, and Associations from the server" do
|
20
|
-
|
21
|
-
it "should determine it's attributes when the class loads" do
|
22
|
-
tst = TestResource.new
|
23
|
-
tst.attribute?(:name).should be_true
|
24
|
-
tst.attribute?(:age).should be_true
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should typecast data if a format is specified" do
|
28
|
-
tst = TestResource.new(:bday => Date.today.to_s)
|
29
|
-
tst.bday.should be_a Date
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should typecast data if a format is specified" do
|
33
|
-
tst = TestResource.new(:roles => [:role1, :role2])
|
34
|
-
tst.roles.should be_a Array
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should default array fields to a blank array" do
|
38
|
-
tst = TestResource.new
|
39
|
-
tst.roles.should be_a Array
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should determine it's associations when the class loads" do
|
43
|
-
tst = TestResource.new
|
44
|
-
tst.association?(:has_many_objects).should be_true
|
45
|
-
tst.association?(:belongs_to_object).should be_true
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should be able to determine scopes when the class loads" do
|
49
|
-
tst = TestResource.new
|
50
|
-
tst.scope?(:paginate).should be_true
|
51
|
-
tst.scope?(:active).should be_true
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should provide attributes without proxies if attributes_without_proxies is called" do
|
55
|
-
tst = TestResource.new({:has_many_objects => []})
|
56
|
-
tst.attributes_without_proxies.each do |k,v|
|
57
|
-
[ApiResource::Associations::SingleObjectProxy, ApiResource::Associations::MultiObjectProxy]
|
58
|
-
.include?(v.class).should be_false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
context "Attributes" do
|
65
|
-
before(:all) do
|
66
|
-
TestResource.define_attributes :attr1, :attr2
|
67
|
-
TestResource.define_protected_attributes :attr3
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should set attributes for the data loaded from a hash" do
|
71
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2"})
|
72
|
-
tst.attr1?.should be_true
|
73
|
-
tst.attr1.should eql("attr1")
|
74
|
-
tst.attr1 = "test"
|
75
|
-
tst.attr1.should eql("test")
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should create protected attributes for unknown attributes trying to be loaded" do
|
79
|
-
tst = TestResource.new({:attr1 => "attr1", :attr3 => "attr3"})
|
80
|
-
tst.attr3?.should be_true
|
81
|
-
tst.attr3.should eql("attr3")
|
82
|
-
lambda {
|
83
|
-
tst.attr3 = "test"
|
84
|
-
}.should raise_error
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should define methods for testing for reading and writing known attributes" do
|
89
|
-
TestResource.define_attributes :attr1, :attr2
|
90
|
-
tst = TestResource.new
|
91
|
-
tst.respond_to?(:attr1).should be_true
|
92
|
-
tst.respond_to?(:attr1=).should be_true
|
93
|
-
tst.respond_to?(:attr1?).should be_true
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should be able to set and change attributes" do
|
97
|
-
TestResource.define_attributes :attr1, :attr2
|
98
|
-
tst = TestResource.new
|
99
|
-
tst.attr1.should be_nil
|
100
|
-
tst.attr1?.should be_false
|
101
|
-
tst.attr1 = "test"
|
102
|
-
tst.attr1.should eql("test")
|
103
|
-
tst.attr1?.should be_true
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should be able to set multiple attributes at once" do
|
107
|
-
TestResource.define_attributes :attr1, :attr2, :attr3
|
108
|
-
tst = TestResource.new
|
109
|
-
tst.attr3 = "123"
|
110
|
-
|
111
|
-
tst.attributes = {:attr1 => "abc", :attr2 => "test"}
|
112
|
-
tst.attr1.should eql "abc"
|
113
|
-
tst.attr2.should eql "test"
|
114
|
-
tst.attr3.should eql "123"
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
context "Protected attributes" do
|
120
|
-
it "should allow protected attributes that cannot be changed" do
|
121
|
-
TestResource.define_protected_attributes :pattr3
|
122
|
-
lambda {
|
123
|
-
tst = TestResource.new
|
124
|
-
tst.pattr3 = "test"
|
125
|
-
}.should raise_error
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context "Dirty tracking" do
|
130
|
-
context "Changes to attributes" do
|
131
|
-
it "should implement dirty tracking for attributes" do
|
132
|
-
TestResource.define_attributes :attr1, :attr2
|
133
|
-
tst = TestResource.new
|
134
|
-
tst.changed.should be_blank
|
135
|
-
tst.attr1 = "Hello"
|
136
|
-
tst.changed.include?("attr1").should be_true
|
137
|
-
tst.changes.should_not be_blank
|
138
|
-
|
139
|
-
# Set an attribute equal to itself
|
140
|
-
tst.attr2 = tst.attr2
|
141
|
-
tst.changes.include?("attr2").should be_false
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
context "Resetting and marking attributes current" do
|
147
|
-
|
148
|
-
before(:each) do
|
149
|
-
TestResource.define_attributes :attr1, :attr2
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should be able to mark any list of attributes as current (unchanged)" do
|
153
|
-
tst = TestResource.new
|
154
|
-
tst.attr1 = "Hello"
|
155
|
-
tst.changed.should_not be_blank
|
156
|
-
tst.set_attributes_as_current :attr1, :attr2
|
157
|
-
tst.changed.should be_blank
|
158
|
-
end
|
159
|
-
|
160
|
-
it "should be able to mark all the attributes as current if none are given" do
|
161
|
-
tst = TestResource.new
|
162
|
-
tst.attr1 = "attr1"
|
163
|
-
tst.attr2 = "attr2"
|
164
|
-
tst.changed.should_not be_blank
|
165
|
-
tst.set_attributes_as_current
|
166
|
-
tst.changed.should be_blank
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should be able to reset any list of attributes" do
|
170
|
-
tst = TestResource.new
|
171
|
-
tst.attr1 = "attr1"
|
172
|
-
tst.reset_attribute_changes :attr1
|
173
|
-
tst.attr1.should be_nil
|
174
|
-
tst.changed.should be_blank
|
175
|
-
end
|
176
|
-
|
177
|
-
it "should be able to reset all the attributes if none are given" do
|
178
|
-
tst = TestResource.new
|
179
|
-
tst.attr1 = "attr1"
|
180
|
-
tst.attr2 = "attr2"
|
181
|
-
|
182
|
-
tst.reset_attribute_changes
|
183
|
-
tst.attr1.should be_nil
|
184
|
-
tst.attr2.should be_nil
|
185
|
-
tst.changed.should be_blank
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
data/spec/lib/base_spec.rb
DELETED
@@ -1,655 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
include ApiResource
|
5
|
-
|
6
|
-
describe "Base" do
|
7
|
-
|
8
|
-
after(:all) do
|
9
|
-
TestResource.reload_class_attributes
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "Loading data from a hash" do
|
13
|
-
|
14
|
-
context "Associations" do
|
15
|
-
before(:all) do
|
16
|
-
TestResource.has_many :has_many_objects
|
17
|
-
TestResource.has_one :has_one_object
|
18
|
-
TestResource.belongs_to :belongs_to_object
|
19
|
-
end
|
20
|
-
|
21
|
-
after(:all) do
|
22
|
-
TestResource.related_objects.each do |key,val|
|
23
|
-
val.clear
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context "MultiObjectProxy" do
|
28
|
-
|
29
|
-
it "should create a MultiObjectProxy for has_many associations" do
|
30
|
-
tst = TestResource.new({:has_many_objects => []})
|
31
|
-
tst.has_many_objects.should be_a(Associations::MultiObjectProxy)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should throw an error if a has many association is not nil or an array or a hash" do
|
35
|
-
TestResource.new({:has_many_objects => nil})
|
36
|
-
lambda {
|
37
|
-
TestResource.new({:has_many_objects => "invalid"})
|
38
|
-
}.should raise_error
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should properly load the data from the provided array or hash" do
|
42
|
-
tst = TestResource.new({:has_many_objects => [{:service_uri => '/path'}]})
|
43
|
-
tst.has_many_objects.remote_path.should eql('/path')
|
44
|
-
tst = TestResource.new({:has_many_objects => {:service_uri => '/path'}})
|
45
|
-
tst.has_many_objects.remote_path.should eql('/path')
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
context "SingleObjectProxy" do
|
51
|
-
|
52
|
-
it "should create a SingleObjectProxy for belongs to and has_one associations" do
|
53
|
-
tst = TestResource.new(:belongs_to_object => {}, :has_one_object => {})
|
54
|
-
tst.belongs_to_object.should be_a(Associations::SingleObjectProxy)
|
55
|
-
tst.has_one_object.should be_a(Associations::SingleObjectProxy)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should throw an error if a belongs_to or has_many association is not a hash or nil" do
|
59
|
-
lambda {
|
60
|
-
TestResource.new(:belongs_to_object => [])
|
61
|
-
}.should raise_error
|
62
|
-
lambda {
|
63
|
-
TestResource.new(:has_one_object => [])
|
64
|
-
}.should raise_error
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should properly load data from the provided hash" do
|
68
|
-
tst = TestResource.new(:has_one_object => {:service_uri => "/path"})
|
69
|
-
tst.has_one_object.remote_path.should eql('/path')
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "Request parameters and paths" do
|
77
|
-
|
78
|
-
after(:each) do
|
79
|
-
TestResource.element_name = TestResource.model_name.element
|
80
|
-
TestResource.collection_name = TestResource.element_name.to_s.pluralize
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should set the element name and collection name by default" do
|
84
|
-
TestResource.element_name.should eql("test_resource")
|
85
|
-
TestResource.collection_name.should eql("test_resources")
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should inherit element name and collection name from its parent class if using SCI" do
|
89
|
-
ChildTestResource.ancestors.should include TestResource
|
90
|
-
ChildTestResource.collection_name.should eql "test_resources"
|
91
|
-
end
|
92
|
-
|
93
|
-
it "should be able to set the element and collection names to anything" do
|
94
|
-
TestResource.element_name = "element"
|
95
|
-
TestResource.collection_name = "elements"
|
96
|
-
TestResource.element_name.should eql("element")
|
97
|
-
TestResource.collection_name.should eql("elements")
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should propery generate collection paths and element paths with the new names and the default format json" do
|
101
|
-
TestResource.element_name = "element"
|
102
|
-
TestResource.collection_name = "elements"
|
103
|
-
TestResource.new_element_path.should eql("/elements/new.json")
|
104
|
-
TestResource.collection_path.should eql("/elements.json")
|
105
|
-
TestResource.element_path(1).should eql("/elements/1.json")
|
106
|
-
TestResource.element_path(1, :active => true).should eql("/elements/1.json?active=true")
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should be able to set the format" do
|
110
|
-
TestResource.format.extension.to_sym.should eql(:json)
|
111
|
-
TestResource.format = :xml
|
112
|
-
TestResource.format.extension.to_sym.should eql(:xml)
|
113
|
-
TestResource.format = :json
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should only allow proper formats to be set" do
|
117
|
-
expect {TestResource.format = :blah}.should raise_error(::ApiResource::Formats::BadFormat)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should be able to set an http timeout" do
|
121
|
-
TestResource.timeout = 5
|
122
|
-
TestResource.timeout.should eql(5)
|
123
|
-
TestResource.connection.timeout.should eql(5)
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
describe "Serialization" do
|
129
|
-
|
130
|
-
before(:all) do
|
131
|
-
TestResource.reload_class_attributes
|
132
|
-
TestResource.has_many :has_many_objects
|
133
|
-
TestResource.define_attributes :attr1, :attr2
|
134
|
-
TestResource.include_root_in_json = true
|
135
|
-
end
|
136
|
-
|
137
|
-
before(:each) do
|
138
|
-
TestResource.include_root_in_json = false
|
139
|
-
end
|
140
|
-
|
141
|
-
context "JSON" do
|
142
|
-
|
143
|
-
it "should be able to serialize itself without the root" do
|
144
|
-
TestResource.include_root_in_json = false
|
145
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2"})
|
146
|
-
hash = JSON.parse(tst.to_json)
|
147
|
-
hash["attr1"].should eql("attr1")
|
148
|
-
hash["attr2"].should eql("attr2")
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should be able to serialize itself with the root" do
|
152
|
-
TestResource.include_root_in_json = true
|
153
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2"})
|
154
|
-
hash = JSON.parse(tst.to_json)
|
155
|
-
hash["test_resource"].should_not be_nil
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should not include associations by default if they have not changed" do
|
159
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => []})
|
160
|
-
hash = JSON.parse(tst.to_json)
|
161
|
-
hash["has_many_objects"].should be_nil
|
162
|
-
end
|
163
|
-
|
164
|
-
it "should include associations passed given in the include_associations array" do
|
165
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => []})
|
166
|
-
hash = JSON.parse(tst.to_json(:include_associations => [:has_many_objects]))
|
167
|
-
hash["has_many_objects"].should_not be_nil
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should include associations by default if they have changed" do
|
171
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => []})
|
172
|
-
tst.has_many_objects = [{:name => "test"}]
|
173
|
-
hash = JSON.parse(tst.to_json)
|
174
|
-
hash["has_many_objects"].should_not be_nil
|
175
|
-
end
|
176
|
-
|
177
|
-
it "should not include unknown attributes unless they are passed in via the include_extras array" do
|
178
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :attr3 => "attr3"})
|
179
|
-
hash = JSON.parse(tst.to_json)
|
180
|
-
hash["attr3"].should be_nil
|
181
|
-
hash = JSON.parse(tst.to_json(:include_extras => [:attr3]))
|
182
|
-
hash["attr3"].should_not be_nil
|
183
|
-
end
|
184
|
-
|
185
|
-
it "should ignore fields set under the except option" do
|
186
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :attr3 => "attr3"})
|
187
|
-
hash = JSON.parse(tst.to_json(:except => [:attr1]))
|
188
|
-
hash["attr1"].should be_nil
|
189
|
-
end
|
190
|
-
|
191
|
-
context "Nested Objects" do
|
192
|
-
before(:all) do
|
193
|
-
TestResource.has_many(:has_many_objects)
|
194
|
-
end
|
195
|
-
after(:all) do
|
196
|
-
TestResource.reload_class_attributes
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should include the id of nested objects in the serialization" do
|
200
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => [{:name => "123", :id => "1"}]})
|
201
|
-
hash = JSON.parse(tst.to_json(:include_associations => [:has_many_objects]))
|
202
|
-
hash["has_many_objects"].first["id"].should_not be nil
|
203
|
-
end
|
204
|
-
it "should include the id of nested objects in the serialization" do
|
205
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => [{:name => "123"}]})
|
206
|
-
hash = JSON.parse(tst.to_json(:include_associations => [:has_many_objects]))
|
207
|
-
hash["has_many_objects"].first.keys.should_not include "id"
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context "XML" do
|
213
|
-
|
214
|
-
it "should only be able to serialize itself with the root" do
|
215
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2"})
|
216
|
-
hash = Hash.from_xml(tst.to_xml)
|
217
|
-
hash["test_resource"].should_not be_nil
|
218
|
-
end
|
219
|
-
|
220
|
-
it "should properly serialize associations if they are included" do
|
221
|
-
tst = TestResource.new({:attr1 => "attr1", :attr2 => "attr2", :has_many_objects => []})
|
222
|
-
hash = Hash.from_xml(tst.to_xml(:include_associations => [:has_many_objects]))
|
223
|
-
hash["test_resource"]["has_many_objects"].should eql([])
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
describe "Finding Data" do
|
230
|
-
|
231
|
-
before(:all) do
|
232
|
-
TestResource.reload_class_attributes
|
233
|
-
end
|
234
|
-
|
235
|
-
it "should be able to find all" do
|
236
|
-
resources = TestResource.find(:all)
|
237
|
-
resources.size.should eql(5)
|
238
|
-
resources.each{|r| r.should be_a TestResource}
|
239
|
-
end
|
240
|
-
|
241
|
-
it "should be able to find first or last" do
|
242
|
-
res = TestResource.first
|
243
|
-
res.should be_a TestResource
|
244
|
-
res.name.should_not be_blank
|
245
|
-
res.age.should_not be_blank
|
246
|
-
|
247
|
-
res = TestResource.last
|
248
|
-
res.should be_a TestResource
|
249
|
-
res.name.should_not be_blank
|
250
|
-
res.age.should_not be_blank
|
251
|
-
end
|
252
|
-
|
253
|
-
it "should be able to find by id" do
|
254
|
-
res = TestResource.find(2)
|
255
|
-
res.should be_a TestResource
|
256
|
-
res.id.to_i.should eql(2)
|
257
|
-
end
|
258
|
-
|
259
|
-
end
|
260
|
-
|
261
|
-
describe "Saving Data" do
|
262
|
-
|
263
|
-
before(:all) do
|
264
|
-
TestResource.include_root_in_json = true
|
265
|
-
TestResource.reload_class_attributes
|
266
|
-
end
|
267
|
-
|
268
|
-
context "Creating new records" do
|
269
|
-
|
270
|
-
before(:all) do
|
271
|
-
TestResource.has_many :has_many_objects
|
272
|
-
end
|
273
|
-
|
274
|
-
it "should be able to post new data via the create method" do
|
275
|
-
tr = TestResource.create({:name => "Ethan", :age => 20})
|
276
|
-
tr.id.should_not be_blank
|
277
|
-
end
|
278
|
-
|
279
|
-
it "should be able to post new data via the save method" do
|
280
|
-
tr = TestResource.build({:name => "Ethan", :age => 20})
|
281
|
-
tr.save.should be_true
|
282
|
-
tr.id.should_not be_blank
|
283
|
-
end
|
284
|
-
|
285
|
-
context("Override create to return the json") do
|
286
|
-
|
287
|
-
before(:all) do
|
288
|
-
RestClient::Payload.stubs(:has_file? => false)
|
289
|
-
end
|
290
|
-
|
291
|
-
it "should be able to include associations when saving if they are specified" do
|
292
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
293
|
-
"/test_resources.json",
|
294
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"age\":20}}",
|
295
|
-
TestResource.headers
|
296
|
-
)
|
297
|
-
|
298
|
-
tr = TestResource.build(:name => "Ethan", :age => 20)
|
299
|
-
tr.save
|
300
|
-
end
|
301
|
-
|
302
|
-
|
303
|
-
it "should not include nil attributes when creating by default" do
|
304
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
305
|
-
"/test_resources.json",
|
306
|
-
"{\"test_resource\":{\"name\":\"Ethan\"}}",
|
307
|
-
TestResource.headers
|
308
|
-
)
|
309
|
-
|
310
|
-
tr = TestResource.build(:name => "Ethan")
|
311
|
-
tr.save
|
312
|
-
end
|
313
|
-
|
314
|
-
it "should include false attributes when creating by default" do
|
315
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
316
|
-
"/test_resources.json",
|
317
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"is_active\":false}}",
|
318
|
-
TestResource.headers
|
319
|
-
)
|
320
|
-
|
321
|
-
tr = TestResource.build(:name => "Ethan", :is_active => false)
|
322
|
-
tr.save
|
323
|
-
end
|
324
|
-
|
325
|
-
|
326
|
-
it "should not include nil attributes for associated objects when creating by default" do
|
327
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
328
|
-
"/test_resources.json",
|
329
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"has_one_object\":{\"size\":\"large\"}}}",
|
330
|
-
TestResource.headers
|
331
|
-
)
|
332
|
-
|
333
|
-
tr = TestResource.build(:name => "Ethan")
|
334
|
-
tr.has_one_object = HasOneObject.new(:size => "large", :color => nil)
|
335
|
-
tr.save(:include_associations => [:has_one_object])
|
336
|
-
end
|
337
|
-
|
338
|
-
|
339
|
-
it "should include nil attributes if they are passed in through the include_extras" do
|
340
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
341
|
-
"/test_resources.json",
|
342
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"age\":null}}",
|
343
|
-
TestResource.headers
|
344
|
-
)
|
345
|
-
|
346
|
-
tr = TestResource.build(:name => "Ethan")
|
347
|
-
tr.save(:include_extras => [:age])
|
348
|
-
end
|
349
|
-
|
350
|
-
|
351
|
-
it "should include nil attributes when creating if include_nil_attributes_on_create is true" do
|
352
|
-
ApiResource::Connection.any_instance.expects(:post).with(
|
353
|
-
"/test_resources.json",
|
354
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"age\":null,\"is_active\":null,\"bday\":null,\"roles\":[]}}",
|
355
|
-
TestResource.headers
|
356
|
-
)
|
357
|
-
|
358
|
-
TestResource.include_nil_attributes_on_create = true
|
359
|
-
tr = TestResource.build(:name => "Ethan")
|
360
|
-
tr.save
|
361
|
-
|
362
|
-
#hash['test_resource'].key?('age').should be_true
|
363
|
-
TestResource.include_nil_attributes_on_create = false
|
364
|
-
end
|
365
|
-
end
|
366
|
-
end
|
367
|
-
|
368
|
-
context "Updating old records" do
|
369
|
-
before(:all) do
|
370
|
-
TestResource.reload_class_attributes
|
371
|
-
TestResource.has_many :has_many_objects
|
372
|
-
RestClient::Payload.stubs(:has_file? => false)
|
373
|
-
end
|
374
|
-
|
375
|
-
it "should be able to put updated data via the update method and
|
376
|
-
should only include changed attributes when updating" do
|
377
|
-
|
378
|
-
# Note that age is a non-nil attribute and is present in the
|
379
|
-
# put request, but name is not present since it has not changed.
|
380
|
-
|
381
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
382
|
-
"/test_resources/1.json",
|
383
|
-
"{\"test_resource\":{\"age\":6}}",
|
384
|
-
TestResource.headers
|
385
|
-
)
|
386
|
-
|
387
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
388
|
-
tr.should_not be_new
|
389
|
-
|
390
|
-
# Thus we know we are calling update
|
391
|
-
tr.age = 6
|
392
|
-
tr.save
|
393
|
-
end
|
394
|
-
|
395
|
-
|
396
|
-
it "should include changed associations without specification" do
|
397
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
398
|
-
"/test_resources/1.json",
|
399
|
-
"{\"test_resource\":{\"has_many_objects\":[{}]}}",
|
400
|
-
TestResource.headers
|
401
|
-
)
|
402
|
-
|
403
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
404
|
-
tr.has_many_objects = [HasManyObject.new]
|
405
|
-
tr.save
|
406
|
-
end
|
407
|
-
|
408
|
-
|
409
|
-
it "should include unchanged associations if they are specified" do
|
410
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
411
|
-
"/test_resources/1.json",
|
412
|
-
"{\"test_resource\":{\"has_many_objects\":[]}}",
|
413
|
-
TestResource.headers
|
414
|
-
)
|
415
|
-
|
416
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
417
|
-
tr.save(:has_many_objects)
|
418
|
-
end
|
419
|
-
|
420
|
-
|
421
|
-
it "should not include nil attributes of associated objects when updating,
|
422
|
-
unless the attributes have changed to nil" do
|
423
|
-
|
424
|
-
correct_order = sequence("ordering")
|
425
|
-
|
426
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
427
|
-
"/test_resources/1.json",
|
428
|
-
"{\"test_resource\":{\"has_one_object\":{\"size\":\"large\"}}}",
|
429
|
-
TestResource.headers
|
430
|
-
).in_sequence(correct_order)
|
431
|
-
|
432
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
433
|
-
tr.has_one_object = HasOneObject.new(:size => "large", :color => nil)
|
434
|
-
tr.save(:include_associations => [:has_one_object])
|
435
|
-
|
436
|
-
|
437
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
438
|
-
"/test_resources/1.json",
|
439
|
-
"{\"test_resource\":{\"has_one_object\":{\"size\":null}}}",
|
440
|
-
TestResource.headers
|
441
|
-
).in_sequence(correct_order)
|
442
|
-
|
443
|
-
tr.has_one_object.size = nil
|
444
|
-
tr.save(:include_associations => [:has_one_object])
|
445
|
-
end
|
446
|
-
|
447
|
-
|
448
|
-
it "should not include nil values for association objects when updating,
|
449
|
-
unless the association has changed to nil" do
|
450
|
-
|
451
|
-
correct_order = sequence("ordering")
|
452
|
-
|
453
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
454
|
-
"/test_resources/1.json",
|
455
|
-
"{\"test_resource\":{\"has_one_object\":{\"size\":\"large\"}}}",
|
456
|
-
TestResource.headers
|
457
|
-
).in_sequence(correct_order)
|
458
|
-
|
459
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
460
|
-
tr.has_one_object = HasOneObject.new(:size => "large", :color => nil)
|
461
|
-
tr.save(:include_associations => [:has_one_object])
|
462
|
-
|
463
|
-
|
464
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
465
|
-
"/test_resources/1.json",
|
466
|
-
"{\"test_resource\":{\"has_one_object\":null}}",
|
467
|
-
TestResource.headers
|
468
|
-
).in_sequence(correct_order)
|
469
|
-
|
470
|
-
tr.has_one_object = nil
|
471
|
-
tr.save(:include_associations => [:has_one_object])
|
472
|
-
end
|
473
|
-
|
474
|
-
|
475
|
-
it "should include all attributes if include_all_attributes_on_update is true" do
|
476
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
477
|
-
"/test_resources/1.json",
|
478
|
-
"{\"test_resource\":{\"name\":\"Ethan\",\"age\":null,\"is_active\":null,\"bday\":null,\"roles\":[]}}",
|
479
|
-
TestResource.headers
|
480
|
-
)
|
481
|
-
|
482
|
-
TestResource.include_all_attributes_on_update = true
|
483
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
484
|
-
tr.save
|
485
|
-
TestResource.include_all_attributes_on_update = false
|
486
|
-
end
|
487
|
-
|
488
|
-
it "should provide an update_attributes method to set attrs and save" do
|
489
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
490
|
-
"/test_resources/1.json",
|
491
|
-
"{\"test_resource\":{\"name\":\"Dan\"}}",
|
492
|
-
TestResource.headers
|
493
|
-
)
|
494
|
-
|
495
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
496
|
-
tr.update_attributes(:name => "Dan")
|
497
|
-
end
|
498
|
-
|
499
|
-
|
500
|
-
it "should include nil attributes when updating if they have
|
501
|
-
changed by default" do
|
502
|
-
|
503
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
504
|
-
"/test_resources/1.json",
|
505
|
-
"{\"test_resource\":{\"is_active\":null}}",
|
506
|
-
TestResource.headers
|
507
|
-
)
|
508
|
-
|
509
|
-
tr = TestResource.new(
|
510
|
-
:id => "1", :name => "Ethan", :is_active => false
|
511
|
-
)
|
512
|
-
tr.update_attributes(:is_active => nil)
|
513
|
-
end
|
514
|
-
|
515
|
-
it "should include attributes that have changed to false by default" do
|
516
|
-
ApiResource::Connection.any_instance.expects(:put).with(
|
517
|
-
"/test_resources/1.json",
|
518
|
-
"{\"test_resource\":{\"is_active\":false}}",
|
519
|
-
TestResource.headers
|
520
|
-
)
|
521
|
-
|
522
|
-
tr = TestResource.new(
|
523
|
-
:id => "1", :name => "Ethan", :is_active => true
|
524
|
-
)
|
525
|
-
tr.update_attributes(:is_active => false)
|
526
|
-
|
527
|
-
end
|
528
|
-
|
529
|
-
end
|
530
|
-
|
531
|
-
end
|
532
|
-
|
533
|
-
describe "Deleting data" do
|
534
|
-
it "should be able to delete an id from the class method" do
|
535
|
-
TestResource.delete(1).should be_true
|
536
|
-
end
|
537
|
-
|
538
|
-
it "should be able to destroy itself as an instance" do
|
539
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
540
|
-
tr.destroy.should be_true
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
describe "Random methods" do
|
545
|
-
|
546
|
-
it "should know if it is persisted" do
|
547
|
-
tr = TestResource.new(:id => 1, :name => "Ethan")
|
548
|
-
tr.persisted?.should be_true
|
549
|
-
tr = TestResource.new(:name => "Ethan")
|
550
|
-
tr.persisted?.should be_false
|
551
|
-
end
|
552
|
-
|
553
|
-
it "should know how to reload attributes" do
|
554
|
-
tr = TestResource.find(1)
|
555
|
-
|
556
|
-
tr.age = 47
|
557
|
-
tr.name = "Ethan"
|
558
|
-
|
559
|
-
tr.reload
|
560
|
-
|
561
|
-
tr.age.should eql "age"
|
562
|
-
tr.name.should eql "name"
|
563
|
-
end
|
564
|
-
|
565
|
-
it "should know how to reload associations" do
|
566
|
-
tr = TestResource.find(1)
|
567
|
-
|
568
|
-
tr.has_one_object.size = "small"
|
569
|
-
tr.has_many_objects.first.name = "Ethan"
|
570
|
-
|
571
|
-
tr.has_one_object.size.should eql "small"
|
572
|
-
tr.has_many_objects.first.name.should eql "Ethan"
|
573
|
-
|
574
|
-
tr.reload
|
575
|
-
|
576
|
-
tr.has_one_object.size.should eql "large"
|
577
|
-
tr.has_many_objects.first.name.should eql "name"
|
578
|
-
end
|
579
|
-
|
580
|
-
end
|
581
|
-
|
582
|
-
describe "Inheritable Accessors" do
|
583
|
-
|
584
|
-
it "should copy the default values down to any level of subclass" do
|
585
|
-
|
586
|
-
class Child < TestResource
|
587
|
-
end
|
588
|
-
|
589
|
-
Child.site.should eql(TestResource.site)
|
590
|
-
Child.site.should_not be_blank
|
591
|
-
end
|
592
|
-
|
593
|
-
end
|
594
|
-
|
595
|
-
describe "Inflections" do
|
596
|
-
|
597
|
-
it "should be able to singularize and pluralize words ending in ess" do
|
598
|
-
"address".singularize.should eql("address")
|
599
|
-
"address".pluralize.should eql("addresses")
|
600
|
-
end
|
601
|
-
|
602
|
-
end
|
603
|
-
|
604
|
-
context ".get" do
|
605
|
-
|
606
|
-
context "with ttl" do
|
607
|
-
around(:each) do |example|
|
608
|
-
|
609
|
-
begin
|
610
|
-
initial = ApiResource::Base.ttl
|
611
|
-
ApiResource::Base.ttl = 1
|
612
|
-
example.run
|
613
|
-
ensure
|
614
|
-
ApiResource::Base.ttl = initial
|
615
|
-
end
|
616
|
-
|
617
|
-
end
|
618
|
-
|
619
|
-
it "should implement caching using the ttl setting" do
|
620
|
-
cache = mock(:fetch => {:id => 123, :name => "Dan"})
|
621
|
-
ApiResource.stubs(:cache => cache)
|
622
|
-
TestResource.find(123)
|
623
|
-
end
|
624
|
-
|
625
|
-
it "should find with expires_in and cache" do
|
626
|
-
ApiResource.cache.expects(:fetch).with(anything, :expires_in => 10.0).returns({:id => 2, :name => "d"})
|
627
|
-
res = TestResource.find("adfa", :expires_in => 10)
|
628
|
-
|
629
|
-
ApiResource::Base.ttl.should eql(1)
|
630
|
-
res.id.to_i.should eql(2)
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
end
|
635
|
-
|
636
|
-
context ".respond_to?" do
|
637
|
-
|
638
|
-
it "should load the resouce definition when respond_to? is called" do
|
639
|
-
# remove our attribute that denotes that the definition was loaded
|
640
|
-
TestResource.send(:remove_instance_variable, :@class_data)
|
641
|
-
TestResource.expects(:set_class_attributes_upon_load)
|
642
|
-
TestResource.respond_to?(:test)
|
643
|
-
end
|
644
|
-
|
645
|
-
it "should not load the resource definition when respond_to? is called
|
646
|
-
if the definition has already been loaded" do
|
647
|
-
TestResource.expects(:set_class_attributes_upon_load).never
|
648
|
-
TestResource.send(:respond_to?, :some_method)
|
649
|
-
end
|
650
|
-
|
651
|
-
end
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
end
|