exception_notification_more_info 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|