activeresource_csi 2.3.5.p6

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.
data/test/base_test.rb ADDED
@@ -0,0 +1,1038 @@
1
+ require 'abstract_unit'
2
+ require "fixtures/person"
3
+ require "fixtures/customer"
4
+ require "fixtures/street_address"
5
+ require "fixtures/beast"
6
+ require "fixtures/proxy"
7
+
8
+ class BaseTest < Test::Unit::TestCase
9
+ def setup
10
+ @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
11
+ @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
12
+ @greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
13
+ @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
14
+ @default_request_headers = { 'Content-Type' => 'application/xml' }
15
+ @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
16
+ @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
17
+ @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
18
+ @addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses')
19
+
20
+ # - deep nested resource -
21
+ # - Luis (Customer)
22
+ # - JK (Customer::Friend)
23
+ # - Mateo (Customer::Friend::Brother)
24
+ # - Edith (Customer::Friend::Brother::Child)
25
+ # - Martha (Customer::Friend::Brother::Child)
26
+ # - Felipe (Customer::Friend::Brother)
27
+ # - Bryan (Customer::Friend::Brother::Child)
28
+ # - Luke (Customer::Friend::Brother::Child)
29
+ # - Eduardo (Customer::Friend)
30
+ # - Sebas (Customer::Friend::Brother)
31
+ # - Andres (Customer::Friend::Brother::Child)
32
+ # - Jorge (Customer::Friend::Brother::Child)
33
+ # - Elsa (Customer::Friend::Brother)
34
+ # - Natacha (Customer::Friend::Brother::Child)
35
+ # - Milena (Customer::Friend::Brother)
36
+ #
37
+ @luis = {:id => 1, :name => 'Luis',
38
+ :friends => [{:name => 'JK',
39
+ :brothers => [{:name => 'Mateo',
40
+ :children => [{:name => 'Edith'},{:name => 'Martha'}]},
41
+ {:name => 'Felipe',
42
+ :children => [{:name => 'Bryan'},{:name => 'Luke'}]}]},
43
+ {:name => 'Eduardo',
44
+ :brothers => [{:name => 'Sebas',
45
+ :children => [{:name => 'Andres'},{:name => 'Jorge'}]},
46
+ {:name => 'Elsa',
47
+ :children => [{:name => 'Natacha'}]},
48
+ {:name => 'Milena',
49
+ :children => []}]}]}.to_xml(:root => 'customer')
50
+ # - resource with yaml array of strings; for ActiveRecords using serialize :bar, Array
51
+ @marty = <<-eof.strip
52
+ <?xml version=\"1.0\" encoding=\"UTF-8\"?>
53
+ <person>
54
+ <id type=\"integer\">5</id>
55
+ <name>Marty</name>
56
+ <colors type=\"yaml\">---
57
+ - \"red\"
58
+ - \"green\"
59
+ - \"blue\"
60
+ </colors>
61
+ </person>
62
+ eof
63
+
64
+ ActiveResource::HttpMock.respond_to do |mock|
65
+ mock.get "/people/1.xml", {}, @matz
66
+ mock.get "/people/2.xml", {}, @david
67
+ mock.get "/people/5.xml", {}, @marty
68
+ mock.get "/people/Greg.xml", {}, @greg
69
+ mock.get "/people/4.xml", {'key' => 'value'}, nil, 404
70
+ mock.put "/people/1.xml", {}, nil, 204
71
+ mock.delete "/people/1.xml", {}, nil, 200
72
+ mock.delete "/people/2.xml", {}, nil, 400
73
+ mock.get "/people/99.xml", {}, nil, 404
74
+ mock.post "/people.xml", {}, @rick, 201, 'Location' => '/people/5.xml'
75
+ mock.get "/people.xml", {}, @people
76
+ mock.get "/people/1/addresses.xml", {}, @addresses
77
+ mock.get "/people/1/addresses/1.xml", {}, @addy
78
+ mock.get "/people/1/addresses/2.xml", {}, nil, 404
79
+ mock.get "/people/2/addresses/1.xml", {}, nil, 404
80
+ mock.get "/people/Greg/addresses/1.xml", {}, @addy
81
+ mock.put "/people/1/addresses/1.xml", {}, nil, 204
82
+ mock.delete "/people/1/addresses/1.xml", {}, nil, 200
83
+ mock.post "/people/1/addresses.xml", {}, nil, 201, 'Location' => '/people/1/addresses/5'
84
+ mock.get "/people//addresses.xml", {}, nil, 404
85
+ mock.get "/people//addresses/1.xml", {}, nil, 404
86
+ mock.put "/people//addresses/1.xml", {}, nil, 404
87
+ mock.delete "/people//addresses/1.xml", {}, nil, 404
88
+ mock.post "/people//addresses.xml", {}, nil, 404
89
+ mock.head "/people/1.xml", {}, nil, 200
90
+ mock.head "/people/Greg.xml", {}, nil, 200
91
+ mock.head "/people/99.xml", {}, nil, 404
92
+ mock.head "/people/1/addresses/1.xml", {}, nil, 200
93
+ mock.head "/people/1/addresses/2.xml", {}, nil, 404
94
+ mock.head "/people/2/addresses/1.xml", {}, nil, 404
95
+ mock.head "/people/Greg/addresses/1.xml", {}, nil, 200
96
+ # customer
97
+ mock.get "/customers/1.xml", {}, @luis
98
+ end
99
+
100
+ Person.user = nil
101
+ Person.password = nil
102
+ end
103
+
104
+
105
+ def test_site_accessor_accepts_uri_or_string_argument
106
+ site = URI.parse('http://localhost')
107
+
108
+ assert_nothing_raised { Person.site = 'http://localhost' }
109
+ assert_equal site, Person.site
110
+
111
+ assert_nothing_raised { Person.site = site }
112
+ assert_equal site, Person.site
113
+ end
114
+
115
+ def test_should_use_site_prefix_and_credentials
116
+ assert_equal 'http://foo:bar@beast.caboo.se', Forum.site.to_s
117
+ assert_equal 'http://foo:bar@beast.caboo.se/forums/:forum_id', Topic.site.to_s
118
+ end
119
+
120
+ def test_site_variable_can_be_reset
121
+ actor = Class.new(ActiveResource::Base)
122
+ assert_nil actor.site
123
+ actor.site = 'http://localhost:31337'
124
+ actor.site = nil
125
+ assert_nil actor.site
126
+ end
127
+
128
+ def test_proxy_accessor_accepts_uri_or_string_argument
129
+ proxy = URI.parse('http://localhost')
130
+
131
+ assert_nothing_raised { Person.proxy = 'http://localhost' }
132
+ assert_equal proxy, Person.proxy
133
+
134
+ assert_nothing_raised { Person.proxy = proxy }
135
+ assert_equal proxy, Person.proxy
136
+ end
137
+
138
+ def test_should_use_proxy_prefix_and_credentials
139
+ assert_equal 'http://user:password@proxy.local:3000', ProxyResource.proxy.to_s
140
+ end
141
+
142
+ def test_proxy_variable_can_be_reset
143
+ actor = Class.new(ActiveResource::Base)
144
+ assert_nil actor.site
145
+ actor.proxy = 'http://localhost:31337'
146
+ actor.proxy = nil
147
+ assert_nil actor.site
148
+ end
149
+
150
+ def test_should_accept_setting_user
151
+ Forum.user = 'david'
152
+ assert_equal('david', Forum.user)
153
+ assert_equal('david', Forum.connection.user)
154
+ end
155
+
156
+ def test_should_accept_setting_password
157
+ Forum.password = 'test123'
158
+ assert_equal('test123', Forum.password)
159
+ assert_equal('test123', Forum.connection.password)
160
+ end
161
+
162
+ def test_should_accept_setting_timeout
163
+ Forum.timeout = 5
164
+ assert_equal(5, Forum.timeout)
165
+ assert_equal(5, Forum.connection.timeout)
166
+ end
167
+
168
+ def test_should_accept_setting_ssl_options
169
+ expected = {:verify => 1}
170
+ Forum.ssl_options= expected
171
+ assert_equal(expected, Forum.ssl_options)
172
+ assert_equal(expected, Forum.connection.ssl_options)
173
+ end
174
+
175
+ def test_user_variable_can_be_reset
176
+ actor = Class.new(ActiveResource::Base)
177
+ actor.site = 'http://cinema'
178
+ assert_nil actor.user
179
+ actor.user = 'username'
180
+ actor.user = nil
181
+ assert_nil actor.user
182
+ assert_nil actor.connection.user
183
+ end
184
+
185
+ def test_password_variable_can_be_reset
186
+ actor = Class.new(ActiveResource::Base)
187
+ actor.site = 'http://cinema'
188
+ assert_nil actor.password
189
+ actor.password = 'username'
190
+ actor.password = nil
191
+ assert_nil actor.password
192
+ assert_nil actor.connection.password
193
+ end
194
+
195
+ def test_timeout_variable_can_be_reset
196
+ actor = Class.new(ActiveResource::Base)
197
+ actor.site = 'http://cinema'
198
+ assert_nil actor.timeout
199
+ actor.timeout = 5
200
+ actor.timeout = nil
201
+ assert_nil actor.timeout
202
+ assert_nil actor.connection.timeout
203
+ end
204
+
205
+ def test_ssl_options_hash_can_be_reset
206
+ actor = Class.new(ActiveResource::Base)
207
+ actor.site = 'https://cinema'
208
+ assert_nil actor.ssl_options
209
+ actor.ssl_options = {:foo => 5}
210
+ actor.ssl_options = nil
211
+ assert_nil actor.ssl_options
212
+ assert_nil actor.connection.ssl_options
213
+ end
214
+
215
+ def test_credentials_from_site_are_decoded
216
+ actor = Class.new(ActiveResource::Base)
217
+ actor.site = 'http://my%40email.com:%31%32%33@cinema'
218
+ assert_equal("my@email.com", actor.user)
219
+ assert_equal("123", actor.password)
220
+ end
221
+
222
+ def test_site_reader_uses_superclass_site_until_written
223
+ # Superclass is Object so returns nil.
224
+ assert_nil ActiveResource::Base.site
225
+ assert_nil Class.new(ActiveResource::Base).site
226
+
227
+ # Subclass uses superclass site.
228
+ actor = Class.new(Person)
229
+ assert_equal Person.site, actor.site
230
+
231
+ # Subclass returns frozen superclass copy.
232
+ assert !Person.site.frozen?
233
+ assert actor.site.frozen?
234
+
235
+ # Changing subclass site doesn't change superclass site.
236
+ actor.site = 'http://localhost:31337'
237
+ assert_not_equal Person.site, actor.site
238
+
239
+ # Changed subclass site is not frozen.
240
+ assert !actor.site.frozen?
241
+
242
+ # Changing superclass site doesn't overwrite subclass site.
243
+ Person.site = 'http://somewhere.else'
244
+ assert_not_equal Person.site, actor.site
245
+
246
+ # Changing superclass site after subclassing changes subclass site.
247
+ jester = Class.new(actor)
248
+ actor.site = 'http://nomad'
249
+ assert_equal actor.site, jester.site
250
+ assert jester.site.frozen?
251
+
252
+ # Subclasses are always equal to superclass site when not overridden
253
+ fruit = Class.new(ActiveResource::Base)
254
+ apple = Class.new(fruit)
255
+
256
+ fruit.site = 'http://market'
257
+ assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
258
+
259
+ fruit.site = 'http://supermarket'
260
+ assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
261
+ end
262
+
263
+ def test_proxy_reader_uses_superclass_site_until_written
264
+ # Superclass is Object so returns nil.
265
+ assert_nil ActiveResource::Base.proxy
266
+ assert_nil Class.new(ActiveResource::Base).proxy
267
+
268
+ # Subclass uses superclass proxy.
269
+ actor = Class.new(Person)
270
+ assert_equal Person.proxy, actor.proxy
271
+
272
+ # Subclass returns frozen superclass copy.
273
+ assert !Person.proxy.frozen?
274
+ assert actor.proxy.frozen?
275
+
276
+ # Changing subclass proxy doesn't change superclass site.
277
+ actor.proxy = 'http://localhost:31337'
278
+ assert_not_equal Person.proxy, actor.proxy
279
+
280
+ # Changed subclass proxy is not frozen.
281
+ assert !actor.proxy.frozen?
282
+
283
+ # Changing superclass proxy doesn't overwrite subclass site.
284
+ Person.proxy = 'http://somewhere.else'
285
+ assert_not_equal Person.proxy, actor.proxy
286
+
287
+ # Changing superclass proxy after subclassing changes subclass site.
288
+ jester = Class.new(actor)
289
+ actor.proxy = 'http://nomad'
290
+ assert_equal actor.proxy, jester.proxy
291
+ assert jester.proxy.frozen?
292
+
293
+ # Subclasses are always equal to superclass proxy when not overridden
294
+ fruit = Class.new(ActiveResource::Base)
295
+ apple = Class.new(fruit)
296
+
297
+ fruit.proxy = 'http://market'
298
+ assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
299
+
300
+ fruit.proxy = 'http://supermarket'
301
+ assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
302
+ end
303
+
304
+ def test_user_reader_uses_superclass_user_until_written
305
+ # Superclass is Object so returns nil.
306
+ assert_nil ActiveResource::Base.user
307
+ assert_nil Class.new(ActiveResource::Base).user
308
+ Person.user = 'anonymous'
309
+
310
+ # Subclass uses superclass user.
311
+ actor = Class.new(Person)
312
+ assert_equal Person.user, actor.user
313
+
314
+ # Subclass returns frozen superclass copy.
315
+ assert !Person.user.frozen?
316
+ assert actor.user.frozen?
317
+
318
+ # Changing subclass user doesn't change superclass user.
319
+ actor.user = 'david'
320
+ assert_not_equal Person.user, actor.user
321
+
322
+ # Changing superclass user doesn't overwrite subclass user.
323
+ Person.user = 'john'
324
+ assert_not_equal Person.user, actor.user
325
+
326
+ # Changing superclass user after subclassing changes subclass user.
327
+ jester = Class.new(actor)
328
+ actor.user = 'john.doe'
329
+ assert_equal actor.user, jester.user
330
+
331
+ # Subclasses are always equal to superclass user when not overridden
332
+ fruit = Class.new(ActiveResource::Base)
333
+ apple = Class.new(fruit)
334
+
335
+ fruit.user = 'manager'
336
+ assert_equal fruit.user, apple.user, 'subclass did not adopt changes from parent class'
337
+
338
+ fruit.user = 'client'
339
+ assert_equal fruit.user, apple.user, 'subclass did not adopt changes from parent class'
340
+ end
341
+
342
+ def test_password_reader_uses_superclass_password_until_written
343
+ # Superclass is Object so returns nil.
344
+ assert_nil ActiveResource::Base.password
345
+ assert_nil Class.new(ActiveResource::Base).password
346
+ Person.password = 'my-password'
347
+
348
+ # Subclass uses superclass password.
349
+ actor = Class.new(Person)
350
+ assert_equal Person.password, actor.password
351
+
352
+ # Subclass returns frozen superclass copy.
353
+ assert !Person.password.frozen?
354
+ assert actor.password.frozen?
355
+
356
+ # Changing subclass password doesn't change superclass password.
357
+ actor.password = 'secret'
358
+ assert_not_equal Person.password, actor.password
359
+
360
+ # Changing superclass password doesn't overwrite subclass password.
361
+ Person.password = 'super-secret'
362
+ assert_not_equal Person.password, actor.password
363
+
364
+ # Changing superclass password after subclassing changes subclass password.
365
+ jester = Class.new(actor)
366
+ actor.password = 'even-more-secret'
367
+ assert_equal actor.password, jester.password
368
+
369
+ # Subclasses are always equal to superclass password when not overridden
370
+ fruit = Class.new(ActiveResource::Base)
371
+ apple = Class.new(fruit)
372
+
373
+ fruit.password = 'mega-secret'
374
+ assert_equal fruit.password, apple.password, 'subclass did not adopt changes from parent class'
375
+
376
+ fruit.password = 'ok-password'
377
+ assert_equal fruit.password, apple.password, 'subclass did not adopt changes from parent class'
378
+ end
379
+
380
+ def test_timeout_reader_uses_superclass_timeout_until_written
381
+ # Superclass is Object so returns nil.
382
+ assert_nil ActiveResource::Base.timeout
383
+ assert_nil Class.new(ActiveResource::Base).timeout
384
+ Person.timeout = 5
385
+
386
+ # Subclass uses superclass timeout.
387
+ actor = Class.new(Person)
388
+ assert_equal Person.timeout, actor.timeout
389
+
390
+ # Changing subclass timeout doesn't change superclass timeout.
391
+ actor.timeout = 10
392
+ assert_not_equal Person.timeout, actor.timeout
393
+
394
+ # Changing superclass timeout doesn't overwrite subclass timeout.
395
+ Person.timeout = 15
396
+ assert_not_equal Person.timeout, actor.timeout
397
+
398
+ # Changing superclass timeout after subclassing changes subclass timeout.
399
+ jester = Class.new(actor)
400
+ actor.timeout = 20
401
+ assert_equal actor.timeout, jester.timeout
402
+
403
+ # Subclasses are always equal to superclass timeout when not overridden.
404
+ fruit = Class.new(ActiveResource::Base)
405
+ apple = Class.new(fruit)
406
+
407
+ fruit.timeout = 25
408
+ assert_equal fruit.timeout, apple.timeout, 'subclass did not adopt changes from parent class'
409
+
410
+ fruit.timeout = 30
411
+ assert_equal fruit.timeout, apple.timeout, 'subclass did not adopt changes from parent class'
412
+ end
413
+
414
+ def test_ssl_options_reader_uses_superclass_ssl_options_until_written
415
+ # Superclass is Object so returns nil.
416
+ assert_nil ActiveResource::Base.ssl_options
417
+ assert_nil Class.new(ActiveResource::Base).ssl_options
418
+ Person.ssl_options = {:foo => 'bar'}
419
+
420
+ # Subclass uses superclass ssl_options.
421
+ actor = Class.new(Person)
422
+ assert_equal Person.ssl_options, actor.ssl_options
423
+
424
+ # Changing subclass ssl_options doesn't change superclass ssl_options.
425
+ actor.ssl_options = {:baz => ''}
426
+ assert_not_equal Person.ssl_options, actor.ssl_options
427
+
428
+ # Changing superclass ssl_options doesn't overwrite subclass ssl_options.
429
+ Person.ssl_options = {:color => 'blue'}
430
+ assert_not_equal Person.ssl_options, actor.ssl_options
431
+
432
+ # Changing superclass ssl_options after subclassing changes subclass ssl_options.
433
+ jester = Class.new(actor)
434
+ actor.ssl_options = {:color => 'red'}
435
+ assert_equal actor.ssl_options, jester.ssl_options
436
+
437
+ # Subclasses are always equal to superclass ssl_options when not overridden.
438
+ fruit = Class.new(ActiveResource::Base)
439
+ apple = Class.new(fruit)
440
+
441
+ fruit.ssl_options = {:alpha => 'betas'}
442
+ assert_equal fruit.ssl_options, apple.ssl_options, 'subclass did not adopt changes from parent class'
443
+
444
+ fruit.ssl_options = {:omega => 'moos'}
445
+ assert_equal fruit.ssl_options, apple.ssl_options, 'subclass did not adopt changes from parent class'
446
+ end
447
+
448
+ def test_updating_baseclass_site_object_wipes_descendent_cached_connection_objects
449
+ # Subclasses are always equal to superclass site when not overridden
450
+ fruit = Class.new(ActiveResource::Base)
451
+ apple = Class.new(fruit)
452
+
453
+ fruit.site = 'http://market'
454
+ assert_equal fruit.connection.site, apple.connection.site
455
+ first_connection = apple.connection.object_id
456
+
457
+ fruit.site = 'http://supermarket'
458
+ assert_equal fruit.connection.site, apple.connection.site
459
+ second_connection = apple.connection.object_id
460
+ assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
461
+ end
462
+
463
+ def test_updating_baseclass_user_wipes_descendent_cached_connection_objects
464
+ # Subclasses are always equal to superclass user when not overridden
465
+ fruit = Class.new(ActiveResource::Base)
466
+ apple = Class.new(fruit)
467
+ fruit.site = 'http://market'
468
+
469
+ fruit.user = 'david'
470
+ assert_equal fruit.connection.user, apple.connection.user
471
+ first_connection = apple.connection.object_id
472
+
473
+ fruit.user = 'john'
474
+ assert_equal fruit.connection.user, apple.connection.user
475
+ second_connection = apple.connection.object_id
476
+ assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
477
+ end
478
+
479
+ def test_updating_baseclass_password_wipes_descendent_cached_connection_objects
480
+ # Subclasses are always equal to superclass password when not overridden
481
+ fruit = Class.new(ActiveResource::Base)
482
+ apple = Class.new(fruit)
483
+ fruit.site = 'http://market'
484
+
485
+ fruit.password = 'secret'
486
+ assert_equal fruit.connection.password, apple.connection.password
487
+ first_connection = apple.connection.object_id
488
+
489
+ fruit.password = 'supersecret'
490
+ assert_equal fruit.connection.password, apple.connection.password
491
+ second_connection = apple.connection.object_id
492
+ assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
493
+ end
494
+
495
+ def test_updating_baseclass_timeout_wipes_descendent_cached_connection_objects
496
+ # Subclasses are always equal to superclass timeout when not overridden
497
+ fruit = Class.new(ActiveResource::Base)
498
+ apple = Class.new(fruit)
499
+ fruit.site = 'http://market'
500
+
501
+ fruit.timeout = 5
502
+ assert_equal fruit.connection.timeout, apple.connection.timeout
503
+ first_connection = apple.connection.object_id
504
+
505
+ fruit.timeout = 10
506
+ assert_equal fruit.connection.timeout, apple.connection.timeout
507
+ second_connection = apple.connection.object_id
508
+ assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
509
+ end
510
+
511
+ def test_collection_name
512
+ assert_equal "people", Person.collection_name
513
+ end
514
+
515
+ def test_collection_path
516
+ assert_equal '/people.xml', Person.collection_path
517
+ end
518
+
519
+ def test_collection_path_with_parameters
520
+ assert_equal '/people.xml?gender=male', Person.collection_path(:gender => 'male')
521
+ assert_equal '/people.xml?gender=false', Person.collection_path(:gender => false)
522
+ assert_equal '/people.xml?gender=', Person.collection_path(:gender => nil)
523
+
524
+ assert_equal '/people.xml?gender=male', Person.collection_path('gender' => 'male')
525
+
526
+ # Use includes? because ordering of param hash is not guaranteed
527
+ assert Person.collection_path(:gender => 'male', :student => true).include?('/people.xml?')
528
+ assert Person.collection_path(:gender => 'male', :student => true).include?('gender=male')
529
+ assert Person.collection_path(:gender => 'male', :student => true).include?('student=true')
530
+
531
+ 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])
532
+
533
+ 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'})
534
+ end
535
+
536
+ def test_custom_element_path
537
+ assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, :person_id => 1)
538
+ assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, 'person_id' => 1)
539
+ assert_equal '/people/Greg/addresses/1.xml', StreetAddress.element_path(1, 'person_id' => 'Greg')
540
+ end
541
+
542
+ def test_custom_element_path_with_redefined_to_param
543
+ Person.module_eval do
544
+ alias_method :original_to_param_element_path, :to_param
545
+ def to_param
546
+ name
547
+ end
548
+ end
549
+
550
+ # Class method.
551
+ assert_equal '/people/Greg.xml', Person.element_path('Greg')
552
+
553
+ # Protected Instance method.
554
+ assert_equal '/people/Greg.xml', Person.find('Greg').send(:element_path)
555
+
556
+ ensure
557
+ # revert back to original
558
+ Person.module_eval do
559
+ # save the 'new' to_param so we don't get a warning about discarding the method
560
+ alias_method :element_path_to_param, :to_param
561
+ alias_method :to_param, :original_to_param_element_path
562
+ end
563
+ end
564
+
565
+ def test_custom_element_path_with_parameters
566
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work')
567
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, 'person_id' => 1, :type => 'work')
568
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :type => 'work', :person_id => 1)
569
+ 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'])
570
+ end
571
+
572
+ def test_custom_element_path_with_prefix_and_parameters
573
+ assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, {:person_id => 1}, {:type => 'work'})
574
+ end
575
+
576
+ def test_custom_collection_path
577
+ assert_equal '/people/1/addresses.xml', StreetAddress.collection_path(:person_id => 1)
578
+ assert_equal '/people/1/addresses.xml', StreetAddress.collection_path('person_id' => 1)
579
+ end
580
+
581
+ def test_custom_collection_path_with_parameters
582
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path(:person_id => 1, :type => 'work')
583
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path('person_id' => 1, :type => 'work')
584
+ end
585
+
586
+ def test_custom_collection_path_with_prefix_and_parameters
587
+ assert_equal '/people/1/addresses.xml?type=work', StreetAddress.collection_path({:person_id => 1}, {:type => 'work'})
588
+ end
589
+
590
+ def test_custom_element_name
591
+ assert_equal 'address', StreetAddress.element_name
592
+ end
593
+
594
+ def test_custom_collection_name
595
+ assert_equal 'addresses', StreetAddress.collection_name
596
+ end
597
+
598
+ def test_prefix
599
+ assert_equal "/", Person.prefix
600
+ assert_equal Set.new, Person.__send__(:prefix_parameters)
601
+ end
602
+
603
+ def test_set_prefix
604
+ SetterTrap.rollback_sets(Person) do |person_class|
605
+ person_class.prefix = "the_prefix"
606
+ assert_equal "the_prefix", person_class.prefix
607
+ end
608
+ end
609
+
610
+ def test_set_prefix_with_inline_keys
611
+ SetterTrap.rollback_sets(Person) do |person_class|
612
+ person_class.prefix = "the_prefix:the_param"
613
+ assert_equal "the_prefixthe_param_value", person_class.prefix(:the_param => "the_param_value")
614
+ end
615
+ end
616
+
617
+ def test_set_prefix_twice_should_clear_params
618
+ SetterTrap.rollback_sets(Person) do |person_class|
619
+ person_class.prefix = "the_prefix/:the_param1"
620
+ assert_equal Set.new([:the_param1]), person_class.prefix_parameters
621
+ person_class.prefix = "the_prefix/:the_param2"
622
+ assert_equal Set.new([:the_param2]), person_class.prefix_parameters
623
+ end
624
+ end
625
+
626
+ def test_set_prefix_with_default_value
627
+ SetterTrap.rollback_sets(Person) do |person_class|
628
+ person_class.set_prefix
629
+ assert_equal "/", person_class.prefix
630
+ end
631
+ end
632
+
633
+ def test_custom_prefix
634
+ assert_equal '/people//', StreetAddress.prefix
635
+ assert_equal '/people/1/', StreetAddress.prefix(:person_id => 1)
636
+ assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters)
637
+ end
638
+
639
+ def test_find_by_id
640
+ matz = Person.find(1)
641
+ assert_kind_of Person, matz
642
+ assert_equal "Matz", matz.name
643
+ assert matz.name?
644
+ end
645
+
646
+ def test_respond_to
647
+ matz = Person.find(1)
648
+ assert matz.respond_to?(:name)
649
+ assert matz.respond_to?(:name=)
650
+ assert matz.respond_to?(:name?)
651
+ assert !matz.respond_to?(:super_scalable_stuff)
652
+ end
653
+
654
+ def test_find_by_id_with_custom_prefix
655
+ addy = StreetAddress.find(1, :params => { :person_id => 1 })
656
+ assert_kind_of StreetAddress, addy
657
+ assert_equal '12345 Street', addy.street
658
+ end
659
+
660
+ def test_find_all
661
+ all = Person.find(:all)
662
+ assert_equal 2, all.size
663
+ assert_kind_of Person, all.first
664
+ assert_equal "Matz", all.first.name
665
+ assert_equal "David", all.last.name
666
+ end
667
+
668
+ def test_find_first
669
+ matz = Person.find(:first)
670
+ assert_kind_of Person, matz
671
+ assert_equal "Matz", matz.name
672
+ end
673
+
674
+ def test_find_last
675
+ david = Person.find(:last)
676
+ assert_kind_of Person, david
677
+ assert_equal 'David', david.name
678
+ end
679
+
680
+ def test_custom_header
681
+ Person.headers['key'] = 'value'
682
+ assert_raise(ActiveResource::ResourceNotFound) { Person.find(4) }
683
+ ensure
684
+ Person.headers.delete('key')
685
+ end
686
+
687
+ def test_find_by_id_not_found
688
+ assert_raise(ActiveResource::ResourceNotFound) { Person.find(99) }
689
+ assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1) }
690
+ end
691
+
692
+ def test_find_all_by_from
693
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
694
+
695
+ people = Person.find(:all, :from => "/companies/1/people.xml")
696
+ assert_equal 1, people.size
697
+ assert_equal "David", people.first.name
698
+ end
699
+
700
+ def test_find_all_by_from_with_options
701
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/people.xml", {}, @people_david }
702
+
703
+ people = Person.find(:all, :from => "/companies/1/people.xml")
704
+ assert_equal 1, people.size
705
+ assert_equal "David", people.first.name
706
+ end
707
+
708
+ def test_find_all_by_symbol_from
709
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/managers.xml", {}, @people_david }
710
+
711
+ people = Person.find(:all, :from => :managers)
712
+ assert_equal 1, people.size
713
+ assert_equal "David", people.first.name
714
+ end
715
+
716
+ def test_find_single_by_from
717
+ ActiveResource::HttpMock.respond_to { |m| m.get "/companies/1/manager.xml", {}, @david }
718
+
719
+ david = Person.find(:one, :from => "/companies/1/manager.xml")
720
+ assert_equal "David", david.name
721
+ end
722
+
723
+ def test_find_single_by_symbol_from
724
+ ActiveResource::HttpMock.respond_to { |m| m.get "/people/leader.xml", {}, @david }
725
+
726
+ david = Person.find(:one, :from => :leader)
727
+ assert_equal "David", david.name
728
+ end
729
+
730
+ def test_save
731
+ rick = Person.new
732
+ assert_equal true, rick.save
733
+ assert_equal '5', rick.id
734
+ end
735
+
736
+ def test_id_from_response
737
+ p = Person.new
738
+ resp = {'Location' => '/foo/bar/1'}
739
+ assert_equal '1', p.__send__(:id_from_response, resp)
740
+
741
+ resp['Location'] << '.xml'
742
+ assert_equal '1', p.__send__(:id_from_response, resp)
743
+ end
744
+
745
+ def test_id_from_response_without_location
746
+ p = Person.new
747
+ resp = {}
748
+ assert_equal nil, p.__send__(:id_from_response, resp)
749
+ end
750
+
751
+ def test_create_with_custom_prefix
752
+ matzs_house = StreetAddress.new(:person_id => 1)
753
+ matzs_house.save
754
+ assert_equal '5', matzs_house.id
755
+ end
756
+
757
+ # Test that loading a resource preserves its prefix_options.
758
+ def test_load_preserves_prefix_options
759
+ address = StreetAddress.find(1, :params => { :person_id => 1 })
760
+ ryan = Person.new(:id => 1, :name => 'Ryan', :address => address)
761
+ assert_equal address.prefix_options, ryan.address.prefix_options
762
+ end
763
+
764
+ def test_reload_works_with_prefix_options
765
+ address = StreetAddress.find(1, :params => { :person_id => 1 })
766
+ assert_equal address, address.reload
767
+ end
768
+
769
+ def test_reload_with_redefined_to_param
770
+ Person.module_eval do
771
+ alias_method :original_to_param_reload, :to_param
772
+ def to_param
773
+ name
774
+ end
775
+ end
776
+
777
+ person = Person.find('Greg')
778
+ assert_equal person, person.reload
779
+
780
+ ensure
781
+ # revert back to original
782
+ Person.module_eval do
783
+ # save the 'new' to_param so we don't get a warning about discarding the method
784
+ alias_method :reload_to_param, :to_param
785
+ alias_method :to_param, :original_to_param_reload
786
+ end
787
+ end
788
+
789
+ def test_reload_works_without_prefix_options
790
+ person = Person.find(:first)
791
+ assert_equal person, person.reload
792
+ end
793
+
794
+ def test_create
795
+ rick = Person.create(:name => 'Rick')
796
+ assert rick.valid?
797
+ assert !rick.new?
798
+ assert_equal '5', rick.id
799
+
800
+ # test additional attribute returned on create
801
+ assert_equal 25, rick.age
802
+
803
+ # Test that save exceptions get bubbled up too
804
+ ActiveResource::HttpMock.respond_to do |mock|
805
+ mock.post "/people.xml", {}, nil, 409
806
+ end
807
+ assert_raise(ActiveResource::ResourceConflict) { Person.create(:name => 'Rick') }
808
+ end
809
+
810
+ def test_create_without_location
811
+ ActiveResource::HttpMock.respond_to do |mock|
812
+ mock.post "/people.xml", {}, nil, 201
813
+ end
814
+ person = Person.create(:name => 'Rick')
815
+ assert_equal nil, person.id
816
+ end
817
+
818
+ def test_clone
819
+ matz = Person.find(1)
820
+ matz_c = matz.clone
821
+ assert matz_c.new?
822
+ matz.attributes.each do |k, v|
823
+ assert_equal v, matz_c.send(k) if k != Person.primary_key
824
+ end
825
+ end
826
+
827
+ def test_nested_clone
828
+ addy = StreetAddress.find(1, :params => {:person_id => 1})
829
+ addy_c = addy.clone
830
+ assert addy_c.new?
831
+ addy.attributes.each do |k, v|
832
+ assert_equal v, addy_c.send(k) if k != StreetAddress.primary_key
833
+ end
834
+ assert_equal addy.prefix_options, addy_c.prefix_options
835
+ end
836
+
837
+ def test_complex_clone
838
+ matz = Person.find(1)
839
+ matz.address = StreetAddress.find(1, :params => {:person_id => matz.id})
840
+ matz.non_ar_hash = {:not => "an ARes instance"}
841
+ matz.non_ar_arr = ["not", "ARes"]
842
+ matz_c = matz.clone
843
+ assert matz_c.new?
844
+ assert_raise(NoMethodError) {matz_c.address}
845
+ assert_equal matz.non_ar_hash, matz_c.non_ar_hash
846
+ assert_equal matz.non_ar_arr, matz_c.non_ar_arr
847
+
848
+ # Test that actual copy, not just reference copy
849
+ matz.non_ar_hash[:not] = "changed"
850
+ assert_not_equal matz.non_ar_hash, matz_c.non_ar_hash
851
+ end
852
+
853
+ def test_update
854
+ matz = Person.find(:first)
855
+ matz.name = "David"
856
+ assert_kind_of Person, matz
857
+ assert_equal "David", matz.name
858
+ assert_equal true, matz.save
859
+ end
860
+
861
+ def test_update_with_custom_prefix_with_specific_id
862
+ addy = StreetAddress.find(1, :params => { :person_id => 1 })
863
+ addy.street = "54321 Street"
864
+ assert_kind_of StreetAddress, addy
865
+ assert_equal "54321 Street", addy.street
866
+ addy.save
867
+ end
868
+
869
+ def test_update_with_custom_prefix_without_specific_id
870
+ addy = StreetAddress.find(:first, :params => { :person_id => 1 })
871
+ addy.street = "54321 Lane"
872
+ assert_kind_of StreetAddress, addy
873
+ assert_equal "54321 Lane", addy.street
874
+ addy.save
875
+ end
876
+
877
+ def test_update_conflict
878
+ ActiveResource::HttpMock.respond_to do |mock|
879
+ mock.get "/people/2.xml", {}, @david
880
+ mock.put "/people/2.xml", @default_request_headers, nil, 409
881
+ end
882
+ assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save }
883
+ end
884
+
885
+ def test_destroy
886
+ assert Person.find(1).destroy
887
+ ActiveResource::HttpMock.respond_to do |mock|
888
+ mock.get "/people/1.xml", {}, nil, 404
889
+ end
890
+ assert_raise(ActiveResource::ResourceNotFound) { Person.find(1).destroy }
891
+ end
892
+
893
+ def test_destroy_with_custom_prefix
894
+ assert StreetAddress.find(1, :params => { :person_id => 1 }).destroy
895
+ ActiveResource::HttpMock.respond_to do |mock|
896
+ mock.get "/people/1/addresses/1.xml", {}, nil, 404
897
+ end
898
+ assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
899
+ end
900
+
901
+ def test_destroy_with_410_gone
902
+ assert Person.find(1).destroy
903
+ ActiveResource::HttpMock.respond_to do |mock|
904
+ mock.get "/people/1.xml", {}, nil, 410
905
+ end
906
+ assert_raise(ActiveResource::ResourceGone) { Person.find(1).destroy }
907
+ end
908
+
909
+ def test_delete
910
+ assert Person.delete(1)
911
+ ActiveResource::HttpMock.respond_to do |mock|
912
+ mock.get "/people/1.xml", {}, nil, 404
913
+ end
914
+ assert_raise(ActiveResource::ResourceNotFound) { Person.find(1) }
915
+ end
916
+
917
+ def test_delete_with_custom_prefix
918
+ assert StreetAddress.delete(1, :person_id => 1)
919
+ ActiveResource::HttpMock.respond_to do |mock|
920
+ mock.get "/people/1/addresses/1.xml", {}, nil, 404
921
+ end
922
+ assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
923
+ end
924
+
925
+ def test_delete_with_410_gone
926
+ assert Person.delete(1)
927
+ ActiveResource::HttpMock.respond_to do |mock|
928
+ mock.get "/people/1.xml", {}, nil, 410
929
+ end
930
+ assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
931
+ end
932
+
933
+ def test_exists
934
+ # Class method.
935
+ assert !Person.exists?(nil)
936
+ assert Person.exists?(1)
937
+ assert !Person.exists?(99)
938
+
939
+ # Instance method.
940
+ assert !Person.new.exists?
941
+ assert Person.find(1).exists?
942
+ assert !Person.new(:id => 99).exists?
943
+
944
+ # Nested class method.
945
+ assert StreetAddress.exists?(1, :params => { :person_id => 1 })
946
+ assert !StreetAddress.exists?(1, :params => { :person_id => 2 })
947
+ assert !StreetAddress.exists?(2, :params => { :person_id => 1 })
948
+
949
+ # Nested instance method.
950
+ assert StreetAddress.find(1, :params => { :person_id => 1 }).exists?
951
+ assert !StreetAddress.new({:id => 1, :person_id => 2}).exists?
952
+ assert !StreetAddress.new({:id => 2, :person_id => 1}).exists?
953
+ end
954
+
955
+ def test_exists_with_redefined_to_param
956
+ Person.module_eval do
957
+ alias_method :original_to_param_exists, :to_param
958
+ def to_param
959
+ name
960
+ end
961
+ end
962
+
963
+ # Class method.
964
+ assert Person.exists?('Greg')
965
+
966
+ # Instance method.
967
+ assert Person.find('Greg').exists?
968
+
969
+ # Nested class method.
970
+ assert StreetAddress.exists?(1, :params => { :person_id => Person.find('Greg').to_param })
971
+
972
+ # Nested instance method.
973
+ assert StreetAddress.find(1, :params => { :person_id => Person.find('Greg').to_param }).exists?
974
+
975
+ ensure
976
+ # revert back to original
977
+ Person.module_eval do
978
+ # save the 'new' to_param so we don't get a warning about discarding the method
979
+ alias_method :exists_to_param, :to_param
980
+ alias_method :to_param, :original_to_param_exists
981
+ end
982
+ end
983
+
984
+ def test_exists_without_http_mock
985
+ http = Net::HTTP.new(Person.site.host, Person.site.port)
986
+ ActiveResource::Connection.any_instance.expects(:http).returns(http)
987
+ http.expects(:request).returns(ActiveResource::Response.new(""))
988
+
989
+ assert Person.exists?('not-mocked')
990
+ end
991
+
992
+ def test_exists_with_410_gone
993
+ ActiveResource::HttpMock.respond_to do |mock|
994
+ mock.head "/people/1.xml", {}, nil, 410
995
+ end
996
+
997
+ assert !Person.exists?(1)
998
+ end
999
+
1000
+ def test_to_xml
1001
+ matz = Person.find(1)
1002
+ xml = matz.encode
1003
+ assert xml.starts_with?('<?xml version="1.0" encoding="UTF-8"?>')
1004
+ assert xml.include?('<name>Matz</name>')
1005
+ assert xml.include?('<id type="integer">1</id>')
1006
+ end
1007
+
1008
+ def test_to_param_quacks_like_active_record
1009
+ new_person = Person.new
1010
+ assert_nil new_person.to_param
1011
+ matz = Person.find(1)
1012
+ assert_equal '1', matz.to_param
1013
+ end
1014
+
1015
+ def test_parse_deep_nested_resources
1016
+ luis = Customer.find(1)
1017
+ assert_kind_of Customer, luis
1018
+ luis.friends.each do |friend|
1019
+ assert_kind_of Customer::Friend, friend
1020
+ friend.brothers.each do |brother|
1021
+ assert_kind_of Customer::Friend::Brother, brother
1022
+ brother.children.each do |child|
1023
+ assert_kind_of Customer::Friend::Brother::Child, child
1024
+ end
1025
+ end
1026
+ end
1027
+ end
1028
+
1029
+ def test_load_yaml_array
1030
+ assert_nothing_raised do
1031
+ marty = Person.find(5)
1032
+ assert_equal 3, marty.colors.size
1033
+ marty.colors.each do |color|
1034
+ assert_kind_of String, color
1035
+ end
1036
+ end
1037
+ end
1038
+ end