exception_notification 4.3.0 → 4.5.0

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 (131) hide show
  1. checksums.yaml +5 -5
  2. data/Appraisals +4 -2
  3. data/CHANGELOG.rdoc +47 -0
  4. data/CONTRIBUTING.md +18 -0
  5. data/Gemfile +3 -1
  6. data/README.md +97 -945
  7. data/Rakefile +4 -2
  8. data/docs/notifiers/campfire.md +50 -0
  9. data/docs/notifiers/custom.md +42 -0
  10. data/docs/notifiers/datadog.md +51 -0
  11. data/docs/notifiers/email.md +195 -0
  12. data/docs/notifiers/google_chat.md +31 -0
  13. data/docs/notifiers/hipchat.md +66 -0
  14. data/docs/notifiers/irc.md +97 -0
  15. data/docs/notifiers/mattermost.md +115 -0
  16. data/docs/notifiers/slack.md +161 -0
  17. data/docs/notifiers/sns.md +37 -0
  18. data/docs/notifiers/teams.md +54 -0
  19. data/docs/notifiers/webhook.md +60 -0
  20. data/examples/sample_app.rb +56 -0
  21. data/examples/sinatra/Gemfile +8 -6
  22. data/examples/sinatra/config.ru +3 -1
  23. data/examples/sinatra/sinatra_app.rb +19 -11
  24. data/exception_notification.gemspec +30 -24
  25. data/gemfiles/{rails4_0.gemfile → rails5_2.gemfile} +2 -2
  26. data/gemfiles/{rails4_1.gemfile → rails6_0.gemfile} +2 -2
  27. data/gemfiles/{rails4_2.gemfile → rails6_1.gemfile} +2 -2
  28. data/gemfiles/{rails5_0.gemfile → rails7_0.gemfile} +2 -2
  29. data/lib/exception_notification/rack.rb +28 -30
  30. data/lib/exception_notification/rails.rb +2 -0
  31. data/lib/exception_notification/resque.rb +10 -10
  32. data/lib/exception_notification/sidekiq.rb +10 -12
  33. data/lib/exception_notification/version.rb +5 -0
  34. data/lib/exception_notification.rb +3 -0
  35. data/lib/exception_notifier/base_notifier.rb +10 -5
  36. data/lib/exception_notifier/datadog_notifier.rb +156 -0
  37. data/lib/exception_notifier/email_notifier.rb +73 -88
  38. data/lib/exception_notifier/google_chat_notifier.rb +27 -119
  39. data/lib/exception_notifier/hipchat_notifier.rb +13 -12
  40. data/lib/exception_notifier/irc_notifier.rb +36 -33
  41. data/lib/exception_notifier/mattermost_notifier.rb +54 -137
  42. data/lib/exception_notifier/modules/backtrace_cleaner.rb +2 -2
  43. data/lib/exception_notifier/modules/error_grouping.rb +24 -13
  44. data/lib/exception_notifier/modules/formatter.rb +125 -0
  45. data/lib/exception_notifier/notifier.rb +9 -6
  46. data/lib/exception_notifier/slack_notifier.rb +65 -40
  47. data/lib/exception_notifier/sns_notifier.rb +23 -13
  48. data/lib/exception_notifier/teams_notifier.rb +67 -46
  49. data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
  50. data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
  51. data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
  52. data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
  53. data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +2 -2
  54. data/lib/exception_notifier/webhook_notifier.rb +17 -14
  55. data/lib/exception_notifier.rb +65 -10
  56. data/lib/generators/exception_notification/install_generator.rb +11 -5
  57. data/lib/generators/exception_notification/templates/{exception_notification.rb → exception_notification.rb.erb} +13 -11
  58. data/test/exception_notification/rack_test.rb +75 -13
  59. data/test/exception_notification/resque_test.rb +54 -0
  60. data/test/exception_notifier/datadog_notifier_test.rb +153 -0
  61. data/test/exception_notifier/email_notifier_test.rb +275 -153
  62. data/test/exception_notifier/google_chat_notifier_test.rb +158 -101
  63. data/test/exception_notifier/hipchat_notifier_test.rb +84 -81
  64. data/test/exception_notifier/irc_notifier_test.rb +36 -34
  65. data/test/exception_notifier/mattermost_notifier_test.rb +213 -67
  66. data/test/exception_notifier/modules/error_grouping_test.rb +41 -40
  67. data/test/exception_notifier/modules/formatter_test.rb +152 -0
  68. data/test/exception_notifier/sidekiq_test.rb +9 -17
  69. data/test/exception_notifier/slack_notifier_test.rb +66 -63
  70. data/test/exception_notifier/sns_notifier_test.rb +84 -32
  71. data/test/exception_notifier/teams_notifier_test.rb +25 -26
  72. data/test/exception_notifier/webhook_notifier_test.rb +52 -48
  73. data/test/exception_notifier_test.rb +150 -41
  74. data/test/support/exception_notifier_helper.rb +14 -0
  75. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.html.erb +0 -0
  76. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.text.erb +0 -0
  77. data/test/{dummy/app → support}/views/exception_notifier/_new_section.html.erb +0 -0
  78. data/test/{dummy/app → support}/views/exception_notifier/_new_section.text.erb +0 -0
  79. data/test/test_helper.rb +14 -13
  80. metadata +134 -175
  81. data/gemfiles/rails5_1.gemfile +0 -7
  82. data/lib/exception_notifier/campfire_notifier.rb +0 -40
  83. data/test/dummy/.gitignore +0 -4
  84. data/test/dummy/Rakefile +0 -7
  85. data/test/dummy/app/controllers/application_controller.rb +0 -3
  86. data/test/dummy/app/controllers/posts_controller.rb +0 -30
  87. data/test/dummy/app/helpers/application_helper.rb +0 -2
  88. data/test/dummy/app/helpers/posts_helper.rb +0 -2
  89. data/test/dummy/app/models/post.rb +0 -2
  90. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  91. data/test/dummy/app/views/posts/_form.html.erb +0 -0
  92. data/test/dummy/app/views/posts/new.html.erb +0 -0
  93. data/test/dummy/app/views/posts/show.html.erb +0 -0
  94. data/test/dummy/config/application.rb +0 -42
  95. data/test/dummy/config/boot.rb +0 -6
  96. data/test/dummy/config/database.yml +0 -22
  97. data/test/dummy/config/environment.rb +0 -17
  98. data/test/dummy/config/environments/development.rb +0 -25
  99. data/test/dummy/config/environments/production.rb +0 -50
  100. data/test/dummy/config/environments/test.rb +0 -35
  101. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  102. data/test/dummy/config/initializers/inflections.rb +0 -10
  103. data/test/dummy/config/initializers/mime_types.rb +0 -5
  104. data/test/dummy/config/initializers/secret_token.rb +0 -8
  105. data/test/dummy/config/initializers/session_store.rb +0 -8
  106. data/test/dummy/config/locales/en.yml +0 -5
  107. data/test/dummy/config/routes.rb +0 -3
  108. data/test/dummy/config.ru +0 -4
  109. data/test/dummy/db/migrate/20110729022608_create_posts.rb +0 -15
  110. data/test/dummy/db/schema.rb +0 -24
  111. data/test/dummy/db/seeds.rb +0 -7
  112. data/test/dummy/lib/tasks/.gitkeep +0 -0
  113. data/test/dummy/public/404.html +0 -26
  114. data/test/dummy/public/422.html +0 -26
  115. data/test/dummy/public/500.html +0 -26
  116. data/test/dummy/public/favicon.ico +0 -0
  117. data/test/dummy/public/images/rails.png +0 -0
  118. data/test/dummy/public/index.html +0 -239
  119. data/test/dummy/public/javascripts/application.js +0 -2
  120. data/test/dummy/public/javascripts/controls.js +0 -965
  121. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  122. data/test/dummy/public/javascripts/effects.js +0 -1123
  123. data/test/dummy/public/javascripts/prototype.js +0 -6001
  124. data/test/dummy/public/javascripts/rails.js +0 -191
  125. data/test/dummy/public/robots.txt +0 -5
  126. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  127. data/test/dummy/public/stylesheets/scaffold.css +0 -56
  128. data/test/dummy/script/rails +0 -6
  129. data/test/dummy/test/functional/posts_controller_test.rb +0 -237
  130. data/test/dummy/test/test_helper.rb +0 -7
  131. data/test/exception_notifier/campfire_notifier_test.rb +0 -120
@@ -1,20 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'httparty'
3
5
 
4
6
  class TeamsNotifierTest < ActiveSupport::TestCase
5
-
6
- test "should send notification if properly configured" do
7
+ test 'should send notification if properly configured' do
7
8
  options = {
8
- :webhook_url => 'http://localhost:8000'
9
+ webhook_url: 'http://localhost:8000'
9
10
  }
10
11
  teams_notifier = ExceptionNotifier::TeamsNotifier.new
11
12
  teams_notifier.httparty = FakeHTTParty.new
12
13
 
13
- options = teams_notifier.call ArgumentError.new("foo"), options
14
+ options = teams_notifier.call ArgumentError.new('foo'), options
14
15
 
15
16
  body = ActiveSupport::JSON.decode options[:body]
16
- assert body.has_key? 'title'
17
- assert body.has_key? 'sections'
17
+ assert body.key? 'title'
18
+ assert body.key? 'sections'
18
19
 
19
20
  sections = body['sections']
20
21
  header = sections[0]
@@ -24,15 +25,15 @@ class TeamsNotifierTest < ActiveSupport::TestCase
24
25
  assert_equal 'foo', header['activitySubtitle']
25
26
  end
26
27
 
27
- test "should send notification with create gitlab issue link if specified" do
28
+ test 'should send notification with create gitlab issue link if specified' do
28
29
  options = {
29
- :webhook_url => 'http://localhost:8000',
30
- :git_url => 'github.com/aschen'
30
+ webhook_url: 'http://localhost:8000',
31
+ git_url: 'github.com/aschen'
31
32
  }
32
33
  teams_notifier = ExceptionNotifier::TeamsNotifier.new
33
34
  teams_notifier.httparty = FakeHTTParty.new
34
35
 
35
- options = teams_notifier.call ArgumentError.new("foo"), options
36
+ options = teams_notifier.call ArgumentError.new('foo'), options
36
37
 
37
38
  body = ActiveSupport::JSON.decode options[:body]
38
39
 
@@ -44,27 +45,27 @@ class TeamsNotifierTest < ActiveSupport::TestCase
44
45
 
45
46
  test 'should add other HTTParty options to params' do
46
47
  options = {
47
- :webhook_url => 'http://localhost:8000',
48
- :username => "Test Bot",
49
- :avatar => 'http://site.com/icon.png',
50
- :basic_auth => {
51
- :username => 'clara',
52
- :password => 'password'
48
+ webhook_url: 'http://localhost:8000',
49
+ username: 'Test Bot',
50
+ avatar: 'http://site.com/icon.png',
51
+ basic_auth: {
52
+ username: 'clara',
53
+ password: 'password'
53
54
  }
54
55
  }
55
56
  teams_notifier = ExceptionNotifier::TeamsNotifier.new
56
57
  teams_notifier.httparty = FakeHTTParty.new
57
58
 
58
- options = teams_notifier.call ArgumentError.new("foo"), options
59
+ options = teams_notifier.call ArgumentError.new('foo'), options
59
60
 
60
- assert options.has_key? :basic_auth
61
+ assert options.key? :basic_auth
61
62
  assert 'clara', options[:basic_auth][:username]
62
63
  assert 'password', options[:basic_auth][:password]
63
64
  end
64
65
 
65
66
  test "should use 'A' for exceptions count if :accumulated_errors_count option is nil" do
66
67
  teams_notifier = ExceptionNotifier::TeamsNotifier.new
67
- exception = ArgumentError.new("foo")
68
+ exception = ArgumentError.new('foo')
68
69
  teams_notifier.instance_variable_set(:@exception, exception)
69
70
  teams_notifier.instance_variable_set(:@options, {})
70
71
 
@@ -73,11 +74,11 @@ class TeamsNotifierTest < ActiveSupport::TestCase
73
74
  assert_equal 'A *ArgumentError* occurred.', header['activityTitle']
74
75
  end
75
76
 
76
- test "should use direct errors count if :accumulated_errors_count option is 5" do
77
+ test 'should use direct errors count if :accumulated_errors_count option is 5' do
77
78
  teams_notifier = ExceptionNotifier::TeamsNotifier.new
78
- exception = ArgumentError.new("foo")
79
+ exception = ArgumentError.new('foo')
79
80
  teams_notifier.instance_variable_set(:@exception, exception)
80
- teams_notifier.instance_variable_set(:@options, { accumulated_errors_count: 5 })
81
+ teams_notifier.instance_variable_set(:@options, accumulated_errors_count: 5)
81
82
  message_text = teams_notifier.send(:message_text)
82
83
  header = message_text['sections'][0]
83
84
  assert_equal '5 *ArgumentError* occurred.', header['activityTitle']
@@ -85,9 +86,7 @@ class TeamsNotifierTest < ActiveSupport::TestCase
85
86
  end
86
87
 
87
88
  class FakeHTTParty
88
-
89
- def post(url, options)
90
- return options
89
+ def post(_url, options)
90
+ options
91
91
  end
92
-
93
92
  end
@@ -1,43 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'httparty'
3
5
 
4
6
  class WebhookNotifierTest < ActiveSupport::TestCase
5
-
6
- test "should send webhook notification if properly configured" do
7
+ test 'should send webhook notification if properly configured' do
7
8
  ExceptionNotifier::WebhookNotifier.stubs(:new).returns(Object.new)
8
- webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
9
+ webhook = ExceptionNotifier::WebhookNotifier.new(url: 'http://localhost:8000')
9
10
  webhook.stubs(:call).returns(fake_response)
10
11
  response = webhook.call(fake_exception)
11
12
 
12
13
  refute_nil response
13
14
  assert_equal response[:status], 200
14
- assert_equal response[:body][:exception][:error_class], "ZeroDivisionError"
15
- assert_includes response[:body][:exception][:message], "divided by 0"
16
- assert_includes response[:body][:exception][:backtrace], "/exception_notification/test/webhook_notifier_test.rb:48"
15
+ assert_equal response[:body][:exception][:error_class], 'ZeroDivisionError'
16
+ assert_includes response[:body][:exception][:message], 'divided by 0'
17
+ assert_includes response[:body][:exception][:backtrace], '/exception_notification/test/webhook_notifier_test.rb:48'
17
18
 
18
- assert response[:body][:request][:cookies].has_key?(:cookie_item1)
19
- assert_equal response[:body][:request][:url], "http://example.com/example"
20
- assert_equal response[:body][:request][:ip_address], "192.168.1.1"
21
- assert response[:body][:request][:environment].has_key?(:env_item1)
22
- assert_equal response[:body][:request][:controller], "#<ControllerName:0x007f9642a04d00>"
23
- assert response[:body][:request][:session].has_key?(:session_item1)
24
- assert response[:body][:request][:parameters].has_key?(:controller)
25
- assert response[:body][:data][:extra_data].has_key?(:data_item1)
19
+ assert response[:body][:request][:cookies].key?(:cookie_item1)
20
+ assert_equal response[:body][:request][:url], 'http://example.com/example'
21
+ assert_equal response[:body][:request][:ip_address], '192.168.1.1'
22
+ assert response[:body][:request][:environment].key?(:env_item1)
23
+ assert_equal response[:body][:request][:controller], '#<ControllerName:0x007f9642a04d00>'
24
+ assert response[:body][:request][:session].key?(:session_item1)
25
+ assert response[:body][:request][:parameters].key?(:controller)
26
+ assert response[:body][:data][:extra_data].key?(:data_item1)
26
27
  end
27
28
 
28
- test "should send webhook notification with correct params data" do
29
+ test 'should send webhook notification with correct params data' do
29
30
  url = 'http://localhost:8000'
30
31
  fake_exception.stubs(:backtrace).returns('the backtrace')
31
- webhook = ExceptionNotifier::WebhookNotifier.new({:url => url})
32
+ webhook = ExceptionNotifier::WebhookNotifier.new(url: url)
32
33
 
33
34
  HTTParty.expects(:send).with(:post, url, fake_params)
34
35
 
35
36
  webhook.call(fake_exception)
36
37
  end
37
38
 
38
- test "should call pre/post_callback if specified" do
39
+ test 'should call pre/post_callback if specified' do
39
40
  HTTParty.stubs(:send).returns(fake_response)
40
- webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
41
+ webhook = ExceptionNotifier::WebhookNotifier.new(url: 'http://localhost:8000')
41
42
  webhook.call(fake_exception)
42
43
  end
43
44
 
@@ -45,50 +46,53 @@ class WebhookNotifierTest < ActiveSupport::TestCase
45
46
 
46
47
  def fake_response
47
48
  {
48
- :status => 200,
49
- :body => {
50
- :exception => {
51
- :error_class => 'ZeroDivisionError',
52
- :message => 'divided by 0',
53
- :backtrace => '/exception_notification/test/webhook_notifier_test.rb:48:in `/'
49
+ status: 200,
50
+ body: {
51
+ exception: {
52
+ error_class: 'ZeroDivisionError',
53
+ message: 'divided by 0',
54
+ backtrace: '/exception_notification/test/webhook_notifier_test.rb:48:in `/'
54
55
  },
55
- :data => {
56
- :extra_data => {:data_item1 => "datavalue1", :data_item2 => "datavalue2"}
56
+ data: {
57
+ extra_data: { data_item1: 'datavalue1', data_item2: 'datavalue2' }
57
58
  },
58
- :request => {
59
- :cookies => {:cookie_item1 => 'cookieitemvalue1', :cookie_item2 => 'cookieitemvalue2'},
60
- :url => 'http://example.com/example',
61
- :ip_address => '192.168.1.1',
62
- :environment => {:env_item1 => "envitem1", :env_item2 => "envitem2"},
63
- :controller => '#<ControllerName:0x007f9642a04d00>',
64
- :session => {:session_item1 => "sessionitem1", :session_item2 => "sessionitem2"},
65
- :parameters => {:action =>"index", :controller =>"projects"}
59
+ request: {
60
+ cookies: { cookie_item1: 'cookieitemvalue1', cookie_item2: 'cookieitemvalue2' },
61
+ url: 'http://example.com/example',
62
+ ip_address: '192.168.1.1',
63
+ environment: { env_item1: 'envitem1', env_item2: 'envitem2' },
64
+ controller: '#<ControllerName:0x007f9642a04d00>',
65
+ session: { session_item1: 'sessionitem1', session_item2: 'sessionitem2' },
66
+ parameters: { action: 'index', controller: 'projects' }
66
67
  }
67
68
  }
68
69
  }
69
70
  end
70
71
 
71
72
  def fake_params
72
- {
73
- :body => {
74
- :server => Socket.gethostname,
75
- :process => $$,
76
- :rails_root => Rails.root,
77
- :exception => {
78
- :error_class => 'ZeroDivisionError',
79
- :message => 'divided by 0'.inspect,
80
- :backtrace => 'the backtrace'
73
+ params = {
74
+ body: {
75
+ server: Socket.gethostname,
76
+ process: $PROCESS_ID,
77
+ exception: {
78
+ error_class: 'ZeroDivisionError',
79
+ message: 'divided by 0'.inspect,
80
+ backtrace: 'the backtrace'
81
81
  },
82
- :data => {}
82
+ data: {}
83
83
  }
84
84
  }
85
+
86
+ params[:body][:rails_root] = Rails.root if defined?(::Rails) && Rails.respond_to?(:root)
87
+
88
+ params
85
89
  end
86
90
 
87
91
  def fake_exception
88
92
  @fake_exception ||= begin
89
- 5/0
90
- rescue Exception => e
91
- e
92
- end
93
+ 5 / 0
94
+ rescue StandardError => e
95
+ e
96
+ end
93
97
  end
94
98
  end
@@ -1,44 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- class ExceptionOne < StandardError;end
4
- class ExceptionTwo < StandardError;end
5
+ class ExceptionOne < StandardError; end
6
+ class ExceptionTwo < StandardError; end
5
7
 
6
8
  class ExceptionNotifierTest < ActiveSupport::TestCase
7
9
  setup do
10
+ ExceptionNotifier.register_exception_notifier(:email, exception_recipients: %w[dummyexceptions@example.com])
11
+
8
12
  @notifier_calls = 0
9
- @test_notifier = lambda { |exception, options| @notifier_calls += 1 }
13
+ @test_notifier = ->(_exception, _options) { @notifier_calls += 1 }
10
14
  end
11
15
 
12
16
  teardown do
13
- ExceptionNotifier.error_grouping = false
14
- ExceptionNotifier.notification_trigger = nil
15
- ExceptionNotifier.class_eval("@@notifiers.delete_if { |k, _| k.to_s != \"email\"}") # reset notifiers
16
- Rails.cache.clear
17
+ ExceptionNotifier.reset_notifiers!
18
+
19
+ Rails.cache.clear if defined?(Rails) && Rails.respond_to?(:cache)
17
20
  end
18
21
 
19
- test "should have default ignored exceptions" do
22
+ test 'should have default ignored exceptions' do
20
23
  assert_equal ExceptionNotifier.ignored_exceptions,
21
- ['ActiveRecord::RecordNotFound', 'Mongoid::Errors::DocumentNotFound', 'AbstractController::ActionNotFound',
22
- 'ActionController::RoutingError', 'ActionController::UnknownFormat', 'ActionController::UrlGenerationError']
24
+ ['ActiveRecord::RecordNotFound', 'Mongoid::Errors::DocumentNotFound',
25
+ 'AbstractController::ActionNotFound', 'ActionController::RoutingError',
26
+ 'ActionController::UnknownFormat', 'ActionController::UrlGenerationError']
23
27
  end
24
28
 
25
- test "should have email notifier registered" do
29
+ test 'should have email notifier registered' do
26
30
  assert_equal ExceptionNotifier.notifiers, [:email]
27
31
  end
28
32
 
29
- test "should have a valid email notifier" do
33
+ test 'should have a valid email notifier' do
30
34
  @email_notifier = ExceptionNotifier.registered_exception_notifier(:email)
31
35
  refute_nil @email_notifier
32
36
  assert_equal @email_notifier.class, ExceptionNotifier::EmailNotifier
33
37
  assert_respond_to @email_notifier, :call
34
38
  end
35
39
 
36
- test "should allow register/unregister another notifier" do
40
+ test 'should allow register/unregister another notifier' do
37
41
  called = false
38
- proc_notifier = lambda { |exception, options| called = true }
42
+ proc_notifier = ->(_exception, _options) { called = true }
39
43
  ExceptionNotifier.register_exception_notifier(:proc, proc_notifier)
40
44
 
41
- assert_equal ExceptionNotifier.notifiers.sort, [:email, :proc]
45
+ assert_equal ExceptionNotifier.notifiers.sort, %i[email proc]
42
46
 
43
47
  exception = StandardError.new
44
48
 
@@ -49,27 +53,27 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
49
53
  assert_equal ExceptionNotifier.notifiers, [:email]
50
54
  end
51
55
 
52
- test "should allow select notifiers to send error to" do
56
+ test 'should allow select notifiers to send error to' do
53
57
  notifier1_calls = 0
54
- notifier1 = lambda { |exception, options| notifier1_calls += 1 }
58
+ notifier1 = ->(_exception, _options) { notifier1_calls += 1 }
55
59
  ExceptionNotifier.register_exception_notifier(:notifier1, notifier1)
56
60
 
57
61
  notifier2_calls = 0
58
- notifier2 = lambda { |exception, options| notifier2_calls += 1 }
62
+ notifier2 = ->(_exception, _options) { notifier2_calls += 1 }
59
63
  ExceptionNotifier.register_exception_notifier(:notifier2, notifier2)
60
64
 
61
- assert_equal ExceptionNotifier.notifiers.sort, [:email, :notifier1, :notifier2]
65
+ assert_equal ExceptionNotifier.notifiers.sort, %i[email notifier1 notifier2]
62
66
 
63
67
  exception = StandardError.new
64
68
  ExceptionNotifier.notify_exception(exception)
65
69
  assert_equal notifier1_calls, 1
66
70
  assert_equal notifier2_calls, 1
67
71
 
68
- ExceptionNotifier.notify_exception(exception, {:notifiers => :notifier1})
72
+ ExceptionNotifier.notify_exception(exception, notifiers: :notifier1)
69
73
  assert_equal notifier1_calls, 2
70
74
  assert_equal notifier2_calls, 1
71
75
 
72
- ExceptionNotifier.notify_exception(exception, {:notifiers => :notifier2})
76
+ ExceptionNotifier.notify_exception(exception, notifiers: :notifier2)
73
77
  assert_equal notifier1_calls, 2
74
78
  assert_equal notifier2_calls, 2
75
79
 
@@ -78,39 +82,112 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
78
82
  assert_equal ExceptionNotifier.notifiers, [:email]
79
83
  end
80
84
 
81
- test "should ignore exception if satisfies conditional ignore" do
82
- env = "production"
83
- ExceptionNotifier.ignore_if do |exception, options|
84
- env != "production"
85
+ test 'should ignore exception if satisfies conditional ignore' do
86
+ env = 'production'
87
+ ExceptionNotifier.ignore_if do |_exception, _options|
88
+ env != 'production'
85
89
  end
86
90
 
87
91
  ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
88
92
 
89
93
  exception = StandardError.new
90
94
 
91
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
95
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
92
96
  assert_equal @notifier_calls, 1
93
97
 
94
- env = "development"
95
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
98
+ env = 'development'
99
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
96
100
  assert_equal @notifier_calls, 1
101
+ end
102
+
103
+ test 'should ignore exception if satisfies by-notifier conditional ignore' do
104
+ notifier1_calls = 0
105
+ notifier1 = ->(_exception, _options) { notifier1_calls += 1 }
106
+ ExceptionNotifier.register_exception_notifier(:notifier1, notifier1)
107
+
108
+ notifier2_calls = 0
109
+ notifier2 = ->(_exception, _options) { notifier2_calls += 1 }
110
+ ExceptionNotifier.register_exception_notifier(:notifier2, notifier2)
111
+
112
+ env = 'production'
113
+ ExceptionNotifier.ignore_notifier_if(:notifier1) do |_exception, _options|
114
+ env == 'development'
115
+ end
116
+ ExceptionNotifier.ignore_notifier_if(:notifier2) do |_exception, _options|
117
+ env == 'production'
118
+ end
119
+
120
+ exception = StandardError.new
121
+
122
+ ExceptionNotifier.notify_exception(exception)
123
+ assert_equal notifier1_calls, 1
124
+ assert_equal notifier2_calls, 0
125
+
126
+ env = 'development'
127
+
128
+ ExceptionNotifier.notify_exception(exception)
129
+ assert_equal notifier1_calls, 1
130
+ assert_equal notifier2_calls, 1
131
+
132
+ env = 'test'
133
+
134
+ ExceptionNotifier.notify_exception(exception)
135
+ assert_equal notifier1_calls, 2
136
+ assert_equal notifier2_calls, 2
137
+ end
138
+
139
+ test 'should return false if all the registered notifiers are ignored' do
140
+ ExceptionNotifier.notifiers.each do |notifier|
141
+ # make sure to register no other notifiers but the tested ones
142
+ ExceptionNotifier.unregister_exception_notifier(notifier)
143
+ end
144
+
145
+ ExceptionNotifier.register_exception_notifier(:notifier1, ->(_, _) {})
146
+ ExceptionNotifier.register_exception_notifier(:notifier2, ->(_, _) {})
147
+
148
+ ExceptionNotifier.ignore_notifier_if(:notifier1) do |exception, _options|
149
+ exception.message =~ /non_critical_error/
150
+ end
151
+ ExceptionNotifier.ignore_notifier_if(:notifier2) do |exception, _options|
152
+ exception.message =~ /non_critical_error/
153
+ end
154
+
155
+ exception = StandardError.new('a non_critical_error occured.')
97
156
 
98
- ExceptionNotifier.clear_ignore_conditions!
157
+ refute ExceptionNotifier.notify_exception(exception)
99
158
  end
100
159
 
101
- test "should not send notification if one of ignored exceptions" do
160
+ test 'should return true if one of the notifiers fires' do
161
+ ExceptionNotifier.notifiers.each do |notifier|
162
+ # make sure to register no other notifiers but the tested ones
163
+ ExceptionNotifier.unregister_exception_notifier(notifier)
164
+ end
165
+
166
+ ExceptionNotifier.register_exception_notifier(:notifier1, ->(_, _) {})
167
+ ExceptionNotifier.register_exception_notifier(:notifier2, ->(_, _) {})
168
+
169
+ ExceptionNotifier.ignore_notifier_if(:notifier1) do |exception, _options|
170
+ exception.message =~ /non-critical\serror/
171
+ end
172
+
173
+ exception = StandardError.new('a non-critical error occured')
174
+
175
+ assert ExceptionNotifier.notify_exception(exception)
176
+ end
177
+
178
+ test 'should not send notification if one of ignored exceptions' do
102
179
  ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
103
180
 
104
181
  exception = StandardError.new
105
182
 
106
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
183
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
107
184
  assert_equal @notifier_calls, 1
108
185
 
109
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test, :ignore_exceptions => 'StandardError' })
186
+ ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: 'StandardError')
110
187
  assert_equal @notifier_calls, 1
111
188
  end
112
189
 
113
- test "should not send notification if subclass of one of ignored exceptions" do
190
+ test 'should not send notification if subclass of one of ignored exceptions' do
114
191
  ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
115
192
 
116
193
  class StandardErrorSubclass < StandardError
@@ -118,16 +195,48 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
118
195
 
119
196
  exception = StandardErrorSubclass.new
120
197
 
121
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
198
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
199
+ assert_equal @notifier_calls, 1
200
+
201
+ ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: 'StandardError')
202
+ assert_equal @notifier_calls, 1
203
+ end
204
+
205
+ test 'should not send notification if extended module one of ignored exceptions' do
206
+ ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
207
+
208
+ module StandardErrorModule; end
209
+
210
+ exception = StandardError.new
211
+ exception.extend StandardErrorModule
212
+
213
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
214
+ assert_equal @notifier_calls, 1
215
+
216
+ ignore_exceptions = 'ExceptionNotifierTest::StandardErrorModule'
217
+ ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: ignore_exceptions)
218
+ assert_equal @notifier_calls, 1
219
+ end
220
+
221
+ test 'should not send notification if prepended module at singleton class one of ignored exceptions' do
222
+ ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
223
+
224
+ module StandardErrorModule; end
225
+
226
+ exception = StandardError.new
227
+ exception.singleton_class.prepend StandardErrorModule
228
+
229
+ ExceptionNotifier.notify_exception(exception, notifiers: :test)
122
230
  assert_equal @notifier_calls, 1
123
231
 
124
- ExceptionNotifier.notify_exception(exception, {:notifiers => :test, :ignore_exceptions => 'StandardError' })
232
+ ignore_exceptions = 'ExceptionNotifierTest::StandardErrorModule'
233
+ ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: ignore_exceptions)
125
234
  assert_equal @notifier_calls, 1
126
235
  end
127
236
 
128
- test "should call received block" do
237
+ test 'should call received block' do
129
238
  @block_called = false
130
- notifier = lambda { |exception, options, &block| block.call }
239
+ notifier = ->(_exception, _options, &block) { block.call }
131
240
  ExceptionNotifier.register_exception_notifier(:test, notifier)
132
241
 
133
242
  exception = ExceptionOne.new
@@ -139,7 +248,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
139
248
  assert @block_called
140
249
  end
141
250
 
142
- test "should not call group_error! or send_notification? if error_grouping false" do
251
+ test 'should not call group_error! or send_notification? if error_grouping false' do
143
252
  exception = StandardError.new
144
253
  ExceptionNotifier.expects(:group_error!).never
145
254
  ExceptionNotifier.expects(:send_notification?).never
@@ -147,7 +256,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
147
256
  ExceptionNotifier.notify_exception(exception)
148
257
  end
149
258
 
150
- test "should call group_error! and send_notification? if error_grouping true" do
259
+ test 'should call group_error! and send_notification? if error_grouping true' do
151
260
  ExceptionNotifier.error_grouping = true
152
261
 
153
262
  exception = StandardError.new
@@ -157,7 +266,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
157
266
  ExceptionNotifier.notify_exception(exception)
158
267
  end
159
268
 
160
- test "should skip notification if send_notification? is false" do
269
+ test 'should skip notification if send_notification? is false' do
161
270
  ExceptionNotifier.error_grouping = true
162
271
 
163
272
  exception = StandardError.new
@@ -167,7 +276,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
167
276
  refute ExceptionNotifier.notify_exception(exception)
168
277
  end
169
278
 
170
- test "should send notification if send_notification? is true" do
279
+ test 'should send notification if send_notification? is true' do
171
280
  ExceptionNotifier.error_grouping = true
172
281
 
173
282
  exception = StandardError.new
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # this extension allows ExceptionNotifier to reset all the glocal settings
4
+ # (i.e. class vars that otherwise remains during the test)
5
+ # please remembeer to call this method each time after you set such settings
6
+ # to prevent order dependent test fails.
7
+ module ExceptionNotifier
8
+ def self.reset_notifiers!
9
+ @@notifiers = {}
10
+ clear_ignore_conditions!
11
+ ExceptionNotifier.error_grouping = false
12
+ ExceptionNotifier.notification_trigger = nil
13
+ end
14
+ end
data/test/test_helper.rb CHANGED
@@ -1,18 +1,19 @@
1
- # Configure Rails Environment
2
- ENV["RAILS_ENV"] = "test"
1
+ # frozen_string_literal: true
3
2
 
4
- begin
5
- require "coveralls"
6
- Coveralls.wear!
7
- rescue LoadError
8
- warn "warning: coveralls gem not found; skipping Coveralls"
9
- end
3
+ require 'coveralls'
4
+ Coveralls.wear!
10
5
 
11
- require File.expand_path("../dummy/config/environment.rb", __FILE__)
12
- require "rails/test_help"
13
- require File.expand_path("../dummy/test/test_helper.rb", __FILE__)
6
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
7
+ require 'exception_notification'
14
8
 
15
- require "mocha/setup"
9
+ require 'minitest/autorun'
10
+ require 'mocha/minitest'
11
+ require 'active_support/test_case'
12
+ require 'action_mailer'
16
13
 
17
- Rails.backtrace_cleaner.remove_silencers!
18
14
  ExceptionNotifier.testing_mode!
15
+ require 'support/exception_notifier_helper'
16
+
17
+ Time.zone = 'UTC'
18
+ ActionMailer::Base.delivery_method = :test
19
+ ActionMailer::Base.append_view_path "#{File.dirname(__FILE__)}/support/views"