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,79 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class LoggerTest < Test::Unit::TestCase
4
+ def stub_http(response, body = nil)
5
+ response.stubs(:body => body) if body
6
+ @http = stub(:post => response,
7
+ :read_timeout= => nil,
8
+ :open_timeout= => nil,
9
+ :use_ssl= => nil)
10
+ Net::HTTP.stubs(:new).returns(@http)
11
+ end
12
+
13
+ def send_notice
14
+ Airbrake.sender.send_to_airbrake({'foo' => "bar"})
15
+ end
16
+
17
+ def stub_verbose_log
18
+ Airbrake.stubs(:write_verbose_log)
19
+ end
20
+
21
+ def configure
22
+ Airbrake.configure { |config| }
23
+ end
24
+
25
+ should "report that notifier is ready when configured" do
26
+ stub_verbose_log
27
+ configure
28
+ assert_logged(/Notifier (.*) ready/)
29
+ end
30
+
31
+ should "not report that notifier is ready when internally configured" do
32
+ stub_verbose_log
33
+ Airbrake.configure(true) { |config| }
34
+ assert_not_logged(/.*/)
35
+ end
36
+
37
+ should "print environment info a successful notification without a body" do
38
+ reset_config
39
+ stub_verbose_log
40
+ stub_http(Net::HTTPSuccess)
41
+ send_notice
42
+ assert_logged(/Environment Info:/)
43
+ assert_not_logged(/Response from Airbrake:/)
44
+ end
45
+
46
+ should "print environment info on a failed notification without a body" do
47
+ reset_config
48
+ stub_verbose_log
49
+ stub_http(Net::HTTPError)
50
+ send_notice
51
+ assert_logged(/Environment Info:/)
52
+ assert_not_logged(/Response from Airbrake:/)
53
+ end
54
+
55
+ should "print environment info and response on a success with a body" do
56
+ reset_config
57
+ stub_verbose_log
58
+ stub_http(Net::HTTPSuccess, 'test')
59
+ send_notice
60
+ assert_logged(/Environment Info:/)
61
+ assert_logged(/Response from Airbrake:/)
62
+ end
63
+
64
+ should "print environment info and response on a failure with a body" do
65
+ reset_config
66
+ stub_verbose_log
67
+ stub_http(Net::HTTPError, 'test')
68
+ send_notice
69
+ assert_logged(/Environment Info:/)
70
+ assert_logged(/Response from Airbrake:/)
71
+ end
72
+
73
+ should "print information about the notice when Airbrake server fails" do
74
+ stub_verbose_log
75
+ stub_http(Net::HTTPError, "test")
76
+ send_notice
77
+ assert_logged(/Notice details:/)
78
+ end
79
+ end
@@ -0,0 +1,494 @@
1
+ require File.expand_path '../helper', __FILE__
2
+
3
+ class NoticeTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ def configure
8
+ Airbrake::Configuration.new.tap do |config|
9
+ config.api_key = 'abc123def456'
10
+ end
11
+ end
12
+
13
+ def build_notice(args = {})
14
+ configuration = args.delete(:configuration) || configure
15
+ Airbrake::Notice.new(configuration.merge(args))
16
+ end
17
+
18
+ def stub_request(attrs = {})
19
+ stub('request', { :parameters => { 'one' => 'two' },
20
+ :protocol => 'http',
21
+ :host => 'some.host',
22
+ :request_uri => '/some/uri',
23
+ :session => { :to_hash => { 'a' => 'b' } },
24
+ :env => { 'three' => 'four' } }.update(attrs))
25
+ end
26
+
27
+ def assert_accepts_exception_attribute(attribute, args = {}, &block)
28
+ exception = build_exception
29
+ block ||= lambda { exception.send(attribute) }
30
+ value = block.call(exception)
31
+
32
+ notice_from_exception = build_notice(args.merge(:exception => exception))
33
+
34
+ assert_equal notice_from_exception.send(attribute),
35
+ value,
36
+ "#{attribute} was not correctly set from an exception"
37
+
38
+ notice_from_hash = build_notice(args.merge(attribute => value))
39
+ assert_equal notice_from_hash.send(attribute),
40
+ value,
41
+ "#{attribute} was not correctly set from a hash"
42
+ end
43
+
44
+ def assert_valid_notice_document(document)
45
+ xsd_path = File.expand_path(File.join(File.dirname(__FILE__),"..", "resources", "airbrake_2_4.xsd"))
46
+ schema = Nokogiri::XML::Schema.new(IO.read(xsd_path))
47
+ errors = schema.validate(document)
48
+ assert errors.empty?, errors.collect{|e| e.message }.join
49
+ end
50
+
51
+ def assert_valid_json(notice)
52
+ json_schema = File.expand_path(File.join(File.dirname(__FILE__),"..", "resources", "airbrake_3_0.json"))
53
+ errors = JSON::Validator.fully_validate(json_schema, notice)
54
+ assert errors.empty?, errors.join
55
+ end
56
+
57
+ def build_backtrace_array
58
+ ["app/models/user.rb:13:in `magic'",
59
+ "app/controllers/users_controller.rb:8:in `index'"]
60
+ end
61
+
62
+ def hostname
63
+ `hostname`.chomp
64
+ end
65
+
66
+ def user
67
+ Struct.new(:email,:id,:name).
68
+ new("darth@vader.com",1,"Anakin Skywalker")
69
+ end
70
+
71
+ should "call the cleaner on initialization" do
72
+ cleaner = stub
73
+ cleaner.expects(:clean).returns(stub(:parameters => {}, :cgi_data => {}, :session_data => {}))
74
+ Airbrake::Notice.new(:cleaner => cleaner)
75
+ end
76
+
77
+ should "set the api key" do
78
+ api_key = 'key'
79
+ notice = build_notice(:api_key => api_key)
80
+ assert_equal api_key, notice.api_key
81
+ end
82
+
83
+ should "accept a project root" do
84
+ project_root = '/path/to/project'
85
+ notice = build_notice(:project_root => project_root)
86
+ assert_equal project_root, notice.project_root
87
+ end
88
+
89
+ should "accept a component" do
90
+ assert_equal 'users_controller', build_notice(:component => 'users_controller').controller
91
+ end
92
+
93
+ should "alias the component as controller" do
94
+ assert_equal 'users_controller', build_notice(:controller => 'users_controller').component
95
+ assert_equal 'users_controller', build_notice(:component => 'users_controller').controller
96
+ end
97
+
98
+ should "accept a action" do
99
+ assert_equal 'index', build_notice(:action => 'index').action
100
+ end
101
+
102
+ should "accept a url" do
103
+ url = 'http://some.host/uri'
104
+ notice = build_notice(:url => url)
105
+ assert_equal url, notice.url
106
+ end
107
+
108
+ should "set the host name" do
109
+ notice = build_notice
110
+ assert_equal hostname, notice.hostname
111
+ end
112
+
113
+ should "accept a backtrace from an exception or hash" do
114
+ array = ["user.rb:34:in `crazy'"]
115
+ exception = build_exception
116
+ exception.set_backtrace array
117
+ backtrace = Airbrake::Backtrace.parse(array)
118
+ notice_from_exception = build_notice(:exception => exception)
119
+
120
+
121
+ assert_equal backtrace,
122
+ notice_from_exception.backtrace,
123
+ "backtrace was not correctly set from an exception"
124
+
125
+ notice_from_hash = build_notice(:backtrace => array)
126
+ assert_equal backtrace,
127
+ notice_from_hash.backtrace,
128
+ "backtrace was not correctly set from a hash"
129
+ end
130
+
131
+ should "accept user" do
132
+ assert_equal user.id, build_notice(:user => user).user.id
133
+ assert_equal user.email, build_notice(:user => user).user.email
134
+ assert_equal user.name, build_notice(:user => user).user.name
135
+ end
136
+
137
+ should "pass its backtrace filters for parsing" do
138
+ backtrace_array = ['my/file/backtrace:3']
139
+ exception = build_exception
140
+ exception.set_backtrace(backtrace_array)
141
+ Airbrake::Backtrace.expects(:parse).with(backtrace_array, {:filters => 'foo'})
142
+
143
+ Airbrake::Notice.new({:exception => exception, :backtrace_filters => 'foo'})
144
+ end
145
+
146
+ should "set the error class from an exception or hash" do
147
+ assert_accepts_exception_attribute :error_class do |exception|
148
+ exception.class.name
149
+ end
150
+ end
151
+
152
+ should "set the error message from an exception or hash" do
153
+ assert_accepts_exception_attribute :error_message do |exception|
154
+ "#{exception.class.name}: #{exception.message}"
155
+ end
156
+ end
157
+
158
+ should "accept parameters from a request or hash" do
159
+ parameters = { 'one' => 'two' }
160
+ notice_from_hash = build_notice(:parameters => parameters)
161
+ assert_equal notice_from_hash.parameters, parameters
162
+ end
163
+
164
+ should "accept session data from a session[:data] hash" do
165
+ data = { 'one' => 'two' }
166
+ notice = build_notice(:session => { :data => data })
167
+ assert_equal data, notice.session_data
168
+ end
169
+
170
+ should "accept session data from a session_data hash" do
171
+ data = { 'one' => 'two' }
172
+ notice = build_notice(:session_data => data)
173
+ assert_equal data, notice.session_data
174
+ end
175
+
176
+ should "accept an environment name" do
177
+ assert_equal 'development', build_notice(:environment_name => 'development').environment_name
178
+ end
179
+
180
+ should "accept CGI data from a hash" do
181
+ data = { 'string' => 'value' }
182
+ notice = build_notice(:cgi_data => data)
183
+ assert_equal data, notice.cgi_data, "should take CGI data from a hash"
184
+ end
185
+
186
+ should "not crash without CGI data" do
187
+ assert_nothing_raised do
188
+ build_notice
189
+ end
190
+ end
191
+
192
+ should "accept any object that responds to :to_hash as CGI data" do
193
+ hashlike_obj = Object.new
194
+ hashlike_obj.instance_eval do
195
+ def to_hash
196
+ {:i => 'am a hash'}
197
+ end
198
+ end
199
+ assert hashlike_obj.respond_to?(:to_hash)
200
+
201
+ notice = build_notice(:cgi_data => hashlike_obj)
202
+ assert_equal({:i => 'am a hash'}, notice.cgi_data, "should take CGI data from any hash-like object")
203
+ end
204
+
205
+ should "accept notifier information" do
206
+ params = { :notifier_name => 'a name for a notifier',
207
+ :notifier_version => '1.0.5',
208
+ :notifier_url => 'http://notifiers.r.us/download' }
209
+ notice = build_notice(params)
210
+ assert_equal params[:notifier_name], notice.notifier_name
211
+ assert_equal params[:notifier_version], notice.notifier_version
212
+ assert_equal params[:notifier_url], notice.notifier_url
213
+ end
214
+
215
+ should "set sensible defaults without an exception" do
216
+ backtrace = Airbrake::Backtrace.parse(build_backtrace_array)
217
+ notice = build_notice(:backtrace => build_backtrace_array)
218
+
219
+ assert_equal 'Notification', notice.error_message
220
+ assert_array_starts_with backtrace.lines, notice.backtrace.lines
221
+ assert_equal({}, notice.parameters)
222
+ assert_equal({}, notice.session_data)
223
+ end
224
+
225
+ should "use the caller as the backtrace for an exception without a backtrace" do
226
+ filters = Airbrake::Configuration.new.backtrace_filters
227
+ backtrace = Airbrake::Backtrace.parse(caller, :filters => filters)
228
+ notice = build_notice(:exception => StandardError.new('error'), :backtrace => nil)
229
+
230
+ assert_array_starts_with backtrace.lines, notice.backtrace.lines
231
+ end
232
+
233
+ context "a Notice turned into JSON" do
234
+ setup do
235
+ @exception = build_exception
236
+
237
+ @notice = build_notice({
238
+ :notifier_name => 'a name',
239
+ :notifier_version => '1.2.3',
240
+ :notifier_url => 'http://some.url/path',
241
+ :exception => @exception,
242
+ :controller => "controller",
243
+ :action => "action",
244
+ :url => "http://url.com",
245
+ :parameters => { "paramskey" => "paramsvalue",
246
+ "nestparentkey" => { "nestkey" => "nestvalue" } },
247
+ :session_data => { "sessionkey" => "sessionvalue" },
248
+ :cgi_data => { "cgikey" => "cgivalue" },
249
+ :project_root => "RAILS_ROOT",
250
+ :environment_name => "RAILS_ENV"
251
+ })
252
+
253
+ @json = @notice.to_json
254
+ end
255
+
256
+ should "validate against the JSON schema" do
257
+ assert_valid_json @json
258
+ end
259
+ end
260
+
261
+ context "a Notice turned into XML" do
262
+ setup do
263
+ Airbrake.configure do |config|
264
+ config.api_key = "1234567890"
265
+ end
266
+
267
+ @exception = build_exception
268
+
269
+ @notice = build_notice({
270
+ :notifier_name => 'a name',
271
+ :notifier_version => '1.2.3',
272
+ :notifier_url => 'http://some.url/path',
273
+ :exception => @exception,
274
+ :controller => "controller",
275
+ :action => "action",
276
+ :url => "http://url.com",
277
+ :parameters => { "paramskey" => "paramsvalue",
278
+ "nestparentkey" => { "nestkey" => "nestvalue" } },
279
+ :session_data => { "sessionkey" => "sessionvalue" },
280
+ :cgi_data => { "cgikey" => "cgivalue" },
281
+ :project_root => "RAILS_ROOT",
282
+ :environment_name => "RAILS_ENV"
283
+ })
284
+
285
+ @xml = @notice.to_xml
286
+
287
+ @document = Nokogiri::XML::Document.parse(@xml)
288
+ end
289
+
290
+ should "validate against the XML schema" do
291
+ assert_valid_notice_document @document
292
+ end
293
+
294
+
295
+ should "serialize a Notice to XML when sent #to_xml" do
296
+ assert_valid_node(@document, "//api-key", @notice.api_key)
297
+
298
+ assert_valid_node(@document, "//notifier/name", @notice.notifier_name)
299
+ assert_valid_node(@document, "//notifier/version", @notice.notifier_version)
300
+ assert_valid_node(@document, "//notifier/url", @notice.notifier_url)
301
+
302
+ assert_valid_node(@document, "//error/class", @notice.error_class)
303
+ assert_valid_node(@document, "//error/message", @notice.error_message)
304
+
305
+ assert_valid_node(@document, "//error/backtrace/line/@number", @notice.backtrace.lines.first.number)
306
+ assert_valid_node(@document, "//error/backtrace/line/@file", @notice.backtrace.lines.first.file)
307
+ assert_valid_node(@document, "//error/backtrace/line/@method", @notice.backtrace.lines.first.method_name)
308
+
309
+ assert_valid_node(@document, "//request/url", @notice.url)
310
+ assert_valid_node(@document, "//request/component", @notice.controller)
311
+ assert_valid_node(@document, "//request/action", @notice.action)
312
+
313
+ assert_valid_node(@document, "//request/params/var/@key", "paramskey")
314
+ assert_valid_node(@document, "//request/params/var", "paramsvalue")
315
+ assert_valid_node(@document, "//request/params/var/@key", "nestparentkey")
316
+ assert_valid_node(@document, "//request/params/var/var/@key", "nestkey")
317
+ assert_valid_node(@document, "//request/params/var/var", "nestvalue")
318
+ assert_valid_node(@document, "//request/session/var/@key", "sessionkey")
319
+ assert_valid_node(@document, "//request/session/var", "sessionvalue")
320
+ assert_valid_node(@document, "//request/cgi-data/var/@key", "cgikey")
321
+ assert_valid_node(@document, "//request/cgi-data/var", "cgivalue")
322
+
323
+ assert_valid_node(@document, "//server-environment/project-root", "RAILS_ROOT")
324
+ assert_valid_node(@document, "//server-environment/environment-name", "RAILS_ENV")
325
+ assert_valid_node(@document, "//server-environment/hostname", hostname)
326
+ end
327
+ end
328
+
329
+ should "not send empty request data" do
330
+ notice = build_notice
331
+ assert_nil notice.url
332
+ assert_nil notice.controller
333
+ assert_nil notice.action
334
+
335
+ xml = notice.to_xml
336
+ document = Nokogiri::XML.parse(xml)
337
+ assert_nil document.at('//request/url')
338
+ assert_nil document.at('//request/component')
339
+ assert_nil document.at('//request/action')
340
+
341
+ assert_valid_notice_document document
342
+ end
343
+
344
+ %w(url controller action).each do |var|
345
+ should "send a request if #{var} is present" do
346
+ notice = build_notice(var.to_sym => 'value')
347
+ xml = notice.to_xml
348
+ document = Nokogiri::XML.parse(xml)
349
+ assert_not_nil document.at('//request')
350
+ end
351
+ end
352
+
353
+ %w(parameters cgi_data session_data).each do |var|
354
+ should "send a request if #{var} is present" do
355
+ notice = build_notice(var.to_sym => { 'key' => 'value' })
356
+ xml = notice.to_xml
357
+ document = Nokogiri::XML.parse(xml)
358
+ assert_not_nil document.at('//request')
359
+ end
360
+ end
361
+
362
+ should "not ignore an exception not matching ignore filters" do
363
+ notice = build_notice(:error_class => 'ArgumentError',
364
+ :ignore => ['Argument'],
365
+ :ignore_by_filters => [lambda { |n| false }])
366
+ assert !notice.ignore?
367
+ end
368
+
369
+ should "ignore an wrapped exception matching ignore filters" do
370
+ notice = build_notice(error_class: "NotIgnored",
371
+ exception_classes: ["Ignored", "NotIgnored"],
372
+ ignore: ["Ignored"])
373
+ assert notice.ignore?
374
+ end
375
+
376
+ should "ignore an exception with a matching error class" do
377
+ notice = build_notice(:error_class => 'ArgumentError',
378
+ :ignore => [ArgumentError])
379
+ assert notice.ignore?
380
+ end
381
+
382
+ should "ignore an exception with a matching error class name" do
383
+ notice = build_notice(:error_class => 'ArgumentError',
384
+ :ignore => ['ArgumentError'])
385
+ assert notice.ignore?
386
+ end
387
+
388
+ should "ignore an exception with a matching filter" do
389
+ filter = lambda {|notice| notice.error_class == 'ArgumentError' }
390
+ notice = build_notice(:error_class => 'ArgumentError',
391
+ :ignore_by_filters => [filter])
392
+ assert notice.ignore?
393
+ end
394
+
395
+ should "not raise without an ignore list" do
396
+ notice = build_notice(:ignore => nil, :ignore_by_filters => nil)
397
+ assert_nothing_raised do
398
+ notice.ignore?
399
+ end
400
+ end
401
+
402
+ ignored_error_classes = Airbrake::Configuration::IGNORE_DEFAULT
403
+
404
+ ignored_error_classes.each do |ignored_error_class|
405
+ should "ignore #{ignored_error_class} error by default" do
406
+ notice = build_notice(:error_class => ignored_error_class)
407
+ assert notice.ignore?
408
+ end
409
+ end
410
+
411
+ should "act like a hash" do
412
+ notice = build_notice(:error_message => 'some message')
413
+ assert_equal notice.error_message, notice[:error_message]
414
+ end
415
+
416
+ should "return params on notice[:request][:params]" do
417
+ params = { 'one' => 'two' }
418
+ notice = build_notice(:parameters => params)
419
+ assert_equal params, notice[:request][:params]
420
+ end
421
+
422
+ should "ensure #to_hash is called on objects that support it" do
423
+ assert_nothing_raised do
424
+ build_notice(:session => { :object => stub(:to_hash => {}) })
425
+ end
426
+ end
427
+
428
+ should "ensure #to_ary is called on objects that support it" do
429
+ assert_nothing_raised do
430
+ build_notice(:session => { :object => stub(:to_ary => []) })
431
+ end
432
+ end
433
+
434
+ should "extract data from a rack environment hash" do
435
+ url = "https://subdomain.happylane.com:100/test/file.rb?var=value&var2=value2"
436
+ parameters = { 'var' => 'value', 'var2' => 'value2' }
437
+ env = Rack::MockRequest.env_for(url)
438
+
439
+ notice = build_notice(:rack_env => env)
440
+
441
+ assert_equal url, notice.url
442
+ assert_equal parameters, notice.parameters
443
+ assert_equal 'GET', notice.cgi_data['REQUEST_METHOD']
444
+ end
445
+
446
+ should "show a nice warning when rack environment exceeds rack keyspace" do
447
+ # simulate exception for too big query
448
+ Rack::Request.any_instance.expects(:params).raises(RangeError.new("exceeded available parameter key space"))
449
+
450
+ url = "https://subdomain.happylane.com:100/test/file.rb?var=x"
451
+ env = Rack::MockRequest.env_for(url)
452
+
453
+ notice = build_notice(:rack_env => env)
454
+
455
+ assert_equal url, notice.url
456
+ assert_equal({:message => "failed to call params on Rack::Request -- exceeded available parameter key space"}, notice.parameters)
457
+ assert_equal 'GET', notice.cgi_data['REQUEST_METHOD']
458
+ end
459
+
460
+ should "extract data from a rack environment hash with action_dispatch info" do
461
+ params = { 'controller' => 'users', 'action' => 'index', 'id' => '7' }
462
+ env = Rack::MockRequest.env_for('/', { 'action_dispatch.request.parameters' => params })
463
+
464
+ notice = build_notice(:rack_env => env)
465
+
466
+ assert_equal params, notice.parameters
467
+ assert_equal params['controller'], notice.component
468
+ assert_equal params['action'], notice.action
469
+ end
470
+
471
+ should "extract session data from a rack environment" do
472
+ session_data = { 'something' => 'some value' }
473
+ env = Rack::MockRequest.env_for('/', 'rack.session' => session_data)
474
+
475
+ notice = build_notice(:rack_env => env)
476
+
477
+ assert_equal session_data, notice.session_data
478
+ end
479
+
480
+ should "prefer passed session data to rack session data" do
481
+ session_data = { 'something' => 'some value' }
482
+ env = Rack::MockRequest.env_for('/')
483
+
484
+ notice = build_notice(:rack_env => env, :session_data => session_data)
485
+
486
+ assert_equal session_data, notice.session_data
487
+ end
488
+
489
+ should "prefer passed error_message to exception message" do
490
+ exception = build_exception
491
+ notice = build_notice(:exception => exception,:error_message => "Random ponies")
492
+ assert_equal "BacktracedException: Random ponies", notice.error_message
493
+ end
494
+ end