filters_test.rb 23.8 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1 2 3 4 5
require File.dirname(__FILE__) + '/../abstract_unit'

class FilterTest < Test::Unit::TestCase
  class TestController < ActionController::Base
    before_filter :ensure_login
6
    after_filter  :clean_up
D
Initial  
David Heinemeier Hansson 已提交
7 8

    def show
9
      render :inline => "ran action"
D
Initial  
David Heinemeier Hansson 已提交
10 11 12 13 14 15 16
    end

    private
      def ensure_login
        @ran_filter ||= []
        @ran_filter << "ensure_login"
      end
17

18 19 20 21
      def clean_up
        @ran_after_filter ||= []
        @ran_after_filter << "clean_up"
      end
D
Initial  
David Heinemeier Hansson 已提交
22
  end
23 24 25 26 27 28 29 30 31

  class ChangingTheRequirementsController < TestController
    before_filter :ensure_login, :except => [:go_wild]

    def go_wild
      render :text => "gobble"
    end
  end

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
  class TestMultipleFiltersController < ActionController::Base
    before_filter :try_1
    before_filter :try_2
    before_filter :try_3

    (1..3).each do |i|
      define_method "fail_#{i}" do
        render :text => i.to_s
      end
    end

    protected
    (1..3).each do |i|
      define_method "try_#{i}" do
        instance_variable_set :@try, i
        action_name != "fail_#{i}"
      end
    end
  end
51 52 53 54 55 56

  class RenderingController < ActionController::Base
    before_filter :render_something_else

    def show
      @ran_action = true
57
      render :inline => "ran action"
58 59 60 61
    end

    private
      def render_something_else
62
        render :inline => "something else"
63 64
      end
  end
65

66 67
  class ConditionalFilterController < ActionController::Base
    def show
68
      render :inline => "ran action"
69 70 71
    end

    def another_action
72
      render :inline => "ran action"
73 74 75
    end

    def show_without_filter
76
      render :inline => "ran action without filter"
77 78 79 80 81 82 83 84 85 86 87 88
    end

    private
      def ensure_login
        @ran_filter ||= []
        @ran_filter << "ensure_login"
      end

      def clean_up_tmp
        @ran_filter ||= []
        @ran_filter << "clean_up_tmp"
      end
89

90 91 92 93 94 95 96
      def rescue_action(e) raise(e) end
  end

  class ConditionalCollectionFilterController < ConditionalFilterController
    before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
  end

97
  class OnlyConditionSymController < ConditionalFilterController
98 99 100 101 102 103 104 105 106
    before_filter :ensure_login, :only => :show
  end

  class ExceptConditionSymController < ConditionalFilterController
    before_filter :ensure_login, :except => :show_without_filter
  end

  class BeforeAndAfterConditionController < ConditionalFilterController
    before_filter :ensure_login, :only => :show
107
    after_filter  :clean_up_tmp, :only => :show
108
  end
109 110

  class OnlyConditionProcController < ConditionalFilterController
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true }
  end

  class ExceptConditionProcController < ConditionalFilterController
    before_filter(:except => :show_without_filter) {|c| c.assigns["ran_proc_filter"] = true }
  end

  class ConditionalClassFilter
    def self.filter(controller) controller.assigns["ran_class_filter"] = true end
  end

  class OnlyConditionClassController < ConditionalFilterController
    before_filter ConditionalClassFilter, :only => :show
  end

  class ExceptConditionClassController < ConditionalFilterController
    before_filter ConditionalClassFilter, :except => :show_without_filter
  end

  class AnomolousYetValidConditionController < ConditionalFilterController
    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true}
  end

134 135 136 137 138 139 140 141
  class EmptyFilterChainController < TestController
    self.filter_chain.clear
    def show
      @action_executed = true
      render :text => "yawp!"
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
142 143
  class PrependingController < TestController
    prepend_before_filter :wonderful_life
144
    # skip_before_filter :fire_flash
D
Initial  
David Heinemeier Hansson 已提交
145 146 147 148 149 150 151 152

    private
      def wonderful_life
        @ran_filter ||= []
        @ran_filter << "wonderful_life"
      end
  end

153 154 155
  class ConditionalSkippingController < TestController
    skip_before_filter :ensure_login, :only => [ :login ]
    skip_after_filter  :clean_up,     :only => [ :login ]
156

157
    before_filter :find_user, :only => [ :change_password ]
158 159 160 161 162 163 164 165

    def login
      render :inline => "ran action"
    end

    def change_password
      render :inline => "ran action"
    end
166

167 168 169 170 171
    protected
      def find_user
        @ran_filter ||= []
        @ran_filter << "find_user"
      end
172
  end
173

174 175 176
  class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
    before_filter :conditional_in_parent, :only => [:show, :another_action]
    after_filter  :conditional_in_parent, :only => [:show, :another_action]
177

178
    private
179

180 181 182 183 184
      def conditional_in_parent
        @ran_filter ||= []
        @ran_filter << 'conditional_in_parent'
      end
  end
185

186 187 188 189
  class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
    skip_before_filter :conditional_in_parent, :only => :another_action
    skip_after_filter  :conditional_in_parent, :only => :another_action
  end
190

191 192 193 194
  class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
    skip_before_filter :conditional_in_parent, :only => :show
  end

D
Initial  
David Heinemeier Hansson 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207
  class ProcController < PrependingController
    before_filter(proc { |c| c.assigns["ran_proc_filter"] = true })
  end

  class ImplicitProcController < PrependingController
    before_filter { |c| c.assigns["ran_proc_filter"] = true }
  end

  class AuditFilter
    def self.filter(controller)
      controller.assigns["was_audited"] = true
    end
  end
208

D
Initial  
David Heinemeier Hansson 已提交
209 210 211 212 213 214 215 216 217 218 219
  class AroundFilter
    def before(controller)
      @execution_log = "before"
      controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
      controller.assigns["before_ran"] = true
    end

    def after(controller)
      controller.assigns["execution_log"] = @execution_log + " and after"
      controller.assigns["after_ran"] = true
      controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
220
    end
D
Initial  
David Heinemeier Hansson 已提交
221 222 223 224 225 226 227 228 229
  end

  class AppendedAroundFilter
    def before(controller)
      controller.class.execution_log << " before appended aroundfilter "
    end

    def after(controller)
      controller.class.execution_log << " after appended aroundfilter "
230 231 232
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
233 234
  class AuditController < ActionController::Base
    before_filter(AuditFilter)
235

D
Initial  
David Heinemeier Hansson 已提交
236 237 238 239 240 241 242 243 244
    def show
      render_text "hello"
    end
  end

  class AroundFilterController < PrependingController
    around_filter AroundFilter.new
  end

245 246 247 248 249 250 251 252
  class BeforeAfterClassFilterController < PrependingController
    begin
      filter = AroundFilter.new
      before_filter filter
      after_filter filter
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
253 254
  class MixedFilterController < PrependingController
    cattr_accessor :execution_log
255 256

    def initialize
D
Initial  
David Heinemeier Hansson 已提交
257 258 259 260 261 262 263 264 265
      @@execution_log = ""
    end

    before_filter { |c| c.class.execution_log << " before procfilter "  }
    prepend_around_filter AroundFilter.new

    after_filter  { |c| c.class.execution_log << " after procfilter " }
    append_around_filter AppendedAroundFilter.new
  end
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
  class MixedSpecializationController < ActionController::Base
    class OutOfOrder < StandardError; end

    before_filter :first
    before_filter :second, :only => :foo

    def foo
      render_text 'foo'
    end

    def bar
      render_text 'bar'
    end

    protected
      def first
        @first = true
      end

      def second
        raise OutOfOrder unless @first
      end
  end

291 292 293 294 295 296 297 298 299 300 301 302
  class DynamicDispatchController < ActionController::Base
    before_filter :choose

    %w(foo bar baz).each do |action|
      define_method(action) { render :text => action }
    end

    private
      def choose
        self.action_name = params[:choose]
      end
  end
D
Initial  
David Heinemeier Hansson 已提交
303

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
  class PrependingBeforeAndAfterController < ActionController::Base
    prepend_before_filter :before_all
    prepend_after_filter :after_all
    before_filter :between_before_all_and_after_all

    def before_all
      @ran_filter ||= []
      @ran_filter << 'before_all'
    end

    def after_all
      @ran_filter ||= []
      @ran_filter << 'after_all'
    end

    def between_before_all_and_after_all
      @ran_filter ||= []
      @ran_filter << 'between_before_all_and_after_all'
    end
    def show
      render :text => 'hello'
    end
  end
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
  
  class ErrorToRescue < Exception; end
  
  class RescuingAroundFilterWithBlock
    def filter(controller)
      begin
        yield
      rescue ErrorToRescue => ex
        controller.send :render, :text => "I rescued this: #{ex.inspect}"
      end
    end
  end
  
  class RescuedController < ActionController::Base
    around_filter RescuingAroundFilterWithBlock.new
    
    def show
      raise ErrorToRescue.new("Something made the bad noise.")
    end
    
  private
    def rescue_action(exception)
      raise exception
    end
  end
352 353 354 355 356 357

  def test_empty_filter_chain
    assert_equal 0, EmptyFilterChainController.filter_chain.size
    assert test_process(EmptyFilterChainController).template.assigns['action_executed']
  end

D
Initial  
David Heinemeier Hansson 已提交
358
  def test_added_filter_to_inheritance_graph
359
    assert_equal [ :ensure_login ], TestController.before_filters
D
Initial  
David Heinemeier Hansson 已提交
360 361 362
  end

  def test_base_class_in_isolation
363
    assert_equal [ ], ActionController::Base.before_filters
D
Initial  
David Heinemeier Hansson 已提交
364
  end
365

D
Initial  
David Heinemeier Hansson 已提交
366
  def test_prepending_filter
367
    assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters
D
Initial  
David Heinemeier Hansson 已提交
368
  end
369

D
Initial  
David Heinemeier Hansson 已提交
370 371 372 373 374 375 376
  def test_running_filters
    assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
  end

  def test_running_filters_with_proc
    assert test_process(ProcController).template.assigns["ran_proc_filter"]
  end
377

D
Initial  
David Heinemeier Hansson 已提交
378 379 380
  def test_running_filters_with_implicit_proc
    assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
  end
381

D
Initial  
David Heinemeier Hansson 已提交
382 383 384
  def test_running_filters_with_class
    assert test_process(AuditController).template.assigns["was_audited"]
  end
385

386 387 388 389 390 391
  def test_running_anomolous_yet_valid_condition_filters
    response = test_process(AnomolousYetValidConditionController)
    assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
    assert response.template.assigns["ran_class_filter"]
    assert response.template.assigns["ran_proc_filter1"]
    assert response.template.assigns["ran_proc_filter2"]
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
    response = test_process(AnomolousYetValidConditionController, "show_without_filter")
    assert_equal nil, response.template.assigns["ran_filter"]
    assert !response.template.assigns["ran_class_filter"]
    assert !response.template.assigns["ran_proc_filter1"]
    assert !response.template.assigns["ran_proc_filter2"]
  end

  def test_running_collection_condition_filters
    assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
    assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
    assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
  end

  def test_running_only_condition_filters
    assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
    assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]

    assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
    assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]

    assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
    assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
  end

  def test_running_except_condition_filters
    assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
    assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]

    assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
    assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]

    assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
    assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
  end

  def test_running_before_and_after_condition_filters
    assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
    assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
  end
432

D
Initial  
David Heinemeier Hansson 已提交
433
  def test_bad_filter
434 435 436 437
    bad_filter_controller = Class.new(ActionController::Base)
    assert_raises(ActionController::ActionControllerError) do
      bad_filter_controller.before_filter 2
    end
D
Initial  
David Heinemeier Hansson 已提交
438
  end
439

D
Initial  
David Heinemeier Hansson 已提交
440 441 442 443 444
  def test_around_filter
    controller = test_process(AroundFilterController)
    assert controller.template.assigns["before_ran"]
    assert controller.template.assigns["after_ran"]
  end
445

446 447 448 449 450 451
  def test_before_after_class_filter
    controller = test_process(BeforeAfterClassFilterController)
    assert controller.template.assigns["before_ran"]
    assert controller.template.assigns["after_ran"]
  end

D
Initial  
David Heinemeier Hansson 已提交
452 453 454 455 456 457 458 459
  def test_having_properties_in_around_filter
    controller = test_process(AroundFilterController)
    assert_equal "before and after", controller.template.assigns["execution_log"]
  end

  def test_prepending_and_appending_around_filter
    controller = test_process(MixedFilterController)
    assert_equal " before aroundfilter  before procfilter  before appended aroundfilter " +
460
                 " after appended aroundfilter  after aroundfilter  after procfilter ",
D
Initial  
David Heinemeier Hansson 已提交
461 462
                 MixedFilterController.execution_log
  end
463

464 465 466 467 468
  def test_rendering_breaks_filtering_chain
    response = test_process(RenderingController)
    assert_equal "something else", response.body
    assert !response.template.assigns["ran_action"]
  end
D
Initial  
David Heinemeier Hansson 已提交
469

470 471 472 473 474 475 476 477 478 479 480 481
  def test_filters_with_mixed_specialization_run_in_order
    assert_nothing_raised do
      response = test_process(MixedSpecializationController, 'bar')
      assert_equal 'bar', response.body
    end

    assert_nothing_raised do
      response = test_process(MixedSpecializationController, 'foo')
      assert_equal 'foo', response.body
    end
  end

482 483 484 485 486 487 488 489 490
  def test_dynamic_dispatch
    %w(foo bar baz).each do |action|
      request = ActionController::TestRequest.new
      request.query_parameters[:choose] = action
      response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
      assert_equal action, response.body
    end
  end

491 492 493 494 495 496
  def test_running_prepended_before_and_after_filter
    assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length
    response = test_process(PrependingBeforeAndAfterController)
    assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"]
  end

497 498
  def test_conditional_skipping_of_filters
    assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
499
    assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
500 501 502 503 504

    assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
    assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
  end

505 506 507 508
  def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
    assert_nil test_process(ChildOfConditionalParentController, 'another_action').template.assigns['ran_filter']
  end
509

510 511 512 513 514 515
  def test_condition_skipping_of_filters_when_siblings_also_have_conditions
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter'], "1"
    assert_equal nil, test_process(AnotherChildOfConditionalParentController).template.assigns['ran_filter']
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
  end

516 517 518
  def test_changing_the_requirements
    assert_equal nil, test_process(ChangingTheRequirementsController, "go_wild").template.assigns['ran_filter']
  end
519 520 521 522 523 524 525 526 527 528
  
  def test_a_rescuing_around_filter
    response = nil
    assert_nothing_raised do
      response = test_process(RescuedController)
    end
    
    assert response.success?
    assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
  end
529

D
Initial  
David Heinemeier Hansson 已提交
530
  private
531
    def test_process(controller, action = "show")
D
Initial  
David Heinemeier Hansson 已提交
532
      request = ActionController::TestRequest.new
533
      request.action = action
D
Initial  
David Heinemeier Hansson 已提交
534 535
      controller.process(request, ActionController::TestResponse.new)
    end
536
end
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756



class PostsController < ActionController::Base
  def rescue_action(e); raise e; end

  module AroundExceptions
    class Error < StandardError ; end
    class Before < Error ; end
    class After < Error ; end
  end
  include AroundExceptions

  class DefaultFilter
    include AroundExceptions
  end

  module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n")

  private
    def default_action
      render :inline => "#{action_name} called"
    end
end

class ControllerWithSymbolAsFilter < PostsController
  around_filter :raise_before, :only => :raises_before
  around_filter :raise_after, :only => :raises_after
  around_filter :without_exception, :only => :no_raise

  private
    def raise_before
      raise Before
      yield
    end

    def raise_after
      yield
      raise After
    end

    def without_exception
      # Do stuff...
      1 + 1

      yield

      # Do stuff...
      1 + 1
    end
end

class ControllerWithFilterClass < PostsController
  class YieldingFilter < DefaultFilter
    def self.filter(controller)
      yield
      raise After
    end
  end

  around_filter YieldingFilter, :only => :raises_after
end

class ControllerWithFilterInstance < PostsController
  class YieldingFilter < DefaultFilter
    def filter(controller)
      yield
      raise After
    end
  end

  around_filter YieldingFilter.new, :only => :raises_after
end

class ControllerWithFilterMethod < PostsController
  class YieldingFilter < DefaultFilter
    def filter(controller)
      yield
      raise After
    end
  end

  around_filter YieldingFilter.new.method(:filter), :only => :raises_after
end

class ControllerWithProcFilter < PostsController
  around_filter(:only => :no_raise) do |c,b|
    c.assigns['before'] = true
    b.call
    c.assigns['after'] = true
  end
end

class ControllerWithWrongFilterType < PostsController
  around_filter lambda { yield }, :only => :no_raise
end

class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
  around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
end

class ControllerWithAllTypesOfFilters < PostsController
  before_filter :before
  around_filter :around
  after_filter :after
  around_filter :around_again

  private
  def before
    @ran_filter ||= []
    @ran_filter << 'before'
  end

  def around
    @ran_filter << 'around (before yield)'
    yield
    @ran_filter << 'around (after yield)'
  end

  def after
    @ran_filter << 'after'
  end

  def around_again
    @ran_filter << 'around_again (before yield)'
    yield
    @ran_filter << 'around_again (after yield)'
  end
end

class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
  skip_filter :around_again
  skip_filter :after
end

class YieldingAroundFiltersTest < Test::Unit::TestCase
  include PostsController::AroundExceptions

  def test_filters_registering
    assert_equal 1, ControllerWithFilterMethod.filter_chain.size
    assert_equal 1, ControllerWithFilterClass.filter_chain.size
    assert_equal 1, ControllerWithFilterInstance.filter_chain.size
    assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
    assert_equal 1, ControllerWithWrongFilterType.filter_chain.size
    assert_equal 6, ControllerWithNestedFilters.filter_chain.size
    assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
  end

  def test_wrong_filter_type
    assert_raise(ActionController::ActionControllerError) do
      test_process(ControllerWithWrongFilterType,'no_raise')
    end
  end

  def test_base
    controller = PostsController
    assert_nothing_raised { test_process(controller,'no_raise') }
    assert_nothing_raised { test_process(controller,'raises_before') }
    assert_nothing_raised { test_process(controller,'raises_after') }
    assert_nothing_raised { test_process(controller,'no_filter') }
  end

  def test_with_symbol
    controller = ControllerWithSymbolAsFilter
    assert_nothing_raised { test_process(controller,'no_raise') }
    assert_raise(Before) { test_process(controller,'raises_before') }
    assert_raise(After) { test_process(controller,'raises_after') }
    assert_nothing_raised { test_process(controller,'no_raise') }
  end

  def test_with_class
    controller = ControllerWithFilterClass
    assert_nothing_raised { test_process(controller,'no_raise') }
    assert_raise(After) { test_process(controller,'raises_after') }
  end

  def test_with_instance
    controller = ControllerWithFilterInstance
    assert_nothing_raised { test_process(controller,'no_raise') }
    assert_raise(After) { test_process(controller,'raises_after') }
  end

  def test_with_method
    controller = ControllerWithFilterMethod
    assert_nothing_raised { test_process(controller,'no_raise') }
    assert_raise(After) { test_process(controller,'raises_after') }
  end

  def test_with_proc
    controller = test_process(ControllerWithProcFilter,'no_raise')
    assert controller.template.assigns['before']
    assert controller.template.assigns['after']
  end

  def test_nested_filters
    controller = ControllerWithNestedFilters
    assert_nothing_raised do
      begin
        test_process(controller,'raises_both')
      rescue Before, After
      end
    end
    assert_raise Before do
      begin
        test_process(controller,'raises_both')
      rescue After
      end
    end
  end

  def test_filter_order_with_all_filter_types
    controller = test_process(ControllerWithAllTypesOfFilters,'no_raise')
    assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after',controller.template.assigns['ran_filter'].join(' ')
  end

  def test_filter_order_with_skip_filter_method
    controller = test_process(ControllerWithTwoLessFilters,'no_raise')
    assert_equal 'before around (before yield) around (after yield)',controller.template.assigns['ran_filter'].join(' ')
  end

757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
  def test_first_filter_in_multiple_before_filter_chain_halts
    controller = ::FilterTest::TestMultipleFiltersController.new
    response = test_process(controller, 'fail_1')
    assert_equal '', response.body
    assert_equal 1, controller.instance_variable_get(:@try)
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
  end

  def test_second_filter_in_multiple_before_filter_chain_halts
    controller = ::FilterTest::TestMultipleFiltersController.new
    response = test_process(controller, 'fail_2')
    assert_equal '', response.body
    assert_equal 2, controller.instance_variable_get(:@try)
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
  end

  def test_last_filter_in_multiple_before_filter_chain_halts
    controller = ::FilterTest::TestMultipleFiltersController.new
    response = test_process(controller, 'fail_3')
    assert_equal '', response.body
    assert_equal 3, controller.instance_variable_get(:@try)
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
  end

781 782 783 784 785 786 787
  protected
    def test_process(controller, action = "show")
      request = ActionController::TestRequest.new
      request.action = action
      controller.process(request, ActionController::TestResponse.new)
    end
end