The code below shows two controllers that have before_filters added in different orders. As a result, the controllers have different behavior.
When current_user is nil (logged out):
- FooController -> redirects to login_path
- BarController -> redirects to root_path
You could, of course, combine the two methods and make them smarter to make this specific example go away -- but that is missing the point of this question.
The issue at hand is that, in ActionController, the order that filters get added is relevant. (You could also argue that that implementation isn't the greatest, but that's how it is -- so let's move on)
Since that's how ActionController works, I would like to test that behavior. However, it isn't necessary to test the results of the before filters on each individual action (not DRY). As far as I can figure, what's actually important is the resulting order of the filter chain on each action.
The only thing that before_filter :require_user
actually does is inject an item into the callback chain - and that's all I should have to test for in my subclasses - that an additional item has been added to the chain. I don't need to test the effect that require_user
has on my actions - they can, and should, be stubbed.
That all said, here's the money question: Is there a public API that returns what methods are in a given controller and action's filter chain? This should include before, after and around filters in their appropriate order.
class ApplicationController < ActionController::Base
def require_user
unless current_user
redirect_to login_path and return
end
end
def require_admin
unless current_user.try(:admin?)
redirect_to root_path and return
end
end
end
class FooController < ApplicationController
before_filter :require_user
before_filter :require_admin
end
class BarController < ApplicationController
# reverse the order of the filters
before_filter :require_admin
before_filter :require_user
end