~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/test/controller/filters_test.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'abstract_unit'
2
 
 
3
 
# FIXME: crashes Ruby 1.9
4
 
class FilterTest < Test::Unit::TestCase
5
 
  class TestController < ActionController::Base
6
 
    before_filter :ensure_login
7
 
    after_filter  :clean_up
8
 
 
9
 
    def show
10
 
      render :inline => "ran action"
11
 
    end
12
 
 
13
 
    private
14
 
      def ensure_login
15
 
        @ran_filter ||= []
16
 
        @ran_filter << "ensure_login"
17
 
      end
18
 
 
19
 
      def clean_up
20
 
        @ran_after_filter ||= []
21
 
        @ran_after_filter << "clean_up"
22
 
      end
23
 
  end
24
 
 
25
 
  class ChangingTheRequirementsController < TestController
26
 
    before_filter :ensure_login, :except => [:go_wild]
27
 
 
28
 
    def go_wild
29
 
      render :text => "gobble"
30
 
    end
31
 
  end
32
 
 
33
 
  class TestMultipleFiltersController < ActionController::Base
34
 
    before_filter :try_1
35
 
    before_filter :try_2
36
 
    before_filter :try_3
37
 
 
38
 
    (1..3).each do |i|
39
 
      define_method "fail_#{i}" do
40
 
        render :text => i.to_s
41
 
      end
42
 
    end
43
 
 
44
 
    protected
45
 
    (1..3).each do |i|
46
 
      define_method "try_#{i}" do
47
 
        instance_variable_set :@try, i
48
 
        if action_name == "fail_#{i}"
49
 
          head(404)
50
 
        end
51
 
      end
52
 
    end
53
 
  end
54
 
 
55
 
  class RenderingController < ActionController::Base
56
 
    before_filter :render_something_else
57
 
 
58
 
    def show
59
 
      @ran_action = true
60
 
      render :inline => "ran action"
61
 
    end
62
 
 
63
 
    private
64
 
      def render_something_else
65
 
        render :inline => "something else"
66
 
      end
67
 
  end
68
 
 
69
 
  class ConditionalFilterController < ActionController::Base
70
 
    def show
71
 
      render :inline => "ran action"
72
 
    end
73
 
 
74
 
    def another_action
75
 
      render :inline => "ran action"
76
 
    end
77
 
 
78
 
    def show_without_filter
79
 
      render :inline => "ran action without filter"
80
 
    end
81
 
 
82
 
    private
83
 
      def ensure_login
84
 
        @ran_filter ||= []
85
 
        @ran_filter << "ensure_login"
86
 
      end
87
 
 
88
 
      def clean_up_tmp
89
 
        @ran_filter ||= []
90
 
        @ran_filter << "clean_up_tmp"
91
 
      end
92
 
 
93
 
      def rescue_action(e) raise(e) end
94
 
  end
95
 
 
96
 
  class ConditionalCollectionFilterController < ConditionalFilterController
97
 
    before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
98
 
  end
99
 
 
100
 
  class OnlyConditionSymController < ConditionalFilterController
101
 
    before_filter :ensure_login, :only => :show
102
 
  end
103
 
 
104
 
  class ExceptConditionSymController < ConditionalFilterController
105
 
    before_filter :ensure_login, :except => :show_without_filter
106
 
  end
107
 
 
108
 
  class BeforeAndAfterConditionController < ConditionalFilterController
109
 
    before_filter :ensure_login, :only => :show
110
 
    after_filter  :clean_up_tmp, :only => :show
111
 
  end
112
 
 
113
 
  class OnlyConditionProcController < ConditionalFilterController
114
 
    before_filter(:only => :show) {|c| c.instance_variable_set(:"@ran_proc_filter", true) }
115
 
  end
116
 
 
117
 
  class ExceptConditionProcController < ConditionalFilterController
118
 
    before_filter(:except => :show_without_filter) {|c| c.instance_variable_set(:"@ran_proc_filter", true) }
119
 
  end
120
 
 
121
 
  class ConditionalClassFilter
122
 
    def self.filter(controller) controller.instance_variable_set(:"@ran_class_filter", true) end
123
 
  end
124
 
 
125
 
  class OnlyConditionClassController < ConditionalFilterController
126
 
    before_filter ConditionalClassFilter, :only => :show
127
 
  end
128
 
 
129
 
  class ExceptConditionClassController < ConditionalFilterController
130
 
    before_filter ConditionalClassFilter, :except => :show_without_filter
131
 
  end
132
 
 
133
 
  class AnomolousYetValidConditionController < ConditionalFilterController
134
 
    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:"@ran_proc_filter1", true)}, :except => :show_without_filter) { |c| c.instance_variable_set(:"@ran_proc_filter2", true)}
135
 
  end
136
 
 
137
 
  class ConditionalOptionsFilter < ConditionalFilterController
138
 
    before_filter :ensure_login, :if => Proc.new { |c| true }
139
 
    before_filter :clean_up_tmp, :if => Proc.new { |c| false }
140
 
  end
141
 
 
142
 
  class EmptyFilterChainController < TestController
143
 
    self.filter_chain.clear
144
 
    def show
145
 
      @action_executed = true
146
 
      render :text => "yawp!"
147
 
    end
148
 
  end
149
 
 
150
 
  class PrependingController < TestController
151
 
    prepend_before_filter :wonderful_life
152
 
    # skip_before_filter :fire_flash
153
 
 
154
 
    private
155
 
      def wonderful_life
156
 
        @ran_filter ||= []
157
 
        @ran_filter << "wonderful_life"
158
 
      end
159
 
  end
160
 
 
161
 
  class SkippingAndLimitedController < TestController
162
 
    skip_before_filter :ensure_login
163
 
    before_filter :ensure_login, :only => :index
164
 
 
165
 
    def index
166
 
      render :text => 'ok'
167
 
    end
168
 
    
169
 
    def public
170
 
    end
171
 
  end
172
 
  
173
 
  class SkippingAndReorderingController < TestController
174
 
    skip_before_filter :ensure_login
175
 
    before_filter :find_record
176
 
    before_filter :ensure_login
177
 
 
178
 
    private
179
 
      def find_record
180
 
        @ran_filter ||= []
181
 
        @ran_filter << "find_record"
182
 
      end
183
 
  end
184
 
 
185
 
  class ConditionalSkippingController < TestController
186
 
    skip_before_filter :ensure_login, :only => [ :login ]
187
 
    skip_after_filter  :clean_up,     :only => [ :login ]
188
 
 
189
 
    before_filter :find_user, :only => [ :change_password ]
190
 
 
191
 
    def login
192
 
      render :inline => "ran action"
193
 
    end
194
 
 
195
 
    def change_password
196
 
      render :inline => "ran action"
197
 
    end
198
 
 
199
 
    protected
200
 
      def find_user
201
 
        @ran_filter ||= []
202
 
        @ran_filter << "find_user"
203
 
      end
204
 
  end
205
 
 
206
 
  class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
207
 
    before_filter :conditional_in_parent, :only => [:show, :another_action]
208
 
    after_filter  :conditional_in_parent, :only => [:show, :another_action]
209
 
 
210
 
    private
211
 
 
212
 
      def conditional_in_parent
213
 
        @ran_filter ||= []
214
 
        @ran_filter << 'conditional_in_parent'
215
 
      end
216
 
  end
217
 
 
218
 
  class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
219
 
    skip_before_filter :conditional_in_parent, :only => :another_action
220
 
    skip_after_filter  :conditional_in_parent, :only => :another_action
221
 
  end
222
 
 
223
 
  class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
224
 
    skip_before_filter :conditional_in_parent, :only => :show
225
 
  end
226
 
 
227
 
  class ProcController < PrependingController
228
 
    before_filter(proc { |c| c.instance_variable_set(:"@ran_proc_filter", true) })
229
 
  end
230
 
 
231
 
  class ImplicitProcController < PrependingController
232
 
    before_filter { |c| c.instance_variable_set(:"@ran_proc_filter", true) }
233
 
  end
234
 
 
235
 
  class AuditFilter
236
 
    def self.filter(controller)
237
 
      controller.instance_variable_set(:"@was_audited", true)
238
 
    end
239
 
  end
240
 
 
241
 
  class AroundFilter
242
 
    def before(controller)
243
 
      @execution_log = "before"
244
 
      controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
245
 
      controller.instance_variable_set(:"@before_ran", true)
246
 
    end
247
 
 
248
 
    def after(controller)
249
 
      controller.instance_variable_set(:"@execution_log", @execution_log + " and after")
250
 
      controller.instance_variable_set(:"@after_ran", true)
251
 
      controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
252
 
    end
253
 
  end
254
 
 
255
 
  class AppendedAroundFilter
256
 
    def before(controller)
257
 
      controller.class.execution_log << " before appended aroundfilter "
258
 
    end
259
 
 
260
 
    def after(controller)
261
 
      controller.class.execution_log << " after appended aroundfilter "
262
 
    end
263
 
  end
264
 
 
265
 
  class AuditController < ActionController::Base
266
 
    before_filter(AuditFilter)
267
 
 
268
 
    def show
269
 
      render :text => "hello"
270
 
    end
271
 
  end
272
 
 
273
 
  class AroundFilterController < PrependingController
274
 
    around_filter AroundFilter.new
275
 
  end
276
 
 
277
 
  class BeforeAfterClassFilterController < PrependingController
278
 
    begin
279
 
      filter = AroundFilter.new
280
 
      before_filter filter
281
 
      after_filter filter
282
 
    end
283
 
  end
284
 
 
285
 
  class MixedFilterController < PrependingController
286
 
    cattr_accessor :execution_log
287
 
 
288
 
    def initialize
289
 
      @@execution_log = ""
290
 
    end
291
 
 
292
 
    before_filter { |c| c.class.execution_log << " before procfilter "  }
293
 
    prepend_around_filter AroundFilter.new
294
 
 
295
 
    after_filter  { |c| c.class.execution_log << " after procfilter " }
296
 
    append_around_filter AppendedAroundFilter.new
297
 
  end
298
 
 
299
 
  class MixedSpecializationController < ActionController::Base
300
 
    class OutOfOrder < StandardError; end
301
 
 
302
 
    before_filter :first
303
 
    before_filter :second, :only => :foo
304
 
 
305
 
    def foo
306
 
      render :text => 'foo'
307
 
    end
308
 
 
309
 
    def bar
310
 
      render :text => 'bar'
311
 
    end
312
 
 
313
 
    protected
314
 
      def first
315
 
        @first = true
316
 
      end
317
 
 
318
 
      def second
319
 
        raise OutOfOrder unless @first
320
 
      end
321
 
  end
322
 
 
323
 
  class DynamicDispatchController < ActionController::Base
324
 
    before_filter :choose
325
 
 
326
 
    %w(foo bar baz).each do |action|
327
 
      define_method(action) { render :text => action }
328
 
    end
329
 
 
330
 
    private
331
 
      def choose
332
 
        self.action_name = params[:choose]
333
 
      end
334
 
  end
335
 
 
336
 
  class PrependingBeforeAndAfterController < ActionController::Base
337
 
    prepend_before_filter :before_all
338
 
    prepend_after_filter :after_all
339
 
    before_filter :between_before_all_and_after_all
340
 
 
341
 
    def before_all
342
 
      @ran_filter ||= []
343
 
      @ran_filter << 'before_all'
344
 
    end
345
 
 
346
 
    def after_all
347
 
      @ran_filter ||= []
348
 
      @ran_filter << 'after_all'
349
 
    end
350
 
 
351
 
    def between_before_all_and_after_all
352
 
      @ran_filter ||= []
353
 
      @ran_filter << 'between_before_all_and_after_all'
354
 
    end
355
 
    def show
356
 
      render :text => 'hello'
357
 
    end
358
 
  end
359
 
 
360
 
  class ErrorToRescue < Exception; end
361
 
 
362
 
  class RescuingAroundFilterWithBlock
363
 
    def filter(controller)
364
 
      begin
365
 
        yield
366
 
      rescue ErrorToRescue => ex
367
 
        controller.__send__ :render, :text => "I rescued this: #{ex.inspect}"
368
 
      end
369
 
    end
370
 
  end
371
 
 
372
 
  class RescuedController < ActionController::Base
373
 
    around_filter RescuingAroundFilterWithBlock.new
374
 
 
375
 
    def show
376
 
      raise ErrorToRescue.new("Something made the bad noise.")
377
 
    end
378
 
 
379
 
  private
380
 
    def rescue_action(exception)
381
 
      raise exception
382
 
    end
383
 
  end
384
 
 
385
 
  class NonYieldingAroundFilterController < ActionController::Base
386
 
 
387
 
    before_filter :filter_one
388
 
    around_filter :non_yielding_filter
389
 
    before_filter :filter_two
390
 
    after_filter :filter_three
391
 
 
392
 
    def index
393
 
      render :inline => "index"
394
 
    end
395
 
 
396
 
    #make sure the controller complains
397
 
    def rescue_action(e); raise e; end
398
 
 
399
 
    private
400
 
 
401
 
      def filter_one
402
 
        @filters  ||= []
403
 
        @filters  << "filter_one"
404
 
      end
405
 
 
406
 
      def filter_two
407
 
        @filters  << "filter_two"
408
 
      end
409
 
 
410
 
      def non_yielding_filter
411
 
        @filters  << "zomg it didn't yield"
412
 
        @filter_return_value
413
 
      end
414
 
 
415
 
      def filter_three
416
 
        @filters  << "filter_three"
417
 
      end
418
 
 
419
 
  end
420
 
 
421
 
  def test_non_yielding_around_filters_not_returning_false_do_not_raise
422
 
    controller = NonYieldingAroundFilterController.new
423
 
    controller.instance_variable_set "@filter_return_value", true
424
 
    assert_nothing_raised do
425
 
      test_process(controller, "index")
426
 
    end
427
 
  end
428
 
 
429
 
  def test_non_yielding_around_filters_returning_false_do_not_raise
430
 
    controller = NonYieldingAroundFilterController.new
431
 
    controller.instance_variable_set "@filter_return_value", false
432
 
    assert_nothing_raised do
433
 
      test_process(controller, "index")
434
 
    end
435
 
  end
436
 
 
437
 
  def test_after_filters_are_not_run_if_around_filter_returns_false
438
 
    controller = NonYieldingAroundFilterController.new
439
 
    controller.instance_variable_set "@filter_return_value", false
440
 
    test_process(controller, "index")
441
 
    assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
442
 
  end
443
 
 
444
 
  def test_after_filters_are_not_run_if_around_filter_does_not_yield
445
 
    controller = NonYieldingAroundFilterController.new
446
 
    controller.instance_variable_set "@filter_return_value", true
447
 
    test_process(controller, "index")
448
 
    assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
449
 
  end
450
 
 
451
 
  def test_empty_filter_chain
452
 
    assert_equal 0, EmptyFilterChainController.filter_chain.size
453
 
    assert test_process(EmptyFilterChainController).template.assigns['action_executed']
454
 
  end
455
 
 
456
 
  def test_added_filter_to_inheritance_graph
457
 
    assert_equal [ :ensure_login ], TestController.before_filters
458
 
  end
459
 
 
460
 
  def test_base_class_in_isolation
461
 
    assert_equal [ ], ActionController::Base.before_filters
462
 
  end
463
 
 
464
 
  def test_prepending_filter
465
 
    assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters
466
 
  end
467
 
 
468
 
  def test_running_filters
469
 
    assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
470
 
  end
471
 
 
472
 
  def test_running_filters_with_proc
473
 
    assert test_process(ProcController).template.assigns["ran_proc_filter"]
474
 
  end
475
 
 
476
 
  def test_running_filters_with_implicit_proc
477
 
    assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
478
 
  end
479
 
 
480
 
  def test_running_filters_with_class
481
 
    assert test_process(AuditController).template.assigns["was_audited"]
482
 
  end
483
 
 
484
 
  def test_running_anomolous_yet_valid_condition_filters
485
 
    response = test_process(AnomolousYetValidConditionController)
486
 
    assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
487
 
    assert response.template.assigns["ran_class_filter"]
488
 
    assert response.template.assigns["ran_proc_filter1"]
489
 
    assert response.template.assigns["ran_proc_filter2"]
490
 
 
491
 
    response = test_process(AnomolousYetValidConditionController, "show_without_filter")
492
 
    assert_equal nil, response.template.assigns["ran_filter"]
493
 
    assert !response.template.assigns["ran_class_filter"]
494
 
    assert !response.template.assigns["ran_proc_filter1"]
495
 
    assert !response.template.assigns["ran_proc_filter2"]
496
 
  end
497
 
 
498
 
  def test_running_conditional_options
499
 
    response = test_process(ConditionalOptionsFilter)
500
 
    assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
501
 
  end
502
 
 
503
 
  def test_running_collection_condition_filters
504
 
    assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
505
 
    assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
506
 
    assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
507
 
  end
508
 
 
509
 
  def test_running_only_condition_filters
510
 
    assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
511
 
    assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]
512
 
 
513
 
    assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
514
 
    assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
515
 
 
516
 
    assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
517
 
    assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
518
 
  end
519
 
 
520
 
  def test_running_except_condition_filters
521
 
    assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
522
 
    assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]
523
 
 
524
 
    assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
525
 
    assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
526
 
 
527
 
    assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
528
 
    assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
529
 
  end
530
 
 
531
 
  def test_running_before_and_after_condition_filters
532
 
    assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
533
 
    assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
534
 
  end
535
 
 
536
 
  def test_around_filter
537
 
    controller = test_process(AroundFilterController)
538
 
    assert controller.template.assigns["before_ran"]
539
 
    assert controller.template.assigns["after_ran"]
540
 
  end
541
 
 
542
 
  def test_before_after_class_filter
543
 
    controller = test_process(BeforeAfterClassFilterController)
544
 
    assert controller.template.assigns["before_ran"]
545
 
    assert controller.template.assigns["after_ran"]
546
 
  end
547
 
 
548
 
  def test_having_properties_in_around_filter
549
 
    controller = test_process(AroundFilterController)
550
 
    assert_equal "before and after", controller.template.assigns["execution_log"]
551
 
  end
552
 
 
553
 
  def test_prepending_and_appending_around_filter
554
 
    controller = test_process(MixedFilterController)
555
 
    assert_equal " before aroundfilter  before procfilter  before appended aroundfilter " +
556
 
                 " after appended aroundfilter  after aroundfilter  after procfilter ",
557
 
                 MixedFilterController.execution_log
558
 
  end
559
 
 
560
 
  def test_rendering_breaks_filtering_chain
561
 
    response = test_process(RenderingController)
562
 
    assert_equal "something else", response.body
563
 
    assert !response.template.assigns["ran_action"]
564
 
  end
565
 
 
566
 
  def test_filters_with_mixed_specialization_run_in_order
567
 
    assert_nothing_raised do
568
 
      response = test_process(MixedSpecializationController, 'bar')
569
 
      assert_equal 'bar', response.body
570
 
    end
571
 
 
572
 
    assert_nothing_raised do
573
 
      response = test_process(MixedSpecializationController, 'foo')
574
 
      assert_equal 'foo', response.body
575
 
    end
576
 
  end
577
 
 
578
 
  def test_dynamic_dispatch
579
 
    %w(foo bar baz).each do |action|
580
 
      request = ActionController::TestRequest.new
581
 
      request.query_parameters[:choose] = action
582
 
      response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
583
 
      assert_equal action, response.body
584
 
    end
585
 
  end
586
 
 
587
 
  def test_running_prepended_before_and_after_filter
588
 
    assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length
589
 
    response = test_process(PrependingBeforeAndAfterController)
590
 
    assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"]
591
 
  end
592
 
  
593
 
  def test_skipping_and_limiting_controller
594
 
    assert_equal %w( ensure_login ), test_process(SkippingAndLimitedController, "index").template.assigns["ran_filter"]
595
 
    assert_nil test_process(SkippingAndLimitedController, "public").template.assigns["ran_filter"]
596
 
  end
597
 
 
598
 
  def test_skipping_and_reordering_controller
599
 
    assert_equal %w( find_record ensure_login ), test_process(SkippingAndReorderingController, "index").template.assigns["ran_filter"]
600
 
  end
601
 
 
602
 
  def test_conditional_skipping_of_filters
603
 
    assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
604
 
    assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
605
 
 
606
 
    assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
607
 
    assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
608
 
  end
609
 
 
610
 
  def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
611
 
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
612
 
    assert_nil test_process(ChildOfConditionalParentController, 'another_action').template.assigns['ran_filter']
613
 
  end
614
 
 
615
 
  def test_condition_skipping_of_filters_when_siblings_also_have_conditions
616
 
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter'], "1"
617
 
    assert_equal nil, test_process(AnotherChildOfConditionalParentController).template.assigns['ran_filter']
618
 
    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
619
 
  end
620
 
 
621
 
  def test_changing_the_requirements
622
 
    assert_equal nil, test_process(ChangingTheRequirementsController, "go_wild").template.assigns['ran_filter']
623
 
  end
624
 
 
625
 
  def test_a_rescuing_around_filter
626
 
    response = nil
627
 
    assert_nothing_raised do
628
 
      response = test_process(RescuedController)
629
 
    end
630
 
 
631
 
    assert response.success?
632
 
    assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
633
 
  end
634
 
 
635
 
  private
636
 
    def test_process(controller, action = "show")
637
 
      ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest
638
 
      request = ActionController::TestRequest.new
639
 
      request.action = action
640
 
      controller = controller.new if controller.is_a?(Class)
641
 
      controller.process_with_test(request, ActionController::TestResponse.new)
642
 
    end
643
 
end
644
 
 
645
 
 
646
 
 
647
 
class PostsController < ActionController::Base
648
 
  def rescue_action(e); raise e; end
649
 
 
650
 
  module AroundExceptions
651
 
    class Error < StandardError ; end
652
 
    class Before < Error ; end
653
 
    class After < Error ; end
654
 
  end
655
 
  include AroundExceptions
656
 
 
657
 
  class DefaultFilter
658
 
    include AroundExceptions
659
 
  end
660
 
 
661
 
  module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n")
662
 
 
663
 
  private
664
 
    def default_action
665
 
      render :inline => "#{action_name} called"
666
 
    end
667
 
end
668
 
 
669
 
class ControllerWithSymbolAsFilter < PostsController
670
 
  around_filter :raise_before, :only => :raises_before
671
 
  around_filter :raise_after, :only => :raises_after
672
 
  around_filter :without_exception, :only => :no_raise
673
 
 
674
 
  private
675
 
    def raise_before
676
 
      raise Before
677
 
      yield
678
 
    end
679
 
 
680
 
    def raise_after
681
 
      yield
682
 
      raise After
683
 
    end
684
 
 
685
 
    def without_exception
686
 
      # Do stuff...
687
 
      1 + 1
688
 
 
689
 
      yield
690
 
 
691
 
      # Do stuff...
692
 
      1 + 1
693
 
    end
694
 
end
695
 
 
696
 
class ControllerWithFilterClass < PostsController
697
 
  class YieldingFilter < DefaultFilter
698
 
    def self.filter(controller)
699
 
      yield
700
 
      raise After
701
 
    end
702
 
  end
703
 
 
704
 
  around_filter YieldingFilter, :only => :raises_after
705
 
end
706
 
 
707
 
class ControllerWithFilterInstance < PostsController
708
 
  class YieldingFilter < DefaultFilter
709
 
    def filter(controller)
710
 
      yield
711
 
      raise After
712
 
    end
713
 
  end
714
 
 
715
 
  around_filter YieldingFilter.new, :only => :raises_after
716
 
end
717
 
 
718
 
class ControllerWithFilterMethod < PostsController
719
 
  class YieldingFilter < DefaultFilter
720
 
    def filter(controller)
721
 
      yield
722
 
      raise After
723
 
    end
724
 
  end
725
 
 
726
 
  around_filter YieldingFilter.new.method(:filter), :only => :raises_after
727
 
end
728
 
 
729
 
class ControllerWithProcFilter < PostsController
730
 
  around_filter(:only => :no_raise) do |c,b|
731
 
    c.instance_variable_set(:"@before", true)
732
 
    b.call
733
 
    c.instance_variable_set(:"@after", true)
734
 
  end
735
 
end
736
 
 
737
 
class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
738
 
  around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
739
 
end
740
 
 
741
 
class ControllerWithAllTypesOfFilters < PostsController
742
 
  before_filter :before
743
 
  around_filter :around
744
 
  after_filter :after
745
 
  around_filter :around_again
746
 
 
747
 
  private
748
 
  def before
749
 
    @ran_filter ||= []
750
 
    @ran_filter << 'before'
751
 
  end
752
 
 
753
 
  def around
754
 
    @ran_filter << 'around (before yield)'
755
 
    yield
756
 
    @ran_filter << 'around (after yield)'
757
 
  end
758
 
 
759
 
  def after
760
 
    @ran_filter << 'after'
761
 
  end
762
 
 
763
 
  def around_again
764
 
    @ran_filter << 'around_again (before yield)'
765
 
    yield
766
 
    @ran_filter << 'around_again (after yield)'
767
 
  end
768
 
end
769
 
 
770
 
class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
771
 
  skip_filter :around_again
772
 
  skip_filter :after
773
 
end
774
 
 
775
 
class YieldingAroundFiltersTest < Test::Unit::TestCase
776
 
  include PostsController::AroundExceptions
777
 
 
778
 
  def test_filters_registering
779
 
    assert_equal 1, ControllerWithFilterMethod.filter_chain.size
780
 
    assert_equal 1, ControllerWithFilterClass.filter_chain.size
781
 
    assert_equal 1, ControllerWithFilterInstance.filter_chain.size
782
 
    assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
783
 
    assert_equal 6, ControllerWithNestedFilters.filter_chain.size
784
 
    assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
785
 
  end
786
 
 
787
 
  def test_base
788
 
    controller = PostsController
789
 
    assert_nothing_raised { test_process(controller,'no_raise') }
790
 
    assert_nothing_raised { test_process(controller,'raises_before') }
791
 
    assert_nothing_raised { test_process(controller,'raises_after') }
792
 
    assert_nothing_raised { test_process(controller,'no_filter') }
793
 
  end
794
 
 
795
 
  def test_with_symbol
796
 
    controller = ControllerWithSymbolAsFilter
797
 
    assert_nothing_raised { test_process(controller,'no_raise') }
798
 
    assert_raise(Before) { test_process(controller,'raises_before') }
799
 
    assert_raise(After) { test_process(controller,'raises_after') }
800
 
    assert_nothing_raised { test_process(controller,'no_raise') }
801
 
  end
802
 
 
803
 
  def test_with_class
804
 
    controller = ControllerWithFilterClass
805
 
    assert_nothing_raised { test_process(controller,'no_raise') }
806
 
    assert_raise(After) { test_process(controller,'raises_after') }
807
 
  end
808
 
 
809
 
  def test_with_instance
810
 
    controller = ControllerWithFilterInstance
811
 
    assert_nothing_raised { test_process(controller,'no_raise') }
812
 
    assert_raise(After) { test_process(controller,'raises_after') }
813
 
  end
814
 
 
815
 
  def test_with_method
816
 
    controller = ControllerWithFilterMethod
817
 
    assert_nothing_raised { test_process(controller,'no_raise') }
818
 
    assert_raise(After) { test_process(controller,'raises_after') }
819
 
  end
820
 
 
821
 
  def test_with_proc
822
 
    controller = test_process(ControllerWithProcFilter,'no_raise')
823
 
    assert controller.template.assigns['before']
824
 
    assert controller.template.assigns['after']
825
 
  end
826
 
 
827
 
  def test_nested_filters
828
 
    controller = ControllerWithNestedFilters
829
 
    assert_nothing_raised do
830
 
      begin
831
 
        test_process(controller,'raises_both')
832
 
      rescue Before, After
833
 
      end
834
 
    end
835
 
    assert_raise Before do
836
 
      begin
837
 
        test_process(controller,'raises_both')
838
 
      rescue After
839
 
      end
840
 
    end
841
 
  end
842
 
 
843
 
  def test_filter_order_with_all_filter_types
844
 
    controller = test_process(ControllerWithAllTypesOfFilters,'no_raise')
845
 
    assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after',controller.template.assigns['ran_filter'].join(' ')
846
 
  end
847
 
 
848
 
  def test_filter_order_with_skip_filter_method
849
 
    controller = test_process(ControllerWithTwoLessFilters,'no_raise')
850
 
    assert_equal 'before around (before yield) around (after yield)',controller.template.assigns['ran_filter'].join(' ')
851
 
  end
852
 
 
853
 
  def test_first_filter_in_multiple_before_filter_chain_halts
854
 
    controller = ::FilterTest::TestMultipleFiltersController.new
855
 
    response = test_process(controller, 'fail_1')
856
 
    assert_equal ' ', response.body
857
 
    assert_equal 1, controller.instance_variable_get(:@try)
858
 
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
859
 
  end
860
 
 
861
 
  def test_second_filter_in_multiple_before_filter_chain_halts
862
 
    controller = ::FilterTest::TestMultipleFiltersController.new
863
 
    response = test_process(controller, 'fail_2')
864
 
    assert_equal ' ', response.body
865
 
    assert_equal 2, controller.instance_variable_get(:@try)
866
 
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
867
 
  end
868
 
 
869
 
  def test_last_filter_in_multiple_before_filter_chain_halts
870
 
    controller = ::FilterTest::TestMultipleFiltersController.new
871
 
    response = test_process(controller, 'fail_3')
872
 
    assert_equal ' ', response.body
873
 
    assert_equal 3, controller.instance_variable_get(:@try)
874
 
    assert controller.instance_variable_get(:@before_filter_chain_aborted)
875
 
  end
876
 
 
877
 
  protected
878
 
    def test_process(controller, action = "show")
879
 
      ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest
880
 
      request = ActionController::TestRequest.new
881
 
      request.action = action
882
 
      controller = controller.new if controller.is_a?(Class)
883
 
      controller.process_with_test(request, ActionController::TestResponse.new)
884
 
    end
885
 
end