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.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1716 -0
  3. data/Gemfile +3 -0
  4. data/Guardfile +6 -0
  5. data/INSTALL +20 -0
  6. data/LICENSE +61 -0
  7. data/README.md +148 -0
  8. data/README_FOR_HEROKU_ADDON.md +102 -0
  9. data/Rakefile +179 -0
  10. data/TESTED_AGAINST +7 -0
  11. data/airbrake.gemspec +41 -0
  12. data/bin/airbrake +12 -0
  13. data/features/metal.feature +34 -0
  14. data/features/rack.feature +60 -0
  15. data/features/rails.feature +324 -0
  16. data/features/rake.feature +33 -0
  17. data/features/sinatra.feature +126 -0
  18. data/features/step_definitions/file_steps.rb +14 -0
  19. data/features/step_definitions/rack_steps.rb +27 -0
  20. data/features/step_definitions/rails_application_steps.rb +267 -0
  21. data/features/step_definitions/rake_steps.rb +22 -0
  22. data/features/support/airbrake_shim.rb.template +11 -0
  23. data/features/support/aruba.rb +5 -0
  24. data/features/support/env.rb +39 -0
  25. data/features/support/matchers.rb +35 -0
  26. data/features/support/rails.rb +156 -0
  27. data/features/support/rake/Rakefile +77 -0
  28. data/features/user_informer.feature +57 -0
  29. data/generators/airbrake/airbrake_generator.rb +94 -0
  30. data/generators/airbrake/lib/insert_commands.rb +34 -0
  31. data/generators/airbrake/lib/rake_commands.rb +24 -0
  32. data/generators/airbrake/templates/airbrake_tasks.rake +25 -0
  33. data/generators/airbrake/templates/capistrano_hook.rb +6 -0
  34. data/generators/airbrake/templates/initializer.rb +4 -0
  35. data/install.rb +1 -0
  36. data/lib/airbrake.rb +191 -0
  37. data/lib/airbrake/backtrace.rb +103 -0
  38. data/lib/airbrake/capistrano.rb +103 -0
  39. data/lib/airbrake/capistrano3.rb +3 -0
  40. data/lib/airbrake/cli/client.rb +76 -0
  41. data/lib/airbrake/cli/options.rb +45 -0
  42. data/lib/airbrake/cli/printer.rb +33 -0
  43. data/lib/airbrake/cli/project.rb +17 -0
  44. data/lib/airbrake/cli/project_factory.rb +33 -0
  45. data/lib/airbrake/cli/runner.rb +49 -0
  46. data/lib/airbrake/cli/validator.rb +8 -0
  47. data/lib/airbrake/configuration.rb +366 -0
  48. data/lib/airbrake/jobs/send_job.rb +7 -0
  49. data/lib/airbrake/notice.rb +411 -0
  50. data/lib/airbrake/rack.rb +64 -0
  51. data/lib/airbrake/rails.rb +45 -0
  52. data/lib/airbrake/rails/action_controller_catcher.rb +32 -0
  53. data/lib/airbrake/rails/controller_methods.rb +146 -0
  54. data/lib/airbrake/rails/error_lookup.rb +35 -0
  55. data/lib/airbrake/rails/middleware.rb +63 -0
  56. data/lib/airbrake/rails3_tasks.rb +126 -0
  57. data/lib/airbrake/railtie.rb +44 -0
  58. data/lib/airbrake/rake_handler.rb +75 -0
  59. data/lib/airbrake/response.rb +29 -0
  60. data/lib/airbrake/sender.rb +213 -0
  61. data/lib/airbrake/shared_tasks.rb +59 -0
  62. data/lib/airbrake/sidekiq.rb +8 -0
  63. data/lib/airbrake/sinatra.rb +40 -0
  64. data/lib/airbrake/tasks.rb +81 -0
  65. data/lib/airbrake/tasks/airbrake.cap +28 -0
  66. data/lib/airbrake/user_informer.rb +36 -0
  67. data/lib/airbrake/utils/params_cleaner.rb +141 -0
  68. data/lib/airbrake/utils/rack_filters.rb +45 -0
  69. data/lib/airbrake/version.rb +3 -0
  70. data/lib/airbrake_tasks.rb +62 -0
  71. data/lib/rails/generators/airbrake/airbrake_generator.rb +155 -0
  72. data/lib/templates/rescue.erb +91 -0
  73. data/rails/init.rb +1 -0
  74. data/resources/README.md +34 -0
  75. data/resources/airbrake_2_4.xsd +89 -0
  76. data/resources/airbrake_3_0.json +52 -0
  77. data/resources/ca-bundle.crt +3376 -0
  78. data/script/integration_test.rb +35 -0
  79. data/test/airbrake_tasks_test.rb +161 -0
  80. data/test/backtrace_test.rb +215 -0
  81. data/test/capistrano_test.rb +44 -0
  82. data/test/configuration_test.rb +303 -0
  83. data/test/controller_methods_test.rb +230 -0
  84. data/test/helper.rb +233 -0
  85. data/test/integration.rb +13 -0
  86. data/test/integration/catcher_test.rb +371 -0
  87. data/test/logger_test.rb +79 -0
  88. data/test/notice_test.rb +494 -0
  89. data/test/notifier_test.rb +288 -0
  90. data/test/params_cleaner_test.rb +204 -0
  91. data/test/rack_test.rb +62 -0
  92. data/test/rails_initializer_test.rb +36 -0
  93. data/test/recursion_test.rb +10 -0
  94. data/test/response_test.rb +18 -0
  95. data/test/sender_test.rb +335 -0
  96. data/test/support/response_shim.xml +4 -0
  97. data/test/user_informer_test.rb +29 -0
  98. metadata +469 -0
@@ -0,0 +1,303 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class ConfigurationTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ should "provide default values" do
8
+ assert_config_default :proxy_host, nil
9
+ assert_config_default :proxy_port, nil
10
+ assert_config_default :proxy_user, nil
11
+ assert_config_default :proxy_pass, nil
12
+ assert_config_default :project_root, nil
13
+ assert_config_default :environment_name, nil
14
+ assert_config_default :logger, nil
15
+ assert_config_default :notifier_version, Airbrake::VERSION
16
+ assert_config_default :notifier_name, 'Airbrake Notifier'
17
+ assert_config_default :notifier_url, 'https://github.com/airbrake/airbrake'
18
+ assert_config_default :secure, false
19
+ assert_config_default :host, 'api.airbrake.io'
20
+ assert_config_default :http_open_timeout, 2
21
+ assert_config_default :http_read_timeout, 5
22
+ assert_config_default :ignore_by_filters, []
23
+ assert_config_default :ignore_user_agent, []
24
+ assert_config_default :params_filters,
25
+ Airbrake::Configuration::DEFAULT_PARAMS_FILTERS
26
+ assert_config_default :params_whitelist_filters,
27
+ Airbrake::Configuration::DEFAULT_PARAMS_WHITELIST_FILTERS
28
+ assert_config_default :backtrace_filters,
29
+ Airbrake::Configuration::DEFAULT_BACKTRACE_FILTERS
30
+ assert_config_default :rake_environment_filters, []
31
+ assert_config_default :ignore,
32
+ Airbrake::Configuration::IGNORE_DEFAULT
33
+ assert_config_default :development_lookup, true
34
+ assert_config_default :framework, 'Standalone'
35
+ assert_config_default :async, nil
36
+ assert_config_default :project_id, nil
37
+ end
38
+
39
+ should "set GirlFriday/SuckerPunch-callable for async=true" do
40
+ config = Airbrake::Configuration.new
41
+ config.async = true
42
+ assert config.async.respond_to?(:call)
43
+ end
44
+
45
+ should "raise error for rake integration if rake handler isn't loaded" do
46
+ config = Airbrake::Configuration.new
47
+ assert_raises(LoadError) { config.rescue_rake_exceptions = true }
48
+ end
49
+
50
+ should "set provided-callable for async {}" do
51
+ config = Airbrake::Configuration.new
52
+ config.async {|notice| :ok}
53
+ assert config.async.respond_to?(:call)
54
+ assert_equal :ok, config.async.call
55
+ end
56
+
57
+ should "provide default values for secure connections" do
58
+ config = Airbrake::Configuration.new
59
+ config.secure = true
60
+ assert_equal 443, config.port
61
+ assert_equal 'https', config.protocol
62
+ end
63
+
64
+ should "provide default values for insecure connections" do
65
+ config = Airbrake::Configuration.new
66
+ config.secure = false
67
+ assert_equal 80, config.port
68
+ assert_equal 'http', config.protocol
69
+ end
70
+
71
+ should "not cache inferred ports" do
72
+ config = Airbrake::Configuration.new
73
+ config.secure = false
74
+ config.port
75
+ config.secure = true
76
+ assert_equal 443, config.port
77
+ end
78
+
79
+ should "allow values to be overwritten" do
80
+ assert_config_overridable :proxy_host
81
+ assert_config_overridable :proxy_port
82
+ assert_config_overridable :proxy_user
83
+ assert_config_overridable :proxy_pass
84
+ assert_config_overridable :secure
85
+ assert_config_overridable :host
86
+ assert_config_overridable :port
87
+ assert_config_overridable :http_open_timeout
88
+ assert_config_overridable :http_read_timeout
89
+ assert_config_overridable :project_root
90
+ assert_config_overridable :notifier_version
91
+ assert_config_overridable :notifier_name
92
+ assert_config_overridable :notifier_url
93
+ assert_config_overridable :environment_name
94
+ assert_config_overridable :development_lookup
95
+ assert_config_overridable :logger
96
+ assert_config_overridable :async
97
+ assert_config_overridable :project_id
98
+ assert_config_overridable :params_filters
99
+ end
100
+
101
+ should "have an api key" do
102
+ assert_config_overridable :api_key
103
+ end
104
+
105
+ should "act like a hash" do
106
+ config = Airbrake::Configuration.new
107
+ hash = config.to_hash
108
+ [:api_key, :backtrace_filters, :development_environments,
109
+ :environment_name, :host, :http_open_timeout,
110
+ :http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent,
111
+ :notifier_name, :notifier_url, :notifier_version, :params_filters,
112
+ :project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
113
+ :proxy_user, :secure, :development_lookup, :async].each do |option|
114
+ assert_equal config[option], hash[option], "Wrong value for #{option}"
115
+ end
116
+ end
117
+
118
+ should "be mergable" do
119
+ config = Airbrake::Configuration.new
120
+ hash = config.to_hash
121
+ assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value')
122
+ end
123
+
124
+ should "allow param filters to be appended" do
125
+ assert_appends_value :params_filters
126
+ end
127
+
128
+ should "allow rake environment filters to be appended" do
129
+ assert_appends_value :rake_environment_filters
130
+ end
131
+
132
+ should "allow ignored user agents to be appended" do
133
+ assert_appends_value :ignore_user_agent
134
+ end
135
+
136
+ should "allow backtrace filters to be appended" do
137
+ assert_appends_value(:backtrace_filters) do |config|
138
+ new_filter = lambda {}
139
+ config.filter_backtrace(&new_filter)
140
+ new_filter
141
+ end
142
+ end
143
+
144
+ should "allow ignore by filters to be appended" do
145
+ assert_appends_value(:ignore_by_filters) do |config|
146
+ new_filter = lambda {}
147
+ config.ignore_by_filter(&new_filter)
148
+ new_filter
149
+ end
150
+ end
151
+
152
+ should "allow ignored exceptions to be appended" do
153
+ config = Airbrake::Configuration.new
154
+ original_filters = config.ignore.dup
155
+ new_filter = 'hello'
156
+ config.ignore << new_filter
157
+ assert_same_elements original_filters + [new_filter], config.ignore
158
+ end
159
+
160
+ should "allow ignored exceptions to be replaced" do
161
+ assert_replaces(:ignore, :ignore_only=)
162
+ end
163
+
164
+ should "allow ignored rake exceptions to be appended" do
165
+ config = Airbrake::Configuration.new
166
+ original_filters = config.ignore_rake.dup
167
+ new_filter = 'hello'
168
+ config.ignore_rake << new_filter
169
+ assert_same_elements original_filters + [new_filter], config.ignore_rake
170
+ end
171
+
172
+ should "allow ignored rake exceptions to be replaced" do
173
+ assert_replaces(:ignore_rake, :ignore_rake_only=)
174
+ end
175
+
176
+ should "allow ignored user agents to be replaced" do
177
+ assert_replaces(:ignore_user_agent, :ignore_user_agent_only=)
178
+ end
179
+
180
+ should "use development and test as development environments by default" do
181
+ config = Airbrake::Configuration.new
182
+ assert_same_elements %w(development test cucumber), config.development_environments
183
+ end
184
+
185
+ context "configured?" do
186
+ setup do
187
+ @config = Airbrake::Configuration.new
188
+ end
189
+
190
+ should "be true if given an api_key" do
191
+ @config.api_key = "1234"
192
+ assert @config.configured?
193
+ end
194
+
195
+ should "be false with a nil api_key" do
196
+ @config.api_key = nil
197
+ assert !@config.configured?
198
+ end
199
+
200
+ should "be false with a blank api_key" do
201
+ @config.api_key = ''
202
+ assert !@config.configured?
203
+ end
204
+ end
205
+
206
+ should "be public in a public environment" do
207
+ config = Airbrake::Configuration.new
208
+ config.development_environments = %w(development)
209
+ config.environment_name = 'production'
210
+ assert config.public?
211
+ end
212
+
213
+ should "not be public in a development environment" do
214
+ config = Airbrake::Configuration.new
215
+ config.development_environments = %w(staging)
216
+ config.environment_name = 'staging'
217
+ assert !config.public?
218
+ end
219
+
220
+ should "be public without an environment name" do
221
+ config = Airbrake::Configuration.new
222
+ assert config.public?
223
+ end
224
+
225
+ should "use the assigned logger if set" do
226
+ config = Airbrake::Configuration.new
227
+ config.logger = "CUSTOM LOGGER"
228
+ assert_equal "CUSTOM LOGGER", config.logger
229
+ end
230
+
231
+ should 'give a new instance if non defined' do
232
+ Airbrake.configuration = nil
233
+ assert_kind_of Airbrake::Configuration, Airbrake.configuration
234
+ end
235
+
236
+ should 'reject invalid user attributes' do
237
+ silence_warnings
238
+ config = Airbrake::Configuration.new
239
+ config.user_attributes = %w(id foo)
240
+ assert_equal %w(id), config.user_attributes
241
+ end
242
+
243
+ should "warn about invalid attributes" do
244
+ stub_warnings
245
+ config = Airbrake::Configuration.new
246
+ config.user_attributes = %w(id foo bar baz)
247
+ %w(foo bar baz).each do |attr|
248
+ assert_match(/Unsupported user attribute: '#{attr}'/, Kernel.warnings)
249
+ end
250
+ end
251
+
252
+ def assert_config_default(option, default_value, config = nil)
253
+ config ||= Airbrake::Configuration.new
254
+ assert_equal default_value, config.send(option)
255
+ end
256
+
257
+ def assert_config_overridable(option, value = 'a value')
258
+ config = Airbrake::Configuration.new
259
+ config.send(:"#{option}=", value)
260
+ assert_equal value, config.send(option)
261
+ end
262
+
263
+ def assert_appends_value(option, &block)
264
+ config = Airbrake::Configuration.new
265
+ original_values = config.send(option).dup
266
+ block ||= lambda do |conf|
267
+ new_value = 'hello'
268
+ conf.send(option) << new_value
269
+ new_value
270
+ end
271
+ new_value = block.call(config)
272
+ assert_same_elements original_values + [new_value], config.send(option)
273
+ end
274
+
275
+ def assert_replaces(option, setter)
276
+ config = Airbrake::Configuration.new
277
+ new_value = 'hello'
278
+ config.send(setter, [new_value])
279
+ assert_equal [new_value], config.send(option)
280
+ config.send(setter, new_value)
281
+ assert_equal [new_value], config.send(option)
282
+ end
283
+
284
+ # monkeypatches Kernel.warn so we can read warnings from
285
+ # Kernel.warnings
286
+ def stub_warnings
287
+ Kernel.class_eval do
288
+ @@warnings = []
289
+
290
+ def warn(*messages)
291
+ @@warnings += messages
292
+ end
293
+
294
+ def self.warnings
295
+ @@warnings.join("\n")
296
+ end
297
+ end
298
+ end
299
+
300
+ def silence_warnings
301
+ Kernel.class_eval { def warn(*args); end }
302
+ end
303
+ end
@@ -0,0 +1,230 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ require 'airbrake/rails/controller_methods'
4
+ class TestController
5
+ include Airbrake::Rails::ControllerMethods
6
+
7
+ def params; {}; end
8
+ def session; nil; end
9
+ def request
10
+ OpenStruct.new(:port=> 80, :protocol => 'http://', host: 'example.com', :fullpath => 'path', :env => [])
11
+ end
12
+ end
13
+
14
+ class NilUserTestController < TestController
15
+ def current_user
16
+ nil
17
+ end
18
+ end
19
+
20
+ class CurrentUserTestController < TestController
21
+ def current_user
22
+ OpenStruct.new(:id => 123, :name => 'tape')
23
+ end
24
+ end
25
+
26
+ class CurrentMemberTestController < TestController
27
+ def current_member
28
+ OpenStruct.new(:id => 321, :name => 'mamba')
29
+ end
30
+ end
31
+
32
+ class CurrentUserErrorTestController < TestController
33
+ def current_user
34
+ fail 'Testing broken implementation for #current_user'
35
+ end
36
+ end
37
+
38
+ class CurrentMemberErrorTestController < TestController
39
+ def current_member
40
+ fail 'Testing broken implementation for #current_member'
41
+ end
42
+ end
43
+
44
+ class CurrentUserAttributeErrorTestController < TestController
45
+ def current_user
46
+ user = OpenStruct.new(:id => 123)
47
+ def user.name
48
+ fail 'Testing attribute that raises error on #current_user'
49
+ end
50
+ user
51
+ end
52
+ end
53
+
54
+ class NoSessionTestController < TestController
55
+ def session
56
+ nil
57
+ end
58
+ end
59
+
60
+ class ParamTestController < TestController
61
+ QUERY_PARAMS = { name: "|" } # URI parameter with invalid character
62
+ def request
63
+ query = QUERY_PARAMS.map { |k, v| "#{k}=#{v}"}.join("&")
64
+ OpenStruct.new(:port=> 80, :protocol => 'http://', host: 'example.com', :fullpath => "path?#{query}", :env => [])
65
+ end
66
+ end
67
+
68
+ class ControllerMethodsTest < Test::Unit::TestCase
69
+ include DefinesConstants
70
+
71
+ context "#airbrake_request_data" do
72
+ context "without a logged in user" do
73
+ setup do
74
+
75
+ NilClass.class_eval do
76
+ @@called = false
77
+
78
+ def self.called
79
+ !! @@called
80
+ end
81
+
82
+ def id
83
+ @@called = true
84
+ end
85
+ end
86
+
87
+ @controller = NilUserTestController.new
88
+ end
89
+
90
+ should "not call #id on NilClass" do
91
+ @controller.airbrake_request_data
92
+ assert_equal false, NilClass.called
93
+ end
94
+ end
95
+
96
+ context "with a logged in User" do
97
+ teardown do
98
+ Object.__send__(:remove_const, :ActiveRecord) if defined?(ActiveRecord)
99
+ Object.__send__(:remove_const, :POOL) if defined?(POOL)
100
+ end
101
+ should 'include user info in the data sent to Ab' do
102
+ Airbrake.configuration.user_attributes = %w(id)
103
+ controller = CurrentUserTestController.new
104
+ ab_data = controller.airbrake_request_data
105
+
106
+ assert_equal( {:id => 123}, ab_data[:user])
107
+ end
108
+
109
+ should 'include more info if asked to, discarding unknown attributes' do
110
+ Airbrake.configuration.user_attributes = %w(id name collar-size)
111
+
112
+ controller = CurrentUserTestController.new
113
+ ab_data = controller.airbrake_request_data
114
+
115
+ assert_equal( {:id => 123, :name => 'tape'}, ab_data[:user])
116
+ end
117
+
118
+ should 'work with a "current_member" method too' do
119
+ Airbrake.configuration.user_attributes = %w(id)
120
+ controller = CurrentMemberTestController.new
121
+ ab_data = controller.airbrake_request_data
122
+
123
+ assert_equal( {:id => 321}, ab_data[:user])
124
+ end
125
+
126
+ should "release DB connections" do
127
+ module ::ActiveRecord; class Base; end; end
128
+ ::ActiveRecord::Base.expects(:clear_active_connections!)
129
+
130
+ CurrentUserTestController.new.airbrake_request_data
131
+ end
132
+ end
133
+
134
+ context 'when loading the user raises an error' do
135
+ should 'send empty user info to Ab when current_user fails' do
136
+ Airbrake.configuration.user_attributes = %w(id)
137
+ controller = CurrentUserErrorTestController.new
138
+ ab_data = controller.airbrake_request_data
139
+
140
+ assert_equal( { }, ab_data[:user] )
141
+ end
142
+
143
+ should 'send empty user info to Ab when current_member fails' do
144
+ Airbrake.configuration.user_attributes = %w(id)
145
+ controller = CurrentMemberErrorTestController.new
146
+ ab_data = controller.airbrake_request_data
147
+
148
+ assert_equal( { }, ab_data[:user] )
149
+ end
150
+
151
+ should 'exclude any user attributes that raise an error' do
152
+ Airbrake.configuration.user_attributes = %w(id name)
153
+ controller = CurrentUserAttributeErrorTestController.new
154
+ ab_data = controller.airbrake_request_data
155
+
156
+ assert_equal( {:id => 123}, ab_data[:user])
157
+ end
158
+ end
159
+ end
160
+
161
+ context '#airbrake_session_data' do
162
+ setup do
163
+ @controller = NoSessionTestController.new
164
+ end
165
+ should 'not call session if no session' do
166
+ no_session = @controller.send(:airbrake_session_data)
167
+ assert_equal no_session, {:session => 'no session found'}
168
+ end
169
+ end
170
+
171
+ context "#airbrake_request_url" do
172
+ setup do
173
+ @controller = NoSessionTestController.new
174
+ end
175
+ should "return correct request url" do
176
+ request_url = @controller.send(:airbrake_request_url)
177
+ assert_equal request_url, "http://example.com/path"
178
+ end
179
+
180
+ should "handle invalid character in param" do
181
+ request_url = ParamTestController.new.send(:airbrake_request_url)
182
+ assert_equal request_url, "http://example.com/path?name=|"
183
+ end
184
+ end
185
+
186
+ context "Rails 3" do
187
+ setup do
188
+ @controller = NilUserTestController.new
189
+ ::Rails = Object.new
190
+ ::Rails.stubs(:version).returns("3.2.17")
191
+ end
192
+
193
+ should "respond to rails_3_or_4? with true" do
194
+ assert @controller.send(:rails_3_or_4?)
195
+ end
196
+
197
+ should "call filter_rails3_parameters" do
198
+ hash = {:a => "b"}
199
+ filtered_hash = {:c => "d"}
200
+
201
+ @controller.expects(:filter_rails3_parameters).with(hash).
202
+ returns(filtered_hash)
203
+ assert_equal filtered_hash,
204
+ @controller.send(:airbrake_filter_if_filtering, hash)
205
+ end
206
+ end
207
+
208
+ context "Rails 4.x" do
209
+ setup do
210
+ @controller = TestController.new
211
+ ::Rails = Object.new
212
+ ::Rails.stubs(:version).returns("4.5.6.7")
213
+ end
214
+
215
+ should 'be true when running Rails 4.x' do
216
+ assert @controller.send(:rails_3_or_4?)
217
+ end
218
+
219
+ should "call filter_rails3_parameters" do
220
+ hash = {:a => "b"}
221
+ filtered_hash = {:c => "d"}
222
+
223
+ @controller.expects(:filter_rails3_parameters).with(hash).
224
+ returns(filtered_hash)
225
+ assert_equal filtered_hash,
226
+ @controller.send(:airbrake_filter_if_filtering, hash)
227
+ end
228
+ end
229
+
230
+ end