action_pack_assertions_test.rb 14.3 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
require File.dirname(__FILE__) + '/../abstract_unit'

# a controller class to facilitate the tests
class ActionPackAssertionsController < ActionController::Base

  # this does absolutely nothing
  def nothing() render_text ""; end

  # a standard template
  def hello_world() render "test/hello_world"; end

  # a standard template
  def hello_xml_world() render "test/hello_xml_world"; end
 
  # a redirect to an internal location
16
  def redirect_internal() redirect_to "/nothing"; end
D
Initial  
David Heinemeier Hansson 已提交
17

18
  def redirect_to_action() redirect_to :action => "flash_me", :id => 1, :params => { "panda" => "fun" }; end
19 20 21

  def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end

22
  def redirect_to_path() redirect_to '/some/path' end
23 24

  def redirect_to_named_route() redirect_to route_one_url end
25
  
D
Initial  
David Heinemeier Hansson 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  # a redirect to an external location
  def redirect_external() redirect_to_url "http://www.rubyonrails.org"; end
  
  # a 404
  def response404() render_text "", "404 AWOL"; end

  # a 500
  def response500() render_text "", "500 Sorry"; end

  # a fictional 599
  def response599() render_text "", "599 Whoah!"; end

  # putting stuff in the flash
  def flash_me
    flash['hello'] = 'my name is inigo montoya...'
    render_text "Inconceivable!"
  end

  # we have a flash, but nothing is in it
  def flash_me_naked
    flash.clear
    render_text "wow!"
  end

  # assign some template instance variables
  def assign_this
    @howdy = "ho"
53
    render :inline => "Mr. Henke"
D
Initial  
David Heinemeier Hansson 已提交
54 55 56 57 58 59
  end

  def render_based_on_parameters
    render_text "Mr. #{@params["name"]}"
  end

60 61 62 63
  def render_url
    render_text "<div>#{url_for(:action => 'flash_me', :only_path => true)}</div>"
  end

D
Initial  
David Heinemeier Hansson 已提交
64 65 66 67 68
  # puts something in the session
  def session_stuffing
    session['xmas'] = 'turkey'
    render_text "ho ho ho"
  end
69 70 71 72 73 74 75 76 77 78 79
  
  # raises exception on get requests
  def raise_on_get
    raise "get" if @request.get?
    render_text "request method: #{@request.env['REQUEST_METHOD']}"
  end

  # raises exception on post requests
  def raise_on_post
    raise "post" if @request.post?
    render_text "request method: #{@request.env['REQUEST_METHOD']}"
T
Tobias Lütke 已提交
80 81 82 83 84 85 86 87 88 89
  end       
  
  def get_valid_record
    @record = Class.new do       
      def valid?
        true
      end

      def errors
        Class.new do 
90
           def full_messages; []; end          
T
Tobias Lütke 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        end.new
      end    
    
    end.new
        
    render :nothing => true    
  end


  def get_invalid_record
    @record = Class.new do 
      
      def valid?
        false
      end
      
      def errors
        Class.new do 
109
           def full_messages; ['...stuff...']; end          
T
Tobias Lütke 已提交
110 111 112 113 114
        end.new
      end
    end.new                
    
    render :nothing => true    
115
  end
D
Initial  
David Heinemeier Hansson 已提交
116 117 118

  # 911
  def rescue_action(e) raise; end
119 120 121 122 123 124 125 126 127 128 129
end

module Admin
  class InnerModuleController < ActionController::Base
    def redirect_to_absolute_controller
      redirect_to :controller => '/content'
    end
    def redirect_to_fellow_controller
      redirect_to :controller => 'user'
    end
  end
D
Initial  
David Heinemeier Hansson 已提交
130 131 132 133 134 135 136 137 138 139 140 141
end

# ---------------------------------------------------------------------------


# tell the controller where to find its templates but start from parent 
# directory of test_request_response to simulate the behaviour of a 
# production environment
ActionPackAssertionsController.template_root = File.dirname(__FILE__) + "/../fixtures/"


# a test case to exercise the new capabilities TestRequest & TestResponse
142
class ActionPackAssertionsControllerTest < Test::Unit::TestCase
D
Initial  
David Heinemeier Hansson 已提交
143 144 145 146 147 148 149 150
  # let's get this party started  
  def setup
    @controller = ActionPackAssertionsController.new
    @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
  end
 
  # -- assertion-based testing ------------------------------------------------

151 152 153 154 155
  def test_assert_tag_and_url_for
    get :render_url
    assert_tag :content => "/action_pack_assertions/flash_me"
  end

D
Initial  
David Heinemeier Hansson 已提交
156 157 158 159 160 161
  # test the session assertion to make sure something is there.
  def test_assert_session_has
    process :session_stuffing
    assert_session_has 'xmas'
    assert_session_has_no 'halloween'
  end
162 163 164 165 166 167 168 169 170 171 172 173 174 175
  
  # test the get method, make sure the request really was a get
  def test_get
    assert_raise(RuntimeError) { get :raise_on_get }
    get :raise_on_post
    assert_equal @response.body, 'request method: GET'
  end

  # test the get method, make sure the request really was a get
  def test_post
    assert_raise(RuntimeError) { post :raise_on_post }
    post :raise_on_get
    assert_equal @response.body, 'request method: POST'
  end
176
  
177 178 179 180 181 182 183 184 185 186 187 188
#   the following test fails because the request_method is now cached on the request instance
#   test the get/post switch within one test action
#   def test_get_post_switch
#     post :raise_on_get
#     assert_equal @response.body, 'request method: POST'
#     get :raise_on_post
#     assert_equal @response.body, 'request method: GET'
#     post :raise_on_get
#     assert_equal @response.body, 'request method: POST'
#     get :raise_on_post
#     assert_equal @response.body, 'request method: GET'
#   end
D
Initial  
David Heinemeier Hansson 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

  # test the assertion of goodies in the template
  def test_assert_template_has
    process :assign_this
    assert_template_has 'howdy'
  end

  # test the assertion for goodies that shouldn't exist in the template
  def test_assert_template_has_no
    process :nothing
    assert_template_has_no 'maple syrup'
    assert_template_has_no 'howdy'
  end
  
  # test the redirection assertions
  def test_assert_redirect
    process :redirect_internal
    assert_redirect
  end

  # test the redirect url string
  def test_assert_redirect_url
    process :redirect_external
    assert_redirect_url 'http://www.rubyonrails.org'
  end

  # test the redirection pattern matching on a string
  def test_assert_redirect_url_match_string
    process :redirect_external
    assert_redirect_url_match 'rails.org'
  end
  
  # test the redirection pattern matching on a pattern
  def test_assert_redirect_url_match_pattern
    process :redirect_external
    assert_redirect_url_match /ruby/
  end
226 227 228

  # test the redirection to a named route
  def test_assert_redirect_to_named_route
229 230 231 232 233 234 235 236 237
    with_routing do |set|
      set.draw do
        set.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing'
        set.connect   ':controller/:action/:id'
      end
      process :redirect_to_named_route
      assert_redirected_to 'http://test.host/route_one'
      assert_redirected_to route_one_url
      assert_redirected_to :route_one
238 239
    end
  end
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263

  def test_assert_redirect_to_named_route_failure
    with_routing do |set|
      set.draw do
        set.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'one'
        set.route_two 'route_two', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
        set.connect   ':controller/:action/:id'
      end
      process :redirect_to_named_route
      assert_raise(Test::Unit::AssertionFailedError) do
        assert_redirected_to 'http://test.host/route_two'
      end
      assert_raise(Test::Unit::AssertionFailedError) do
        assert_redirected_to :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
      end
      assert_raise(Test::Unit::AssertionFailedError) do
        assert_redirected_to route_two_url
      end
      assert_raise(Test::Unit::AssertionFailedError) do
        assert_redirected_to :route_two
      end
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
  # test the flash-based assertions with something is in the flash
  def test_flash_assertions_full
    process :flash_me
    assert @response.has_flash_with_contents?
    assert_flash_exists
    assert_flash_not_empty
    assert_flash_has 'hello'
    assert_flash_has_no 'stds'
  end

  # test the flash-based assertions with no flash at all
  def test_flash_assertions_negative
    process :nothing
    assert_flash_empty
    assert_flash_has_no 'hello'
    assert_flash_has_no 'qwerty'
  end
  
  # test the assert_rendered_file 
  def test_assert_rendered_file
    process :hello_world
    assert_rendered_file 'test/hello_world'
    assert_rendered_file 'hello_world'
  end
  
  # test the assert_success assertion
  def test_assert_success
    process :nothing
    assert_success
J
Jamis Buck 已提交
293
    assert_rendered_file
D
Initial  
David Heinemeier Hansson 已提交
294 295
  end
  
296
  # -- standard request/response object testing --------------------------------
D
Initial  
David Heinemeier Hansson 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
 
  # ensure our session is working properly
  def test_session_objects
    process :session_stuffing
    assert @response.has_session_object?('xmas')
    assert_session_equal 'turkey', 'xmas'
    assert !@response.has_session_object?('easter')
  end
  
  # make sure that the template objects exist
  def test_template_objects_alive
    process :assign_this
    assert !@response.has_template_object?('hi')
    assert @response.has_template_object?('howdy')
  end
  
  # make sure we don't have template objects when we shouldn't
  def test_template_object_missing
    process :nothing
    assert_nil @response.template_objects['howdy']
  end
  
  def test_assigned_equal
    process :assign_this
    assert_assigned_equal "ho", :howdy
  end

  # check the empty flashing
  def test_flash_me_naked
    process :flash_me_naked
327
    assert !@response.has_flash?
D
Initial  
David Heinemeier Hansson 已提交
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    assert !@response.has_flash_with_contents?
  end

  # check if we have flash objects
  def test_flash_haves
    process :flash_me
    assert @response.has_flash?
    assert @response.has_flash_with_contents?
    assert @response.has_flash_object?('hello')
  end

  # ensure we don't have flash objects
  def test_flash_have_nots
    process :nothing
    assert !@response.has_flash?
    assert !@response.has_flash_with_contents?
    assert_nil @response.flash['hello']
  end
  
  # examine that the flash objects are what we expect
  def test_flash_equals
    process :flash_me
    assert_flash_equal 'my name is inigo montoya...', 'hello'
  end
  
  # check if we were rendered by a file-based template? 
  def test_rendered_action
    process :nothing
    assert !@response.rendered_with_file?

    process :hello_world
    assert @response.rendered_with_file?
    assert 'hello_world', @response.rendered_file
  end
  
  # check the redirection location
  def test_redirection_location
    process :redirect_internal
366
    assert_equal 'http://test.host/nothing', @response.redirect_url
D
Initial  
David Heinemeier Hansson 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432

    process :redirect_external
    assert_equal 'http://www.rubyonrails.org', @response.redirect_url

    process :nothing
    assert_nil @response.redirect_url
  end
  
 
  # check server errors 
  def test_server_error_response_code
    process :response500
    assert @response.server_error?
    
    process :response599
    assert @response.server_error?
    
    process :response404
    assert !@response.server_error?
  end
  
  # check a 404 response code
  def test_missing_response_code
    process :response404
    assert @response.missing?
  end

  # check to see if our redirection matches a pattern
  def test_redirect_url_match
    process :redirect_external
    assert @response.redirect?
    assert @response.redirect_url_match?("rubyonrails")
    assert @response.redirect_url_match?(/rubyonrails/)
    assert !@response.redirect_url_match?("phpoffrails")
    assert !@response.redirect_url_match?(/perloffrails/)
  end
  
  # check for a redirection
  def test_redirection
    process :redirect_internal
    assert @response.redirect?

    process :redirect_external
    assert @response.redirect?

    process :nothing
    assert !@response.redirect?
  end
  
  # check a successful response code
  def test_successful_response_code
    process :nothing
    assert @response.success?
  end 
  
  # a basic check to make sure we have a TestResponse object
  def test_has_response
    process :nothing
    assert_kind_of ActionController::TestResponse, @response
  end
  
  def test_render_based_on_parameters
    process :render_based_on_parameters, "name" => "David"
    assert_equal "Mr. David", @response.body
  end

433 434 435 436 437 438 439
  def test_assert_template_xpath_match_no_matches
    process :hello_xml_world
    assert_raises Test::Unit::AssertionFailedError do
      assert_template_xpath_match('/no/such/node/in/document')
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
440 441 442 443 444 445 446 447 448
  def test_simple_one_element_xpath_match
    process :hello_xml_world
    assert_template_xpath_match('//title', "Hello World")
  end

  def test_array_of_elements_in_xpath_match
    process :hello_xml_world
    assert_template_xpath_match('//p', %w( abes monks wiseguys ))
  end
449 450 451 452 453 454

  def test_follow_redirect
    process :redirect_to_action
    assert_redirected_to :action => "flash_me"
    
    follow_redirect
455
    assert_equal 1, @request.parameters["id"].to_i
456

457 458 459 460 461 462 463 464 465
    assert "Inconceivable!", @response.body
  end
  
  def test_follow_redirect_outside_current_action
    process :redirect_to_controller
    assert_redirected_to :controller => "elsewhere", :action => "flash_me"

    assert_raises(RuntimeError, "Can't follow redirects outside of current controller (elsewhere)") { follow_redirect }
  end
466 467 468 469 470 471 472 473 474 475 476 477 478

  def test_redirected_to_url_leadling_slash
    process :redirect_to_path
    assert_redirected_to '/some/path'
  end
  def test_redirected_to_url_no_leadling_slash
    process :redirect_to_path
    assert_redirected_to 'some/path'
  end
  def test_redirected_to_url_full_url
    process :redirect_to_path
    assert_redirected_to 'http://test.host/some/path'
  end
479 480 481 482 483 484 485 486

  def test_redirected_to_with_nested_controller
    @controller = Admin::InnerModuleController.new
    get :redirect_to_absolute_controller
    assert_redirected_to :controller => 'content'
    
    get :redirect_to_fellow_controller
    assert_redirected_to :controller => 'admin/user'
T
Tobias Lütke 已提交
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
  end                 
  
  def test_assert_valid
    get :get_valid_record
    assert_valid assigns('record')    
  end                
  
  def test_assert_valid_failing
    get :get_invalid_record
    
    begin
      assert_valid assigns('record')    
      assert false
    rescue Test::Unit::AssertionFailedError => e             
    end
502
  end
D
Initial  
David Heinemeier Hansson 已提交
503 504 505 506 507 508 509
end

class ActionPackHeaderTest < Test::Unit::TestCase  
  def setup
    @controller = ActionPackAssertionsController.new
    @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
  end
510

D
Initial  
David Heinemeier Hansson 已提交
511 512
  def test_rendering_xml_sets_content_type
    process :hello_xml_world
513
    assert_equal('application/xml', @controller.headers['Content-Type'])
D
Initial  
David Heinemeier Hansson 已提交
514
  end
515

D
Initial  
David Heinemeier Hansson 已提交
516
  def test_rendering_xml_respects_content_type
517 518 519
    @response.headers['Content-Type'] = 'application/pdf'
    process :hello_xml_world
    assert_equal('application/pdf', @controller.headers['Content-Type'])
D
Initial  
David Heinemeier Hansson 已提交
520
  end
521
end