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,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __dir__)
4
+
5
+ module ExceptionHandling
6
+ describe Sensu do
7
+ context "#generate_event" do
8
+ it "create an event" do
9
+ expect(ExceptionHandling::Sensu).to receive(:send_event).with(name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1)
10
+
11
+ ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye")
12
+ end
13
+
14
+ it "add the sensu prefix" do
15
+ ExceptionHandling.sensu_prefix = "cnn_"
16
+
17
+ expect(ExceptionHandling::Sensu).to receive(:send_event).with(name: "cnn_world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1)
18
+
19
+ ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye")
20
+ end
21
+
22
+ it "allow the level to be set to critical" do
23
+ expect(ExceptionHandling::Sensu).to receive(:send_event).with(name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 2)
24
+
25
+ ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye", :critical)
26
+ end
27
+
28
+ it "error if an invalid level is supplied" do
29
+ expect(ExceptionHandling::Sensu).to_not receive(:send_event)
30
+
31
+ expect do
32
+ ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye", :hair_on_fire)
33
+ end.to raise_exception(RuntimeError, /Invalid alert level/)
34
+ end
35
+ end
36
+
37
+ context "#send_event" do
38
+ before do
39
+ @event = { name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1 }
40
+ @socket = SocketStub.new
41
+ end
42
+
43
+ it "send event json to sensu client" do
44
+ expect_any_instance_of(Addrinfo).to receive(:connect).with(any_args) { @socket }
45
+ ExceptionHandling::Sensu.send_event(@event)
46
+
47
+ expect(@socket.sent.first).to eq(@event.to_json)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,14 +1,14 @@
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
- class ExceptionHandlingTest < ActiveSupport::TestCase
7
+ describe ExceptionHandling do
8
8
  include ControllerHelpers
9
9
  include ExceptionHelpers
10
10
 
11
- setup do
11
+ before do
12
12
  @fail_count = 0
13
13
  end
14
14
 
@@ -108,228 +108,228 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
108
108
  end
109
109
 
110
110
  context "with warn and honeybadger notify stubbed" do
111
- setup do
112
- stub(ExceptionHandling).warn(anything)
113
- stub(Honeybadger).notify(anything)
111
+ before do
112
+ allow(ExceptionHandling).to receive(:warn).with(anything)
113
+ allow(Honeybadger).to receive(:notify).with(anything)
114
114
  end
115
115
 
116
116
  context "with logger stashed" do
117
- setup { @original_logger = ExceptionHandling.logger }
118
- teardown { ExceptionHandling.logger = @original_logger }
117
+ before { @original_logger = ExceptionHandling.logger }
118
+ after { ExceptionHandling.logger = @original_logger }
119
119
 
120
- should "store logger as-is if it has ContextualLogger::Mixin" do
120
+ it "store logger as-is if it has ContextualLogger::Mixin" do
121
121
  logger = Logger.new('/dev/null')
122
122
  logger.extend(ContextualLogger::LoggerMixin)
123
123
  ancestors = logger.singleton_class.ancestors.*.name
124
124
 
125
125
  ExceptionHandling.logger = logger
126
- assert_equal ancestors, ExceptionHandling.logger.singleton_class.ancestors.*.name
126
+ expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to eq(ancestors)
127
127
  end
128
128
 
129
- should "allow logger = nil (no deprecation warning)" do
130
- mock(STDERR).puts(/DEPRECATION WARNING/).never
129
+ it "allow logger = nil (no deprecation warning)" do
130
+ expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING/).never
131
131
  ExceptionHandling.logger = nil
132
132
  end
133
133
 
134
- should "[deprecated] mix in ContextualLogger::Mixin if not there" do
135
- mock(STDERR).puts(/DEPRECATION WARNING: implicit extend with ContextualLogger::LoggerMixin is deprecated and will be removed from exception_handling 3\.0/)
134
+ it "[deprecated] mix in ContextualLogger::Mixin if not there" do
135
+ expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING: implicit extend with ContextualLogger::LoggerMixin is deprecated and will be removed from exception_handling 3\.0/)
136
136
  logger = Logger.new('/dev/null')
137
137
  ancestors = logger.singleton_class.ancestors.*.name
138
138
 
139
139
  ExceptionHandling.logger = logger
140
- assert_not_equal ancestors, ExceptionHandling.logger.singleton_class.ancestors.*.name
141
- assert_kind_of ContextualLogger::LoggerMixin, ExceptionHandling.logger
140
+ expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to_not eq(ancestors)
141
+ expect(ExceptionHandling.logger).to be_kind_of(ContextualLogger::LoggerMixin)
142
142
  end
143
143
  end
144
144
 
145
145
  context "#log_error" do
146
- should "take in additional logging context hash and pass it to the logger" do
146
+ it "take in additional logging context hash and pass it to the logger" do
147
147
  ExceptionHandling.log_error('This is an Error', 'This is the prefix context', service_name: 'exception_handling')
148
- assert_match(/This is an Error/, logged_excluding_reload_filter.last[:message])
149
- assert_not_empty logged_excluding_reload_filter.last[:context]
150
- assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
148
+ expect(logged_excluding_reload_filter.last[:message]).to match(/This is an Error/)
149
+ expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
150
+ expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
151
151
  end
152
152
 
153
- should "log with Severity::FATAL" do
153
+ it "log with Severity::FATAL" do
154
154
  ExceptionHandling.log_error('This is a Warning', service_name: 'exception_handling')
155
- assert_equal logged_excluding_reload_filter.last[:severity], 'FATAL'
155
+ expect('FATAL').to eq(logged_excluding_reload_filter.last[:severity])
156
156
  end
157
157
  end
158
158
 
159
159
  context "#log_warning" do
160
- should "have empty array as a backtrace" do
161
- mock(ExceptionHandling).log_error(is_a(ExceptionHandling::Warning), anything) do |error|
162
- assert_equal [], error.backtrace
160
+ it "have empty array as a backtrace" do
161
+ expect(ExceptionHandling).to receive(:log_error).with((ExceptionHandling::Warning), anything) do |error|
162
+ expect(error.backtrace).to eq([])
163
163
  end
164
164
  ExceptionHandling.log_warning('Now with empty array as a backtrace!')
165
165
  end
166
166
 
167
- should "take in additional key word args as logging context and pass them to the logger" do
167
+ it "take in additional key word args as logging context and pass them to the logger" do
168
168
  ExceptionHandling.log_warning('This is a Warning', service_name: 'exception_handling')
169
- assert_match(/This is a Warning/, logged_excluding_reload_filter.last[:message])
170
- assert_not_empty logged_excluding_reload_filter.last[:context]
171
- assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
169
+ expect(logged_excluding_reload_filter.last[:message]).to match(/This is a Warning/)
170
+ expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
171
+ expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
172
172
  end
173
173
 
174
- should "log with Severity::WARN" do
174
+ it "log with Severity::WARN" do
175
175
  ExceptionHandling.log_warning('This is a Warning', service_name: 'exception_handling')
176
- assert_equal logged_excluding_reload_filter.last[:severity], 'WARN'
176
+ expect('WARN').to eq(logged_excluding_reload_filter.last[:severity])
177
177
  end
178
178
  end
179
179
 
180
180
  context "#log_info" do
181
- should "take in additional key word args as logging context and pass them to the logger" do
181
+ it "take in additional key word args as logging context and pass them to the logger" do
182
182
  ExceptionHandling.log_info('This is an Info', service_name: 'exception_handling')
183
- assert_match(/This is an Info/, logged_excluding_reload_filter.last[:message])
184
- assert_not_empty logged_excluding_reload_filter.last[:context]
185
- assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
183
+ expect(logged_excluding_reload_filter.last[:message]).to match(/This is an Info/)
184
+ expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
185
+ expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
186
186
  end
187
187
 
188
- should "log with Severity::INFO" do
188
+ it "log with Severity::INFO" do
189
189
  ExceptionHandling.log_info('This is a Warning', service_name: 'exception_handling')
190
- assert_equal logged_excluding_reload_filter.last[:severity], 'INFO'
190
+ expect('INFO').to eq(logged_excluding_reload_filter.last[:severity])
191
191
  end
192
192
  end
193
193
 
194
194
  context "#log_debug" do
195
- should "take in additional key word args as logging context and pass them to the logger" do
195
+ it "take in additional key word args as logging context and pass them to the logger" do
196
196
  ExceptionHandling.log_debug('This is a Debug', service_name: 'exception_handling')
197
- assert_match(/This is a Debug/, logged_excluding_reload_filter.last[:message])
198
- assert_not_empty logged_excluding_reload_filter.last[:context]
199
- assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
197
+ expect(logged_excluding_reload_filter.last[:message]).to match(/This is a Debug/)
198
+ expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
199
+ expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
200
200
  end
201
201
 
202
- should "log with Severity::DEBUG" do
202
+ it "log with Severity::DEBUG" do
203
203
  ExceptionHandling.log_debug('This is a Warning', service_name: 'exception_handling')
204
- assert_equal logged_excluding_reload_filter.last[:severity], 'DEBUG'
204
+ expect('DEBUG').to eq(logged_excluding_reload_filter.last[:severity])
205
205
  end
206
206
  end
207
207
 
208
208
  context "#write_exception_to_log" do
209
- should "log warnings with Severity::WARN" do
209
+ it "log warnings with Severity::WARN" do
210
210
  warning = ExceptionHandling::Warning.new('This is a Warning')
211
211
  ExceptionHandling.write_exception_to_log(warning, '', Time.now.to_i, service_name: 'exception_handling')
212
- assert_equal logged_excluding_reload_filter.last[:severity], 'WARN'
212
+ expect('WARN').to eq(logged_excluding_reload_filter.last[:severity])
213
213
  end
214
214
 
215
- should "log everything else with Severity::FATAL" do
215
+ it "log everything else with Severity::FATAL" do
216
216
  error = RuntimeError.new('This is a runtime error')
217
217
  ExceptionHandling.write_exception_to_log(error, '', Time.now.to_i, service_name: 'exception_handling')
218
- assert_equal logged_excluding_reload_filter.last[:severity], 'FATAL'
218
+ expect('FATAL').to eq(logged_excluding_reload_filter.last[:severity])
219
219
  end
220
220
  end
221
221
 
222
222
  context "configuration with custom_data_hook or post_log_error_hook" do
223
- teardown do
223
+ after do
224
224
  ExceptionHandling.custom_data_hook = nil
225
225
  ExceptionHandling.post_log_error_hook = nil
226
226
  end
227
227
 
228
- should "support a custom_data_hook" do
228
+ it "support a custom_data_hook" do
229
229
  capture_notifications
230
230
 
231
231
  ExceptionHandling.custom_data_hook = method(:append_organization_info_config)
232
232
  ExceptionHandling.ensure_safe("context") { raise "Some Exception" }
233
233
 
234
- assert_match(/Invoca Engineering Dept./, sent_notifications.last.enhanced_data['user_details'].to_s)
234
+ expect(sent_notifications.last.enhanced_data['user_details'].to_s).to match(/Invoca Engineering Dept./)
235
235
  end
236
236
 
237
- should "support a log_error hook, and pass exception_data, treat_like_warning, and logged_to_honeybadger to it" do
237
+ it "support a log_error hook, and pass exception_data, treat_like_warning, and logged_to_honeybadger to it" do
238
238
  @honeybadger_status = nil
239
239
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
240
240
 
241
241
  notify_args = []
242
- mock(Honeybadger).notify.with_any_args { |info| notify_args << info; '06220c5a-b471-41e5-baeb-de247da45a56' }
242
+ expect(Honeybadger).to receive(:notify).with(any_args) { |info| notify_args << info; '06220c5a-b471-41e5-baeb-de247da45a56' }
243
243
  ExceptionHandling.ensure_safe("context") { raise "Some Exception" }
244
- assert_equal 1, @fail_count
245
- assert_equal false, @treat_like_warning
246
- assert_equal :success, @honeybadger_status
244
+ expect(@fail_count).to eq(1)
245
+ expect(@treat_like_warning).to eq(false)
246
+ expect(@honeybadger_status).to eq(:success)
247
247
 
248
- assert_equal "this is used by a test", @callback_data["notes"]
249
- assert_equal 1, notify_args.size, notify_args.inspect
250
- assert_match(/this is used by a test/, notify_args.last[:context].to_s)
248
+ expect(@callback_data["notes"]).to eq("this is used by a test")
249
+ expect(notify_args.size).to eq(1), notify_args.inspect
250
+ expect(notify_args.last[:context].to_s).to match(/this is used by a test/)
251
251
  end
252
252
 
253
- should "plumb treat_like_warning and logged_to_honeybadger to log error hook" do
253
+ it "plumb treat_like_warning and logged_to_honeybadger to log error hook" do
254
254
  @honeybadger_status = nil
255
255
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
256
256
  ExceptionHandling.log_error(StandardError.new("Some Exception"), "mooo", treat_like_warning: true)
257
- assert_equal 1, @fail_count
258
- assert_equal true, @treat_like_warning
259
- assert_equal :skipped, @honeybadger_status
257
+ expect(@fail_count).to eq(1)
258
+ expect(@treat_like_warning).to eq(true)
259
+ expect(@honeybadger_status).to eq(:skipped)
260
260
  end
261
261
 
262
- should "include logging context in the exception data" do
262
+ it "include logging context in the exception data" do
263
263
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
264
264
  ExceptionHandling.log_error(StandardError.new("Some Exception"), "mooo", treat_like_warning: true, log_context_test: "contextual_logging")
265
265
 
266
266
  expected_log_context = {
267
267
  "log_context_test" => "contextual_logging"
268
268
  }
269
- assert_equal expected_log_context, @callback_data[:log_context]
269
+ expect(@callback_data[:log_context]).to eq(expected_log_context)
270
270
  end
271
271
 
272
- should "support rescue exceptions from a log_error hook" do
272
+ it "support rescue exceptions from a log_error hook" do
273
273
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_with_failure)
274
274
  log_info_messages = []
275
- stub(ExceptionHandling.logger).info.with_any_args do |message, _|
275
+ allow(ExceptionHandling.logger).to receive(:info).with(any_args) do |message, _|
276
276
  log_info_messages << message
277
277
  end
278
- assert_nothing_raised { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }
279
- assert log_info_messages.find { |message| message =~ /Unable to execute custom log_error callback/ }
278
+ expect { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }.to_not raise_error
279
+ expect(log_info_messages.find { |message| message =~ /Unable to execute custom log_error callback/ }).to be_truthy
280
280
  end
281
281
 
282
- should "handle nil message exceptions resulting from the log_error hook" do
282
+ it "handle nil message exceptions resulting from the log_error hook" do
283
283
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_returns_nil_message_exception)
284
284
  log_info_messages = []
285
- stub(ExceptionHandling.logger).info.with_any_args do |message, _|
285
+ allow(ExceptionHandling.logger).to receive(:info).with(any_args) do |message, _|
286
286
  log_info_messages << message
287
287
  end
288
- assert_nothing_raised { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }
289
- assert log_info_messages.find { |message| message =~ /Unable to execute custom log_error callback/ }
288
+ expect { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }.to_not raise_error
289
+ expect(log_info_messages.find { |message| message =~ /Unable to execute custom log_error callback/ }).to be_truthy
290
290
  end
291
291
 
292
- should "handle nil message exceptions resulting from the custom data hook" do
292
+ it "handle nil message exceptions resulting from the custom data hook" do
293
293
  ExceptionHandling.custom_data_hook = method(:custom_data_callback_returns_nil_message_exception)
294
294
  log_info_messages = []
295
- stub(ExceptionHandling.logger).info.with_any_args do |message, _|
295
+ allow(ExceptionHandling.logger).to receive(:info).with(any_args) do |message, _|
296
296
  log_info_messages << message
297
297
  end
298
- assert_nothing_raised { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }
299
- assert log_info_messages.find { |message| message =~ /Unable to execute custom custom_data_hook callback/ }
298
+ expect { ExceptionHandling.ensure_safe("mooo") { raise "Some Exception" } }.not_to raise_error
299
+ expect(log_info_messages.find { |message| message =~ /Unable to execute custom custom_data_hook callback/ }).to be_truthy
300
300
  end
301
301
  end
302
302
 
303
303
  context "Exception Handling" do
304
304
  context "default_metric_name" do
305
305
  context "when metric_name is present in exception_data" do
306
- should "include metric_name in resulting metric name" do
306
+ it "include metric_name in resulting metric name" do
307
307
  exception = StandardError.new('this is an exception')
308
308
  metric = ExceptionHandling.default_metric_name({ 'metric_name' => 'special_metric' }, exception, true)
309
- assert_equal 'exception_handling.special_metric', metric
309
+ expect(metric).to eq('exception_handling.special_metric')
310
310
  end
311
311
  end
312
312
 
313
313
  context "when metric_name is not present in exception_data" do
314
- should "return exception_handling.warning when using log warning" do
314
+ it "return exception_handling.warning when using log warning" do
315
315
  warning = ExceptionHandling::Warning.new('this is a warning')
316
316
  metric = ExceptionHandling.default_metric_name({}, warning, false)
317
- assert_equal 'exception_handling.warning', metric
317
+ expect(metric).to eq('exception_handling.warning')
318
318
  end
319
319
 
320
- should "return exception_handling.exception when using log error" do
320
+ it "return exception_handling.exception when using log error" do
321
321
  exception = StandardError.new('this is an exception')
322
322
  metric = ExceptionHandling.default_metric_name({}, exception, false)
323
- assert_equal 'exception_handling.exception', metric
323
+ expect(metric).to eq('exception_handling.exception')
324
324
  end
325
325
 
326
326
  context "when using log error with treat_like_warning" do
327
- should "return exception_handling.unforwarded_exception when exception not present" do
327
+ it "return exception_handling.unforwarded_exception when exception not present" do
328
328
  metric = ExceptionHandling.default_metric_name({}, nil, true)
329
- assert_equal 'exception_handling.unforwarded_exception', metric
329
+ expect(metric).to eq('exception_handling.unforwarded_exception')
330
330
  end
331
331
 
332
- should "return exception_handling.unforwarded_exception with exception classname when exception is present" do
332
+ it "return exception_handling.unforwarded_exception with exception classname when exception is present" do
333
333
  module SomeModule
334
334
  class SomeException < StandardError
335
335
  end
@@ -337,43 +337,43 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
337
337
 
338
338
  exception = SomeModule::SomeException.new('this is an exception')
339
339
  metric = ExceptionHandling.default_metric_name({}, exception, true)
340
- assert_equal 'exception_handling.unforwarded_exception_SomeException', metric
340
+ expect(metric).to eq('exception_handling.unforwarded_exception_SomeException')
341
341
  end
342
342
  end
343
343
  end
344
344
  end
345
345
 
346
346
  context "default_honeybadger_metric_name" do
347
- should "return exception_handling.honeybadger.success when status is :success" do
347
+ it "return exception_handling.honeybadger.success when status is :success" do
348
348
  metric = ExceptionHandling.default_honeybadger_metric_name(:success)
349
- assert_equal 'exception_handling.honeybadger.success', metric
349
+ expect(metric).to eq('exception_handling.honeybadger.success')
350
350
  end
351
351
 
352
- should "return exception_handling.honeybadger.failure when status is :failure" do
352
+ it "return exception_handling.honeybadger.failure when status is :failure" do
353
353
  metric = ExceptionHandling.default_honeybadger_metric_name(:failure)
354
- assert_equal 'exception_handling.honeybadger.failure', metric
354
+ expect(metric).to eq('exception_handling.honeybadger.failure')
355
355
  end
356
356
 
357
- should "return exception_handling.honeybadger.skipped when status is :skipped" do
357
+ it "return exception_handling.honeybadger.skipped when status is :skipped" do
358
358
  metric = ExceptionHandling.default_honeybadger_metric_name(:skipped)
359
- assert_equal 'exception_handling.honeybadger.skipped', metric
359
+ expect(metric).to eq('exception_handling.honeybadger.skipped')
360
360
  end
361
361
 
362
- should "return exception_handling.honeybadger.unknown_status when status is not recognized" do
362
+ it "return exception_handling.honeybadger.unknown_status when status is not recognized" do
363
363
  metric = ExceptionHandling.default_honeybadger_metric_name(nil)
364
- assert_equal 'exception_handling.honeybadger.unknown_status', metric
364
+ expect(metric).to eq('exception_handling.honeybadger.unknown_status')
365
365
  end
366
366
  end
367
367
 
368
368
  context "ExceptionHandling.ensure_safe" do
369
- should "log an exception with call stack if an exception is raised." do
370
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
369
+ it "log an exception with call stack if an exception is raised." do
370
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
371
371
  ExceptionHandling.ensure_safe { raise ArgumentError, "blah" }
372
372
  end
373
373
 
374
374
  if ActionView::VERSION::MAJOR >= 5
375
- should "log an exception with call stack if an ActionView template exception is raised." do
376
- mock(ExceptionHandling.logger).fatal(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
375
+ it "log an exception with call stack if an ActionView template exception is raised." do
376
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
377
377
  ExceptionHandling.ensure_safe do
378
378
  begin
379
379
  # Rails 5 made the switch from ActionView::TemplateError taking in the original exception
@@ -385,297 +385,292 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
385
385
  end
386
386
  end
387
387
  else
388
- should "log an exception with call stack if an ActionView template exception is raised." do
389
- mock(ExceptionHandling.logger).fatal(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
388
+ it "log an exception with call stack if an ActionView template exception is raised." do
389
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
390
390
  ExceptionHandling.ensure_safe { raise ActionView::TemplateError.new({}, ArgumentError.new("blah")) }
391
391
  end
392
392
  end
393
393
 
394
- should "should not log an exception if an exception is not raised." do
395
- dont_allow(ExceptionHandling.logger).fatal
394
+ it "should not log an exception if an exception is not raised." do
395
+ expect(ExceptionHandling.logger).to_not receive(:fatal)
396
396
  ExceptionHandling.ensure_safe { ; }
397
397
  end
398
398
 
399
- should "return its value if used during an assignment" do
400
- dont_allow(ExceptionHandling.logger).fatal
399
+ it "return its value if used during an assignment" do
400
+ expect(ExceptionHandling.logger).to_not receive(:fatal)
401
401
  b = ExceptionHandling.ensure_safe { 5 }
402
- assert_equal 5, b
402
+ expect(b).to eq(5)
403
403
  end
404
404
 
405
- should "return nil if an exception is raised during an assignment" do
406
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
405
+ it "return nil if an exception is raised during an assignment" do
406
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
407
407
  b = ExceptionHandling.ensure_safe { raise ArgumentError, "blah" }
408
- assert_nil b
408
+ expect(b).to be_nil
409
409
  end
410
410
 
411
- should "allow a message to be appended to the error when logged." do
412
- mock(ExceptionHandling.logger).fatal(/mooo\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
411
+ it "allow a message to be appended to the error when logged." do
412
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/mooo\nArgumentError: \(blah\):\n.*exception_handling_spec\.rb/, anything)
413
413
  b = ExceptionHandling.ensure_safe("mooo") { raise ArgumentError, "blah" }
414
- assert_nil b
414
+ expect(b).to be_nil
415
415
  end
416
416
 
417
- should "only rescue StandardError and descendents" do
418
- assert_raise(Exception) { ExceptionHandling.ensure_safe("mooo") { raise Exception } }
417
+ it "only rescue StandardError and descendents" do
418
+ expect { ExceptionHandling.ensure_safe("mooo") { raise Exception } }.to raise_exception(Exception)
419
419
 
420
- mock(ExceptionHandling.logger).fatal(/mooo\nStandardError: \(blah\):\n.*exception_handling_test\.rb/, anything)
420
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/mooo\nStandardError: \(blah\):\n.*exception_handling_spec\.rb/, anything)
421
421
 
422
422
  b = ExceptionHandling.ensure_safe("mooo") { raise StandardError, "blah" }
423
- assert_nil b
423
+ expect(b).to be_nil
424
424
  end
425
425
  end
426
426
 
427
427
  context "ExceptionHandling.ensure_completely_safe" do
428
- should "log an exception if an exception is raised." do
429
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
428
+ it "log an exception if an exception is raised." do
429
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
430
430
  ExceptionHandling.ensure_completely_safe { raise ArgumentError, "blah" }
431
431
  end
432
432
 
433
- should "should not log an exception if an exception is not raised." do
434
- mock(ExceptionHandling.logger).fatal.times(0)
433
+ it "should not log an exception if an exception is not raised." do
434
+ expect(ExceptionHandling.logger).to receive(:fatal).exactly(0)
435
435
  ExceptionHandling.ensure_completely_safe { ; }
436
436
  end
437
437
 
438
- should "return its value if used during an assignment" do
439
- mock(ExceptionHandling.logger).fatal.times(0)
438
+ it "return its value if used during an assignment" do
439
+ expect(ExceptionHandling.logger).to receive(:fatal).exactly(0)
440
440
  b = ExceptionHandling.ensure_completely_safe { 5 }
441
- assert_equal 5, b
441
+ expect(b).to eq(5)
442
442
  end
443
443
 
444
- should "return nil if an exception is raised during an assignment" do
445
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything) { nil }
444
+ it "return nil if an exception is raised during an assignment" do
445
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything) { nil }
446
446
  b = ExceptionHandling.ensure_completely_safe { raise ArgumentError, "blah" }
447
- assert_nil b
447
+ expect(b).to be_nil
448
448
  end
449
449
 
450
- should "allow a message to be appended to the error when logged." do
451
- mock(ExceptionHandling.logger).fatal(/mooo\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
450
+ it "allow a message to be appended to the error when logged." do
451
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/mooo\nArgumentError: \(blah\):\n.*exception_handling_spec\.rb/, anything)
452
452
  b = ExceptionHandling.ensure_completely_safe("mooo") { raise ArgumentError, "blah" }
453
- assert_nil b
453
+ expect(b).to be_nil
454
454
  end
455
455
 
456
- should "rescue any instance or child of Exception" do
457
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
456
+ it "rescue any instance or child of Exception" do
457
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
458
458
  ExceptionHandling.ensure_completely_safe { raise Exception, "blah" }
459
459
  end
460
460
 
461
- should "not rescue the special exceptions that Ruby uses" do
461
+ it "not rescue the special exceptions that Ruby uses" do
462
462
  [SystemExit, SystemStackError, NoMemoryError, SecurityError].each do |exception|
463
- assert_raise exception do
463
+ expect do
464
464
  ExceptionHandling.ensure_completely_safe do
465
465
  raise exception
466
466
  end
467
- end
467
+ end.to raise_exception(exception)
468
468
  end
469
469
  end
470
470
  end
471
471
 
472
472
  context "ExceptionHandling.ensure_escalation" do
473
- setup do
473
+ before do
474
474
  capture_notifications
475
475
  ActionMailer::Base.deliveries.clear
476
476
  end
477
477
 
478
- should "log the exception as usual and send the proper email" do
479
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
478
+ it "log the exception as usual and send the proper email" do
479
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
480
480
  ExceptionHandling.ensure_escalation("Favorite Feature") { raise ArgumentError, "blah" }
481
- assert_equal 1, ActionMailer::Base.deliveries.count
482
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
481
+ expect(ActionMailer::Base.deliveries.count).to eq(1)
482
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
483
483
 
484
484
  email = ActionMailer::Base.deliveries.last
485
- assert_equal "#{ExceptionHandling.email_environment} Escalation: Favorite Feature", email.subject
486
- assert_match 'ArgumentError: blah', email.body.to_s
487
- assert_match ExceptionHandling.last_exception_timestamp.to_s, email.body.to_s
485
+ expect(email.subject).to eq("#{ExceptionHandling.email_environment} Escalation: Favorite Feature")
486
+ expect(email.body.to_s).to match('ArgumentError: blah')
487
+ expect(email.body.to_s).to match(ExceptionHandling.last_exception_timestamp.to_s)
488
488
  end
489
489
 
490
- should "should not escalate if an exception is not raised." do
491
- dont_allow(ExceptionHandling.logger).fatal
490
+ it "should not escalate if an exception is not raised." do
491
+ expect(ExceptionHandling.logger).to_not receive(:fatal)
492
492
  ExceptionHandling.ensure_escalation('Ignored') { ; }
493
- assert_equal 0, ActionMailer::Base.deliveries.count
493
+ expect(ActionMailer::Base.deliveries.count).to eq(0)
494
494
  end
495
495
 
496
- should "log if the escalation email cannot be sent" do
497
- any_instance_of(Mail::Message) do |message|
498
- mock(message).deliver { raise RuntimeError.new, "Delivery Error" }
499
- end
496
+ it "log if the escalation email cannot be sent" do
497
+ expect_any_instance_of(Mail::Message).to receive(:deliver).and_raise(RuntimeError.new, "Delivery Error")
500
498
  log_fatals = []
501
- stub(ExceptionHandling.logger) do |logger|
502
- logger.fatal.with_any_args { |*args| log_fatals << args }
499
+ expect(ExceptionHandling.logger).to receive(:fatal).with(any_args).at_least(:once) do |*args|
500
+ log_fatals << args
503
501
  end
504
502
 
505
503
  ExceptionHandling.ensure_escalation("ensure context") { raise ArgumentError, "first_test_exception" }
504
+ expect(log_fatals[0].first).to match(/ArgumentError.*first_test_exception/)
505
+ expect(log_fatals[1].first).to match(/safe_email_deliver.*Delivery Error/m)
506
506
 
507
- assert_match(/ArgumentError.*first_test_exception/, log_fatals[0].first)
508
- assert_match(/safe_email_deliver.*Delivery Error/m, log_fatals[1].first)
507
+ expect(log_fatals.size).to eq(2), log_fatals.inspect
509
508
 
510
- assert_equal 2, log_fatals.size, log_fatals.inspect
511
-
512
- assert_equal 1, sent_notifications.size, sent_notifications.inspect # still sent to honeybadger
509
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect # still sent to honeybadger
513
510
  end
514
511
 
515
- should "allow the caller to specify custom recipients" do
512
+ it "allow the caller to specify custom recipients" do
516
513
  custom_recipients = ['something@invoca.com']
517
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
514
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
518
515
  ExceptionHandling.ensure_escalation("Favorite Feature", custom_recipients) { raise ArgumentError, "blah" }
519
- assert_equal 1, ActionMailer::Base.deliveries.count
520
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
516
+ expect(ActionMailer::Base.deliveries.count).to eq(1)
517
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
521
518
 
522
519
  email = ActionMailer::Base.deliveries.last
523
- assert_equal "#{ExceptionHandling.email_environment} Escalation: Favorite Feature", email.subject
524
- assert_match 'ArgumentError: blah', email.body.to_s
525
- assert_match ExceptionHandling.last_exception_timestamp.to_s, email.body.to_s
526
- assert_equal custom_recipients, email.to
520
+ expect(email.subject).to eq("#{ExceptionHandling.email_environment} Escalation: Favorite Feature")
521
+ expect(email.body.to_s).to match('ArgumentError: blah')
522
+ expect(email.body.to_s).to match(ExceptionHandling.last_exception_timestamp.to_s)
523
+ expect(email.to).to eq(custom_recipients)
527
524
  end
528
525
  end
529
526
 
530
527
  context "ExceptionHandling.ensure_alert" do
531
- should "log the exception as usual and fire a sensu event" do
532
- mock(ExceptionHandling::Sensu).generate_event("Favorite Feature", "test context\nblah")
533
- mock(ExceptionHandling.logger).fatal(/\(blah\):\n.*exception_handling_test\.rb/, anything)
528
+ it "log the exception as usual and fire a sensu event" do
529
+ expect(ExceptionHandling::Sensu).to receive(:generate_event).with("Favorite Feature", "test context\nblah")
530
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, anything)
534
531
  ExceptionHandling.ensure_alert('Favorite Feature', 'test context') { raise ArgumentError, "blah" }
535
532
  end
536
533
 
537
- should "should not send sensu event if an exception is not raised." do
538
- dont_allow(ExceptionHandling.logger).fatal
539
- dont_allow(ExceptionHandling::Sensu).generate_event
534
+ it "should not send sensu event if an exception is not raised." do
535
+ expect(ExceptionHandling.logger).to_not receive(:fatal)
536
+ expect(ExceptionHandling::Sensu).to_not receive(:generate_event)
540
537
  ExceptionHandling.ensure_alert('Ignored', 'test context') { ; }
541
538
  end
542
539
 
543
- should "log if the sensu event could not be sent" do
544
- mock(ExceptionHandling::Sensu).send_event(anything) { raise "Failed to send" }
545
- mock(ExceptionHandling.logger) do |logger|
546
- logger.fatal(/first_test_exception/, anything)
547
- logger.fatal(/Failed to send/, anything)
548
- end
540
+ it "log if the sensu event could not be sent" do
541
+ expect(ExceptionHandling::Sensu).to receive(:send_event).with(anything) { raise "Failed to send" }
542
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/first_test_exception/, anything)
543
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to send/, anything)
549
544
  ExceptionHandling.ensure_alert("Not Used", 'test context') { raise ArgumentError, "first_test_exception" }
550
545
  end
551
546
 
552
- should "log if the exception message is nil" do
553
- mock(ExceptionHandling::Sensu).generate_event("some alert", "test context\n")
547
+ it "log if the exception message is nil" do
548
+ expect(ExceptionHandling::Sensu).to receive(:generate_event).with("some alert", "test context\n")
554
549
  ExceptionHandling.ensure_alert('some alert', 'test context') { raise_exception_with_nil_message }
555
550
  end
556
551
  end
557
552
 
558
553
  context "ExceptionHandling.escalate_to_production_support" do
559
- should "notify production support" do
554
+ it "notify production support" do
560
555
  subject = "Runtime Error found!"
561
556
  exception = RuntimeError.new("Test")
562
557
  recipients = ["prodsupport@example.com"]
563
558
 
564
- mock(ExceptionHandling).production_support_recipients { recipients }.times(2)
565
- mock(ExceptionHandling).escalate(subject, exception, ExceptionHandling.last_exception_timestamp, recipients)
559
+ expect(ExceptionHandling).to receive(:production_support_recipients).and_return(recipients).exactly(2)
560
+ expect(ExceptionHandling).to receive(:escalate).with(subject, exception, ExceptionHandling.last_exception_timestamp, recipients)
566
561
  ExceptionHandling.escalate_to_production_support(exception, subject)
567
562
  end
568
563
  end
569
564
 
570
565
  context "exception timestamp" do
571
- setup do
566
+ before do
572
567
  Time.now_override = Time.parse('1986-5-21 4:17 am UTC')
573
568
  end
574
569
 
575
- should "include the timestamp when the exception is logged" do
570
+ it "include the timestamp when the exception is logged" do
576
571
  capture_notifications
577
572
 
578
- mock(ExceptionHandling.logger).fatal(/\(Error:517033020\) context\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
573
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/\(Error:517033020\) context\nArgumentError: \(blah\):\n.*exception_handling_spec\.rb/, anything)
579
574
  b = ExceptionHandling.ensure_safe("context") { raise ArgumentError, "blah" }
580
- assert_nil b
575
+ expect(b).to be_nil
581
576
 
582
- assert_equal 517_033_020, ExceptionHandling.last_exception_timestamp
577
+ expect(ExceptionHandling.last_exception_timestamp).to eq(517_033_020)
583
578
 
584
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
579
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
585
580
 
586
- assert_equal 517_033_020, sent_notifications.last.enhanced_data['timestamp']
581
+ expect(sent_notifications.last.enhanced_data['timestamp']).to eq(517_033_020)
587
582
  end
588
583
  end
589
584
 
590
- should "log the error if the exception message is nil" do
585
+ it "log the error if the exception message is nil" do
591
586
  capture_notifications
592
587
 
593
588
  ExceptionHandling.log_error(exception_with_nil_message)
594
589
 
595
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
596
- assert_equal 'RuntimeError: ', sent_notifications.last.enhanced_data['error_string']
590
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
591
+ expect(sent_notifications.last.enhanced_data['error_string']).to eq('RuntimeError: ')
597
592
  end
598
593
 
599
- should "log the error if the exception message is nil and the exception context is a hash" do
594
+ it "log the error if the exception message is nil and the exception context is a hash" do
600
595
  capture_notifications
601
596
 
602
597
  ExceptionHandling.log_error(exception_with_nil_message, "SERVER_NAME" => "exceptional.com")
603
598
 
604
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
605
- assert_equal 'RuntimeError: ', sent_notifications.last.enhanced_data['error_string']
599
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
600
+ expect(sent_notifications.last.enhanced_data['error_string']).to eq('RuntimeError: ')
606
601
  end
607
602
 
608
603
  context "Honeybadger integration" do
609
604
  context "with Honeybadger not defined" do
610
- setup do
611
- stub(ExceptionHandling).honeybadger_defined? { false }
605
+ before do
606
+ allow(ExceptionHandling).to receive(:honeybadger_defined?) { false }
612
607
  end
613
608
 
614
- should "not invoke send_exception_to_honeybadger when log_error is executed" do
615
- dont_allow(ExceptionHandling).send_exception_to_honeybadger
609
+ it "not invoke send_exception_to_honeybadger when log_error is executed" do
610
+ expect(ExceptionHandling).to_not receive(:send_exception_to_honeybadger)
616
611
  ExceptionHandling.log_error(exception_1)
617
612
  end
618
613
 
619
- should "not invoke send_exception_to_honeybadger when ensure_safe is executed" do
620
- dont_allow(ExceptionHandling).send_exception_to_honeybadger
614
+ it "not invoke send_exception_to_honeybadger when ensure_safe is executed" do
615
+ expect(ExceptionHandling).to_not receive(:send_exception_to_honeybadger)
621
616
  ExceptionHandling.ensure_safe { raise exception_1 }
622
617
  end
623
618
  end
624
619
 
625
620
  context "with Honeybadger defined" do
626
- should "not send_exception_to_honeybadger when log_warning is executed" do
627
- dont_allow(ExceptionHandling).send_exception_to_honeybadger
621
+ it "not send_exception_to_honeybadger when log_warning is executed" do
622
+ expect(ExceptionHandling).to_not receive(:send_exception_to_honeybadger)
628
623
  ExceptionHandling.log_warning("This should not go to honeybadger")
629
624
  end
630
625
 
631
- should "not send_exception_to_honeybadger when log_error is called with a Warning" do
632
- dont_allow(ExceptionHandling).send_exception_to_honeybadger
626
+ it "not send_exception_to_honeybadger when log_error is called with a Warning" do
627
+ expect(ExceptionHandling).to_not receive(:send_exception_to_honeybadger)
633
628
  ExceptionHandling.log_error(ExceptionHandling::Warning.new("This should not go to honeybadger"))
634
629
  end
635
630
 
636
- should "invoke send_exception_to_honeybadger when log_error is executed" do
637
- mock.proxy(ExceptionHandling).send_exception_to_honeybadger.with_any_args
631
+ it "invoke send_exception_to_honeybadger when log_error is executed" do
632
+ expect(ExceptionHandling).to receive(:send_exception_to_honeybadger).with(any_args).and_call_original
638
633
  ExceptionHandling.log_error(exception_1)
639
634
  end
640
635
 
641
- should "invoke send_exception_to_honeybadger when log_error_rack is executed" do
642
- mock.proxy(ExceptionHandling).send_exception_to_honeybadger.with_any_args
636
+ it "invoke send_exception_to_honeybadger when log_error_rack is executed" do
637
+ expect(ExceptionHandling).to receive(:send_exception_to_honeybadger).with(any_args).and_call_original
643
638
  ExceptionHandling.log_error_rack(exception_1, {}, nil)
644
639
  end
645
640
 
646
- should "invoke send_exception_to_honeybadger when ensure_safe is executed" do
647
- mock.proxy(ExceptionHandling).send_exception_to_honeybadger.with_any_args
641
+ it "invoke send_exception_to_honeybadger when ensure_safe is executed" do
642
+ expect(ExceptionHandling).to receive(:send_exception_to_honeybadger).with(any_args).and_call_original
648
643
  ExceptionHandling.ensure_safe { raise exception_1 }
649
644
  end
650
645
 
651
- should "specify error message as an empty string when notifying honeybadger if exception message is nil" do
652
- mock(Honeybadger).notify.with_any_args do |args|
653
- assert_equal "", args[:error_message]
646
+ it "specify error message as an empty string when notifying honeybadger if exception message is nil" do
647
+ expect(Honeybadger).to receive(:notify).with(any_args) do |args|
648
+ expect(args[:error_message]).to eq("")
654
649
  end
655
650
  ExceptionHandling.log_error(exception_with_nil_message)
656
651
  end
657
652
 
658
653
  context "with stubbed values" do
659
- setup do
654
+ before do
660
655
  Time.now_override = Time.now
661
656
  @env = { server: "fe98" }
662
657
  @parameters = { advertiser_id: 435, controller: "some_controller" }
663
658
  @session = { username: "jsmith" }
664
659
  @request_uri = "host/path"
665
660
  @controller = create_dummy_controller(@env, @parameters, @session, @request_uri)
666
- stub(ExceptionHandling).server_name { "invoca_fe98" }
661
+ allow(ExceptionHandling).to receive(:server_name) { "invoca_fe98" }
667
662
 
668
663
  @exception = StandardError.new("Some Exception")
669
664
  @exception.set_backtrace([
670
- "test/unit/exception_handling_test.rb:847:in `exception_1'",
671
- "test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
665
+ "spec/unit/exception_handling_spec.rb:847:in `exception_1'",
666
+ "spec/unit/exception_handling_spec.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
672
667
  ])
673
668
  @exception_context = { "SERVER_NAME" => "exceptional.com" }
674
669
  end
675
670
 
676
- should "send error details and relevant context data to Honeybadger with log_context" do
671
+ it "send error details and relevant context data to Honeybadger with log_context" do
677
672
  honeybadger_data = nil
678
- mock(Honeybadger).notify.with_any_args do |data|
673
+ expect(Honeybadger).to receive(:notify).with(any_args) do |data|
679
674
  honeybadger_data = data
680
675
  end
681
676
  ExceptionHandling.logger.global_context = { service_name: "rails", region: "AWS-us-east-1" }
@@ -713,19 +708,19 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
713
708
  "SERVER_NAME" => "exceptional.com"
714
709
  },
715
710
  backtrace: [
716
- "test/unit/exception_handling_test.rb:847:in `exception_1'",
717
- "test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
711
+ "spec/unit/exception_handling_spec.rb:847:in `exception_1'",
712
+ "spec/unit/exception_handling_spec.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
718
713
  ],
719
714
  event_response: "Event successfully received",
720
715
  log_context: { "service_name" => "bin/console", "region" => "AWS-us-east-1", "log_source" => "gem/listen" }
721
716
  }
722
717
  }
723
- assert_equal_with_diff expected_data, honeybadger_data
718
+ expect(honeybadger_data).to eq(expected_data)
724
719
  end
725
720
 
726
- should "send error details and relevant context data to Honeybadger with empty log_context" do
721
+ it "send error details and relevant context data to Honeybadger with empty log_context" do
727
722
  honeybadger_data = nil
728
- mock(Honeybadger).notify.with_any_args do |data|
723
+ expect(Honeybadger).to receive(:notify).with(any_args) do |data|
729
724
  honeybadger_data = data
730
725
  end
731
726
  ExceptionHandling.logger.global_context = {}
@@ -763,22 +758,22 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
763
758
  "SERVER_NAME" => "exceptional.com"
764
759
  },
765
760
  backtrace: [
766
- "test/unit/exception_handling_test.rb:847:in `exception_1'",
767
- "test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
761
+ "spec/unit/exception_handling_spec.rb:847:in `exception_1'",
762
+ "spec/unit/exception_handling_spec.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
768
763
  ],
769
764
  event_response: "Event successfully received"
770
765
  }
771
766
  }
772
- assert_equal_with_diff expected_data, honeybadger_data
767
+ expect(honeybadger_data).to eq(expected_data)
773
768
  end
774
769
  end
775
770
 
776
771
  context "with post_log_error_hook set" do
777
- teardown do
772
+ after do
778
773
  ExceptionHandling.post_log_error_hook = nil
779
774
  end
780
775
 
781
- should "not send notification to honeybadger when exception description has the flag turned off and call log error callback with logged_to_honeybadger set to nil" do
776
+ it "not send notification to honeybadger when exception description has the flag turned off and call log error callback with logged_to_honeybadger set to nil" do
782
777
  @honeybadger_status = nil
783
778
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
784
779
  filter_list = {
@@ -787,37 +782,37 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
787
782
  send_to_honeybadger: false
788
783
  }
789
784
  }
790
- stub(File).mtime { incrementing_mtime }
791
- mock(YAML).load_file.with_any_args { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }.at_least(1)
785
+ allow(File).to receive(:mtime) { incrementing_mtime }
786
+ expect(YAML).to receive(:load_file).with(any_args) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }.at_least(1)
792
787
 
793
- mock.proxy(ExceptionHandling).send_exception_to_honeybadger_unless_filtered.with_any_args.once
794
- dont_allow(Honeybadger).notify
788
+ expect(ExceptionHandling).to receive(:send_exception_to_honeybadger_unless_filtered).with(any_args).exactly(1).and_call_original
789
+ expect(Honeybadger).to_not receive(:notify)
795
790
  ExceptionHandling.log_error(StandardError.new("suppress Honeybadger notification"))
796
- assert_equal :skipped, @honeybadger_status
791
+ expect(@honeybadger_status).to eq(:skipped)
797
792
  end
798
793
 
799
- should "call log error callback with logged_to_honeybadger set to false if an error occurs while attempting to notify honeybadger" do
794
+ it "call log error callback with logged_to_honeybadger set to false if an error occurs while attempting to notify honeybadger" do
800
795
  @honeybadger_status = nil
801
796
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
802
- mock(Honeybadger).notify.with_any_args { raise "Honeybadger Notification Failure" }
797
+ expect(Honeybadger).to receive(:notify).with(any_args) { raise "Honeybadger Notification Failure" }
803
798
  ExceptionHandling.log_error(exception_1)
804
- assert_equal :failure, @honeybadger_status
799
+ expect(@honeybadger_status).to eq(:failure)
805
800
  end
806
801
 
807
- should "call log error callback with logged_to_honeybadger set to false on unsuccessful honeybadger notification" do
802
+ it "call log error callback with logged_to_honeybadger set to false on unsuccessful honeybadger notification" do
808
803
  @honeybadger_status = nil
809
804
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
810
- mock(Honeybadger).notify.with_any_args { false }
805
+ expect(Honeybadger).to receive(:notify).with(any_args) { false }
811
806
  ExceptionHandling.log_error(exception_1)
812
- assert_equal :failure, @honeybadger_status
807
+ expect(@honeybadger_status).to eq(:failure)
813
808
  end
814
809
 
815
- should "call log error callback with logged_to_honeybadger set to true on successful honeybadger notification" do
810
+ it "call log error callback with logged_to_honeybadger set to true on successful honeybadger notification" do
816
811
  @honeybadger_status = nil
817
812
  ExceptionHandling.post_log_error_hook = method(:log_error_callback_config)
818
- mock(Honeybadger).notify.with_any_args { '06220c5a-b471-41e5-baeb-de247da45a56' }
813
+ expect(Honeybadger).to receive(:notify).with(any_args) { '06220c5a-b471-41e5-baeb-de247da45a56' }
819
814
  ExceptionHandling.log_error(exception_1)
820
- assert_equal :success, @honeybadger_status
815
+ expect(@honeybadger_status).to eq(:success)
821
816
  end
822
817
  end
823
818
  end
@@ -829,33 +824,33 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
829
824
  end
830
825
  end
831
826
 
832
- should "allow sections to have data with just a to_s method" do
827
+ it "allow sections to have data with just a to_s method" do
833
828
  capture_notifications
834
829
 
835
830
  ExceptionHandling.log_error("This is my RingSwitch example.") do |data|
836
831
  data.merge!(event_response: EventResponse.new)
837
832
  end
838
833
 
839
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
840
- assert_match(/message from to_s!/, sent_notifications.last.enhanced_data['event_response'].to_s)
834
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
835
+ expect(sent_notifications.last.enhanced_data['event_response'].to_s).to match(/message from to_s!/)
841
836
  end
842
837
  end
843
838
 
844
- should "return the error ID (timestamp)" do
839
+ it "return the error ID (timestamp)" do
845
840
  result = ExceptionHandling.log_error(RuntimeError.new("A runtime error"), "Runtime message")
846
- assert_equal ExceptionHandling.last_exception_timestamp, result
841
+ expect(result).to eq(ExceptionHandling.last_exception_timestamp)
847
842
  end
848
843
 
849
- should "rescue exceptions that happen in log_error" do
850
- stub(ExceptionHandling).make_exception { raise ArgumentError, "Bad argument" }
851
- mock(ExceptionHandling).write_exception_to_log(satisfy { |ex| ex.to_s['Bad argument'] },
844
+ it "rescue exceptions that happen in log_error" do
845
+ allow(ExceptionHandling).to receive(:make_exception) { raise ArgumentError, "Bad argument" }
846
+ expect(ExceptionHandling).to receive(:write_exception_to_log).with(satisfy { |ex| ex.to_s['Bad argument'] },
852
847
  satisfy { |context| context['ExceptionHandlingError: log_error rescued exception while logging Runtime message'] },
853
848
  anything)
854
849
  ExceptionHandling.log_error(RuntimeError.new("A runtime error"), "Runtime message")
855
850
  end
856
851
 
857
- should "rescue exceptions that happen when log_error yields" do
858
- mock(ExceptionHandling).write_exception_to_log(satisfy { |ex| ex.to_s['Bad argument'] },
852
+ it "rescue exceptions that happen when log_error yields" do
853
+ expect(ExceptionHandling).to receive(:write_exception_to_log).with(satisfy { |ex| ex.to_s['Bad argument'] },
859
854
  satisfy { |context| context['Context message'] },
860
855
  anything,
861
856
  anything)
@@ -863,38 +858,38 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
863
858
  end
864
859
 
865
860
  context "Exception Filtering" do
866
- setup do
861
+ before do
867
862
  filter_list = { exception1: { 'error' => "my error message" },
868
863
  exception2: { 'error' => "some other message", :session => "misc data" } }
869
- stub(YAML).load_file { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
864
+ allow(YAML).to receive(:load_file) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
870
865
 
871
866
  # bump modified time up to get the above filter loaded
872
- stub(File).mtime { incrementing_mtime }
867
+ allow(File).to receive(:mtime) { incrementing_mtime }
873
868
  end
874
869
 
875
- should "handle case where filter list is not found" do
876
- stub(YAML).load_file { raise Errno::ENOENT, "File not found" }
870
+ it "handle case where filter list is not found" do
871
+ allow(YAML).to receive(:load_file) { raise Errno::ENOENT, "File not found" }
877
872
 
878
873
  capture_notifications
879
874
 
880
875
  ExceptionHandling.log_error("My error message is in list")
881
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
876
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
882
877
  end
883
878
 
884
- should "log exception and suppress email when exception is on filter list" do
879
+ it "log exception and suppress email when exception is on filter list" do
885
880
  capture_notifications
886
881
 
887
882
  ExceptionHandling.log_error("Error message is not in list")
888
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
883
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
889
884
 
890
885
  sent_notifications.clear
891
886
  ExceptionHandling.log_error("My error message is in list")
892
- assert_equal 0, sent_notifications.size, sent_notifications.inspect
887
+ expect(sent_notifications.size).to eq(0), sent_notifications.inspect
893
888
  end
894
889
 
895
- should "allow filtering exception on any text in exception data" do
890
+ it "allow filtering exception on any text in exception data" do
896
891
  filters = { exception1: { session: "data: my extra session data" } }
897
- stub(YAML).load_file { ActiveSupport::HashWithIndifferentAccess.new(filters) }
892
+ allow(YAML).to receive(:load_file) { ActiveSupport::HashWithIndifferentAccess.new(filters) }
898
893
 
899
894
  capture_notifications
900
895
 
@@ -904,7 +899,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
904
899
  data: "my extra session data"
905
900
  }
906
901
  end
907
- assert_equal 0, sent_notifications.size, sent_notifications.inspect
902
+ expect(sent_notifications.size).to eq(0), sent_notifications.inspect
908
903
 
909
904
  ExceptionHandling.log_error("No match here") do |data|
910
905
  data[:session] = {
@@ -912,86 +907,86 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
912
907
  data: "my extra session <no match!> data"
913
908
  }
914
909
  end
915
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
910
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
916
911
  end
917
912
 
918
- should "reload filter list on the next exception if file was modified" do
913
+ it "reload filter list on the next exception if file was modified" do
919
914
  capture_notifications
920
915
 
921
916
  ExceptionHandling.log_error("Error message is not in list")
922
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
917
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
923
918
 
924
919
  filter_list = { exception1: { 'error' => "Error message is not in list" } }
925
- stub(YAML).load_file { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
926
- stub(File).mtime { incrementing_mtime }
920
+ allow(YAML).to receive(:load_file) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
921
+ allow(File).to receive(:mtime) { incrementing_mtime }
927
922
 
928
923
  sent_notifications.clear
929
924
  ExceptionHandling.log_error("Error message is not in list")
930
- assert_equal 0, sent_notifications.size, sent_notifications.inspect
925
+ expect(sent_notifications.size).to eq(0), sent_notifications.inspect
931
926
  end
932
927
 
933
- should "not consider filter if both error message and body do not match" do
928
+ it "not consider filter if both error message and body do not match" do
934
929
  capture_notifications
935
930
 
936
931
  # error message matches, but not full text
937
932
  ExceptionHandling.log_error("some other message")
938
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
933
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
939
934
 
940
935
  # now both match
941
936
  sent_notifications.clear
942
937
  ExceptionHandling.log_error("some other message") do |data|
943
938
  data[:session] = { some_random_key: "misc data" }
944
939
  end
945
- assert_equal 0, sent_notifications.size, sent_notifications.inspect
940
+ expect(sent_notifications.size).to eq(0), sent_notifications.inspect
946
941
  end
947
942
 
948
- should "skip environment keys not on whitelist" do
943
+ it "skip environment keys not on whitelist" do
949
944
  capture_notifications
950
945
 
951
946
  ExceptionHandling.log_error("some message") do |data|
952
947
  data[:environment] = { SERVER_PROTOCOL: "HTTP/1.0", RAILS_SECRETS_YML_CONTENTS: 'password: VERY_SECRET_PASSWORD' }
953
948
  end
954
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
949
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
955
950
 
956
951
  mail = sent_notifications.last
957
952
  environment = mail.enhanced_data['environment']
958
953
 
959
- assert_nil environment["RAILS_SECRETS_YML_CONTENTS"], environment.inspect # this is not on whitelist
960
- assert environment["SERVER_PROTOCOL"], environment.inspect # this is
954
+ expect(environment["RAILS_SECRETS_YML_CONTENTS"]).to be_nil, environment.inspect # this is not on whitelist).to be_nil
955
+ expect(environment["SERVER_PROTOCOL"]).to be_truthy, environment.inspect # this is
961
956
  end
962
957
 
963
- should "omit environment defaults" do
958
+ it "omit environment defaults" do
964
959
  capture_notifications
965
960
 
966
- stub(ExceptionHandling).send_exception_to_honeybadger(anything) { |exception_info| sent_notifications << exception_info }
961
+ allow(ExceptionHandling).to receive(:send_exception_to_honeybadger).with(anything) { |exception_info| sent_notifications << exception_info }
967
962
 
968
963
  ExceptionHandling.log_error("some message") do |data|
969
964
  data[:environment] = { SERVER_PORT: '80', SERVER_PROTOCOL: "HTTP/1.0" }
970
965
  end
971
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
966
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
972
967
  mail = sent_notifications.last
973
968
  environment = mail.enhanced_data['environment']
974
969
 
975
- assert_nil environment["SERVER_PORT"], environment.inspect # this was default
976
- assert environment["SERVER_PROTOCOL"], environment # this was not
970
+ expect(environment["SERVER_PORT"]).to be_nil, environment.inspect # this was default).to be_nil
971
+ expect(environment["SERVER_PROTOCOL"]).to be_truthy, environment.inspect # this was not
977
972
  end
978
973
 
979
- should "reject the filter file if any contain all empty regexes" do
974
+ it "reject the filter file if any contain all empty regexes" do
980
975
  filter_list = { exception1: { 'error' => "", :session => "" },
981
976
  exception2: { 'error' => "is not in list", :session => "" } }
982
- stub(YAML).load_file { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
983
- stub(File).mtime { incrementing_mtime }
977
+ allow(YAML).to receive(:load_file) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }
978
+ allow(File).to receive(:mtime) { incrementing_mtime }
984
979
 
985
980
  capture_notifications
986
981
 
987
982
  ExceptionHandling.log_error("Error message is not in list")
988
- assert_equal 1, sent_notifications.size, sent_notifications.inspect
983
+ expect(sent_notifications.size).to eq(1), sent_notifications.inspect
989
984
  end
990
985
 
991
- should "reload filter file if filename changes" do
986
+ it "reload filter file if filename changes" do
992
987
  catalog = ExceptionHandling.exception_catalog
993
988
  ExceptionHandling.filter_list_filename = "./config/other_exception_filters.yml"
994
- assert_not_equal catalog, ExceptionHandling.exception_catalog
989
+ expect(ExceptionHandling.exception_catalog).to_not eq(catalog)
995
990
  end
996
991
 
997
992
  context "Exception Handling Mailer" do
@@ -1005,7 +1000,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1005
1000
 
1006
1001
  [[true, false], [true, true]].each do |em_flag, synchrony_flag|
1007
1002
  context "eventmachine_safe = #{em_flag} && eventmachine_synchrony = #{synchrony_flag}" do
1008
- setup do
1003
+ before do
1009
1004
  ExceptionHandling.eventmachine_safe = em_flag
1010
1005
  ExceptionHandling.eventmachine_synchrony = synchrony_flag
1011
1006
  EventMachineStub.block = nil
@@ -1015,61 +1010,60 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1015
1010
  set_test_const('EventMachine::DNS::Resolver', DNSResolvStub)
1016
1011
  end
1017
1012
 
1018
- teardown do
1013
+ after do
1019
1014
  ExceptionHandling.eventmachine_safe = false
1020
1015
  ExceptionHandling.eventmachine_synchrony = false
1021
1016
  end
1022
1017
 
1023
- should "schedule EventMachine STMP when EventMachine defined" do
1018
+ it "schedule EventMachine STMP when EventMachine defined" do
1024
1019
  ActionMailer::Base.deliveries.clear
1025
1020
 
1026
1021
  set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientStub)
1027
1022
 
1028
1023
  ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
1029
- assert EventMachineStub.block
1024
+ expect(EventMachineStub.block).to be_truthy
1030
1025
  EventMachineStub.block.call
1031
- assert DNSResolvStub.callback_block
1026
+ expect(DNSResolvStub.callback_block).to be_truthy
1032
1027
  DNSResolvStub.callback_block.call ['127.0.0.1']
1033
- assert_equal_with_diff EXPECTED_SMTP_HASH, (SmtpClientStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }, SmtpClientStub.send_hash.inspect
1034
- assert_equal((synchrony_flag ? :asend : :send), SmtpClientStub.last_method)
1035
- assert_match(/Exception to escalate/, SmtpClientStub.send_hash[:content])
1028
+ expect((SmtpClientStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }) .to eq(EXPECTED_SMTP_HASH), SmtpClientStub.send_hash.inspect
1029
+ expect(SmtpClientStub.last_method).to eq((synchrony_flag ? :asend : :send))
1030
+ expect(SmtpClientStub.send_hash[:content]).to match(/Exception to escalate/)
1036
1031
  assert_emails 0, ActionMailer::Base.deliveries.*.to_s
1037
1032
  end
1038
1033
 
1039
- should "pass the content as a proper rfc 2822 message" do
1034
+ it "pass the content as a proper rfc 2822 message" do
1040
1035
  set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientStub)
1041
1036
  ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
1042
- assert EventMachineStub.block
1037
+ expect(EventMachineStub.block).to be_truthy
1043
1038
  EventMachineStub.block.call
1044
- assert DNSResolvStub.callback_block
1039
+ expect(DNSResolvStub.callback_block).to be_truthy
1045
1040
  DNSResolvStub.callback_block.call ['127.0.0.1']
1046
- assert content = SmtpClientStub.send_hash[:content]
1047
- assert_match(/Content-Transfer-Encoding: 7bit/, content)
1048
- assert_match(/\r\n\.\r\n\z/, content)
1041
+ expect(content = SmtpClientStub.send_hash[:content]).to be_truthy
1042
+ expect(content).to match(/Content-Transfer-Encoding: 7bit/)
1043
+ expect(content).to match(/\r\n\.\r\n\z/)
1049
1044
  end
1050
1045
 
1051
- should "log fatal on EventMachine STMP errback" do
1046
+ it "log fatal on EventMachine STMP errback" do
1052
1047
  ActionMailer::Base.deliveries.clear
1053
1048
 
1054
1049
  set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientErrbackStub)
1055
- mock(ExceptionHandling.logger).fatal(/Exception to escalate/, anything)
1056
- mock(ExceptionHandling.logger).fatal(/Failed to email by SMTP: "credential mismatch"/)
1050
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/Exception to escalate/, anything)
1051
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to email by SMTP: "credential mismatch"/)
1057
1052
 
1058
1053
  ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
1059
- assert EventMachineStub.block
1054
+ expect(EventMachineStub.block).to be_truthy
1060
1055
  EventMachineStub.block.call
1061
- assert DNSResolvStub.callback_block
1056
+ expect(DNSResolvStub.callback_block).to be_truthy
1062
1057
  DNSResolvStub.callback_block.call(['127.0.0.1'])
1063
1058
  SmtpClientErrbackStub.block.call("credential mismatch")
1064
- assert_equal_with_diff EXPECTED_SMTP_HASH, (SmtpClientErrbackStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }, SmtpClientErrbackStub.send_hash.inspect
1065
- end
1059
+ expect((SmtpClientErrbackStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }).to eq(EXPECTED_SMTP_HASH), SmtpClientErrbackStub.send_hash.inspect end
1066
1060
 
1067
- should "log fatal on EventMachine dns resolver errback" do
1068
- mock(ExceptionHandling.logger).fatal(/Exception to escalate/, anything)
1069
- mock(ExceptionHandling.logger).fatal(/Failed to resolv DNS for localhost: "softlayer sucks"/)
1061
+ it "log fatal on EventMachine dns resolver errback" do
1062
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/Exception to escalate/, anything)
1063
+ expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to resolv DNS for localhost: "softlayer sucks"/)
1070
1064
 
1071
1065
  ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
1072
- assert EventMachineStub.block
1066
+ expect(EventMachineStub.block).to be_truthy
1073
1067
  EventMachineStub.block.call
1074
1068
  DNSResolvStub.errback_block.call("softlayer sucks")
1075
1069
  end
@@ -1079,7 +1073,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1079
1073
  end
1080
1074
 
1081
1075
  context "Exception mapping" do
1082
- setup do
1076
+ before do
1083
1077
  @data = {
1084
1078
  environment: {
1085
1079
  'HTTP_HOST' => "localhost",
@@ -1104,17 +1098,17 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1104
1098
  }
1105
1099
  end
1106
1100
 
1107
- should "clean backtraces" do
1101
+ it "clean backtraces" do
1108
1102
  begin
1109
1103
  raise "test exception"
1110
1104
  rescue => ex
1111
1105
  backtrace = ex.backtrace
1112
1106
  end
1113
1107
  result = ExceptionHandling.send(:clean_backtrace, ex).to_s
1114
- assert_not_equal result, backtrace
1108
+ expect(backtrace).to_not eq(result)
1115
1109
  end
1116
1110
 
1117
- should "return entire backtrace if cleaned is emtpy" do
1111
+ it "return entire backtrace if cleaned is emtpy" do
1118
1112
  begin
1119
1113
  backtrace = ["/Users/peter/ringrevenue/web/vendor/rails-3.2.12/activerecord/lib/active_record/relation/finder_methods.rb:312:in `find_with_ids'",
1120
1114
  "/Users/peter/ringrevenue/web/vendor/rails-3.2.12/activerecord/lib/active_record/relation/finder_methods.rb:107:in `find'",
@@ -1152,12 +1146,14 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1152
1146
  end
1153
1147
  end
1154
1148
 
1155
- mock(Rails).backtrace_cleaner { Rails::BacktraceCleaner.new }
1149
+ rails = double(Rails)
1150
+ expect(rails).to receive(:backtrace_cleaner) { Rails::BacktraceCleaner.new }
1151
+ rails.backtrace_cleaner
1156
1152
 
1157
1153
  ex = Exception.new
1158
1154
  ex.set_backtrace(backtrace)
1159
1155
  result = ExceptionHandling.send(:clean_backtrace, ex)
1160
- assert_equal backtrace, result
1156
+ expect(result).to eq(backtrace)
1161
1157
  ensure
1162
1158
  Object.send(:remove_const, :Rails)
1163
1159
  end
@@ -1165,40 +1161,63 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
1165
1161
  end
1166
1162
 
1167
1163
  context "log_perodically" do
1168
- setup do
1164
+ before do
1169
1165
  Time.now_override = Time.now # Freeze time
1170
1166
  ExceptionHandling.logger.clear
1171
1167
  end
1172
1168
 
1173
- teardown do
1169
+ after do
1174
1170
  Time.now_override = nil
1175
1171
  end
1176
1172
 
1177
- should "take in additional logging context and pass them to the logger" do
1173
+ it "take in additional logging context and pass them to the logger" do
1178
1174
  ExceptionHandling.log_periodically(:test_context_with_periodic, 30.minutes, "this will be written", service_name: 'exception_handling')
1179
- assert_not_empty logged_excluding_reload_filter.last[:context]
1180
- assert_equal({ service_name: 'exception_handling' }, logged_excluding_reload_filter.last[:context])
1175
+ expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
1176
+ expect(logged_excluding_reload_filter.last[:context]).to eq({ service_name: 'exception_handling' })
1181
1177
  end
1182
1178
 
1183
- should "log immediately when we are expected to log" do
1179
+ it "log immediately when we are expected to log" do
1184
1180
  ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will be written")
1185
- assert_equal 1, logged_excluding_reload_filter.size
1181
+ expect(logged_excluding_reload_filter.size).to eq(1)
1186
1182
 
1187
1183
  Time.now_override = Time.now + 5.minutes
1188
1184
  ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will not be written")
1189
- assert_equal 1, logged_excluding_reload_filter.size
1185
+ expect(logged_excluding_reload_filter.size).to eq(1)
1190
1186
 
1191
1187
  ExceptionHandling.log_periodically(:test_another_periodic_exception, 30.minutes, "this will be written")
1192
- assert_equal 2, logged_excluding_reload_filter.size
1188
+ expect(logged_excluding_reload_filter.size).to eq(2)
1193
1189
 
1194
1190
  Time.now_override = Time.now + 26.minutes
1195
1191
 
1196
1192
  ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will be written")
1197
- assert_equal 3, logged_excluding_reload_filter.size
1193
+ expect(logged_excluding_reload_filter.size).to eq(3)
1198
1194
  end
1199
1195
  end
1200
1196
  end
1201
1197
 
1198
+ context "ExceptionHandling < 3.0 " do
1199
+ it "should return a deprecation warning" do
1200
+ ExceptionHandling.production_support_recipients = "prodsupport@example.com"
1201
+ expect { ExceptionHandling.escalate_to_production_support("blah", "invoca@example.com") }
1202
+ .to output(/DEPRECATION WARNING: escalate_to_production_support is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
1203
+ end
1204
+
1205
+ it "should return a deprecation warning" do
1206
+ expect { ExceptionHandling.escalate_error("blah", "invoca@example.com") }
1207
+ .to output(/DEPRECATION WARNING: escalate_error is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
1208
+ end
1209
+
1210
+ it "should return a deprecation warning" do
1211
+ expect { ExceptionHandling.escalate_warning("blah", "invoca@example.com") }
1212
+ .to output(/DEPRECATION WARNING: escalate_warning is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
1213
+ end
1214
+
1215
+ it "should return a deprecation warning" do
1216
+ expect { ExceptionHandling.ensure_escalation("blah", "invoca@example.com") }
1217
+ .to output(/DEPRECATION WARNING: ensure_escalation is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
1218
+ end
1219
+ end
1220
+
1202
1221
  private
1203
1222
 
1204
1223
  def logged_excluding_reload_filter