exception_notification_more_info 1.0.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.
- checksums.yaml +7 -0
- data/Appraisals +7 -0
- data/CHANGELOG.rdoc +141 -0
- data/CODE_OF_CONDUCT.md +22 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +839 -0
- data/Rakefile +23 -0
- data/examples/sinatra/Gemfile +8 -0
- data/examples/sinatra/Gemfile.lock +95 -0
- data/examples/sinatra/Procfile +2 -0
- data/examples/sinatra/README.md +11 -0
- data/examples/sinatra/config.ru +3 -0
- data/examples/sinatra/sinatra_app.rb +32 -0
- data/exception_notification_more_info.gemspec +34 -0
- data/gemfiles/rails4_0.gemfile +7 -0
- data/gemfiles/rails4_1.gemfile +7 -0
- data/gemfiles/rails4_2.gemfile +7 -0
- data/lib/exception_notification.rb +11 -0
- data/lib/exception_notification/rack.rb +59 -0
- data/lib/exception_notification/rails.rb +8 -0
- data/lib/exception_notification/resque.rb +24 -0
- data/lib/exception_notification/sidekiq.rb +31 -0
- data/lib/exception_notifier.rb +121 -0
- data/lib/exception_notifier/base_notifier.rb +25 -0
- data/lib/exception_notifier/campfire_notifier.rb +36 -0
- data/lib/exception_notifier/email_notifier.rb +204 -0
- data/lib/exception_notifier/hipchat_notifier.rb +45 -0
- data/lib/exception_notifier/irc_notifier.rb +51 -0
- data/lib/exception_notifier/modules/backtrace_cleaner.rb +13 -0
- data/lib/exception_notifier/notifier.rb +16 -0
- data/lib/exception_notifier/slack_notifier.rb +73 -0
- data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +3 -0
- data/lib/exception_notifier/views/exception_notifier/_backtrace.text.erb +1 -0
- data/lib/exception_notifier/views/exception_notifier/_data.html.erb +6 -0
- data/lib/exception_notifier/views/exception_notifier/_data.text.erb +1 -0
- data/lib/exception_notifier/views/exception_notifier/_environment.html.erb +10 -0
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +5 -0
- data/lib/exception_notifier/views/exception_notifier/_request.html.erb +36 -0
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +10 -0
- data/lib/exception_notifier/views/exception_notifier/_session.html.erb +10 -0
- data/lib/exception_notifier/views/exception_notifier/_session.text.erb +2 -0
- data/lib/exception_notifier/views/exception_notifier/_title.html.erb +3 -0
- data/lib/exception_notifier/views/exception_notifier/_title.text.erb +3 -0
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.html.erb +53 -0
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb +14 -0
- data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +54 -0
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +24 -0
- data/lib/exception_notifier/webhook_notifier.rb +47 -0
- data/lib/generators/exception_notification/install_generator.rb +15 -0
- data/lib/generators/exception_notification/templates/exception_notification.rb +53 -0
- data/test/dummy/.gitignore +4 -0
- data/test/dummy/Gemfile +34 -0
- data/test/dummy/Gemfile.lock +137 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/posts_controller.rb +30 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/posts_helper.rb +2 -0
- data/test/dummy/app/models/post.rb +2 -0
- data/test/dummy/app/views/exception_notifier/_new_bkg_section.html.erb +1 -0
- data/test/dummy/app/views/exception_notifier/_new_bkg_section.text.erb +1 -0
- data/test/dummy/app/views/exception_notifier/_new_section.html.erb +1 -0
- data/test/dummy/app/views/exception_notifier/_new_section.text.erb +1 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/posts/_form.html.erb +0 -0
- data/test/dummy/app/views/posts/new.html.erb +0 -0
- data/test/dummy/app/views/posts/show.html.erb +0 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +42 -0
- data/test/dummy/config/boot.rb +6 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +17 -0
- data/test/dummy/config/environments/development.rb +25 -0
- data/test/dummy/config/environments/production.rb +50 -0
- data/test/dummy/config/environments/test.rb +38 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +8 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/db/migrate/20110729022608_create_posts.rb +15 -0
- data/test/dummy/db/schema.rb +24 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/lib/tasks/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/images/rails.png +0 -0
- data/test/dummy/public/index.html +239 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/prototype.js +6001 -0
- data/test/dummy/public/javascripts/rails.js +191 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/public/stylesheets/scaffold.css +56 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/posts.yml +11 -0
- data/test/dummy/test/functional/posts_controller_test.rb +224 -0
- data/test/dummy/test/test_helper.rb +13 -0
- data/test/exception_notification/rack_test.rb +20 -0
- data/test/exception_notifier/campfire_notifier_test.rb +100 -0
- data/test/exception_notifier/email_notifier_test.rb +185 -0
- data/test/exception_notifier/hipchat_notifier_test.rb +177 -0
- data/test/exception_notifier/irc_notifier_test.rb +121 -0
- data/test/exception_notifier/sidekiq_test.rb +27 -0
- data/test/exception_notifier/slack_notifier_test.rb +179 -0
- data/test/exception_notifier/webhook_notifier_test.rb +68 -0
- data/test/exception_notifier_test.rb +103 -0
- data/test/test_helper.rb +18 -0
- metadata +428 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
|
2
|
+
require File.expand_path('../../config/environment', __FILE__)
|
|
3
|
+
require 'rails/test_help'
|
|
4
|
+
|
|
5
|
+
class ActiveSupport::TestCase
|
|
6
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
|
7
|
+
#
|
|
8
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
|
9
|
+
# -- they do not yet inherit this setting
|
|
10
|
+
fixtures :all
|
|
11
|
+
|
|
12
|
+
# Add more helper methods to be used by all tests here...
|
|
13
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class RackTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
setup do
|
|
6
|
+
@pass_app = Object.new
|
|
7
|
+
@pass_app.stubs(:call).returns([nil, { 'X-Cascade' => 'pass' }, nil])
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "should ignore \"X-Cascade\" header by default" do
|
|
11
|
+
ExceptionNotifier.expects(:notify_exception).never
|
|
12
|
+
ExceptionNotification::Rack.new(@pass_app).call({})
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "should notify on \"X-Cascade\" = \"pass\" if ignore_cascade_pass option is false" do
|
|
16
|
+
ExceptionNotifier.expects(:notify_exception).once
|
|
17
|
+
ExceptionNotification::Rack.new(@pass_app, :ignore_cascade_pass => false).call({})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'tinder'
|
|
3
|
+
|
|
4
|
+
class CampfireNotifierTest < ActiveSupport::TestCase
|
|
5
|
+
|
|
6
|
+
test "should send campfire notification if properly configured" do
|
|
7
|
+
ExceptionNotifier::CampfireNotifier.stubs(:new).returns(Object.new)
|
|
8
|
+
campfire = ExceptionNotifier::CampfireNotifier.new({:subdomain => 'test', :token => 'test_token', :room_name => 'test_room'})
|
|
9
|
+
campfire.stubs(:call).returns(fake_notification)
|
|
10
|
+
notif = campfire.call(fake_exception)
|
|
11
|
+
|
|
12
|
+
assert !notif[:message].empty?
|
|
13
|
+
assert_equal notif[:message][:type], 'PasteMessage'
|
|
14
|
+
assert_includes notif[:message][:body], "A new exception occurred:"
|
|
15
|
+
assert_includes notif[:message][:body], "divided by 0"
|
|
16
|
+
assert_includes notif[:message][:body], "/exception_notification/test/campfire_test.rb:45"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "should send campfire notification without backtrace info if properly configured" do
|
|
20
|
+
ExceptionNotifier::CampfireNotifier.stubs(:new).returns(Object.new)
|
|
21
|
+
campfire = ExceptionNotifier::CampfireNotifier.new({:subdomain => 'test', :token => 'test_token', :room_name => 'test_room'})
|
|
22
|
+
campfire.stubs(:call).returns(fake_notification_without_backtrace)
|
|
23
|
+
notif = campfire.call(fake_exception_without_backtrace)
|
|
24
|
+
|
|
25
|
+
assert !notif[:message].empty?
|
|
26
|
+
assert_equal notif[:message][:type], 'PasteMessage'
|
|
27
|
+
assert_includes notif[:message][:body], "A new exception occurred:"
|
|
28
|
+
assert_includes notif[:message][:body], "my custom error"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test "should not send campfire notification if badly configured" do
|
|
32
|
+
wrong_params = {:subdomain => 'test', :token => 'bad_token', :room_name => 'test_room'}
|
|
33
|
+
Tinder::Campfire.stubs(:new).with('test', {:token => 'bad_token'}).returns(nil)
|
|
34
|
+
campfire = ExceptionNotifier::CampfireNotifier.new(wrong_params)
|
|
35
|
+
|
|
36
|
+
assert_nil campfire.room
|
|
37
|
+
assert_nil campfire.call(fake_exception)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test "should not send campfire notification if config attr missing" do
|
|
41
|
+
wrong_params = {:subdomain => 'test', :room_name => 'test_room'}
|
|
42
|
+
Tinder::Campfire.stubs(:new).with('test', {}).returns(nil)
|
|
43
|
+
campfire = ExceptionNotifier::CampfireNotifier.new(wrong_params)
|
|
44
|
+
|
|
45
|
+
assert_nil campfire.room
|
|
46
|
+
assert_nil campfire.call(fake_exception)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "should call pre/post_callback if specified" do
|
|
50
|
+
pre_callback_called, post_callback_called = 0,0
|
|
51
|
+
Tinder::Campfire.stubs(:new).returns(Object.new)
|
|
52
|
+
|
|
53
|
+
campfire = ExceptionNotifier::CampfireNotifier.new(
|
|
54
|
+
{
|
|
55
|
+
:subdomain => 'test',
|
|
56
|
+
:token => 'test_token',
|
|
57
|
+
:room_name => 'test_room',
|
|
58
|
+
:pre_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
|
59
|
+
pre_callback_called += 1
|
|
60
|
+
},
|
|
61
|
+
:post_callback => proc { |opts, notifier, backtrace, message, message_opts|
|
|
62
|
+
post_callback_called += 1
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
campfire.room = Object.new
|
|
67
|
+
campfire.room.stubs(:paste).returns(fake_notification)
|
|
68
|
+
campfire.call(fake_exception)
|
|
69
|
+
assert_equal(1, pre_callback_called)
|
|
70
|
+
assert_equal(1, post_callback_called)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def fake_notification
|
|
76
|
+
{:message => {:type => 'PasteMessage',
|
|
77
|
+
:body => "A new exception occurred: 'divided by 0' on '/Users/sebastian/exception_notification/test/campfire_test.rb:45:in `/'"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def fake_exception
|
|
83
|
+
exception = begin
|
|
84
|
+
5/0
|
|
85
|
+
rescue Exception => e
|
|
86
|
+
e
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def fake_notification_without_backtrace
|
|
91
|
+
{:message => {:type => 'PasteMessage',
|
|
92
|
+
:body => "A new exception occurred: 'my custom error'"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def fake_exception_without_backtrace
|
|
98
|
+
StandardError.new('my custom error')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'action_mailer'
|
|
3
|
+
|
|
4
|
+
class EmailNotifierTest < ActiveSupport::TestCase
|
|
5
|
+
setup do
|
|
6
|
+
Time.stubs(:current).returns('Sat, 20 Apr 2013 20:58:55 UTC +00:00')
|
|
7
|
+
@email_notifier = ExceptionNotifier.registered_exception_notifier(:email)
|
|
8
|
+
begin
|
|
9
|
+
1/0
|
|
10
|
+
rescue => e
|
|
11
|
+
@exception = e
|
|
12
|
+
@mail = @email_notifier.create_email(@exception,
|
|
13
|
+
:data => {:job => 'DivideWorkerJob', :payload => '1/0', :message => 'My Custom Message'})
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "should call pre/post_callback if specified" do
|
|
18
|
+
assert_equal @email_notifier.options[:pre_callback_called], 1
|
|
19
|
+
assert_equal @email_notifier.options[:post_callback_called], 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test "should have default sender address overridden" do
|
|
23
|
+
assert_equal @email_notifier.sender_address, %("Dummy Notifier" <dummynotifier@example.com>)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "should have default exception recipients overridden" do
|
|
27
|
+
assert_equal @email_notifier.exception_recipients, %w(dummyexceptions@example.com)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test "should have default email prefix overridden" do
|
|
31
|
+
assert_equal @email_notifier.email_prefix, "[Dummy ERROR] "
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "should have default email headers overridden" do
|
|
35
|
+
assert_equal @email_notifier.email_headers, { "X-Custom-Header" => "foobar"}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "should have default sections overridden" do
|
|
39
|
+
for section in %w(new_section request session environment backtrace)
|
|
40
|
+
assert_includes @email_notifier.sections, section
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test "should have default background sections" do
|
|
45
|
+
for section in %w(new_bkg_section backtrace data)
|
|
46
|
+
assert_includes @email_notifier.background_sections, section
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test "should have email format by default" do
|
|
51
|
+
assert_equal @email_notifier.email_format, :text
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test "should have verbose subject by default" do
|
|
55
|
+
assert @email_notifier.verbose_subject
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test "should have normalize_subject false by default" do
|
|
59
|
+
refute @email_notifier.normalize_subject
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test "should have delivery_method nil by default" do
|
|
63
|
+
assert_nil @email_notifier.delivery_method
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test "should have mailer_settings nil by default" do
|
|
67
|
+
assert_nil @email_notifier.mailer_settings
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
test "should have mailer_parent by default" do
|
|
71
|
+
assert_equal @email_notifier.mailer_parent, 'ActionMailer::Base'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
test "should have template_path by default" do
|
|
75
|
+
assert_equal @email_notifier.template_path, 'exception_notifier'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
test "should normalize multiple digits into one N" do
|
|
79
|
+
assert_equal 'N foo N bar N baz N',
|
|
80
|
+
ExceptionNotifier::EmailNotifier.normalize_digits('1 foo 12 bar 123 baz 1234')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
test "mail should be plain text and UTF-8 enconded by default" do
|
|
84
|
+
assert_equal @mail.content_type, "text/plain; charset=UTF-8"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test "should have raised an exception" do
|
|
88
|
+
refute_nil @exception
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
test "should have generated a notification email" do
|
|
92
|
+
refute_nil @mail
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
test "mail should have a from address set" do
|
|
96
|
+
assert_equal @mail.from, ["dummynotifier@example.com"]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test "mail should have a to address set" do
|
|
100
|
+
assert_equal @mail.to, ["dummyexceptions@example.com"]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
test "mail should have a descriptive subject" do
|
|
104
|
+
assert_match /^\[Dummy ERROR\]\s+\(ZeroDivisionError\) "divided by 0"$/, @mail.subject
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test "mail should say exception was raised in background at show timestamp" do
|
|
108
|
+
assert_includes @mail.encoded, "A ZeroDivisionError occurred in background at #{Time.current}"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
test "mail should prefix exception class with 'an' instead of 'a' when it starts with a vowel" do
|
|
112
|
+
begin
|
|
113
|
+
raise ActiveRecord::RecordNotFound
|
|
114
|
+
rescue => e
|
|
115
|
+
@vowel_exception = e
|
|
116
|
+
@vowel_mail = @email_notifier.create_email(@vowel_exception)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
assert_includes @vowel_mail.encoded, "An ActiveRecord::RecordNotFound occurred in background at #{Time.current}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
test "mail should contain backtrace in body" do
|
|
123
|
+
assert @mail.encoded.include?("test/exception_notifier/email_notifier_test.rb:9"), "\n#{@mail.inspect}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test "mail should contain data in body" do
|
|
127
|
+
assert_includes @mail.encoded, '* data:'
|
|
128
|
+
assert_includes @mail.encoded, ':payload=>"1/0"'
|
|
129
|
+
assert_includes @mail.encoded, ':job=>"DivideWorkerJob"'
|
|
130
|
+
assert_includes @mail.encoded, "My Custom Message"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test "mail should not contain any attachments" do
|
|
134
|
+
assert_equal @mail.attachments, []
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
test "should not send notification if one of ignored exceptions" do
|
|
138
|
+
begin
|
|
139
|
+
raise ActiveRecord::RecordNotFound
|
|
140
|
+
rescue => e
|
|
141
|
+
@ignored_exception = e
|
|
142
|
+
unless ExceptionNotifier.ignored_exceptions.include?(@ignored_exception.class.name)
|
|
143
|
+
@ignored_mail = @email_notifier.create_email(@ignored_exception)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
assert_equal @ignored_exception.class.inspect, "ActiveRecord::RecordNotFound"
|
|
148
|
+
assert_nil @ignored_mail
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
test "should encode environment strings" do
|
|
152
|
+
email_notifier = ExceptionNotifier::EmailNotifier.new(
|
|
153
|
+
:sender_address => "<dummynotifier@example.com>",
|
|
154
|
+
:exception_recipients => %w{dummyexceptions@example.com},
|
|
155
|
+
:deliver_with => :deliver_now
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
mail = email_notifier.create_email(
|
|
159
|
+
@exception,
|
|
160
|
+
:env => {
|
|
161
|
+
"REQUEST_METHOD" => "GET",
|
|
162
|
+
"rack.input" => "",
|
|
163
|
+
"invalid_encoding" => "R\xC3\xA9sum\xC3\xA9".force_encoding(Encoding::ASCII),
|
|
164
|
+
},
|
|
165
|
+
:email_format => :text
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
assert_match /invalid_encoding\s+: R__sum__/, mail.encoded
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test "should send email using ActionMailer" do
|
|
172
|
+
ActionMailer::Base.deliveries.clear
|
|
173
|
+
|
|
174
|
+
email_notifier = ExceptionNotifier::EmailNotifier.new(
|
|
175
|
+
:email_prefix => '[Dummy ERROR] ',
|
|
176
|
+
:sender_address => %{"Dummy Notifier" <dummynotifier@example.com>},
|
|
177
|
+
:exception_recipients => %w{dummyexceptions@example.com},
|
|
178
|
+
:delivery_method => :test
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
email_notifier.call(@exception)
|
|
182
|
+
|
|
183
|
+
assert_equal 1, ActionMailer::Base.deliveries.count
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'hipchat'
|
|
3
|
+
|
|
4
|
+
class HipchatNotifierTest < ActiveSupport::TestCase
|
|
5
|
+
|
|
6
|
+
test "should send hipchat notification if properly configured" do
|
|
7
|
+
options = {
|
|
8
|
+
:api_token => 'good_token',
|
|
9
|
+
:room_name => 'room_name',
|
|
10
|
+
:color => 'yellow',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', fake_body, { :color => 'yellow' })
|
|
14
|
+
|
|
15
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
16
|
+
hipchat.call(fake_exception)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "should call pre/post_callback if specified" do
|
|
20
|
+
pre_callback_called, post_callback_called = 0,0
|
|
21
|
+
options = {
|
|
22
|
+
:api_token => 'good_token',
|
|
23
|
+
:room_name => 'room_name',
|
|
24
|
+
:color => 'yellow',
|
|
25
|
+
:pre_callback => proc { |*| pre_callback_called += 1},
|
|
26
|
+
:post_callback => proc { |*| post_callback_called += 1}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', fake_body, { :color => 'yellow' }.merge(options.except(:api_token, :room_name)))
|
|
30
|
+
|
|
31
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
32
|
+
hipchat.call(fake_exception)
|
|
33
|
+
assert_equal(1, pre_callback_called)
|
|
34
|
+
assert_equal(1, post_callback_called)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test "should send hipchat notification without backtrace info if properly configured" do
|
|
38
|
+
options = {
|
|
39
|
+
:api_token => 'good_token',
|
|
40
|
+
:room_name => 'room_name',
|
|
41
|
+
:color => 'yellow',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', fake_body_without_backtrace, { :color => 'yellow' })
|
|
45
|
+
|
|
46
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
47
|
+
hipchat.call(fake_exception_without_backtrace)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test "should allow custom from value if set" do
|
|
51
|
+
options = {
|
|
52
|
+
:api_token => 'good_token',
|
|
53
|
+
:room_name => 'room_name',
|
|
54
|
+
:from => 'TrollFace',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
HipChat::Room.any_instance.expects(:send).with('TrollFace', fake_body, { :color => 'red' })
|
|
58
|
+
|
|
59
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
60
|
+
hipchat.call(fake_exception)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test "should not send hipchat notification if badly configured" do
|
|
64
|
+
wrong_params = {
|
|
65
|
+
:api_token => 'bad_token',
|
|
66
|
+
:room_name => 'test_room'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
HipChat::Client.stubs(:new).with('bad_token', {:api_version => 'v1'}).returns(nil)
|
|
70
|
+
|
|
71
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
|
72
|
+
assert_nil hipchat.room
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test "should not send hipchat notification if api_key is missing" do
|
|
76
|
+
wrong_params = {:room_name => 'test_room'}
|
|
77
|
+
|
|
78
|
+
HipChat::Client.stubs(:new).with(nil, {:api_version => 'v1'}).returns(nil)
|
|
79
|
+
|
|
80
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
|
81
|
+
assert_nil hipchat.room
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
test "should not send hipchat notification if room_name is missing" do
|
|
85
|
+
wrong_params = {:api_token => 'good_token'}
|
|
86
|
+
|
|
87
|
+
HipChat::Client.stubs(:new).with('good_token', {:api_version => 'v1'}).returns({})
|
|
88
|
+
|
|
89
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
|
90
|
+
assert_nil hipchat.room
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
test "should send hipchat notification with message_template" do
|
|
94
|
+
options = {
|
|
95
|
+
:api_token => 'good_token',
|
|
96
|
+
:room_name => 'room_name',
|
|
97
|
+
:color => 'yellow',
|
|
98
|
+
:message_template => ->(exception) { "This is custom message: '#{exception.message}'" }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', "This is custom message: '#{fake_exception.message}'", { :color => 'yellow' })
|
|
102
|
+
|
|
103
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
104
|
+
hipchat.call(fake_exception)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test "should send hipchat notification with HTML-escaped meessage if using default message_template" do
|
|
108
|
+
options = {
|
|
109
|
+
:api_token => 'good_token',
|
|
110
|
+
:room_name => 'room_name',
|
|
111
|
+
:color => 'yellow',
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
exception = fake_exception_with_html_characters
|
|
115
|
+
body = "A new exception occurred: '#{Rack::Utils.escape_html(exception.message)}' on '#{exception.backtrace.first}'"
|
|
116
|
+
|
|
117
|
+
HipChat::Room.any_instance.expects(:send).with('Exception', body, { :color => 'yellow' })
|
|
118
|
+
|
|
119
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
120
|
+
hipchat.call(exception)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
test "should use APIv1 if api_version is not specified" do
|
|
124
|
+
options = {
|
|
125
|
+
:api_token => 'good_token',
|
|
126
|
+
:room_name => 'room_name',
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
HipChat::Client.stubs(:new).with('good_token', {:api_version => 'v1'}).returns({})
|
|
130
|
+
|
|
131
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
132
|
+
hipchat.call(fake_exception)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
test "should use APIv2 when specified" do
|
|
136
|
+
options = {
|
|
137
|
+
:api_token => 'good_token',
|
|
138
|
+
:room_name => 'room_name',
|
|
139
|
+
:api_version => 'v2',
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
HipChat::Client.stubs(:new).with('good_token', {:api_version => 'v2'}).returns({})
|
|
143
|
+
|
|
144
|
+
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
|
145
|
+
hipchat.call(fake_exception)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
private
|
|
149
|
+
|
|
150
|
+
def fake_body
|
|
151
|
+
"A new exception occurred: '#{fake_exception.message}' on '#{fake_exception.backtrace.first}'"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def fake_exception
|
|
155
|
+
exception = begin
|
|
156
|
+
5/0
|
|
157
|
+
rescue Exception => e
|
|
158
|
+
e
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def fake_exception_with_html_characters
|
|
163
|
+
exception = begin
|
|
164
|
+
raise StandardError.new('an error with <html> characters')
|
|
165
|
+
rescue Exception => e
|
|
166
|
+
e
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def fake_body_without_backtrace
|
|
171
|
+
"A new exception occurred: '#{fake_exception_without_backtrace.message}'"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def fake_exception_without_backtrace
|
|
175
|
+
StandardError.new('my custom error')
|
|
176
|
+
end
|
|
177
|
+
end
|