module Shoulda module Matchers module ActionController # The `use_before_filter` matcher is used to test that a before_filter # callback is defined within your controller. # # class UsersController < ApplicationController # before_filter :authenticate_user! # end # # # RSpec # RSpec.describe UsersController, type: :controller do # it { should use_before_filter(:authenticate_user!) } # it { should_not use_before_filter(:prevent_ssl) } # end # # # Minitest (Shoulda) # class UsersControllerTest < ActionController::TestCase # should use_before_filter(:authenticate_user!) # should_not use_before_filter(:prevent_ssl) # end # # @return [CallbackMatcher] # def use_before_filter(callback) CallbackMatcher.new(callback, :before, :filter) end # The `use_after_filter` matcher is used to test that an after_filter # callback is defined within your controller. # # class IssuesController < ApplicationController # after_filter :log_activity # end # # # RSpec # RSpec.describe IssuesController, type: :controller do # it { should use_after_filter(:log_activity) } # it { should_not use_after_filter(:destroy_user) } # end # # # Minitest (Shoulda) # class IssuesControllerTest < ActionController::TestCase # should use_after_filter(:log_activity) # should_not use_after_filter(:destroy_user) # end # # @return [CallbackMatcher] # def use_after_filter(callback) CallbackMatcher.new(callback, :after, :filter) end # The `use_before_action` matcher is used to test that a before_action # callback is defined within your controller. # # class UsersController < ApplicationController # before_action :authenticate_user! # end # # # RSpec # RSpec.describe UsersController, type: :controller do # it { should use_before_action(:authenticate_user!) } # it { should_not use_before_action(:prevent_ssl) } # end # # # Minitest (Shoulda) # class UsersControllerTest < ActionController::TestCase # should use_before_action(:authenticate_user!) # should_not use_before_action(:prevent_ssl) # end # # @return [CallbackMatcher] # def use_before_action(callback) CallbackMatcher.new(callback, :before, :action) end # The `use_after_action` matcher is used to test that an after_action # callback is defined within your controller. # # class IssuesController < ApplicationController # after_action :log_activity # end # # # RSpec # RSpec.describe IssuesController, type: :controller do # it { should use_after_action(:log_activity) } # it { should_not use_after_action(:destroy_user) } # end # # # Minitest (Shoulda) # class IssuesControllerTest < ActionController::TestCase # should use_after_action(:log_activity) # should_not use_after_action(:destroy_user) # end # # @return [CallbackMatcher] # def use_after_action(callback) CallbackMatcher.new(callback, :after, :action) end # The `use_around_filter` matcher is used to test that an around_filter # callback is defined within your controller. # # class ChangesController < ApplicationController # around_filter :wrap_in_transaction # end # # # RSpec # RSpec.describe ChangesController, type: :controller do # it { should use_around_filter(:wrap_in_transaction) } # it { should_not use_around_filter(:save_view_context) } # end # # # Minitest (Shoulda) # class ChangesControllerTest < ActionController::TestCase # should use_around_filter(:wrap_in_transaction) # should_not use_around_filter(:save_view_context) # end # # @return [CallbackMatcher] # def use_around_filter(callback) CallbackMatcher.new(callback, :around, :filter) end # The `use_around_action` matcher is used to test that an around_action # callback is defined within your controller. # # class ChangesController < ApplicationController # around_action :wrap_in_transaction # end # # # RSpec # RSpec.describe ChangesController, type: :controller do # it { should use_around_action(:wrap_in_transaction) } # it { should_not use_around_action(:save_view_context) } # end # # # Minitest (Shoulda) # class ChangesControllerTest < ActionController::TestCase # should use_around_action(:wrap_in_transaction) # should_not use_around_action(:save_view_context) # end # # @return [CallbackMatcher] # def use_around_action(callback) CallbackMatcher.new(callback, :around, :action) end # @private class CallbackMatcher def initialize(method_name, kind, callback_type) @method_name = method_name @kind = kind @callback_type = callback_type end def matches?(controller) @controller = controller @controller_class = controller.class callbacks.map(&:filter).include?(method_name) end def failure_message "Expected that #{controller_class.name} would have :#{method_name} as a #{kind}_#{callback_type}" end def failure_message_when_negated "Expected that #{controller_class.name} would not have :#{method_name} as a #{kind}_#{callback_type}" end def description "have :#{method_name} as a #{kind}_#{callback_type}" end protected def callbacks controller_class._process_action_callbacks.select do |callback| callback.kind == kind end end attr_reader :method_name, :controller, :controller_class, :kind, :callback_type end end end end