exception_handling 2.5.1.pre.1 → 2.8.0.pre.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.jenkins/Jenkinsfile +24 -8
  4. data/.rspec +3 -0
  5. data/CHANGELOG.md +19 -2
  6. data/Gemfile +4 -4
  7. data/Gemfile.lock +67 -58
  8. data/Rakefile +7 -6
  9. data/gemfiles/rails_4.gemfile +4 -4
  10. data/gemfiles/rails_5.gemfile +4 -4
  11. data/gemfiles/rails_6.gemfile +4 -4
  12. data/lib/exception_handling.rb +5 -2
  13. data/lib/exception_handling/exception_info.rb +3 -6
  14. data/lib/exception_handling/log_stub_error.rb +2 -1
  15. data/lib/exception_handling/logging_methods.rb +27 -0
  16. data/lib/exception_handling/methods.rb +6 -53
  17. data/lib/exception_handling/testing.rb +20 -10
  18. data/lib/exception_handling/version.rb +1 -1
  19. data/{test → spec}/helpers/controller_helpers.rb +0 -0
  20. data/{test → spec}/helpers/exception_helpers.rb +2 -2
  21. data/{test → spec}/rake_test_warning_false.rb +0 -0
  22. data/{test/test_helper.rb → spec/spec_helper.rb} +50 -39
  23. data/spec/unit/exception_handling/exception_catalog_spec.rb +85 -0
  24. data/spec/unit/exception_handling/exception_description_spec.rb +82 -0
  25. data/{test/unit/exception_handling/exception_info_test.rb → spec/unit/exception_handling/exception_info_spec.rb} +118 -99
  26. data/{test/unit/exception_handling/honeybadger_callbacks_test.rb → spec/unit/exception_handling/honeybadger_callbacks_spec.rb} +20 -20
  27. data/{test/unit/exception_handling/log_error_stub_test.rb → spec/unit/exception_handling/log_error_stub_spec.rb} +38 -22
  28. data/spec/unit/exception_handling/logging_methods_spec.rb +38 -0
  29. data/{test/unit/exception_handling/mailer_test.rb → spec/unit/exception_handling/mailer_spec.rb} +17 -17
  30. data/spec/unit/exception_handling/methods_spec.rb +105 -0
  31. data/spec/unit/exception_handling/sensu_spec.rb +51 -0
  32. data/{test/unit/exception_handling_test.rb → spec/unit/exception_handling_spec.rb} +348 -329
  33. metadata +32 -28
  34. data/test/unit/exception_handling/exception_catalog_test.rb +0 -85
  35. data/test/unit/exception_handling/exception_description_test.rb +0 -82
  36. data/test/unit/exception_handling/methods_test.rb +0 -84
  37. data/test/unit/exception_handling/sensu_test.rb +0 -52
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __dir__)
4
+
5
+ module ExceptionHandling
6
+ describe ExceptionDescription do
7
+
8
+ context "Filter" do
9
+ it "allow direct matching of strings" do
10
+ @f = ExceptionDescription.new(:filter1, error: "my error message")
11
+ expect(@f.match?('error' => "my error message")).to be_truthy
12
+ end
13
+
14
+ it "allow direct matching of strings on with symbol keys" do
15
+ @f = ExceptionDescription.new(:filter1, error: "my error message")
16
+ expect(@f.match?(error: "my error message")).to be_truthy
17
+ end
18
+
19
+ it "allow wildcards to cross line boundries" do
20
+ @f = ExceptionDescription.new(:filter1, error: "my error message.*with multiple lines")
21
+ expect(@f.match?(error: "my error message\nwith more than one, with multiple lines")).to be_truthy
22
+ end
23
+
24
+ it "complain when no regexps have a value" do
25
+ expect { ExceptionDescription.new(:filter1, error: nil) }.to raise_exception(ArgumentError, /has all blank regexes/)
26
+ end
27
+
28
+ it "report when an invalid key is passed" do
29
+ expect { ExceptionDescription.new(:filter1, error: "my error message", not_a_parameter: false) }.to raise_exception(ArgumentError, "Unknown section: not_a_parameter")
30
+ end
31
+
32
+ it "allow send_to_honeybadger to be specified and have it disabled by default" do
33
+ expect(!ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: false).send_to_honeybadger).to be_truthy
34
+ expect(ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: true).send_to_honeybadger).to be_truthy
35
+ expect(!ExceptionDescription.new(:filter1, error: "my error message").send_to_honeybadger).to be_truthy
36
+ end
37
+
38
+ it "allow send_metric to be configured" do
39
+ expect(!ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).send_metric).to be_truthy
40
+ expect(ExceptionDescription.new(:filter1, error: "my error message").send_metric).to be_truthy
41
+ end
42
+
43
+ it "provide metric name" do
44
+ expect(ExceptionDescription.new(:filter1, error: "my error message").metric_name).to eq("filter1")
45
+ expect(ExceptionDescription.new(:filter1, error: "my error message", metric_name: :some_other_metric_name).metric_name).to eq("some_other_metric_name")
46
+ end
47
+
48
+ it "replace spaces in metric name" do
49
+ @f = ExceptionDescription.new(:"filter has spaces", error: "my error message")
50
+ expect(@f.metric_name).to eq( "filter_has_spaces")
51
+ end
52
+
53
+ it "allow notes to be recorded" do
54
+ expect(ExceptionDescription.new(:filter1, error: "my error message").notes).to be_nil
55
+ expect(ExceptionDescription.new(:filter1, error: "my error message", notes: "a long string").notes).to eq("a long string")
56
+ end
57
+
58
+ it "not consider config options in the filter set" do
59
+ expect(ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).match?(error: "my error message")).to be_truthy
60
+ expect(ExceptionDescription.new(:filter1, error: "my error message", metric_name: "false").match?(error: "my error message")).to be_truthy
61
+ expect(ExceptionDescription.new(:filter1, error: "my error message", notes: "hey").match?(error: "my error message")).to be_truthy
62
+ end
63
+
64
+ it "provide exception details" do
65
+ exception_description = ExceptionDescription.new(:filter1, error: "my error message", notes: "hey")
66
+
67
+ expected = { "send_metric" => true, "metric_name" => "filter1", "notes" => "hey" }
68
+
69
+ expect(exception_description.exception_data).to eq( expected)
70
+ end
71
+
72
+ it "match multiple email addresses" do
73
+ mobi = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'mcc@mobistreak.com'"
74
+ credit = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'damon@thecreditpros.com'"
75
+
76
+ exception_description = ExceptionDescription.new(:filter1, error: "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for '(mcc\@mobistreak|damon\@thecreditpros).com'")
77
+ expect(exception_description.match?(error: mobi)).to be_truthy
78
+ expect(exception_description.match?(error: credit)).to be_truthy
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,58 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../../test_helper', __dir__)
3
+ require File.expand_path('../../spec_helper', __dir__)
4
4
  require_test_helper 'controller_helpers'
5
5
  require_test_helper 'exception_helpers'
6
6
 
7
7
  module ExceptionHandling
8
- class ExceptionInfoTest < ActiveSupport::TestCase
8
+ describe ExceptionInfo do
9
9
  include ControllerHelpers
10
10
  include ExceptionHelpers
11
11
 
12
12
  context "initialize" do
13
- setup do
13
+ before do
14
14
  @exception = StandardError.new("something went wrong")
15
15
  @timestamp = Time.now
16
16
  @controller = Object.new
17
17
  end
18
18
 
19
19
  context "controller_from_context" do
20
- should "extract controller from context when not specified explicitly" do
20
+ it "extract controller from context when not specified explicitly" do
21
21
  exception_context = {
22
22
  "action_controller.instance" => @controller
23
23
  }
24
24
  exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp)
25
- assert_equal @controller, exception_info.controller
25
+ expect(exception_info.controller).to eq(@controller)
26
26
  end
27
27
 
28
- should "prefer the explicit controller over the one from context" do
28
+ it "prefer the explicit controller over the one from context" do
29
29
  exception_context = {
30
30
  "action_controller.instance" => Object.new
31
31
  }
32
32
  exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp, controller: @controller)
33
- assert_equal @controller, exception_info.controller
34
- assert_not_equal exception_context["action_controller.instance"], exception_info.controller
33
+ expect(exception_info.controller).to eq(@controller)
34
+ expect(exception_info.controller).not_to eq(exception_context["action_controller.instance"])
35
35
  end
36
36
 
37
- should "leave controller unset when not included in the context hash" do
37
+ it "leave controller unset when not included in the context hash" do
38
38
  exception_info = ExceptionInfo.new(@exception, {}, @timestamp)
39
- assert_nil exception_info.controller
39
+ expect(exception_info.controller).to be_nil
40
40
  end
41
41
 
42
- should "leave controller unset when context is not in hash format" do
42
+ it "leave controller unset when context is not in hash format" do
43
43
  exception_info = ExceptionInfo.new(@exception, "string context", @timestamp)
44
- assert_nil exception_info.controller
44
+ expect(exception_info.controller).to be_nil
45
45
  end
46
46
  end
47
47
  end
48
48
 
49
49
  context "data" do
50
- setup do
50
+ before do
51
51
  @exception = StandardError.new("something went wrong")
52
52
  @timestamp = Time.now
53
53
  end
54
54
 
55
- should "return a hash with exception specific data including context hash" do
55
+ it "return a hash with exception specific data including context hash" do
56
56
  exception_context = {
57
57
  "rack.session" => {
58
58
  user_id: 23,
@@ -73,17 +73,17 @@ module ExceptionHandling
73
73
  }
74
74
  }
75
75
 
76
- assert_equal_with_diff expected_data, exception_info.data
76
+ expect(exception_info.data).to eq(expected_data)
77
77
  end
78
78
 
79
- should "generate exception data appropriately if exception message is nil" do
79
+ it "generate exception data appropriately if exception message is nil" do
80
80
  exception_info = ExceptionInfo.new(exception_with_nil_message, "custom context data", @timestamp)
81
81
  exception_data = exception_info.data
82
- assert_equal "RuntimeError: ", exception_data["error_string"]
83
- assert_equal "RuntimeError: : custom context data", exception_data["error"]
82
+ expect(exception_data["error_string"]).to eq("RuntimeError: ")
83
+ expect(exception_data["error"]).to eq("RuntimeError: : custom context data")
84
84
  end
85
85
 
86
- should "return a hash with exception specific data including context string" do
86
+ it "return a hash with exception specific data including context string" do
87
87
  exception_context = "custom context data"
88
88
  exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp)
89
89
  expected_data = {
@@ -96,11 +96,10 @@ module ExceptionHandling
96
96
  "message" => "custom context data"
97
97
  }
98
98
  }
99
-
100
- assert_equal_with_diff expected_data, exception_info.data
99
+ expect(exception_info.data).to eq(expected_data)
101
100
  end
102
101
 
103
- should "not include enhanced data from controller or custom data callback" do
102
+ it "not include enhanced data from controller or custom data callback" do
104
103
  env = { server: "fe98" }
105
104
  parameters = { advertiser_id: 435 }
106
105
  session = { username: "jsmith" }
@@ -109,8 +108,8 @@ module ExceptionHandling
109
108
  data_callback = ->(data) { data[:custom_section] = "value" }
110
109
  exception_info = ExceptionInfo.new(@exception, "custom context data", @timestamp, controller: controller, data_callback: data_callback)
111
110
 
112
- dont_allow(exception_info).extract_and_merge_controller_data
113
- dont_allow(exception_info).customize_from_data_callback
111
+ expect(exception_info).to_not receive(:extract_and_merge_controller_data)
112
+ expect(exception_info).to_not receive(:customize_from_data_callback)
114
113
  expected_data = {
115
114
  "error_class" => "StandardError",
116
115
  "error_string" => "StandardError: something went wrong",
@@ -122,12 +121,12 @@ module ExceptionHandling
122
121
  }
123
122
  }
124
123
 
125
- assert_equal_with_diff expected_data, exception_info.data
124
+ expect(exception_info.data).to eq(expected_data)
126
125
  end
127
126
  end
128
127
 
129
128
  context "enhanced_data" do
130
- setup do
129
+ before do
131
130
  @exception = StandardError.new("something went wrong")
132
131
  @timestamp = Time.now
133
132
  @exception_context = {
@@ -145,13 +144,13 @@ module ExceptionHandling
145
144
  @data_callback = ->(data) { data[:custom_section] = "check this out" }
146
145
  end
147
146
 
148
- should "not return a mutable object for the session" do
147
+ it "not return a mutable object for the session" do
149
148
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
150
149
  exception_info.enhanced_data["session"]["hello"] = "world"
151
- assert_nil @controller.session["hello"]
150
+ expect(@controller.session["hello"]).to be_nil
152
151
  end
153
152
 
154
- should "return a hash with generic exception attributes as well as context data" do
153
+ it "return a hash with generic exception attributes as well as context data" do
155
154
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
156
155
  expected_data = {
157
156
  "error_class" => "StandardError",
@@ -164,19 +163,19 @@ module ExceptionHandling
164
163
  "location" => { "file" => "<no backtrace>", "line" => nil }
165
164
  }
166
165
 
167
- assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
166
+ expect(prepare_data(exception_info.enhanced_data)).to eq(expected_data)
168
167
  end
169
168
 
170
- should "generate exception data appropriately if exception message is nil" do
169
+ it "generate exception data appropriately if exception message is nil" do
171
170
  exception_with_nil_message = RuntimeError.new(nil)
172
- stub(exception_with_nil_message).message { nil }
171
+ allow(exception_with_nil_message).to receive(:message).and_return(nil)
173
172
  exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp)
174
173
  exception_data = exception_info.enhanced_data
175
- assert_equal "RuntimeError: ", exception_data["error_string"]
176
- assert_equal "RuntimeError: ", exception_data["error"]
174
+ expect(exception_data["error_string"]).to eq("RuntimeError: ")
175
+ expect(exception_data["error"]).to eq("RuntimeError: ")
177
176
  end
178
177
 
179
- should "include controller data when available" do
178
+ it "include controller data when available" do
180
179
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: @controller)
181
180
  expected_data = {
182
181
  "error_class" => "StandardError",
@@ -194,10 +193,10 @@ module ExceptionHandling
194
193
  "location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
195
194
  }
196
195
 
197
- assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
196
+ expect(prepare_data(exception_info.enhanced_data)).to eq(expected_data)
198
197
  end
199
198
 
200
- should "extract controller from rack specific exception context when not provided explicitly" do
199
+ it "extract controller from rack specific exception context when not provided explicitly" do
201
200
  @exception_context["action_controller.instance"] = @controller
202
201
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
203
202
  expected_data = {
@@ -216,10 +215,10 @@ module ExceptionHandling
216
215
  "location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
217
216
  }
218
217
 
219
- assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
218
+ expect(prepare_data(exception_info.enhanced_data)).to eq(expected_data)
220
219
  end
221
220
 
222
- should "add to_s attribute to specific sections that have their content in hash format" do
221
+ it "add to_s attribute to specific sections that have their content in hash format" do
223
222
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: @controller)
224
223
  expected_data = {
225
224
  "error_class" => "StandardError",
@@ -245,10 +244,10 @@ module ExceptionHandling
245
244
  "location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
246
245
  }
247
246
 
248
- assert_equal_with_diff expected_data, exception_info.enhanced_data
247
+ expect(exception_info.enhanced_data).to eq(expected_data)
249
248
  end
250
249
 
251
- should "filter out sensitive parameters like passwords" do
250
+ it "filter out sensitive parameters like passwords" do
252
251
  @controller.request.parameters[:password] = "super_secret"
253
252
  @controller.request.parameters[:user] = { "password" => "also super secret", "password_confirmation" => "also super secret" }
254
253
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: @controller)
@@ -261,10 +260,10 @@ module ExceptionHandling
261
260
  "password_confirmation" => "[FILTERED]"
262
261
  }
263
262
  }
264
- assert_equal_with_diff expected_params, exception_info.enhanced_data["request"]["params"]
263
+ expect(exception_info.enhanced_data["request"]["params"]).to eq(expected_params)
265
264
  end
266
265
 
267
- should "include the changes from the custom data callback" do
266
+ it "include the changes from the custom data callback" do
268
267
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: nil, data_callback: @data_callback)
269
268
  expected_data = {
270
269
  "error_class" => "StandardError",
@@ -278,11 +277,11 @@ module ExceptionHandling
278
277
  "location" => { "file" => "<no backtrace>", "line" => nil }
279
278
  }
280
279
 
281
- assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
280
+ expect(prepare_data(exception_info.enhanced_data)).to eq(expected_data)
282
281
  end
283
282
 
284
- should "apply the custom_data_hook results" do
285
- stub(ExceptionHandling).custom_data_hook { ->(data) { data[:custom_hook] = "changes from custom hook" } }
283
+ it "apply the custom_data_hook results" do
284
+ allow(ExceptionHandling).to receive(:custom_data_hook).and_return(->(data) { data[:custom_hook] = "changes from custom hook" })
286
285
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
287
286
  expected_data = {
288
287
  "error_class" => "StandardError",
@@ -296,35 +295,35 @@ module ExceptionHandling
296
295
  "location" => { "file" => "<no backtrace>", "line" => nil }
297
296
  }
298
297
 
299
- assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
298
+ expect(prepare_data(exception_info.enhanced_data)).to eq(expected_data)
300
299
  end
301
300
 
302
- should "log info if the custom data hook results in a nil message exception" do
301
+ it "log info if the custom data hook results in a nil message exception" do
303
302
  ExceptionHandling.custom_data_hook = ->(_data) do
304
303
  raise_exception_with_nil_message
305
304
  end
306
305
  log_info_messages = []
307
- stub(ExceptionHandling.logger).info.with_any_args do |message, _|
306
+ allow(ExceptionHandling.logger).to receive(:info).with(any_args) do |message, _|
308
307
  log_info_messages << message
309
308
  end
310
309
 
311
310
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
312
311
  exception_info.enhanced_data
313
- assert log_info_messages.find { |message| message =~ /Unable to execute custom custom_data_hook callback/ }
312
+ expect(log_info_messages.find { |message| message =~ /Unable to execute custom custom_data_hook callback/ }).to be_truthy
314
313
  ExceptionHandling.custom_data_hook = nil
315
314
  end
316
315
  end
317
316
 
318
317
  context "exception_description" do
319
- should "return the exception description from the global exception filter list" do
318
+ it "return the exception description from the global exception filter list" do
320
319
  exception = StandardError.new("No route matches")
321
320
  exception_info = ExceptionInfo.new(exception, {}, Time.now)
322
321
  description = exception_info.exception_description
323
- assert_not_nil description
324
- assert_equal :NoRoute, description.filter_name
322
+ expect(description).to_not be_nil
323
+ expect(description.filter_name).to eq(:NoRoute)
325
324
  end
326
325
 
327
- should "find the description when filter criteria includes section in hash format" do
326
+ it "find the description when filter criteria includes section in hash format" do
328
327
  env = { server: "fe98" }
329
328
  parameters = { advertiser_id: 435, controller: "sessions", action: "fail" }
330
329
  session = { username: "jsmith", id: "session_key" }
@@ -332,25 +331,25 @@ module ExceptionHandling
332
331
  controller = create_dummy_controller(env, parameters, session, request_uri)
333
332
  exception = StandardError.new("Request to click domain rejected")
334
333
  exception_info = ExceptionInfo.new(exception, nil, Time.now, controller: controller)
335
- assert_equal true, exception_info.enhanced_data[:request].is_a?(Hash)
334
+ expect(exception_info.enhanced_data[:request].is_a?(Hash)).to eq(true)
336
335
  description = exception_info.exception_description
337
- assert_not_nil description
338
- assert_equal :"Click Request Rejected", description.filter_name
336
+ expect(description).to_not be_nil
337
+ expect(description.filter_name).to eq(:"Click Request Rejected")
339
338
  end
340
339
 
341
- should "return same description object for related errors (avoid reloading exception catalog from disk)" do
340
+ it "return same description object for related errors (avoid reloading exception catalog from disk)" do
342
341
  exception = StandardError.new("No route matches")
343
342
  exception_info = ExceptionInfo.new(exception, nil, Time.now)
344
343
  description = exception_info.exception_description
345
344
 
346
345
  repeat_ex = StandardError.new("No route matches 2")
347
346
  repeat_ex_info = ExceptionInfo.new(repeat_ex, nil, Time.now)
348
- assert_equal description.object_id, repeat_ex_info.exception_description.object_id
347
+ expect(repeat_ex_info.exception_description.object_id).to eq(description.object_id)
349
348
  end
350
349
  end
351
350
 
352
351
  context "controller_name" do
353
- setup do
352
+ before do
354
353
  @exception = StandardError.new('something went wrong')
355
354
  @timestamp = Time.now
356
355
  @exception_context = {
@@ -362,7 +361,7 @@ module ExceptionHandling
362
361
  }
363
362
  end
364
363
 
365
- should "return controller_name when controller is present" do
364
+ it "return controller_name when controller is present" do
366
365
  env = { server: 'fe98' }
367
366
  parameters = { controller: 'some_controller' }
368
367
  session = { username: 'smith' }
@@ -370,65 +369,85 @@ module ExceptionHandling
370
369
  controller = create_dummy_controller(env, parameters, session, request_uri)
371
370
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: controller)
372
371
 
373
- assert_equal 'some_controller', exception_info.controller_name
372
+ expect(exception_info.controller_name).to eq('some_controller')
374
373
  end
375
374
 
376
- should "return an empty string when controller is not present" do
375
+ it "return an empty string when controller is not present" do
377
376
  exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
378
377
 
379
- assert_equal '', exception_info.controller_name
378
+ expect(exception_info.controller_name).to eq('')
380
379
  end
381
380
  end
382
381
 
383
382
  context "send_to_honeybadger?" do
384
- should "be enabled when Honeybadger is defined and exception is not in the filter list" do
385
- stub(ExceptionHandling).honeybadger_defined? { true }
383
+ it "be enabled when Honeybadger is defined and exception is not in the filter list" do
384
+ allow(ExceptionHandling).to receive(:honeybadger_defined?).and_return(true)
386
385
  exception = StandardError.new("something went wrong")
387
386
  exception_info = ExceptionInfo.new(exception, nil, Time.now)
388
- assert_nil exception_info.exception_description
389
- assert_equal true, exception_info.send_to_honeybadger?
387
+ expect(exception_info.exception_description).to be_nil
388
+ expect(exception_info.send_to_honeybadger?).to eq(true)
390
389
  end
391
390
 
392
- should "be enabled when Honeybadger is defined and exception is on the filter list with the flag turned on" do
393
- stub(ExceptionHandling).honeybadger_defined? { true }
391
+ it "be enabled when Honeybadger is defined and exception is on the filter list with the flag turned on" do
392
+ allow(ExceptionHandling).to receive(:honeybadger_defined?).and_return(true)
394
393
  exception = StandardError.new("No route matches")
395
394
  exception_info = ExceptionInfo.new(exception, nil, Time.now)
396
- assert_not_nil exception_info.exception_description
397
- assert_equal true, exception_info.exception_description.send_to_honeybadger
398
- assert_equal true, exception_info.send_to_honeybadger?
395
+ expect(exception_info.exception_description).to_not be_nil
396
+ expect(exception_info.exception_description.send_to_honeybadger).to eq(true)
397
+ expect(exception_info.send_to_honeybadger?).to eq(true)
399
398
  end
400
399
 
401
- should "be disabled when Honeybadger is defined and exception is on the filter list with the flag turned off" do
402
- stub(ExceptionHandling).honeybadger_defined? { true }
400
+ it "be disabled when Honeybadger is defined and exception is on the filter list with the flag turned off" do
401
+ allow(ExceptionHandling).to receive(:honeybadger_defined?).and_return(true)
403
402
  exception = StandardError.new("No route matches")
404
403
  exception_info = ExceptionInfo.new(exception, nil, Time.now)
405
- assert_not_nil exception_info.exception_description
406
- stub(exception_info.exception_description).send_to_honeybadger { false }
407
- assert_equal false, exception_info.send_to_honeybadger?
404
+ expect(exception_info.exception_description).to_not be_nil
405
+ allow(exception_info.exception_description).to receive(:send_to_honeybadger).and_return(false)
406
+ expect(exception_info.send_to_honeybadger?).to eq(false)
408
407
  end
409
408
 
410
- should "be disabled when Honeybadger is not defined" do
411
- stub(ExceptionHandling).honeybadger_defined? { false }
409
+ it "be disabled when Honeybadger is not defined" do
410
+ allow(ExceptionHandling).to receive(:honeybadger_defined?).and_return(false)
412
411
  exception = StandardError.new("something went wrong")
413
412
  exception_info = ExceptionInfo.new(exception, nil, Time.now)
414
- assert_nil exception_info.exception_description
415
- assert_equal false, exception_info.send_to_honeybadger?
413
+ expect(exception_info.exception_description).to be_nil
414
+ expect(exception_info.send_to_honeybadger?).to eq(false)
416
415
  end
417
416
  end
418
417
 
419
418
  context "honeybadger_context_data" do
420
- should "return the error details and relevant context data to be used as honeybadger notification context while filtering sensitive data" do
419
+ before do
420
+ allow(ExceptionHandling.logger).to receive(:current_context_for_thread).and_return({ cuid: 'ABCD' })
421
+ end
422
+
423
+ it "include thread_context when log_context: is nil" do
424
+ exception_with_nil_message = RuntimeError.new(nil)
425
+ allow(exception_with_nil_message).to receive(:message).and_return(nil)
426
+ exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp)
427
+ honeybadger_context_data = exception_info.honeybadger_context_data
428
+ expect(honeybadger_context_data[:log_context]).to eq({ "cuid" => 'ABCD' })
429
+ end
430
+
431
+ it "include thread context merged with log_context:" do
432
+ exception_with_nil_message = RuntimeError.new(nil)
433
+ allow(exception_with_nil_message).to receive(:message).and_return(nil)
434
+ exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp, log_context: { url: 'http://example.com' })
435
+ honeybadger_context_data = exception_info.honeybadger_context_data
436
+ expect(honeybadger_context_data[:log_context]).to eq({ "cuid" => 'ABCD', "url" => 'http://example.com' })
437
+ end
438
+
439
+ it "return the error details and relevant context data to be used as honeybadger notification context while filtering sensitive data" do
421
440
  env = { server: "fe98" }
422
441
  parameters = { advertiser_id: 435 }
423
442
  session = { username: "jsmith" }
424
443
  request_uri = "host/path"
425
444
  controller = create_dummy_controller(env, parameters, session, request_uri)
426
- stub(ExceptionHandling).server_name { "invoca_fe98" }
445
+ allow(ExceptionHandling).to receive(:server_name).and_return("invoca_fe98")
427
446
 
428
447
  exception = StandardError.new("Some Exception")
429
448
  exception.set_backtrace([
430
- "test/unit/exception_handling_test.rb:847:in `exception_1'",
431
- "test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
449
+ "spec/unit/exception_handling_test.rb:847:in `exception_1'",
450
+ "spec/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
432
451
  ])
433
452
  exception_context = { "SERVER_NAME" => "exceptional.com" }
434
453
  data_callback = ->(data) do
@@ -446,7 +465,6 @@ module ExceptionHandling
446
465
  exception_context: { "SERVER_NAME" => "exceptional.com" },
447
466
  server: "invoca_fe98",
448
467
  scm_revision: "5b24eac37aaa91f5784901e9aabcead36fd9df82",
449
- notes: "this is used by a test",
450
468
  user_details: { "username" => "jsmith" },
451
469
  request: {
452
470
  "params" => { "advertiser_id" => 435 },
@@ -461,28 +479,30 @@ module ExceptionHandling
461
479
  "SERVER_NAME" => "exceptional.com"
462
480
  },
463
481
  backtrace: [
464
- "test/unit/exception_handling_test.rb:847:in `exception_1'",
465
- "test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
482
+ "spec/unit/exception_handling_test.rb:847:in `exception_1'",
483
+ "spec/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
466
484
  ],
467
- event_response: "Event successfully received"
485
+ event_response: "Event successfully received",
486
+ log_context: { "cuid" => "ABCD" },
487
+ notes: "this is used by a test"
468
488
  }
469
- assert_equal_with_diff expected_data, exception_info.honeybadger_context_data
489
+ expect(exception_info.honeybadger_context_data).to eq(expected_data)
470
490
  end
471
491
 
472
492
  [['Hash', { 'cookie' => 'cookie_context' }],
473
493
  ['String', 'Entering Error State'],
474
494
  ['Array', ['Error1', 'Error2']]].each do |klass, value|
475
- should "extract context from exception_context when it is a #{klass}" do
495
+ it "extract context from exception_context when it is a #{klass}" do
476
496
  exception = StandardError.new("Exception")
477
497
  exception_context = value
478
498
  exception_info = ExceptionInfo.new(exception, exception_context, Time.now)
479
499
 
480
- assert_equal klass, value.class.name
481
- assert_equal value, exception_info.honeybadger_context_data[:exception_context]
500
+ expect(value.class.name).to eq(klass)
501
+ expect(exception_info.honeybadger_context_data[:exception_context]).to eq(value)
482
502
  end
483
503
  end
484
504
 
485
- should "filter out sensitive data from exception context such as [password, password_confirmation, oauth_token]" do
505
+ it "filter out sensitive data from exception context such as [password, password_confirmation, oauth_token]" do
486
506
  sensitive_data = {
487
507
  "password" => "super_secret",
488
508
  "password_confirmation" => "super_secret_confirmation",
@@ -517,15 +537,14 @@ module ExceptionHandling
517
537
  }
518
538
  }.merge(expected_sensitive_data)
519
539
 
520
- assert_equal_with_diff expected_exception_context, exception_info.honeybadger_context_data[:exception_context]
540
+ expect(exception_info.honeybadger_context_data[:exception_context]).to eq(expected_exception_context)
521
541
  end
522
542
 
523
- should "omit context if exception_context is empty" do
543
+ it "omit context if exception_context is empty" do
524
544
  exception = StandardError.new("Exception")
525
545
  exception_context = ""
526
546
  exception_info = ExceptionInfo.new(exception, exception_context, Time.now)
527
-
528
- assert_nil exception_info.honeybadger_context_data[:exception_context]
547
+ expect(exception_info.honeybadger_context_data[:exception_context]).to be_nil
529
548
  end
530
549
  end
531
550