PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/integration-tests/apps/rails2/frozen/vendor/rails/activeresource/test/base_test.rb

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