/vendor/gems/hoptoad_notifier-2.4.4/test/catcher_test.rb
Ruby | 331 lines | 307 code | 23 blank | 1 comment | 10 complexity | fa36034abff9cc3c44bcaf26a14086d8 MD5 | raw file
- require File.dirname(__FILE__) + '/helper'
- class ActionControllerCatcherTest < Test::Unit::TestCase
- include DefinesConstants
- def setup
- super
- reset_config
- HoptoadNotifier.sender = CollectingSender.new
- define_constant('RAILS_ROOT', '/path/to/rails/root')
- end
- def ignore(exception_class)
- HoptoadNotifier.configuration.ignore << exception_class
- end
- def build_controller_class(&definition)
- returning Class.new(ActionController::Base) do |klass|
- klass.__send__(:include, HoptoadNotifier::Rails::ActionControllerCatcher)
- klass.class_eval(&definition) if definition
- define_constant('HoptoadTestController', klass)
- end
- end
- def assert_sent_hash(hash, xpath)
- hash.each do |key, value|
- next if key.match(/^hoptoad\./) # We added this key.
- element_xpath = "#{xpath}/var[@key = '#{key}']"
- if value.respond_to?(:to_hash)
- assert_sent_hash value.to_hash, element_xpath
- else
- assert_sent_element value, element_xpath
- end
- end
- end
- def assert_sent_element(value, xpath)
- assert_valid_node last_sent_notice_document, xpath, stringify_array_elements(value).to_s
- end
- def stringify_array_elements(data)
- if data.respond_to?(:to_ary)
- data.collect do |value|
- stringify_array_elements(value)
- end
- else
- data.to_s
- end
- end
- def assert_sent_request_info_for(request)
- params = request.parameters.to_hash
- assert_sent_hash params, '/notice/request/params'
- assert_sent_element params['controller'], '/notice/request/component'
- assert_sent_element params['action'], '/notice/request/action'
- assert_sent_element url_from_request(request), '/notice/request/url'
- assert_sent_hash request.env, '/notice/request/cgi-data'
- end
- def url_from_request(request)
- url = "#{request.protocol}#{request.host}"
- unless [80, 443].include?(request.port)
- url << ":#{request.port}"
- end
- url << request.request_uri
- url
- end
- def sender
- HoptoadNotifier.sender
- end
- def last_sent_notice_xml
- sender.collected.last
- end
- def last_sent_notice_document
- assert_not_nil xml = last_sent_notice_xml, "No xml was sent"
- Nokogiri::XML.parse(xml)
- end
- def process_action(opts = {}, &action)
- opts[:request] ||= ActionController::TestRequest.new
- opts[:response] ||= ActionController::TestResponse.new
- klass = build_controller_class do
- cattr_accessor :local
- define_method(:index, &action)
- def local_request?
- local
- end
- end
- if opts[:filters]
- klass.filter_parameter_logging *opts[:filters]
- end
- if opts[:user_agent]
- if opts[:request].respond_to?(:user_agent=)
- opts[:request].user_agent = opts[:user_agent]
- else
- opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent]
- end
- end
- if opts[:port]
- opts[:request].port = opts[:port]
- end
- klass.consider_all_requests_local = opts[:all_local]
- klass.local = opts[:local]
- controller = klass.new
- controller.stubs(:rescue_action_in_public_without_hoptoad)
- opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
- opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
- controller.process(opts[:request], opts[:response])
- controller
- end
- def process_action_with_manual_notification(args = {})
- process_action(args) do
- notify_hoptoad(:error_message => 'fail')
- # Rails will raise a template error if we don't render something
- render :nothing => true
- end
- end
- def process_action_with_automatic_notification(args = {})
- process_action(args) { raise "Hello" }
- end
- should "deliver notices from exceptions raised in public requests" do
- process_action_with_automatic_notification
- assert_caught_and_sent
- end
- should "not deliver notices from exceptions in local requests" do
- process_action_with_automatic_notification(:local => true)
- assert_caught_and_not_sent
- end
- should "not deliver notices from exceptions when all requests are local" do
- process_action_with_automatic_notification(:all_local => true)
- assert_caught_and_not_sent
- end
- should "not deliver notices from actions that don't raise" do
- controller = process_action { render :text => 'Hello' }
- assert_caught_and_not_sent
- assert_equal 'Hello', controller.response.body
- end
- should "not deliver ignored exceptions raised by actions" do
- ignore(RuntimeError)
- process_action_with_automatic_notification
- assert_caught_and_not_sent
- end
- should "deliver ignored exception raised manually" do
- ignore(RuntimeError)
- process_action_with_manual_notification
- assert_caught_and_sent
- end
- should "deliver manually sent notices in public requests" do
- process_action_with_manual_notification
- assert_caught_and_sent
- end
- should "not deliver manually sent notices in local requests" do
- process_action_with_manual_notification(:local => true)
- assert_caught_and_not_sent
- end
- should "not deliver manually sent notices when all requests are local" do
- process_action_with_manual_notification(:all_local => true)
- assert_caught_and_not_sent
- end
- should "continue with default behavior after delivering an exception" do
- controller = process_action_with_automatic_notification(:public => true)
- # TODO: can we test this without stubbing?
- assert_received(controller, :rescue_action_in_public_without_hoptoad)
- end
- should "not create actions from Hoptoad methods" do
- controller = build_controller_class.new
- assert_equal [], HoptoadNotifier::Rails::ActionControllerCatcher.instance_methods
- end
- should "ignore exceptions when user agent is being ignored by regular expression" do
- HoptoadNotifier.configuration.ignore_user_agent_only = [/Ignored/]
- process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored')
- assert_caught_and_not_sent
- end
- should "ignore exceptions when user agent is being ignored by string" do
- HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
- process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent')
- assert_caught_and_not_sent
- end
- should "not ignore exceptions when user agent is not being ignored" do
- HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
- process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent')
- assert_caught_and_sent
- end
- should "send session data for manual notifications" do
- data = { 'one' => 'two' }
- process_action_with_manual_notification(:session => data)
- assert_sent_hash data, "/notice/request/session"
- end
- should "send session data for automatic notification" do
- data = { 'one' => 'two' }
- process_action_with_automatic_notification(:session => data)
- assert_sent_hash data, "/notice/request/session"
- end
- should "send request data for manual notification" do
- params = { 'controller' => "hoptoad_test", 'action' => "index" }
- controller = process_action_with_manual_notification(:params => params)
- assert_sent_request_info_for controller.request
- end
- should "send request data for manual notification with non-standard port" do
- params = { 'controller' => "hoptoad_test", 'action' => "index" }
- controller = process_action_with_manual_notification(:params => params, :port => 81)
- assert_sent_request_info_for controller.request
- end
- should "send request data for automatic notification" do
- params = { 'controller' => "hoptoad_test", 'action' => "index" }
- controller = process_action_with_automatic_notification(:params => params)
- assert_sent_request_info_for controller.request
- end
- should "send request data for automatic notification with non-standard port" do
- params = { 'controller' => "hoptoad_test", 'action' => "index" }
- controller = process_action_with_automatic_notification(:params => params, :port => 81)
- assert_sent_request_info_for controller.request
- end
- should "use standard rails logging filters on params and session and env" do
- filtered_params = { "abc" => "123",
- "def" => "456",
- "ghi" => "[FILTERED]" }
- filtered_session = { "abc" => "123",
- "ghi" => "[FILTERED]" }
- ENV['ghi'] = 'abc'
- filtered_env = { 'ghi' => '[FILTERED]' }
- filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' }
- process_action_with_automatic_notification(:filters => [:ghi, :request_method],
- :params => { "abc" => "123",
- "def" => "456",
- "ghi" => "789" },
- :session => { "abc" => "123",
- "ghi" => "789" })
- assert_sent_hash filtered_params, '/notice/request/params'
- assert_sent_hash filtered_cgi, '/notice/request/cgi-data'
- assert_sent_hash filtered_session, '/notice/request/session'
- end
- context "for a local error with development lookup enabled" do
- setup do
- HoptoadNotifier.configuration.development_lookup = true
- HoptoadNotifier.stubs(:build_lookup_hash_for).returns({ :awesome => 2 })
- @controller = process_action_with_automatic_notification(:local => true)
- @response = @controller.response
- end
- should "append custom CSS and JS to response body for a local error" do
- assert_match /text\/css/, @response.body
- assert_match /text\/javascript/, @response.body
- end
- should "contain host, API key and notice JSON" do
- assert_match HoptoadNotifier.configuration.host.to_json, @response.body
- assert_match HoptoadNotifier.configuration.api_key.to_json, @response.body
- assert_match ({ :awesome => 2 }).to_json, @response.body
- end
- end
- context "for a local error with development lookup disabled" do
- setup do
- HoptoadNotifier.configuration.development_lookup = false
- @controller = process_action_with_automatic_notification(:local => true)
- @response = @controller.response
- end
- should "not append custom CSS and JS to response for a local error" do
- assert_no_match /text\/css/, @response.body
- assert_no_match /text\/javascript/, @response.body
- end
- end
- should "call session.to_hash if available" do
- hash_data = {:key => :value}
- session = ActionController::TestSession.new
- ActionController::TestSession.stubs(:new).returns(session)
- session.stubs(:to_hash).returns(hash_data)
- process_action_with_automatic_notification
- assert_received(session, :to_hash)
- assert_received(session, :data) { |expect| expect.never }
- assert_caught_and_sent
- end
- should "call session.data if session.to_hash is undefined" do
- hash_data = {:key => :value}
- session = ActionController::TestSession.new
- ActionController::TestSession.stubs(:new).returns(session)
- session.stubs(:data).returns(hash_data)
- if session.respond_to?(:to_hash)
- class << session
- undef to_hash
- end
- end
- process_action_with_automatic_notification
- assert_received(session, :to_hash) { |expect| expect.never }
- assert_received(session, :data) { |expect| expect.at_least_once }
- assert_caught_and_sent
- end
- end