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