activeresource 2.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activeresource might be problematic. Click here for more details.

@@ -0,0 +1,43 @@
1
+ require "#{File.dirname(__FILE__)}/../abstract_unit"
2
+ require "fixtures/person"
3
+ require "fixtures/street_address"
4
+
5
+ class BaseEqualityTest < Test::Unit::TestCase
6
+ def setup
7
+ @new = Person.new
8
+ @one = Person.new(:id => 1)
9
+ @two = Person.new(:id => 2)
10
+ @street = StreetAddress.new(:id => 2)
11
+ end
12
+
13
+ def test_should_equal_self
14
+ assert @new == @new, '@new == @new'
15
+ assert @one == @one, '@one == @one'
16
+ end
17
+
18
+ def test_shouldnt_equal_new_resource
19
+ assert @new != @one, '@new != @one'
20
+ assert @one != @new, '@one != @new'
21
+ end
22
+
23
+ def test_shouldnt_equal_different_class
24
+ assert @two != @street, 'person != street_address with same id'
25
+ assert @street != @two, 'street_address != person with same id'
26
+ end
27
+
28
+ def test_eql_should_alias_equals_operator
29
+ assert_equal @new == @new, @new.eql?(@new)
30
+ assert_equal @new == @one, @new.eql?(@one)
31
+
32
+ assert_equal @one == @one, @one.eql?(@one)
33
+ assert_equal @one == @new, @one.eql?(@new)
34
+
35
+ assert_equal @one == @street, @one.eql?(@street)
36
+ end
37
+
38
+ def test_hash_should_be_id_hash
39
+ [@new, @one, @two, @street].each do |resource|
40
+ assert_equal resource.id.hash, resource.hash
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,111 @@
1
+ require "#{File.dirname(__FILE__)}/../abstract_unit"
2
+ require "fixtures/person"
3
+ require "fixtures/street_address"
4
+
5
+ module Highrise
6
+ class Note < ActiveResource::Base
7
+ self.site = "http://37s.sunrise.i:3000"
8
+ end
9
+
10
+ class Comment < ActiveResource::Base
11
+ self.site = "http://37s.sunrise.i:3000"
12
+ end
13
+ end
14
+
15
+
16
+ class BaseLoadTest < Test::Unit::TestCase
17
+ def setup
18
+ @matz = { :id => 1, :name => 'Matz' }
19
+
20
+ @first_address = { :id => 1, :street => '12345 Street' }
21
+ @addresses = [@first_address, { :id => 2, :street => '67890 Street' }]
22
+ @addresses_from_xml = { :street_addresses => @addresses }
23
+ @addresses_from_xml_single = { :street_addresses => [ @first_address ] }
24
+
25
+ @deep = { :id => 1, :street => {
26
+ :id => 1, :state => { :id => 1, :name => 'Oregon',
27
+ :notable_rivers => [
28
+ { :id => 1, :name => 'Willamette' },
29
+ { :id => 2, :name => 'Columbia', :rafted_by => @matz }] }}}
30
+
31
+ @person = Person.new
32
+ end
33
+
34
+ def test_load_expects_hash
35
+ assert_raise(ArgumentError) { @person.load nil }
36
+ assert_raise(ArgumentError) { @person.load '<person id="1"/>' }
37
+ end
38
+
39
+ def test_load_simple_hash
40
+ assert_equal Hash.new, @person.attributes
41
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
42
+ end
43
+
44
+ def test_load_one_with_existing_resource
45
+ address = @person.load(:street_address => @first_address).street_address
46
+ assert_kind_of StreetAddress, address
47
+ assert_equal @first_address.stringify_keys, address.attributes
48
+ end
49
+
50
+ def test_load_one_with_unknown_resource
51
+ address = silence_warnings { @person.load(:address => @first_address).address }
52
+ assert_kind_of Person::Address, address
53
+ assert_equal @first_address.stringify_keys, address.attributes
54
+ end
55
+
56
+ def test_load_collection_with_existing_resource
57
+ addresses = @person.load(@addresses_from_xml).street_addresses
58
+ assert_kind_of Array, addresses
59
+ addresses.each { |address| assert_kind_of StreetAddress, address }
60
+ assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
61
+ end
62
+
63
+ def test_load_collection_with_unknown_resource
64
+ Person.send!(:remove_const, :Address) if Person.const_defined?(:Address)
65
+ assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
66
+ addresses = silence_warnings { @person.load(:addresses => @addresses).addresses }
67
+ assert Person.const_defined?(:Address), "Address should have been autocreated"
68
+ addresses.each { |address| assert_kind_of Person::Address, address }
69
+ assert_equal @addresses.map(&:stringify_keys), addresses.map(&:attributes)
70
+ end
71
+
72
+ def test_load_collection_with_single_existing_resource
73
+ addresses = @person.load(@addresses_from_xml_single).street_addresses
74
+ assert_kind_of Array, addresses
75
+ addresses.each { |address| assert_kind_of StreetAddress, address }
76
+ assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
77
+ end
78
+
79
+ def test_load_collection_with_single_unknown_resource
80
+ Person.send!(:remove_const, :Address) if Person.const_defined?(:Address)
81
+ assert !Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
82
+ addresses = silence_warnings { @person.load(:addresses => [ @first_address ]).addresses }
83
+ assert Person.const_defined?(:Address), "Address should have been autocreated"
84
+ addresses.each { |address| assert_kind_of Person::Address, address }
85
+ assert_equal [ @first_address ].map(&:stringify_keys), addresses.map(&:attributes)
86
+ end
87
+
88
+ def test_recursively_loaded_collections
89
+ person = @person.load(@deep)
90
+ assert_equal @deep[:id], person.id
91
+
92
+ street = person.street
93
+ assert_kind_of Person::Street, street
94
+ assert_equal @deep[:street][:id], street.id
95
+
96
+ state = street.state
97
+ assert_kind_of Person::Street::State, state
98
+ assert_equal @deep[:street][:state][:id], state.id
99
+
100
+ rivers = state.notable_rivers
101
+ assert_kind_of Array, rivers
102
+ assert_kind_of Person::Street::State::NotableRiver, rivers.first
103
+ assert_equal @deep[:street][:state][:notable_rivers].first[:id], rivers.first.id
104
+ assert_equal @matz[:id], rivers.last.rafted_by.id
105
+ end
106
+
107
+ def test_nested_collections_within_the_same_namespace
108
+ n = Highrise::Note.new(:comments => [{ :name => "1" }])
109
+ assert_kind_of Highrise::Comment, n.comments.first
110
+ end
111
+ end
@@ -0,0 +1,48 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_unit"
2
+ require "fixtures/person"
3
+
4
+ class BaseErrorsTest < Test::Unit::TestCase
5
+ def setup
6
+ ActiveResource::HttpMock.respond_to do |mock|
7
+ mock.post "/people.xml", {}, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><errors><error>Age can't be blank</error><error>Name can't be blank</error><error>Name must start with a letter</error><error>Person quota full for today.</error></errors>", 422
8
+ end
9
+ @person = Person.new(:name => '', :age => '')
10
+ assert_equal @person.save, false
11
+ end
12
+
13
+ def test_should_mark_as_invalid
14
+ assert !@person.valid?
15
+ end
16
+
17
+ def test_should_parse_xml_errors
18
+ assert_kind_of ActiveResource::Errors, @person.errors
19
+ assert_equal 4, @person.errors.size
20
+ end
21
+
22
+ def test_should_parse_errors_to_individual_attributes
23
+ assert @person.errors.invalid?(:name)
24
+ assert_equal "can't be blank", @person.errors.on(:age)
25
+ assert_equal ["can't be blank", "must start with a letter"], @person.errors[:name]
26
+ assert_equal "Person quota full for today.", @person.errors.on_base
27
+ end
28
+
29
+ def test_should_iterate_over_errors
30
+ errors = []
31
+ @person.errors.each { |attribute, message| errors << [attribute, message] }
32
+ assert errors.include?(["name", "can't be blank"])
33
+ end
34
+
35
+ def test_should_iterate_over_full_errors
36
+ errors = []
37
+ @person.errors.each_full { |message| errors << message }
38
+ assert errors.include?("Name can't be blank")
39
+ end
40
+
41
+ def test_should_format_full_errors
42
+ full = @person.errors.full_messages
43
+ assert full.include?("Age can't be blank")
44
+ assert full.include?("Name can't be blank")
45
+ assert full.include?("Name must start with a letter")
46
+ assert full.include?("Person quota full for today.")
47
+ end
48
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,454 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_unit"
2
+ require "fixtures/person"
3
+ require "fixtures/street_address"
4
+ require "fixtures/beast"
5
+
6
+ class BaseTest < Test::Unit::TestCase
7
+ def setup
8
+ @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
9
+ @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
10
+ @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
11
+ @default_request_headers = { 'Content-Type' => 'application/xml' }
12
+ @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
13
+ @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
14
+ @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
15
+ @addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses')
16
+
17
+ ActiveResource::HttpMock.respond_to do |mock|
18
+ mock.get "/people/1.xml", {}, @matz
19
+ mock.get "/people/2.xml", {}, @david
20
+ mock.get "/people/3.xml", {'key' => 'value'}, nil, 404
21
+ mock.put "/people/1.xml", {}, nil, 204
22
+ mock.delete "/people/1.xml", {}, nil, 200
23
+ mock.delete "/people/2.xml", {}, nil, 400
24
+ mock.get "/people/99.xml", {}, nil, 404
25
+ mock.post "/people.xml", {}, @rick, 201, 'Location' => '/people/5.xml'
26
+ mock.get "/people.xml", {}, @people
27
+ mock.get "/people/1/addresses.xml", {}, @addresses
28
+ mock.get "/people/1/addresses/1.xml", {}, @addy
29
+ mock.get "/people/1/addresses/2.xml", {}, nil, 404
30
+ mock.get "/people/2/addresses/1.xml", {}, nil, 404
31
+ mock.put "/people/1/addresses/1.xml", {}, nil, 204
32
+ mock.delete "/people/1/addresses/1.xml", {}, nil, 200
33
+ mock.post "/people/1/addresses.xml", {}, nil, 201, 'Location' => '/people/1/addresses/5'
34
+ mock.get "/people//addresses.xml", {}, nil, 404
35
+ mock.get "/people//addresses/1.xml", {}, nil, 404
36
+ mock.put "/people//addresses/1.xml", {}, nil, 404
37
+ mock.delete "/people//addresses/1.xml", {}, nil, 404
38
+ mock.post "/people//addresses.xml", {}, nil, 404
39
+ end
40
+ end
41
+
42
+
43
+ def test_site_accessor_accepts_uri_or_string_argument
44
+ site = URI.parse('http://localhost')
45
+
46
+ assert_nothing_raised { Person.site = 'http://localhost' }
47
+ assert_equal site, Person.site
48
+
49
+ assert_nothing_raised { Person.site = site }
50
+ assert_equal site, Person.site
51
+ end
52
+
53
+ def test_should_use_site_prefix_and_credentials
54
+ assert_equal 'http://foo:bar@beast.caboo.se', Forum.site.to_s
55
+ assert_equal 'http://foo:bar@beast.caboo.se/forums/:forum_id', Topic.site.to_s
56
+ end
57
+
58
+ def test_site_variable_can_be_reset
59
+ actor = Class.new(ActiveResource::Base)
60
+ assert_nil actor.site
61
+ actor.site = 'http://localhost:31337'
62
+ actor.site = nil
63
+ assert_nil actor.site
64
+ end
65
+
66
+ def test_site_reader_uses_superclass_site_until_written
67
+ # Superclass is Object so returns nil.
68
+ assert_nil ActiveResource::Base.site
69
+ assert_nil Class.new(ActiveResource::Base).site
70
+
71
+ # Subclass uses superclass site.
72
+ actor = Class.new(Person)
73
+ assert_equal Person.site, actor.site
74
+
75
+ # Subclass returns frozen superclass copy.
76
+ assert !Person.site.frozen?
77
+ assert actor.site.frozen?
78
+
79
+ # Changing subclass site doesn't change superclass site.
80
+ actor.site = 'http://localhost:31337'
81
+ assert_not_equal Person.site, actor.site
82
+
83
+ # Changed subclass site is not frozen.
84
+ assert !actor.site.frozen?
85
+
86
+ # Changing superclass site doesn't overwrite subclass site.
87
+ Person.site = 'http://somewhere.else'
88
+ assert_not_equal Person.site, actor.site
89
+
90
+ # Changing superclass site after subclassing changes subclass site.
91
+ jester = Class.new(actor)
92
+ actor.site = 'http://nomad'
93
+ assert_equal actor.site, jester.site
94
+ assert jester.site.frozen?
95
+
96
+ # Subclasses are always equal to superclass site when not overridden
97
+ fruit = Class.new(ActiveResource::Base)
98
+ apple = Class.new(fruit)
99
+
100
+ fruit.site = 'http://market'
101
+ assert_equal fruit.site, apple.site, 'subclass did not adopt changes to parent class'
102
+
103
+ fruit.site = 'http://supermarket'
104
+ assert_equal fruit.site, apple.site, 'subclass did not adopt changes to parent class'
105
+ end
106
+
107
+ def test_updating_baseclass_site_object_wipes_descendent_cached_connection_objects
108
+ # Subclasses are always equal to superclass site when not overridden
109
+ fruit = Class.new(ActiveResource::Base)
110
+ apple = Class.new(fruit)
111
+
112
+ fruit.site = 'http://market'
113
+ assert_equal fruit.connection.site, apple.connection.site
114
+
115
+ fruit.site = 'http://supermarket'
116
+ assert_equal fruit.connection.site, apple.connection.site
117
+ end
118
+
119
+ def test_collection_name
120
+ assert_equal "people", Person.collection_name
121
+ end
122
+
123
+ def test_collection_path
124
+ assert_equal '/people.xml', Person.collection_path
125
+ end
126
+
127
+ def test_collection_path_with_parameters
128
+ assert_equal '/people.xml?gender=male', Person.collection_path(:gender => 'male')
129
+ assert_equal '/people.xml?gender=false', Person.collection_path(:gender => false)
130
+ assert_equal '/people.xml?gender=', Person.collection_path(:gender => nil)
131
+
132
+ assert_equal '/people.xml?gender=male', Person.collection_path('gender' => 'male')
133
+
134
+ # Use includes? because ordering of param hash is not guaranteed
135
+ assert Person.collection_path(:gender => 'male', :student => true).include?('/people.xml?')
136
+ assert Person.collection_path(:gender => 'male', :student => true).include?('gender=male')
137
+ assert Person.collection_path(:gender => 'male', :student => true).include?('student=true')
138
+
139
+ assert_equal '/people.xml?name%5B%5D=bob&name%5B%5D=your+uncle%2Bme&name%5B%5D=&name%5B%5D=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false])
140
+
141
+ assert_equal '/people.xml?struct%5Ba%5D%5B%5D=2&struct%5Ba%5D%5B%5D=1&struct%5Bb%5D=fred', Person.collection_path(:struct => {:a => [2,1], 'b' => 'fred'})
142
+ end
143
+
144
+ def test_custom_element_path
145
+ assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, :person_id => 1)
146
+ assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, 'person_id' => 1)
147
+ end
148
+
149
+ def test_custom_element_path_with_parameters
150
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work')
151
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, 'person_id' => 1, :type => 'work')
152
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :type => 'work', :person_id => 1)
153
+ assert_equal '/people/1/addresses/1.xml?type%5B%5D=work&type%5B%5D=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time'])
154
+ end
155
+
156
+ def test_custom_element_path_with_prefix_and_parameters
157
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, {:person_id => 1}, {:type => 'work'})
158
+ end
159
+
160
+ def test_custom_collection_path
161
+ assert_equal '/people/1/addresses.xml', StreetAddress.collection_path(:person_id => 1)
162
+ assert_equal '/people/1/addresses.xml', StreetAddress.collection_path('person_id' => 1)
163
+ end
164
+
165
+ def test_custom_collection_path_with_parameters
166
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path(:person_id => 1, :type => 'work')
167
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path('person_id' => 1, :type => 'work')
168
+ end
169
+
170
+ def test_custom_collection_path_with_prefix_and_parameters
171
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path({:person_id => 1}, {:type => 'work'})
172
+ end
173
+
174
+ def test_custom_element_name
175
+ assert_equal 'address', StreetAddress.element_name
176
+ end
177
+
178
+ def test_custom_collection_name
179
+ assert_equal 'addresses', StreetAddress.collection_name
180
+ end
181
+
182
+ def test_prefix
183
+ assert_equal "/", Person.prefix
184
+ assert_equal Set.new, Person.send!(:prefix_parameters)
185
+ end
186
+
187
+ def test_set_prefix
188
+ SetterTrap.rollback_sets(Person) do |person_class|
189
+ person_class.prefix = "the_prefix"
190
+ assert_equal "the_prefix", person_class.prefix
191
+ end
192
+ end
193
+
194
+ def test_set_prefix_with_inline_keys
195
+ SetterTrap.rollback_sets(Person) do |person_class|
196
+ person_class.prefix = "the_prefix:the_param"
197
+ assert_equal "the_prefixthe_param_value", person_class.prefix(:the_param => "the_param_value")
198
+ end
199
+ end
200
+
201
+ def test_set_prefix_with_default_value
202
+ SetterTrap.rollback_sets(Person) do |person_class|
203
+ person_class.set_prefix
204
+ assert_equal "/", person_class.prefix
205
+ end
206
+ end
207
+
208
+ def test_custom_prefix
209
+ assert_equal '/people//', StreetAddress.prefix
210
+ assert_equal '/people/1/', StreetAddress.prefix(:person_id => 1)
211
+ assert_equal [:person_id].to_set, StreetAddress.send!(:prefix_parameters)
212
+ end
213
+
214
+ def test_find_by_id
215
+ matz = Person.find(1)
216
+ assert_kind_of Person, matz
217
+ assert_equal "Matz", matz.name
218
+ assert matz.name?
219
+ end
220
+
221
+ def test_respond_to
222
+ matz = Person.find(1)
223
+ assert matz.respond_to?(:name)
224
+ assert matz.respond_to?(:name=)
225
+ assert matz.respond_to?(:name?)
226
+ assert !matz.respond_to?(:super_scalable_stuff)
227
+ end
228
+
229
+ def test_find_by_id_with_custom_prefix
230
+ addy = StreetAddress.find(1, :params => { :person_id => 1 })
231
+ assert_kind_of StreetAddress, addy
232
+ assert_equal '12345 Street', addy.street
233
+ end
234
+
235
+ def test_find_all
236
+ all = Person.find(:all)
237
+ assert_equal 2, all.size
238
+ assert_kind_of Person, all.first
239
+ assert_equal "Matz", all.first.name
240
+ assert_equal "David", all.last.name
241
+ end
242
+
243
+ def test_find_first
244
+ matz = Person.find(:first)
245
+ assert_kind_of Person, matz
246
+ assert_equal "Matz", matz.name
247
+ end
248
+
249
+ def test_custom_header
250
+ Person.headers['key'] = 'value'
251
+ assert_raises(ActiveResource::ResourceNotFound) { Person.find(3) }
252
+ ensure
253
+ Person.headers.delete('key')
254
+ end
255
+
256
+ def test_find_by_id_not_found
257
+ assert_raises(ActiveResource::ResourceNotFound) { Person.find(99) }
258
+ assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1) }
259
+ end
260
+
261
+ def test_find_all_by_from
262
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
263
+
264
+ people = Person.find(:all, :from => "/companies/1/people.xml")
265
+ assert_equal 1, people.size
266
+ assert_equal "David", people.first.name
267
+ end
268
+
269
+ def test_find_all_by_from_with_options
270
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
271
+
272
+ people = Person.find(:all, :from => "/companies/1/people.xml")
273
+ assert_equal 1, people.size
274
+ assert_equal "David", people.first.name
275
+ end
276
+
277
+ def test_find_all_by_symbol_from
278
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, @people_david }
279
+
280
+ people = Person.find(:all, :from => :managers)
281
+ assert_equal 1, people.size
282
+ assert_equal "David", people.first.name
283
+ end
284
+
285
+ def test_find_single_by_from
286
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david }
287
+
288
+ david = Person.find(:one, :from => "/companies/1/manager.xml")
289
+ assert_equal "David", david.name
290
+ end
291
+
292
+ def test_find_single_by_symbol_from
293
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david }
294
+
295
+ david = Person.find(:one, :from => :leader)
296
+ assert_equal "David", david.name
297
+ end
298
+
299
+ def test_save
300
+ rick = Person.new
301
+ assert_equal true, rick.save
302
+ assert_equal '5', rick.id
303
+ end
304
+
305
+ def test_id_from_response
306
+ p = Person.new
307
+ resp = {'Location' => '/foo/bar/1'}
308
+ assert_equal '1', p.send!(:id_from_response, resp)
309
+
310
+ resp['Location'] << '.xml'
311
+ assert_equal '1', p.send!(:id_from_response, resp)
312
+ end
313
+
314
+ def test_create_with_custom_prefix
315
+ matzs_house = StreetAddress.new(:person_id => 1)
316
+ matzs_house.save
317
+ assert_equal '5', matzs_house.id
318
+ end
319
+
320
+ # Test that loading a resource preserves its prefix_options.
321
+ def test_load_preserves_prefix_options
322
+ address = StreetAddress.find(1, :params => { :person_id => 1 })
323
+ ryan = Person.new(:id => 1, :name => 'Ryan', :address => address)
324
+ assert_equal address.prefix_options, ryan.address.prefix_options
325
+ end
326
+
327
+ def test_reload_works_with_prefix_options
328
+ address = StreetAddress.find(1, :params => { :person_id => 1 })
329
+ assert_equal address, address.reload
330
+ end
331
+
332
+ def test_reload_works_without_prefix_options
333
+ person = Person.find(:first)
334
+ assert_equal person, person.reload
335
+ end
336
+
337
+
338
+ def test_create
339
+ rick = Person.create(:name => 'Rick')
340
+ assert rick.valid?
341
+ assert !rick.new?
342
+ assert_equal '5', rick.id
343
+
344
+ # test additional attribute returned on create
345
+ assert_equal 25, rick.age
346
+
347
+ # Test that save exceptions get bubbled up too
348
+ ActiveResource::HttpMock.respond_to do |mock|
349
+ mock.post "/people.xml", {}, nil, 409
350
+ end
351
+ assert_raises(ActiveResource::ResourceConflict) { Person.create(:name => 'Rick') }
352
+ end
353
+
354
+ def test_update
355
+ matz = Person.find(:first)
356
+ matz.name = "David"
357
+ assert_kind_of Person, matz
358
+ assert_equal "David", matz.name
359
+ assert_equal true, matz.save
360
+ end
361
+
362
+ def test_update_with_custom_prefix_with_specific_id
363
+ addy = StreetAddress.find(1, :params => { :person_id => 1 })
364
+ addy.street = "54321 Street"
365
+ assert_kind_of StreetAddress, addy
366
+ assert_equal "54321 Street", addy.street
367
+ addy.save
368
+ end
369
+
370
+ def test_update_with_custom_prefix_without_specific_id
371
+ addy = StreetAddress.find(:first, :params => { :person_id => 1 })
372
+ addy.street = "54321 Lane"
373
+ assert_kind_of StreetAddress, addy
374
+ assert_equal "54321 Lane", addy.street
375
+ addy.save
376
+ end
377
+
378
+ def test_update_conflict
379
+ ActiveResource::HttpMock.respond_to do |mock|
380
+ mock.get "/people/2.xml", {}, @david
381
+ mock.put "/people/2.xml", @default_request_headers, nil, 409
382
+ end
383
+ assert_raises(ActiveResource::ResourceConflict) { Person.find(2).save }
384
+ end
385
+
386
+ def test_destroy
387
+ assert Person.find(1).destroy
388
+ ActiveResource::HttpMock.respond_to do |mock|
389
+ mock.get "/people/1.xml", {}, nil, 404
390
+ end
391
+ assert_raises(ActiveResource::ResourceNotFound) { Person.find(1).destroy }
392
+ end
393
+
394
+ def test_destroy_with_custom_prefix
395
+ assert StreetAddress.find(1, :params => { :person_id => 1 }).destroy
396
+ ActiveResource::HttpMock.respond_to do |mock|
397
+ mock.get "/people/1/addresses/1.xml", {}, nil, 404
398
+ end
399
+ assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
400
+ end
401
+
402
+ def test_delete
403
+ assert Person.delete(1)
404
+ ActiveResource::HttpMock.respond_to do |mock|
405
+ mock.get "/people/1.xml", {}, nil, 404
406
+ end
407
+ assert_raises(ActiveResource::ResourceNotFound) { Person.find(1) }
408
+ end
409
+
410
+ def test_delete_with_custom_prefix
411
+ assert StreetAddress.delete(1, :person_id => 1)
412
+ ActiveResource::HttpMock.respond_to do |mock|
413
+ mock.get "/people/1/addresses/1.xml", {}, nil, 404
414
+ end
415
+ assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
416
+ end
417
+
418
+ def test_exists
419
+ # Class method.
420
+ assert !Person.exists?(nil)
421
+ assert Person.exists?(1)
422
+ assert !Person.exists?(99)
423
+
424
+ # Instance method.
425
+ assert !Person.new.exists?
426
+ assert Person.find(1).exists?
427
+ assert !Person.new(:id => 99).exists?
428
+
429
+ # Nested class method.
430
+ assert StreetAddress.exists?(1, :params => { :person_id => 1 })
431
+ assert !StreetAddress.exists?(1, :params => { :person_id => 2 })
432
+ assert !StreetAddress.exists?(2, :params => { :person_id => 1 })
433
+
434
+ # Nested instance method.
435
+ assert StreetAddress.find(1, :params => { :person_id => 1 }).exists?
436
+ assert !StreetAddress.new({:id => 1, :person_id => 2}).exists?
437
+ assert !StreetAddress.new({:id => 2, :person_id => 1}).exists?
438
+ end
439
+
440
+ def test_to_xml
441
+ matz = Person.find(1)
442
+ xml = matz.to_xml
443
+ assert xml.starts_with?('<?xml version="1.0" encoding="UTF-8"?>')
444
+ assert xml.include?('<name>Matz</name>')
445
+ assert xml.include?('<id type="integer">1</id>')
446
+ end
447
+
448
+ def test_to_param_quacks_like_active_record
449
+ new_person = Person.new
450
+ assert_nil new_person.to_param
451
+ matz = Person.find(1)
452
+ assert_equal '1', matz.to_param
453
+ end
454
+ end