PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/actionpack/test/controller/integration_test.rb

https://bitbucket.org/druly/rails_cherry_pick
Ruby | 640 lines | 528 code | 106 blank | 6 comment | 2 complexity | ecbf991cac012e98c1a164930077e6fc MD5 | raw file
  1. require 'abstract_unit'
  2. require 'controller/fake_controllers'
  3. require 'action_controller/vendor/html-scanner'
  4. class SessionTest < Test::Unit::TestCase
  5. StubApp = lambda { |env|
  6. [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, ["Hello, World!"]]
  7. }
  8. def setup
  9. @session = ActionDispatch::Integration::Session.new(StubApp)
  10. end
  11. def test_https_bang_works_and_sets_truth_by_default
  12. assert !@session.https?
  13. @session.https!
  14. assert @session.https?
  15. @session.https! false
  16. assert !@session.https?
  17. end
  18. def test_host!
  19. assert_not_equal "glu.ttono.us", @session.host
  20. @session.host! "rubyonrails.com"
  21. assert_equal "rubyonrails.com", @session.host
  22. end
  23. def test_follow_redirect_raises_when_no_redirect
  24. @session.stubs(:redirect?).returns(false)
  25. assert_raise(RuntimeError) { @session.follow_redirect! }
  26. end
  27. def test_request_via_redirect_uses_given_method
  28. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
  29. @session.expects(:process).with(:put, path, args, headers)
  30. @session.stubs(:redirect?).returns(false)
  31. @session.request_via_redirect(:put, path, args, headers)
  32. end
  33. def test_request_via_redirect_follows_redirects
  34. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
  35. @session.stubs(:redirect?).returns(true, true, false)
  36. @session.expects(:follow_redirect!).times(2)
  37. @session.request_via_redirect(:get, path, args, headers)
  38. end
  39. def test_request_via_redirect_returns_status
  40. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
  41. @session.stubs(:redirect?).returns(false)
  42. @session.stubs(:status).returns(200)
  43. assert_equal 200, @session.request_via_redirect(:get, path, args, headers)
  44. end
  45. def test_get_via_redirect
  46. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
  47. @session.expects(:request_via_redirect).with(:get, path, args, headers)
  48. @session.get_via_redirect(path, args, headers)
  49. end
  50. def test_post_via_redirect
  51. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
  52. @session.expects(:request_via_redirect).with(:post, path, args, headers)
  53. @session.post_via_redirect(path, args, headers)
  54. end
  55. def test_put_via_redirect
  56. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
  57. @session.expects(:request_via_redirect).with(:put, path, args, headers)
  58. @session.put_via_redirect(path, args, headers)
  59. end
  60. def test_delete_via_redirect
  61. path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
  62. @session.expects(:request_via_redirect).with(:delete, path, args, headers)
  63. @session.delete_via_redirect(path, args, headers)
  64. end
  65. def test_get
  66. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  67. @session.expects(:process).with(:get,path,params,headers)
  68. @session.get(path,params,headers)
  69. end
  70. def test_post
  71. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  72. @session.expects(:process).with(:post,path,params,headers)
  73. @session.post(path,params,headers)
  74. end
  75. def test_put
  76. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  77. @session.expects(:process).with(:put,path,params,headers)
  78. @session.put(path,params,headers)
  79. end
  80. def test_delete
  81. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  82. @session.expects(:process).with(:delete,path,params,headers)
  83. @session.delete(path,params,headers)
  84. end
  85. def test_head
  86. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  87. @session.expects(:process).with(:head,path,params,headers)
  88. @session.head(path,params,headers)
  89. end
  90. def test_xml_http_request_get
  91. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  92. headers_after_xhr = headers.merge(
  93. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
  94. "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*"
  95. )
  96. @session.expects(:process).with(:get,path,params,headers_after_xhr)
  97. @session.xml_http_request(:get,path,params,headers)
  98. end
  99. def test_xml_http_request_post
  100. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  101. headers_after_xhr = headers.merge(
  102. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
  103. "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*"
  104. )
  105. @session.expects(:process).with(:post,path,params,headers_after_xhr)
  106. @session.xml_http_request(:post,path,params,headers)
  107. end
  108. def test_xml_http_request_put
  109. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  110. headers_after_xhr = headers.merge(
  111. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
  112. "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*"
  113. )
  114. @session.expects(:process).with(:put,path,params,headers_after_xhr)
  115. @session.xml_http_request(:put,path,params,headers)
  116. end
  117. def test_xml_http_request_delete
  118. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  119. headers_after_xhr = headers.merge(
  120. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
  121. "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*"
  122. )
  123. @session.expects(:process).with(:delete,path,params,headers_after_xhr)
  124. @session.xml_http_request(:delete,path,params,headers)
  125. end
  126. def test_xml_http_request_head
  127. path = "/index"; params = "blah"; headers = {:location => 'blah'}
  128. headers_after_xhr = headers.merge(
  129. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
  130. "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*"
  131. )
  132. @session.expects(:process).with(:head,path,params,headers_after_xhr)
  133. @session.xml_http_request(:head,path,params,headers)
  134. end
  135. def test_xml_http_request_override_accept
  136. path = "/index"; params = "blah"; headers = {:location => 'blah', "HTTP_ACCEPT" => "application/xml"}
  137. headers_after_xhr = headers.merge(
  138. "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
  139. )
  140. @session.expects(:process).with(:post,path,params,headers_after_xhr)
  141. @session.xml_http_request(:post,path,params,headers)
  142. end
  143. end
  144. class IntegrationTestTest < Test::Unit::TestCase
  145. def setup
  146. @test = ::ActionDispatch::IntegrationTest.new(:app)
  147. @test.class.stubs(:fixture_table_names).returns([])
  148. @session = @test.open_session
  149. end
  150. def test_opens_new_session
  151. session1 = @test.open_session { |sess| }
  152. session2 = @test.open_session # implicit session
  153. assert_respond_to session1, :assert_template, "open_session makes assert_template available"
  154. assert_respond_to session2, :assert_template, "open_session makes assert_template available"
  155. assert !session1.equal?(session2)
  156. end
  157. # RSpec mixes Matchers (which has a #method_missing) into
  158. # IntegrationTest's superclass. Make sure IntegrationTest does not
  159. # try to delegate these methods to the session object.
  160. def test_does_not_prevent_method_missing_passing_up_to_ancestors
  161. mixin = Module.new do
  162. def method_missing(name, *args)
  163. name.to_s == 'foo' ? 'pass' : super
  164. end
  165. end
  166. @test.class.superclass.__send__(:include, mixin)
  167. begin
  168. assert_equal 'pass', @test.foo
  169. ensure
  170. # leave other tests as unaffected as possible
  171. mixin.__send__(:remove_method, :method_missing)
  172. end
  173. end
  174. end
  175. # Tests that integration tests don't call Controller test methods for processing.
  176. # Integration tests have their own setup and teardown.
  177. class IntegrationTestUsesCorrectClass < ActionDispatch::IntegrationTest
  178. def self.fixture_table_names
  179. []
  180. end
  181. def test_integration_methods_called
  182. reset!
  183. @integration_session.stubs(:generic_url_rewriter)
  184. @integration_session.stubs(:process)
  185. %w( get post head put delete ).each do |verb|
  186. assert_nothing_raised("'#{verb}' should use integration test methods") { __send__(verb, '/') }
  187. end
  188. end
  189. end
  190. class IntegrationProcessTest < ActionDispatch::IntegrationTest
  191. class IntegrationController < ActionController::Base
  192. def get
  193. respond_to do |format|
  194. format.html { render :text => "OK", :status => 200 }
  195. format.js { render :text => "JS OK", :status => 200 }
  196. end
  197. end
  198. def get_with_params
  199. render :text => "foo: #{params[:foo]}", :status => 200
  200. end
  201. def post
  202. render :text => "Created", :status => 201
  203. end
  204. def method
  205. render :text => "method: #{request.method.downcase}"
  206. end
  207. def cookie_monster
  208. cookies["cookie_1"] = nil
  209. cookies["cookie_3"] = "chocolate"
  210. render :text => "Gone", :status => 410
  211. end
  212. def set_cookie
  213. cookies["foo"] = 'bar'
  214. head :ok
  215. end
  216. def get_cookie
  217. render :text => cookies["foo"]
  218. end
  219. def redirect
  220. redirect_to :action => "get"
  221. end
  222. end
  223. def test_get
  224. with_test_route_set do
  225. get '/get'
  226. assert_equal 200, status
  227. assert_equal "OK", status_message
  228. assert_response 200
  229. assert_response :success
  230. assert_response :ok
  231. assert_equal({}, cookies.to_hash)
  232. assert_equal "OK", body
  233. assert_equal "OK", response.body
  234. assert_kind_of HTML::Document, html_document
  235. assert_equal 1, request_count
  236. end
  237. end
  238. def test_post
  239. with_test_route_set do
  240. post '/post'
  241. assert_equal 201, status
  242. assert_equal "Created", status_message
  243. assert_response 201
  244. assert_response :success
  245. assert_response :created
  246. assert_equal({}, cookies.to_hash)
  247. assert_equal "Created", body
  248. assert_equal "Created", response.body
  249. assert_kind_of HTML::Document, html_document
  250. assert_equal 1, request_count
  251. end
  252. end
  253. test 'response cookies are added to the cookie jar for the next request' do
  254. with_test_route_set do
  255. self.cookies['cookie_1'] = "sugar"
  256. self.cookies['cookie_2'] = "oatmeal"
  257. get '/cookie_monster'
  258. _headers = headers["Set-Cookie"].split("\n")
  259. assert _headers.include?("cookie_1=; path=/")
  260. assert _headers.include?("cookie_3=chocolate; path=/")
  261. assert_equal cookies.to_hash["cookie_1"], ""
  262. assert_equal cookies.to_hash["cookie_2"], "oatmeal"
  263. assert_equal cookies.to_hash["cookie_3"], "chocolate"
  264. end
  265. end
  266. test 'cookie persist to next request' do
  267. with_test_route_set do
  268. get '/set_cookie'
  269. assert_response :success
  270. assert_equal "foo=bar; path=/", headers["Set-Cookie"]
  271. assert_equal({"foo"=>"bar"}, cookies.to_hash)
  272. get '/get_cookie'
  273. assert_response :success
  274. assert_equal "bar", body
  275. assert_equal nil, headers["Set-Cookie"]
  276. assert_equal({"foo"=>"bar"}, cookies.to_hash)
  277. end
  278. end
  279. test 'cookie persist to next request on another domain' do
  280. with_test_route_set do
  281. host! "37s.backpack.test"
  282. get '/set_cookie'
  283. assert_response :success
  284. assert_equal "foo=bar; path=/", headers["Set-Cookie"]
  285. assert_equal({"foo"=>"bar"}, cookies.to_hash)
  286. get '/get_cookie'
  287. assert_response :success
  288. assert_equal "bar", body
  289. assert_equal nil, headers["Set-Cookie"]
  290. assert_equal({"foo"=>"bar"}, cookies.to_hash)
  291. end
  292. end
  293. def test_redirect
  294. with_test_route_set do
  295. get '/redirect'
  296. assert_equal 302, status
  297. assert_equal "Found", status_message
  298. assert_response 302
  299. assert_response :redirect
  300. assert_response :found
  301. assert_equal "<html><body>You are being <a href=\"http://www.example.com/get\">redirected</a>.</body></html>", response.body
  302. assert_kind_of HTML::Document, html_document
  303. assert_equal 1, request_count
  304. follow_redirect!
  305. assert_response :success
  306. assert_equal "/get", path
  307. end
  308. end
  309. def test_xml_http_request_get
  310. with_test_route_set do
  311. xhr :get, '/get'
  312. assert_equal 200, status
  313. assert_equal "OK", status_message
  314. assert_response 200
  315. assert_response :success
  316. assert_response :ok
  317. assert_equal "JS OK", response.body
  318. end
  319. end
  320. def test_get_with_query_string
  321. with_test_route_set do
  322. get '/get_with_params?foo=bar'
  323. assert_equal '/get_with_params?foo=bar', request.env["REQUEST_URI"]
  324. assert_equal '/get_with_params?foo=bar', request.fullpath
  325. assert_equal "foo=bar", request.env["QUERY_STRING"]
  326. assert_equal 'foo=bar', request.query_string
  327. assert_equal 'bar', request.parameters['foo']
  328. assert_equal 200, status
  329. assert_equal "foo: bar", response.body
  330. end
  331. end
  332. def test_get_with_parameters
  333. with_test_route_set do
  334. get '/get_with_params', :foo => "bar"
  335. assert_equal '/get_with_params', request.env["PATH_INFO"]
  336. assert_equal '/get_with_params', request.path_info
  337. assert_equal 'foo=bar', request.env["QUERY_STRING"]
  338. assert_equal 'foo=bar', request.query_string
  339. assert_equal 'bar', request.parameters['foo']
  340. assert_equal 200, status
  341. assert_equal "foo: bar", response.body
  342. end
  343. end
  344. def test_head
  345. with_test_route_set do
  346. head '/get'
  347. assert_equal 200, status
  348. assert_equal "", body
  349. head '/post'
  350. assert_equal 201, status
  351. assert_equal "", body
  352. get '/get/method'
  353. assert_equal 200, status
  354. assert_equal "method: get", body
  355. head '/get/method'
  356. assert_equal 200, status
  357. assert_equal "", body
  358. end
  359. end
  360. def test_generate_url_with_controller
  361. assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
  362. end
  363. private
  364. def with_test_route_set
  365. with_routing do |set|
  366. controller = ::IntegrationProcessTest::IntegrationController.clone
  367. controller.class_eval do
  368. include set.url_helpers
  369. end
  370. set.draw do
  371. match ':action', :to => controller
  372. get 'get/:action', :to => controller
  373. end
  374. self.singleton_class.send(:include, set.url_helpers)
  375. yield
  376. end
  377. end
  378. end
  379. class MetalIntegrationTest < ActionDispatch::IntegrationTest
  380. include SharedTestRoutes.url_helpers
  381. class Poller
  382. def self.call(env)
  383. if env["PATH_INFO"] =~ /^\/success/
  384. [200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, ["Hello World!"]]
  385. else
  386. [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
  387. end
  388. end
  389. end
  390. def setup
  391. @app = Poller
  392. end
  393. def test_successful_get
  394. get "/success"
  395. assert_response 200
  396. assert_response :success
  397. assert_response :ok
  398. assert_equal "Hello World!", response.body
  399. end
  400. def test_failed_get
  401. get "/failure"
  402. assert_response 404
  403. assert_response :not_found
  404. assert_equal '', response.body
  405. end
  406. def test_generate_url_without_controller
  407. assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
  408. end
  409. end
  410. class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
  411. class TestController < ActionController::Base
  412. def index
  413. render :text => "index"
  414. end
  415. end
  416. def self.call(env)
  417. routes.call(env)
  418. end
  419. def self.routes
  420. @routes ||= ActionDispatch::Routing::RouteSet.new
  421. end
  422. class MountedApp
  423. def self.routes
  424. @routes ||= ActionDispatch::Routing::RouteSet.new
  425. end
  426. routes.draw do
  427. match 'baz', :to => 'application_integration_test/test#index', :as => :baz
  428. end
  429. def self.call(*)
  430. end
  431. end
  432. routes.draw do
  433. match '', :to => 'application_integration_test/test#index', :as => :empty_string
  434. match 'foo', :to => 'application_integration_test/test#index', :as => :foo
  435. match 'bar', :to => 'application_integration_test/test#index', :as => :bar
  436. mount MountedApp => '/mounted', :as => "mounted"
  437. end
  438. def app
  439. self.class
  440. end
  441. test "includes route helpers" do
  442. assert_equal '/', empty_string_path
  443. assert_equal '/foo', foo_path
  444. assert_equal '/bar', bar_path
  445. end
  446. test "includes mounted helpers" do
  447. assert_equal '/mounted/baz', mounted.baz_path
  448. end
  449. test "route helpers after controller access" do
  450. get '/'
  451. assert_equal '/', empty_string_path
  452. get '/foo'
  453. assert_equal '/foo', foo_path
  454. get '/bar'
  455. assert_equal '/bar', bar_path
  456. end
  457. test "missing route helper before controller access" do
  458. assert_raise(NameError) { missing_path }
  459. end
  460. test "missing route helper after controller access" do
  461. get '/foo'
  462. assert_raise(NameError) { missing_path }
  463. end
  464. test "process do not modify the env passed as argument" do
  465. env = { :SERVER_NAME => 'server', 'action_dispatch.custom' => 'custom' }
  466. old_env = env.dup
  467. get '/foo', nil, env
  468. assert_equal old_env, env
  469. end
  470. end
  471. class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
  472. class FooController < ActionController::Base
  473. def index
  474. render :text => "foo#index"
  475. end
  476. def show
  477. render :text => "foo#show"
  478. end
  479. def edit
  480. render :text => "foo#show"
  481. end
  482. end
  483. class BarController < ActionController::Base
  484. def default_url_options
  485. { :host => "bar.com" }
  486. end
  487. def index
  488. render :text => "foo#index"
  489. end
  490. end
  491. def self.routes
  492. @routes ||= ActionDispatch::Routing::RouteSet.new
  493. end
  494. def self.call(env)
  495. routes.call(env)
  496. end
  497. def app
  498. self.class
  499. end
  500. routes.draw do
  501. default_url_options :host => "foo.com"
  502. scope :module => "url_options_integration_test" do
  503. get "/foo" => "foo#index", :as => :foos
  504. get "/foo/:id" => "foo#show", :as => :foo
  505. get "/foo/:id/edit" => "foo#edit", :as => :edit_foo
  506. get "/bar" => "bar#index", :as => :bars
  507. end
  508. end
  509. test "session uses default url options from routes" do
  510. assert_equal "http://foo.com/foo", foos_url
  511. end
  512. test "current host overrides default url options from routes" do
  513. get "/foo"
  514. assert_response :success
  515. assert_equal "http://www.example.com/foo", foos_url
  516. end
  517. test "controller can override default url options from request" do
  518. get "/bar"
  519. assert_response :success
  520. assert_equal "http://bar.com/foo", foos_url
  521. end
  522. test "test can override default url options" do
  523. default_url_options[:host] = "foobar.com"
  524. assert_equal "http://foobar.com/foo", foos_url
  525. get "/bar"
  526. assert_response :success
  527. assert_equal "http://foobar.com/foo", foos_url
  528. end
  529. test "current request path parameters are recalled" do
  530. get "/foo/1"
  531. assert_response :success
  532. assert_equal "/foo/1/edit", url_for(:action => 'edit', :only_path => true)
  533. end
  534. end