airbrakeV4rails5 4.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG +1716 -0
- data/Gemfile +3 -0
- data/Guardfile +6 -0
- data/INSTALL +20 -0
- data/LICENSE +61 -0
- data/README.md +148 -0
- data/README_FOR_HEROKU_ADDON.md +102 -0
- data/Rakefile +179 -0
- data/TESTED_AGAINST +7 -0
- data/airbrake.gemspec +41 -0
- data/bin/airbrake +12 -0
- data/features/metal.feature +34 -0
- data/features/rack.feature +60 -0
- data/features/rails.feature +324 -0
- data/features/rake.feature +33 -0
- data/features/sinatra.feature +126 -0
- data/features/step_definitions/file_steps.rb +14 -0
- data/features/step_definitions/rack_steps.rb +27 -0
- data/features/step_definitions/rails_application_steps.rb +267 -0
- data/features/step_definitions/rake_steps.rb +22 -0
- data/features/support/airbrake_shim.rb.template +11 -0
- data/features/support/aruba.rb +5 -0
- data/features/support/env.rb +39 -0
- data/features/support/matchers.rb +35 -0
- data/features/support/rails.rb +156 -0
- data/features/support/rake/Rakefile +77 -0
- data/features/user_informer.feature +57 -0
- data/generators/airbrake/airbrake_generator.rb +94 -0
- data/generators/airbrake/lib/insert_commands.rb +34 -0
- data/generators/airbrake/lib/rake_commands.rb +24 -0
- data/generators/airbrake/templates/airbrake_tasks.rake +25 -0
- data/generators/airbrake/templates/capistrano_hook.rb +6 -0
- data/generators/airbrake/templates/initializer.rb +4 -0
- data/install.rb +1 -0
- data/lib/airbrake.rb +191 -0
- data/lib/airbrake/backtrace.rb +103 -0
- data/lib/airbrake/capistrano.rb +103 -0
- data/lib/airbrake/capistrano3.rb +3 -0
- data/lib/airbrake/cli/client.rb +76 -0
- data/lib/airbrake/cli/options.rb +45 -0
- data/lib/airbrake/cli/printer.rb +33 -0
- data/lib/airbrake/cli/project.rb +17 -0
- data/lib/airbrake/cli/project_factory.rb +33 -0
- data/lib/airbrake/cli/runner.rb +49 -0
- data/lib/airbrake/cli/validator.rb +8 -0
- data/lib/airbrake/configuration.rb +366 -0
- data/lib/airbrake/jobs/send_job.rb +7 -0
- data/lib/airbrake/notice.rb +411 -0
- data/lib/airbrake/rack.rb +64 -0
- data/lib/airbrake/rails.rb +45 -0
- data/lib/airbrake/rails/action_controller_catcher.rb +32 -0
- data/lib/airbrake/rails/controller_methods.rb +146 -0
- data/lib/airbrake/rails/error_lookup.rb +35 -0
- data/lib/airbrake/rails/middleware.rb +63 -0
- data/lib/airbrake/rails3_tasks.rb +126 -0
- data/lib/airbrake/railtie.rb +44 -0
- data/lib/airbrake/rake_handler.rb +75 -0
- data/lib/airbrake/response.rb +29 -0
- data/lib/airbrake/sender.rb +213 -0
- data/lib/airbrake/shared_tasks.rb +59 -0
- data/lib/airbrake/sidekiq.rb +8 -0
- data/lib/airbrake/sinatra.rb +40 -0
- data/lib/airbrake/tasks.rb +81 -0
- data/lib/airbrake/tasks/airbrake.cap +28 -0
- data/lib/airbrake/user_informer.rb +36 -0
- data/lib/airbrake/utils/params_cleaner.rb +141 -0
- data/lib/airbrake/utils/rack_filters.rb +45 -0
- data/lib/airbrake/version.rb +3 -0
- data/lib/airbrake_tasks.rb +62 -0
- data/lib/rails/generators/airbrake/airbrake_generator.rb +155 -0
- data/lib/templates/rescue.erb +91 -0
- data/rails/init.rb +1 -0
- data/resources/README.md +34 -0
- data/resources/airbrake_2_4.xsd +89 -0
- data/resources/airbrake_3_0.json +52 -0
- data/resources/ca-bundle.crt +3376 -0
- data/script/integration_test.rb +35 -0
- data/test/airbrake_tasks_test.rb +161 -0
- data/test/backtrace_test.rb +215 -0
- data/test/capistrano_test.rb +44 -0
- data/test/configuration_test.rb +303 -0
- data/test/controller_methods_test.rb +230 -0
- data/test/helper.rb +233 -0
- data/test/integration.rb +13 -0
- data/test/integration/catcher_test.rb +371 -0
- data/test/logger_test.rb +79 -0
- data/test/notice_test.rb +494 -0
- data/test/notifier_test.rb +288 -0
- data/test/params_cleaner_test.rb +204 -0
- data/test/rack_test.rb +62 -0
- data/test/rails_initializer_test.rb +36 -0
- data/test/recursion_test.rb +10 -0
- data/test/response_test.rb +18 -0
- data/test/sender_test.rb +335 -0
- data/test/support/response_shim.xml +4 -0
- data/test/user_informer_test.rb +29 -0
- metadata +469 -0
data/test/helper.rb
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
require "simplecov"
|
2
|
+
|
3
|
+
if ENV["INTEGRATION"] then SimpleCov.command_name "test:integration"
|
4
|
+
else SimpleCov.command_name "test:units"
|
5
|
+
end
|
6
|
+
|
7
|
+
SimpleCov.merge_timeout 3600
|
8
|
+
SimpleCov.start
|
9
|
+
|
10
|
+
if ENV["CI"]
|
11
|
+
require "coveralls"
|
12
|
+
Coveralls.wear_merged!
|
13
|
+
end
|
14
|
+
|
15
|
+
$VERBOSE = ENV["VERBOSE"]
|
16
|
+
|
17
|
+
module Kernel
|
18
|
+
def silence_warnings
|
19
|
+
with_warnings(nil) { yield }
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_warnings(flag)
|
23
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
$VERBOSE = old_verbose
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
silence_warnings do
|
31
|
+
require 'test/unit'
|
32
|
+
require 'rubygems'
|
33
|
+
|
34
|
+
require 'thread'
|
35
|
+
|
36
|
+
require 'mocha/setup'
|
37
|
+
require 'nokogiri'
|
38
|
+
require 'rack'
|
39
|
+
require 'bourne'
|
40
|
+
require 'sham_rack'
|
41
|
+
require 'json-schema'
|
42
|
+
require "shoulda-matchers"
|
43
|
+
require "shoulda-context"
|
44
|
+
require "fakeweb"
|
45
|
+
require "pry"
|
46
|
+
|
47
|
+
begin require 'redgreen'; rescue LoadError; end
|
48
|
+
end
|
49
|
+
|
50
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
51
|
+
|
52
|
+
require "airbrake"
|
53
|
+
|
54
|
+
XSD_SCHEMA_PATH = "http://airbrake.io/airbrake_#{Airbrake::API_VERSION.tr(".","_")}.xsd"
|
55
|
+
COVERALLS_API_URL = "https://coveralls.io/api/v1"
|
56
|
+
|
57
|
+
FakeWeb.allow_net_connect = %r{#{XSD_SCHEMA_PATH}|#{COVERALLS_API_URL}}
|
58
|
+
|
59
|
+
module TestMethods
|
60
|
+
def rescue_action e
|
61
|
+
raise e
|
62
|
+
end
|
63
|
+
|
64
|
+
def do_raise
|
65
|
+
raise "Airbrake"
|
66
|
+
end
|
67
|
+
|
68
|
+
def do_not_raise
|
69
|
+
render :text => "Success"
|
70
|
+
end
|
71
|
+
|
72
|
+
def do_raise_ignored
|
73
|
+
raise ActiveRecord::RecordNotFound.new("404")
|
74
|
+
end
|
75
|
+
|
76
|
+
def do_raise_not_ignored
|
77
|
+
raise ActiveRecord::StatementInvalid.new("Statement invalid")
|
78
|
+
end
|
79
|
+
|
80
|
+
def manual_notify
|
81
|
+
notify_airbrake(Exception.new)
|
82
|
+
render :text => "Success"
|
83
|
+
end
|
84
|
+
|
85
|
+
def manual_notify_ignored
|
86
|
+
notify_airbrake(ActiveRecord::RecordNotFound.new("404"))
|
87
|
+
render :text => "Success"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module TestHelpers
|
92
|
+
def stub_sender
|
93
|
+
stub('sender', :send_to_airbrake => nil)
|
94
|
+
end
|
95
|
+
|
96
|
+
def stub_sender!
|
97
|
+
Airbrake.sender = stub_sender
|
98
|
+
end
|
99
|
+
|
100
|
+
def stub_notice
|
101
|
+
stub('notice', :to_xml => 'some yaml', :ignore? => false)
|
102
|
+
end
|
103
|
+
|
104
|
+
def stub_notice!
|
105
|
+
stub_notice.tap do |notice|
|
106
|
+
Airbrake::Notice.stubs(:new => notice)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def reset_config
|
111
|
+
Airbrake.configuration = nil
|
112
|
+
Airbrake.configure do |config|
|
113
|
+
config.api_key = 'abc123'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def clear_backtrace_filters
|
118
|
+
Airbrake.configuration.backtrace_filters.clear
|
119
|
+
end
|
120
|
+
|
121
|
+
def build_exception(opts = {})
|
122
|
+
backtrace = ["airbrake/test/helper.rb:132:in `build_exception'",
|
123
|
+
"airbrake/test/backtrace.rb:4:in `build_notice_data'",
|
124
|
+
"/var/lib/gems/1.8/gems/airbrake-2.4.5/rails/init.rb:2:in `send_exception'"]
|
125
|
+
opts = {:backtrace => backtrace}.merge(opts)
|
126
|
+
BacktracedException.new(opts)
|
127
|
+
end
|
128
|
+
|
129
|
+
def build_notice_data(exception = nil)
|
130
|
+
exception ||= build_exception
|
131
|
+
{
|
132
|
+
:api_key => 'abc123',
|
133
|
+
:error_class => exception.class.name,
|
134
|
+
:error_message => "#{exception.class.name}: #{exception.message}",
|
135
|
+
:backtrace => exception.backtrace,
|
136
|
+
:environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
|
137
|
+
:request => {
|
138
|
+
:params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
|
139
|
+
:rails_root => '/path/to/application',
|
140
|
+
:url => "http://test.host/users/1"
|
141
|
+
},
|
142
|
+
:session => {
|
143
|
+
:key => '123abc',
|
144
|
+
:data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
|
145
|
+
}
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
def assert_caught_and_sent
|
150
|
+
assert !Airbrake.sender.collected.empty?
|
151
|
+
end
|
152
|
+
|
153
|
+
def assert_caught_and_not_sent
|
154
|
+
assert Airbrake.sender.collected.empty?
|
155
|
+
end
|
156
|
+
|
157
|
+
def assert_array_starts_with(expected, actual)
|
158
|
+
assert_respond_to actual, :to_ary
|
159
|
+
array = actual.to_ary.reverse
|
160
|
+
expected.reverse.each_with_index do |value, i|
|
161
|
+
assert_equal value, array[i]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def assert_valid_node(document, xpath, content)
|
166
|
+
nodes = document.xpath(xpath)
|
167
|
+
assert nodes.any?{|node| node.content == content },
|
168
|
+
"Expected xpath #{xpath} to have content #{content}, " +
|
169
|
+
"but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
|
170
|
+
"Document:\n#{document.to_s}"
|
171
|
+
end
|
172
|
+
|
173
|
+
def assert_logged(expected)
|
174
|
+
assert_received(Airbrake, :write_verbose_log) do |expect|
|
175
|
+
expect.with {|actual| actual =~ expected }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def assert_not_logged(expected)
|
180
|
+
assert_received(Airbrake, :write_verbose_log) do |expect|
|
181
|
+
expect.with {|actual| actual =~ expected }.never
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class Test::Unit::TestCase
|
187
|
+
include ::TestHelpers
|
188
|
+
end
|
189
|
+
|
190
|
+
module DefinesConstants
|
191
|
+
def setup
|
192
|
+
@defined_constants = []
|
193
|
+
end
|
194
|
+
|
195
|
+
def teardown
|
196
|
+
@defined_constants.each do |constant|
|
197
|
+
Object.__send__(:remove_const, constant)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def define_constant(name, value)
|
202
|
+
Object.const_set(name, value)
|
203
|
+
@defined_constants << name
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class CollectingSender
|
208
|
+
attr_reader :collected
|
209
|
+
|
210
|
+
def initialize
|
211
|
+
@collected = []
|
212
|
+
end
|
213
|
+
|
214
|
+
def send_to_airbrake(data)
|
215
|
+
@collected << data
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class BacktracedException < Exception
|
220
|
+
attr_accessor :backtrace
|
221
|
+
|
222
|
+
def initialize(opts)
|
223
|
+
@backtrace = opts[:backtrace]
|
224
|
+
end
|
225
|
+
|
226
|
+
def set_backtrace(bt)
|
227
|
+
@backtrace = bt
|
228
|
+
end
|
229
|
+
|
230
|
+
def message
|
231
|
+
"Something went wrong. Did you press the red button?"
|
232
|
+
end
|
233
|
+
end
|
data/test/integration.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path '../helper', __FILE__
|
2
|
+
|
3
|
+
silence_warnings do
|
4
|
+
require 'action_controller'
|
5
|
+
require 'action_dispatch'
|
6
|
+
require 'active_support/dependencies'
|
7
|
+
require 'active_support/core_ext/kernel/reporting'
|
8
|
+
|
9
|
+
require "erb"
|
10
|
+
require "action_view"
|
11
|
+
end
|
12
|
+
|
13
|
+
require File.expand_path "../integration/catcher_test", __FILE__
|
@@ -0,0 +1,371 @@
|
|
1
|
+
require 'airbrake/rails/controller_methods'
|
2
|
+
require 'airbrake/rails/middleware'
|
3
|
+
|
4
|
+
unless defined?(ActionDispatch::IntegrationTest) # Rails 3.0
|
5
|
+
# what follows is a dirty hack which makes
|
6
|
+
# AD::IntegrationTest possible in Rails 3.0
|
7
|
+
ActiveSupport::Deprecation.debug = true
|
8
|
+
|
9
|
+
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
|
10
|
+
FIXTURES = Pathname.new(FIXTURE_LOAD_PATH)
|
11
|
+
|
12
|
+
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
|
13
|
+
|
14
|
+
class RoutedRackApp
|
15
|
+
attr_reader :routes
|
16
|
+
|
17
|
+
def initialize(routes, &blk)
|
18
|
+
@routes = routes
|
19
|
+
@stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
@stack.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ActionController::IntegrationTest < ActiveSupport::TestCase
|
28
|
+
def self.build_app(routes = nil)
|
29
|
+
RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
|
30
|
+
yield(middleware) if block_given?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
self.app = build_app
|
35
|
+
|
36
|
+
# Stub Rails dispatcher so it does not get controller references and
|
37
|
+
# simply return the controller#action as Rack::Body.
|
38
|
+
class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
|
39
|
+
protected
|
40
|
+
def controller_reference(controller_param)
|
41
|
+
controller_param
|
42
|
+
end
|
43
|
+
|
44
|
+
def dispatch(controller, action, env)
|
45
|
+
[200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.stub_controllers
|
50
|
+
old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
|
51
|
+
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
|
52
|
+
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
|
53
|
+
yield ActionDispatch::Routing::RouteSet.new
|
54
|
+
ensure
|
55
|
+
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
|
56
|
+
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
|
57
|
+
end
|
58
|
+
|
59
|
+
def with_routing(&block)
|
60
|
+
temporary_routes = ActionDispatch::Routing::RouteSet.new
|
61
|
+
old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
|
62
|
+
old_routes = SharedTestRoutes
|
63
|
+
silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
|
64
|
+
|
65
|
+
yield temporary_routes
|
66
|
+
ensure
|
67
|
+
self.class.app = old_app
|
68
|
+
silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def with_autoload_path(path)
|
72
|
+
path = File.join(File.dirname(__FILE__), "fixtures", path)
|
73
|
+
if ActiveSupport::Dependencies.autoload_paths.include?(path)
|
74
|
+
yield
|
75
|
+
else
|
76
|
+
begin
|
77
|
+
ActiveSupport::Dependencies.autoload_paths << path
|
78
|
+
yield
|
79
|
+
ensure
|
80
|
+
ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
|
81
|
+
ActiveSupport::Dependencies.clear
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
|
88
|
+
setup do
|
89
|
+
@routes = SharedTestRoutes
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
module ActionController
|
94
|
+
class Base
|
95
|
+
include ActionController::Testing
|
96
|
+
end
|
97
|
+
|
98
|
+
Base.view_paths = FIXTURE_LOAD_PATH
|
99
|
+
|
100
|
+
class TestCase
|
101
|
+
include ActionDispatch::TestProcess
|
102
|
+
|
103
|
+
setup do
|
104
|
+
@routes = SharedTestRoutes
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# This stub emulates the Railtie including the URL helpers from a Rails application
|
110
|
+
module ActionController
|
111
|
+
class Base
|
112
|
+
include SharedTestRoutes.url_helpers
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end # end Rails 3.0 hack
|
116
|
+
|
117
|
+
module ActionDispatch
|
118
|
+
class ShowExceptions
|
119
|
+
private
|
120
|
+
def public_path
|
121
|
+
"/null"
|
122
|
+
end
|
123
|
+
|
124
|
+
# Silence logger
|
125
|
+
def logger
|
126
|
+
Logger.new("/dev/null")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class ActionControllerCatcherTest < ActionDispatch::IntegrationTest
|
132
|
+
|
133
|
+
include DefinesConstants
|
134
|
+
include TestHelpers
|
135
|
+
|
136
|
+
def setup
|
137
|
+
super
|
138
|
+
reset_config
|
139
|
+
Airbrake.sender = CollectingSender.new
|
140
|
+
Airbrake.configuration.development_environments = []
|
141
|
+
define_constant('RAILS_ROOT', '/path/to/rails/root')
|
142
|
+
end
|
143
|
+
|
144
|
+
def ignore(exception_class)
|
145
|
+
Airbrake.configuration.ignore << exception_class
|
146
|
+
end
|
147
|
+
|
148
|
+
def assert_sent_hash(hash, xpath)
|
149
|
+
hash.each do |key, value|
|
150
|
+
next if key.match(/^airbrake\./) || # We added this key.
|
151
|
+
hash[key] !~ /\S/
|
152
|
+
|
153
|
+
element_xpath = "#{xpath}/var[@key = '#{key}']"
|
154
|
+
if value.respond_to?(:to_hash)
|
155
|
+
assert_sent_hash value.to_hash, element_xpath
|
156
|
+
else
|
157
|
+
next if key == "action_dispatch.exception" # TODO: Rails 3.2 only - review
|
158
|
+
value.gsub!(/\d/,"") if key == "PATH_INFO" # TODO: Rails 3.2 only - review
|
159
|
+
assert_sent_element value, element_xpath
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def assert_sent_element(value, xpath)
|
165
|
+
assert_valid_node last_sent_notice_document, xpath, stringify_array_elements(value).to_s
|
166
|
+
end
|
167
|
+
|
168
|
+
def stringify_array_elements(data)
|
169
|
+
if data.respond_to?(:to_ary)
|
170
|
+
data.collect do |value|
|
171
|
+
stringify_array_elements(value)
|
172
|
+
end
|
173
|
+
else
|
174
|
+
data.to_s
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def assert_sent_request_info_for(request)
|
179
|
+
params = request.parameters.to_hash
|
180
|
+
assert_sent_hash params, '/notice/request/params'
|
181
|
+
assert_sent_element params['controller'], '/notice/request/component'
|
182
|
+
assert_sent_element params['action'], '/notice/request/action'
|
183
|
+
assert_sent_element url_from_request(request), '/notice/request/url'
|
184
|
+
assert_sent_hash request.env, '/notice/request/cgi-data'
|
185
|
+
end
|
186
|
+
|
187
|
+
def url_from_request(request)
|
188
|
+
url = "#{request.protocol}#{request.host}"
|
189
|
+
|
190
|
+
unless [80, 443].include?(request.port)
|
191
|
+
url << ":#{request.port}"
|
192
|
+
end
|
193
|
+
|
194
|
+
url << request.fullpath.gsub(%r{\d},"") # TODO: Rails 3.2 only - review
|
195
|
+
|
196
|
+
url
|
197
|
+
end
|
198
|
+
|
199
|
+
def sender
|
200
|
+
Airbrake.sender
|
201
|
+
end
|
202
|
+
|
203
|
+
def last_sent_notice_xml
|
204
|
+
sender.collected.last.to_xml
|
205
|
+
end
|
206
|
+
|
207
|
+
def last_sent_notice_document
|
208
|
+
assert_not_nil xml = last_sent_notice_xml, "No xml was sent"
|
209
|
+
Nokogiri::XML.parse(xml)
|
210
|
+
end
|
211
|
+
|
212
|
+
class AirbrakeTestController < ActionController::Base
|
213
|
+
begin
|
214
|
+
use ActionDispatch::ShowExceptions, ActionDispatch::PublicExceptions.new("/null")
|
215
|
+
rescue NameError
|
216
|
+
use ActionDispatch::ShowExceptions
|
217
|
+
end
|
218
|
+
|
219
|
+
use Airbrake::Rails::Middleware
|
220
|
+
|
221
|
+
include Airbrake::Rails::ControllerMethods
|
222
|
+
|
223
|
+
cattr_accessor :local
|
224
|
+
|
225
|
+
before_filter :set_session
|
226
|
+
|
227
|
+
def set_session
|
228
|
+
unless params.empty?
|
229
|
+
request.session = ActionController::TestSession.new(params[:session] || {})
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def boom
|
234
|
+
raise "boom"
|
235
|
+
render :nothing => true
|
236
|
+
end
|
237
|
+
|
238
|
+
def hello
|
239
|
+
render :text => "hello"
|
240
|
+
end
|
241
|
+
|
242
|
+
def manual_airbrake
|
243
|
+
notify_airbrake(:error_message => "fail")
|
244
|
+
render :nothing => true
|
245
|
+
end
|
246
|
+
|
247
|
+
protected
|
248
|
+
|
249
|
+
def airbrake_local_request?
|
250
|
+
@@local
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
setup do
|
255
|
+
Airbrake.configuration.development_environments = []
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
def test_deliver_notices_from_exceptions_raised_in_public_requests
|
260
|
+
@app = AirbrakeTestController.action(:boom)
|
261
|
+
get '/'
|
262
|
+
assert_caught_and_sent
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_not_deliver_notices_from_exceptions_in_development_environments
|
266
|
+
Airbrake.configuration.development_environments = ["test"]
|
267
|
+
Airbrake.configuration.environment_name = "test"
|
268
|
+
@app = AirbrakeTestController.action(:boom)
|
269
|
+
get '/'
|
270
|
+
assert_caught_and_not_sent
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_not_deliver_notices_from_exceptions_with_no_api_key
|
274
|
+
Airbrake.configuration.api_key = nil
|
275
|
+
@app = AirbrakeTestController.action(:boom)
|
276
|
+
get '/'
|
277
|
+
assert_caught_and_not_sent
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_not_deliver_notices_from_actions_that_dont_raise
|
281
|
+
@app = AirbrakeTestController.action(:hello)
|
282
|
+
get '/'
|
283
|
+
assert_caught_and_not_sent
|
284
|
+
assert_equal 'hello', response.body
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_not_deliver_ignored_exceptions_raised_by_actions
|
288
|
+
@app = AirbrakeTestController.action(:boom)
|
289
|
+
ignore(RuntimeError)
|
290
|
+
get '/'
|
291
|
+
assert_caught_and_not_sent
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_deliver_ignored_exception_raised_manually
|
295
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
296
|
+
ignore(RuntimeError)
|
297
|
+
get '/'
|
298
|
+
assert_caught_and_sent
|
299
|
+
end
|
300
|
+
|
301
|
+
def test_not_deliver_manually_sent_notices_in_local_requests
|
302
|
+
AirbrakeTestController.local = true
|
303
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
304
|
+
get '/'
|
305
|
+
assert_caught_and_not_sent
|
306
|
+
AirbrakeTestController.local = false
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_not_create_actions_from_airbrake_methods
|
310
|
+
Airbrake::Rails::ControllerMethods.instance_methods.each do |method|
|
311
|
+
assert !(AirbrakeTestController.new.action_methods.include?(method))
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_ignore_exceptions_when_user_agent_is_being_ignored_by_regular_expression
|
316
|
+
Airbrake.configuration.ignore_user_agent_only = [/Ignored/]
|
317
|
+
@app = AirbrakeTestController.action(:boom)
|
318
|
+
get "/", {}, {"HTTP_USER_AGENT" => "ShouldBeIgnored"}
|
319
|
+
assert_caught_and_not_sent
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_ignore_exceptions_when_user_agent_is_being_ignored_by_string
|
323
|
+
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
324
|
+
@app = AirbrakeTestController.action(:boom)
|
325
|
+
get "/", {}, {"HTTP_USER_AGENT" => "IgnoredUserAgent"}
|
326
|
+
assert_caught_and_not_sent
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_not_ignore_exceptions_when_user_agent_is_not_being_ignored
|
330
|
+
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
331
|
+
@app = AirbrakeTestController.action(:boom)
|
332
|
+
get "/", {}, {"HTTP_USER_AGENT" => "NonIgnoredAgent"}
|
333
|
+
assert_caught_and_sent
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_send_session_data_for_manual_notifications
|
337
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
338
|
+
data = { 'one' => 'two' }
|
339
|
+
get "/", :session => data
|
340
|
+
assert_sent_hash data, "/notice/request/session"
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_send_request_data_for_manual_notification
|
344
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
345
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
346
|
+
get "/", params
|
347
|
+
assert_sent_request_info_for @request
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_send_request_data_for_manual_notification_with_non_standard_port
|
351
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
352
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
353
|
+
get "/", params, {"SERVER_PORT" => 81}
|
354
|
+
assert_sent_request_info_for @request
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_send_request_data_for_automatic_notification
|
358
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
359
|
+
@app = AirbrakeTestController.action(:boom)
|
360
|
+
get "/", params
|
361
|
+
assert_sent_request_info_for @request
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_send_request_data_for_automatic_notification_with_non_standard_port
|
365
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
366
|
+
@app = AirbrakeTestController.action(:boom)
|
367
|
+
get "/", params, {"SERVER_PORT" => 81}
|
368
|
+
assert_sent_request_info_for @request
|
369
|
+
assert_sent_element 81, "/notice/request/cgi-data/var[@key = 'SERVER_PORT']"
|
370
|
+
end
|
371
|
+
end
|