exception_notification 4.3.0 → 4.4.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 +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.rdoc +14 -0
  4. data/CONTRIBUTING.md +18 -0
  5. data/Gemfile +1 -1
  6. data/README.md +64 -935
  7. data/Rakefile +2 -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 +54 -0
  21. data/examples/sinatra/Gemfile +6 -6
  22. data/examples/sinatra/config.ru +1 -1
  23. data/examples/sinatra/sinatra_app.rb +14 -10
  24. data/exception_notification.gemspec +27 -22
  25. data/gemfiles/rails4_0.gemfile +3 -3
  26. data/gemfiles/rails4_1.gemfile +3 -3
  27. data/gemfiles/rails4_2.gemfile +3 -3
  28. data/gemfiles/rails5_0.gemfile +3 -3
  29. data/gemfiles/rails5_1.gemfile +3 -3
  30. data/gemfiles/rails5_2.gemfile +7 -0
  31. data/gemfiles/rails6_0.gemfile +7 -0
  32. data/lib/exception_notification.rb +1 -0
  33. data/lib/exception_notification/rack.rb +8 -21
  34. data/lib/exception_notification/resque.rb +8 -10
  35. data/lib/exception_notification/sidekiq.rb +8 -12
  36. data/lib/exception_notification/version.rb +3 -0
  37. data/lib/exception_notifier.rb +20 -3
  38. data/lib/exception_notifier/base_notifier.rb +2 -3
  39. data/lib/exception_notifier/campfire_notifier.rb +12 -13
  40. data/lib/exception_notifier/datadog_notifier.rb +153 -0
  41. data/lib/exception_notifier/email_notifier.rb +64 -87
  42. data/lib/exception_notifier/google_chat_notifier.rb +25 -119
  43. data/lib/exception_notifier/hipchat_notifier.rb +11 -12
  44. data/lib/exception_notifier/irc_notifier.rb +32 -30
  45. data/lib/exception_notifier/mattermost_notifier.rb +47 -140
  46. data/lib/exception_notifier/modules/backtrace_cleaner.rb +0 -2
  47. data/lib/exception_notifier/modules/error_grouping.rb +5 -5
  48. data/lib/exception_notifier/modules/formatter.rb +118 -0
  49. data/lib/exception_notifier/notifier.rb +5 -6
  50. data/lib/exception_notifier/slack_notifier.rb +63 -40
  51. data/lib/exception_notifier/sns_notifier.rb +17 -11
  52. data/lib/exception_notifier/teams_notifier.rb +58 -44
  53. data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
  54. data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
  55. data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
  56. data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
  57. data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +2 -2
  58. data/lib/exception_notifier/webhook_notifier.rb +14 -11
  59. data/lib/generators/exception_notification/install_generator.rb +5 -5
  60. data/lib/generators/exception_notification/templates/{exception_notification.rb → exception_notification.rb.erb} +13 -11
  61. data/test/exception_notification/rack_test.rb +27 -11
  62. data/test/exception_notification/resque_test.rb +52 -0
  63. data/test/exception_notifier/campfire_notifier_test.rb +42 -42
  64. data/test/exception_notifier/datadog_notifier_test.rb +151 -0
  65. data/test/exception_notifier/email_notifier_test.rb +269 -153
  66. data/test/exception_notifier/google_chat_notifier_test.rb +154 -101
  67. data/test/exception_notifier/hipchat_notifier_test.rb +78 -81
  68. data/test/exception_notifier/irc_notifier_test.rb +34 -34
  69. data/test/exception_notifier/mattermost_notifier_test.rb +164 -67
  70. data/test/exception_notifier/modules/error_grouping_test.rb +39 -40
  71. data/test/exception_notifier/modules/formatter_test.rb +150 -0
  72. data/test/exception_notifier/sidekiq_test.rb +6 -6
  73. data/test/exception_notifier/slack_notifier_test.rb +61 -60
  74. data/test/exception_notifier/sns_notifier_test.rb +27 -32
  75. data/test/exception_notifier/teams_notifier_test.rb +23 -26
  76. data/test/exception_notifier/webhook_notifier_test.rb +48 -46
  77. data/test/exception_notifier_test.rb +41 -38
  78. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.html.erb +0 -0
  79. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.text.erb +0 -0
  80. data/test/{dummy/app → support}/views/exception_notifier/_new_section.html.erb +0 -0
  81. data/test/{dummy/app → support}/views/exception_notifier/_new_section.text.erb +0 -0
  82. data/test/test_helper.rb +11 -14
  83. metadata +136 -166
  84. data/test/dummy/.gitignore +0 -4
  85. data/test/dummy/Rakefile +0 -7
  86. data/test/dummy/app/controllers/application_controller.rb +0 -3
  87. data/test/dummy/app/controllers/posts_controller.rb +0 -30
  88. data/test/dummy/app/helpers/application_helper.rb +0 -2
  89. data/test/dummy/app/helpers/posts_helper.rb +0 -2
  90. data/test/dummy/app/models/post.rb +0 -2
  91. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  92. data/test/dummy/app/views/posts/_form.html.erb +0 -0
  93. data/test/dummy/app/views/posts/new.html.erb +0 -0
  94. data/test/dummy/app/views/posts/show.html.erb +0 -0
  95. data/test/dummy/config.ru +0 -4
  96. data/test/dummy/config/application.rb +0 -42
  97. data/test/dummy/config/boot.rb +0 -6
  98. data/test/dummy/config/database.yml +0 -22
  99. data/test/dummy/config/environment.rb +0 -17
  100. data/test/dummy/config/environments/development.rb +0 -25
  101. data/test/dummy/config/environments/production.rb +0 -50
  102. data/test/dummy/config/environments/test.rb +0 -35
  103. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  104. data/test/dummy/config/initializers/inflections.rb +0 -10
  105. data/test/dummy/config/initializers/mime_types.rb +0 -5
  106. data/test/dummy/config/initializers/secret_token.rb +0 -8
  107. data/test/dummy/config/initializers/session_store.rb +0 -8
  108. data/test/dummy/config/locales/en.yml +0 -5
  109. data/test/dummy/config/routes.rb +0 -3
  110. data/test/dummy/db/migrate/20110729022608_create_posts.rb +0 -15
  111. data/test/dummy/db/schema.rb +0 -24
  112. data/test/dummy/db/seeds.rb +0 -7
  113. data/test/dummy/lib/tasks/.gitkeep +0 -0
  114. data/test/dummy/public/404.html +0 -26
  115. data/test/dummy/public/422.html +0 -26
  116. data/test/dummy/public/500.html +0 -26
  117. data/test/dummy/public/favicon.ico +0 -0
  118. data/test/dummy/public/images/rails.png +0 -0
  119. data/test/dummy/public/index.html +0 -239
  120. data/test/dummy/public/javascripts/application.js +0 -2
  121. data/test/dummy/public/javascripts/controls.js +0 -965
  122. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  123. data/test/dummy/public/javascripts/effects.js +0 -1123
  124. data/test/dummy/public/javascripts/prototype.js +0 -6001
  125. data/test/dummy/public/javascripts/rails.js +0 -191
  126. data/test/dummy/public/robots.txt +0 -5
  127. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  128. data/test/dummy/public/stylesheets/scaffold.css +0 -56
  129. data/test/dummy/script/rails +0 -6
  130. data/test/dummy/test/functional/posts_controller_test.rb +0 -237
  131. data/test/dummy/test/test_helper.rb +0 -7
@@ -0,0 +1,150 @@
1
+ require 'test_helper'
2
+ require 'timecop'
3
+
4
+ class FormatterTest < ActiveSupport::TestCase
5
+ setup do
6
+ @exception = RuntimeError.new('test')
7
+ Timecop.freeze('2018-12-09 12:07:16 UTC')
8
+ end
9
+
10
+ teardown do
11
+ Timecop.return
12
+ end
13
+
14
+ #
15
+ # #title
16
+ #
17
+ test 'title returns correct content' do
18
+ formatter = ExceptionNotifier::Formatter.new(@exception)
19
+
20
+ title = if defined?(::Rails) && ::Rails.respond_to?(:env)
21
+ '⚠️ Error occurred in test ⚠️'
22
+ else
23
+ '⚠️ Error occurred ⚠️'
24
+ end
25
+
26
+ assert_equal title, formatter.title
27
+ end
28
+
29
+ #
30
+ # #subtitle
31
+ #
32
+ test 'subtitle without accumulated error' do
33
+ formatter = ExceptionNotifier::Formatter.new(@exception)
34
+ assert_equal 'A *RuntimeError* occurred.', formatter.subtitle
35
+ end
36
+
37
+ test 'subtitle with accumulated error' do
38
+ formatter = ExceptionNotifier::Formatter.new(@exception, accumulated_errors_count: 3)
39
+ assert_equal '3 *RuntimeError* occurred.', formatter.subtitle
40
+ end
41
+
42
+ test 'subtitle with controller' do
43
+ env = Rack::MockRequest.env_for(
44
+ '/', 'action_controller.instance' => test_controller
45
+ )
46
+
47
+ formatter = ExceptionNotifier::Formatter.new(@exception, env: env)
48
+ assert_equal 'A *RuntimeError* occurred in *home#index*.', formatter.subtitle
49
+ end
50
+
51
+ #
52
+ # #app_name
53
+ #
54
+ test 'app_name defaults to Rails app name' do
55
+ formatter = ExceptionNotifier::Formatter.new(@exception)
56
+
57
+ if defined?(::Rails) && ::Rails.respond_to?(:application)
58
+ assert_equal 'dummy', formatter.app_name
59
+ else
60
+ assert_nil formatter.app_name
61
+ end
62
+ end
63
+
64
+ test 'app_name can be overwritten using options' do
65
+ formatter = ExceptionNotifier::Formatter.new(@exception, app_name: 'test')
66
+ assert_equal 'test', formatter.app_name
67
+ end
68
+
69
+ #
70
+ # #request_message
71
+ #
72
+ test 'request_message when env set' do
73
+ text = [
74
+ '```',
75
+ '* url : http://test.address/?id=foo',
76
+ '* http_method : GET',
77
+ '* ip_address : 127.0.0.1',
78
+ '* parameters : {"id"=>"foo"}',
79
+ '* timestamp : 2018-12-09 12:07:16 UTC',
80
+ '```'
81
+ ].join("\n")
82
+
83
+ env = Rack::MockRequest.env_for(
84
+ '/',
85
+ 'HTTP_HOST' => 'test.address',
86
+ 'REMOTE_ADDR' => '127.0.0.1',
87
+ params: { id: 'foo' }
88
+ )
89
+
90
+ formatter = ExceptionNotifier::Formatter.new(@exception, env: env)
91
+ assert_equal text, formatter.request_message
92
+ end
93
+
94
+ test 'request_message when env not set' do
95
+ formatter = ExceptionNotifier::Formatter.new(@exception)
96
+ assert_nil formatter.request_message
97
+ end
98
+
99
+ #
100
+ # #backtrace_message
101
+ #
102
+ test 'backtrace_message when backtrace set' do
103
+ text = [
104
+ '```',
105
+ "* app/controllers/my_controller.rb:53:in `my_controller_params'",
106
+ "* app/controllers/my_controller.rb:34:in `update'",
107
+ '```'
108
+ ].join("\n")
109
+
110
+ @exception.set_backtrace([
111
+ "app/controllers/my_controller.rb:53:in `my_controller_params'",
112
+ "app/controllers/my_controller.rb:34:in `update'"
113
+ ])
114
+
115
+ formatter = ExceptionNotifier::Formatter.new(@exception)
116
+ assert_equal text, formatter.backtrace_message
117
+ end
118
+
119
+ test 'backtrace_message when no backtrace' do
120
+ formatter = ExceptionNotifier::Formatter.new(@exception)
121
+ assert_nil formatter.backtrace_message
122
+ end
123
+
124
+ #
125
+ # #controller_and_action
126
+ #
127
+ test 'correct controller_and_action if controller is present' do
128
+ env = Rack::MockRequest.env_for(
129
+ '/', 'action_controller.instance' => test_controller
130
+ )
131
+
132
+ formatter = ExceptionNotifier::Formatter.new(@exception, env: env)
133
+ assert_equal 'home#index', formatter.controller_and_action
134
+ end
135
+
136
+ test 'controller_and_action is nil if no controller' do
137
+ env = Rack::MockRequest.env_for('/')
138
+
139
+ formatter = ExceptionNotifier::Formatter.new(@exception, env: env)
140
+ assert_nil formatter.controller_and_action
141
+ end
142
+
143
+ def test_controller
144
+ controller = mock('controller')
145
+ controller.stubs(:action_name).returns('index')
146
+ controller.stubs(:controller_name).returns('home')
147
+
148
+ controller
149
+ end
150
+ end
@@ -1,11 +1,11 @@
1
- require "test_helper"
1
+ require 'test_helper'
2
2
 
3
3
  # To allow sidekiq error handlers to be registered, sidekiq must be in
4
4
  # "server mode". This mode is triggered by loading sidekiq/cli. Note this
5
5
  # has to be loaded before exception_notification/sidekiq.
6
- require "sidekiq/cli"
6
+ require 'sidekiq/cli'
7
7
 
8
- require "exception_notification/sidekiq"
8
+ require 'exception_notification/sidekiq'
9
9
 
10
10
  class MockSidekiqServer
11
11
  include ::Sidekiq::ExceptionHandler
@@ -19,14 +19,14 @@ class SidekiqTest < ActiveSupport::TestCase
19
19
  Sidekiq::Logging.logger = nil
20
20
  end
21
21
 
22
- test "should call notify_exception when sidekiq raises an error" do
22
+ test 'should call notify_exception when sidekiq raises an error' do
23
23
  server = MockSidekiqServer.new
24
- message = Hash.new
24
+ message = {}
25
25
  exception = RuntimeError.new
26
26
 
27
27
  ExceptionNotifier.expects(:notify_exception).with(
28
28
  exception,
29
- :data => { :sidekiq => message }
29
+ data: { sidekiq: message }
30
30
  )
31
31
 
32
32
  server.handle_exception(exception, message)
@@ -2,17 +2,17 @@ require 'test_helper'
2
2
  require 'slack-notifier'
3
3
 
4
4
  class SlackNotifierTest < ActiveSupport::TestCase
5
-
6
5
  def setup
7
6
  @exception = fake_exception
8
7
  @exception.stubs(:backtrace).returns(fake_backtrace)
9
8
  @exception.stubs(:message).returns('exception message')
9
+ ExceptionNotifier::SlackNotifier.any_instance.stubs(:clean_backtrace).returns(fake_cleaned_backtrace)
10
10
  Socket.stubs(:gethostname).returns('example.com')
11
11
  end
12
12
 
13
- test "should send a slack notification if properly configured" do
13
+ test 'should send a slack notification if properly configured' do
14
14
  options = {
15
- webhook_url: "http://slack.webhook.url"
15
+ webhook_url: 'http://slack.webhook.url'
16
16
  }
17
17
 
18
18
  Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
@@ -21,9 +21,9 @@ class SlackNotifierTest < ActiveSupport::TestCase
21
21
  slack_notifier.call(@exception)
22
22
  end
23
23
 
24
- test "should send a slack notification without backtrace info if properly configured" do
24
+ test 'should send a slack notification without backtrace info if properly configured' do
25
25
  options = {
26
- webhook_url: "http://slack.webhook.url"
26
+ webhook_url: 'http://slack.webhook.url'
27
27
  }
28
28
 
29
29
  Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(fake_exception_without_backtrace))
@@ -32,10 +32,10 @@ class SlackNotifierTest < ActiveSupport::TestCase
32
32
  slack_notifier.call(fake_exception_without_backtrace)
33
33
  end
34
34
 
35
- test "should send the notification to the specified channel" do
35
+ test 'should send the notification to the specified channel' do
36
36
  options = {
37
- webhook_url: "http://slack.webhook.url",
38
- channel: "channel"
37
+ webhook_url: 'http://slack.webhook.url',
38
+ channel: 'channel'
39
39
  }
40
40
 
41
41
  Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
@@ -47,10 +47,10 @@ class SlackNotifierTest < ActiveSupport::TestCase
47
47
  assert_equal channel, options[:channel]
48
48
  end
49
49
 
50
- test "should send the notification to the specified username" do
50
+ test 'should send the notification to the specified username' do
51
51
  options = {
52
- webhook_url: "http://slack.webhook.url",
53
- username: "username"
52
+ webhook_url: 'http://slack.webhook.url',
53
+ username: 'username'
54
54
  }
55
55
 
56
56
  Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
@@ -62,9 +62,9 @@ class SlackNotifierTest < ActiveSupport::TestCase
62
62
  assert_equal username, options[:username]
63
63
  end
64
64
 
65
- test "should send the notification with specific backtrace lines" do
65
+ test 'should send the notification with specific backtrace lines' do
66
66
  options = {
67
- webhook_url: "http://slack.webhook.url",
67
+ webhook_url: 'http://slack.webhook.url',
68
68
  backtrace_lines: 1
69
69
  }
70
70
 
@@ -74,10 +74,10 @@ class SlackNotifierTest < ActiveSupport::TestCase
74
74
  slack_notifier.call(@exception)
75
75
  end
76
76
 
77
- test "should send the notification with additional fields" do
78
- field = {title: "Branch", value: "master", short: true}
77
+ test 'should send the notification with additional fields' do
78
+ field = { title: 'Branch', value: 'master', short: true }
79
79
  options = {
80
- webhook_url: "http://slack.webhook.url",
80
+ webhook_url: 'http://slack.webhook.url',
81
81
  additional_fields: [field]
82
82
  }
83
83
 
@@ -90,17 +90,17 @@ class SlackNotifierTest < ActiveSupport::TestCase
90
90
  assert_equal additional_fields, options[:additional_fields]
91
91
  end
92
92
 
93
- test "should pass the additional parameters to Slack::Notifier.ping" do
93
+ test 'should pass the additional parameters to Slack::Notifier.ping' do
94
94
  options = {
95
- webhook_url: "http://slack.webhook.url",
96
- username: "test",
97
- custom_hook: "hook",
95
+ webhook_url: 'http://slack.webhook.url',
96
+ username: 'test',
97
+ custom_hook: 'hook',
98
98
  additional_parameters: {
99
- icon_url: "icon",
99
+ icon_url: 'icon'
100
100
  }
101
101
  }
102
102
 
103
- Slack::Notifier.any_instance.expects(:ping).with('', options[:additional_parameters].merge(fake_notification) )
103
+ Slack::Notifier.any_instance.expects(:ping).with('', options[:additional_parameters].merge(fake_notification))
104
104
 
105
105
  slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
106
106
  slack_notifier.call(@exception)
@@ -115,22 +115,22 @@ class SlackNotifierTest < ActiveSupport::TestCase
115
115
  assert_nil slack_notifier.call(@exception)
116
116
  end
117
117
 
118
- test "should pass along environment data" do
118
+ test 'should pass along environment data' do
119
119
  options = {
120
- webhook_url: "http://slack.webhook.url",
121
- ignore_data_if: lambda {|k,v|
122
- "#{k}" == 'key_to_be_ignored' || v.is_a?(Hash)
120
+ webhook_url: 'http://slack.webhook.url',
121
+ ignore_data_if: lambda { |k, v|
122
+ k.to_s == 'key_to_be_ignored' || v.is_a?(Hash)
123
123
  }
124
124
  }
125
125
 
126
126
  notification_options = {
127
127
  env: {
128
- 'exception_notifier.exception_data' => {foo: 'bar', john: 'doe'}
128
+ 'exception_notifier.exception_data' => { foo: 'bar', john: 'doe' }
129
129
  },
130
130
  data: {
131
131
  'user_id' => 5,
132
132
  'key_to_be_ignored' => 'whatever',
133
- 'ignore_as_well' => {what: 'ever'}
133
+ 'ignore_as_well' => { what: 'ever' }
134
134
  }
135
135
  }
136
136
 
@@ -141,29 +141,29 @@ class SlackNotifierTest < ActiveSupport::TestCase
141
141
  slack_notifier.call(@exception, notification_options)
142
142
  end
143
143
 
144
- test "should call pre/post_callback proc if specified" do
144
+ test 'should call pre/post_callback proc if specified' do
145
145
  post_callback_called = 0
146
146
  options = {
147
- webhook_url: "http://slack.webhook.url",
148
- username: "test",
149
- custom_hook: "hook",
150
- :pre_callback => proc { |opts, notifier, backtrace, message, message_opts|
151
- (message_opts[:attachments] = []) << { text: "#{backtrace.join("\n")}", color: 'danger' }
147
+ webhook_url: 'http://slack.webhook.url',
148
+ username: 'test',
149
+ custom_hook: 'hook',
150
+ pre_callback: proc { |_opts, _notifier, backtrace, _message, message_opts|
151
+ (message_opts[:attachments] = []) << { text: backtrace.join("\n").to_s, color: 'danger' }
152
152
  },
153
- :post_callback => proc { |opts, notifier, backtrace, message, message_opts|
153
+ post_callback: proc { |_opts, _notifier, _backtrace, _message, _message_opts|
154
154
  post_callback_called = 1
155
155
  },
156
156
  additional_parameters: {
157
- icon_url: "icon",
157
+ icon_url: 'icon'
158
158
  }
159
159
  }
160
160
 
161
161
  Slack::Notifier.any_instance.expects(:ping).with('',
162
- {:icon_url => 'icon',
163
- :attachments => [
164
- {:text => fake_backtrace.join("\n"),
165
- :color => 'danger'}
166
- ]})
162
+ icon_url: 'icon',
163
+ attachments: [{
164
+ text: fake_backtrace.join("\n"),
165
+ color: 'danger'
166
+ }])
167
167
 
168
168
  slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
169
169
  slack_notifier.call(@exception)
@@ -173,11 +173,9 @@ class SlackNotifierTest < ActiveSupport::TestCase
173
173
  private
174
174
 
175
175
  def fake_exception
176
- begin
177
- 5/0
178
- rescue Exception => e
179
- e
180
- end
176
+ 5 / 0
177
+ rescue StandardError => e
178
+ e
181
179
  end
182
180
 
183
181
  def fake_exception_without_backtrace
@@ -186,17 +184,21 @@ class SlackNotifierTest < ActiveSupport::TestCase
186
184
 
187
185
  def fake_backtrace
188
186
  [
189
- "backtrace line 1",
190
- "backtrace line 2",
191
- "backtrace line 3",
192
- "backtrace line 4",
193
- "backtrace line 5",
194
- "backtrace line 6",
187
+ 'backtrace line 1',
188
+ 'backtrace line 2',
189
+ 'backtrace line 3',
190
+ 'backtrace line 4',
191
+ 'backtrace line 5',
192
+ 'backtrace line 6'
195
193
  ]
196
194
  end
197
195
 
196
+ def fake_cleaned_backtrace
197
+ fake_backtrace[2..-1]
198
+ end
199
+
198
200
  def fake_notification(exception = @exception, notification_options = {}, data_string = nil, expected_backtrace_lines = 10, additional_fields = [])
199
- exception_name = "*#{exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A'}* `#{exception.class.to_s}`"
201
+ exception_name = "*#{exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A'}* `#{exception.class}`"
200
202
  if notification_options[:env].nil?
201
203
  text = "#{exception_name} *occured in background*"
202
204
  else
@@ -211,16 +213,15 @@ class SlackNotifierTest < ActiveSupport::TestCase
211
213
 
212
214
  text += "\n"
213
215
 
214
- fields = [ { title: 'Exception', value: exception.message} ]
215
- fields.push({ title: 'Hostname', value: 'example.com' })
216
+ fields = [{ title: 'Exception', value: exception.message }]
217
+ fields.push(title: 'Hostname', value: 'example.com')
216
218
  if exception.backtrace
217
- formatted_backtrace = "```#{exception.backtrace.first(expected_backtrace_lines).join("\n")}```"
218
- fields.push({ title: 'Backtrace', value: formatted_backtrace })
219
+ formatted_backtrace = "```#{fake_cleaned_backtrace.first(expected_backtrace_lines).join("\n")}```"
220
+ fields.push(title: 'Backtrace', value: formatted_backtrace)
219
221
  end
220
- fields.push({ title: 'Data', value: "```#{data_string}```" }) if data_string
222
+ fields.push(title: 'Data', value: "```#{data_string}```") if data_string
221
223
  additional_fields.each { |f| fields.push(f) }
222
224
 
223
- { attachments: [ color: 'danger', text: text, fields: fields, mrkdwn_in: %w(text fields) ] }
225
+ { attachments: [color: 'danger', text: text, fields: fields, mrkdwn_in: %w[text fields]] }
224
226
  end
225
-
226
227
  end
@@ -12,7 +12,7 @@ class SnsNotifierTest < ActiveSupport::TestCase
12
12
  secret_access_key: 'my-secret_access_key',
13
13
  region: 'us-east',
14
14
  topic_arn: 'topicARN',
15
- sns_prefix: '[App Exception]',
15
+ sns_prefix: '[App Exception]'
16
16
  }
17
17
  Socket.stubs(:gethostname).returns('example.com')
18
18
  end
@@ -60,53 +60,48 @@ class SnsNotifierTest < ActiveSupport::TestCase
60
60
 
61
61
  test 'should send a sns notification in background' do
62
62
  Aws::SNS::Client.any_instance.expects(:publish).with(
63
- {
64
- topic_arn: "topicARN",
63
+ topic_arn: 'topicARN',
65
64
  message: "3 MyException occured in background\n"\
66
- "Exception: undefined method 'method=' for Empty\n"\
67
- "Hostname: example.com\n"\
68
- "Backtrace:\n#{fake_backtrace.join("\n")}\n",
69
- subject: "[App Exception] - 3 MyException occurred"
70
- })
65
+ "Exception: undefined method 'method=' for Empty\n"\
66
+ "Hostname: example.com\n"\
67
+ "Backtrace:\n#{fake_backtrace.join("\n")}\n",
68
+ subject: '[App Exception] - 3 MyException occurred'
69
+ )
71
70
 
72
71
  sns_notifier = ExceptionNotifier::SnsNotifier.new(@options)
73
- sns_notifier.call(@exception, { accumulated_errors_count: 3 })
72
+ sns_notifier.call(@exception, accumulated_errors_count: 3)
74
73
  end
75
74
 
76
75
  test 'should send a sns notification with controller#action information' do
77
- ExamplesController.any_instance.stubs(:action_name).returns('index')
76
+ controller = mock('controller')
77
+ controller.stubs(:action_name).returns('index')
78
+ controller.stubs(:controller_name).returns('examples')
78
79
 
79
80
  Aws::SNS::Client.any_instance.expects(:publish).with(
80
- {
81
- topic_arn: "topicARN",
82
- message: "A MyException occurred while GET </examples> "\
83
- "was processed by examples#index\n"\
84
- "Exception: undefined method 'method=' for Empty\n"\
85
- "Hostname: example.com\n"\
86
- "Backtrace:\n#{fake_backtrace.join("\n")}\n",
87
- subject: "[App Exception] - A MyException occurred"
88
- })
81
+ topic_arn: 'topicARN',
82
+ message: 'A MyException occurred while GET </examples> '\
83
+ "was processed by examples#index\n"\
84
+ "Exception: undefined method 'method=' for Empty\n"\
85
+ "Hostname: example.com\n"\
86
+ "Backtrace:\n#{fake_backtrace.join("\n")}\n",
87
+ subject: '[App Exception] - A MyException occurred'
88
+ )
89
89
 
90
90
  sns_notifier = ExceptionNotifier::SnsNotifier.new(@options)
91
91
  sns_notifier.call(@exception,
92
- env: {
93
- 'REQUEST_METHOD' => 'GET',
94
- 'REQUEST_URI' => '/examples',
95
- 'action_controller.instance' => ExamplesController.new
96
- }
97
- )
92
+ env: {
93
+ 'REQUEST_METHOD' => 'GET',
94
+ 'REQUEST_URI' => '/examples',
95
+ 'action_controller.instance' => controller
96
+ })
98
97
  end
99
98
 
100
99
  private
101
100
 
102
- class ExamplesController < ActionController::Base; end
103
-
104
101
  def fake_exception
105
- begin
106
- 1 / 0
107
- rescue Exception => e
108
- e
109
- end
102
+ 1 / 0
103
+ rescue StandardError => e
104
+ e
110
105
  end
111
106
 
112
107
  def fake_exception_without_backtrace