smoke_detector 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +50 -0
  4. data/Rakefile +30 -0
  5. data/lib/smoke_detector.rb +37 -0
  6. data/lib/smoke_detector/controller_methods.rb +11 -0
  7. data/lib/smoke_detector/engine.rb +16 -0
  8. data/lib/smoke_detector/exceptions.rb +3 -0
  9. data/lib/smoke_detector/providers.rb +37 -0
  10. data/lib/smoke_detector/providers/airbrake.rb +30 -0
  11. data/lib/smoke_detector/providers/provider.rb +15 -0
  12. data/lib/smoke_detector/providers/rollbar.rb +41 -0
  13. data/lib/smoke_detector/version.rb +3 -0
  14. data/lib/tasks/smoke_detector_tasks.rake +4 -0
  15. data/spec/dummy/README.rdoc +261 -0
  16. data/spec/dummy/Rakefile +7 -0
  17. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  18. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  19. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  20. data/spec/dummy/app/controllers/widgets_controller.rb +26 -0
  21. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  22. data/spec/dummy/app/models/widget.rb +13 -0
  23. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/spec/dummy/app/views/widgets/index.html.erb +1 -0
  25. data/spec/dummy/config.ru +4 -0
  26. data/spec/dummy/config/application.rb +69 -0
  27. data/spec/dummy/config/boot.rb +10 -0
  28. data/spec/dummy/config/database.yml +25 -0
  29. data/spec/dummy/config/environment.rb +5 -0
  30. data/spec/dummy/config/environments/development.rb +37 -0
  31. data/spec/dummy/config/environments/production.rb +67 -0
  32. data/spec/dummy/config/environments/test.rb +37 -0
  33. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  34. data/spec/dummy/config/initializers/inflections.rb +15 -0
  35. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  36. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  37. data/spec/dummy/config/initializers/session_store.rb +8 -0
  38. data/spec/dummy/config/initializers/watch_tower.rb +24 -0
  39. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  40. data/spec/dummy/config/locales/en.yml +5 -0
  41. data/spec/dummy/config/routes.rb +6 -0
  42. data/spec/dummy/db/development.sqlite3 +0 -0
  43. data/spec/dummy/db/schema.rb +16 -0
  44. data/spec/dummy/db/test.sqlite3 +0 -0
  45. data/spec/dummy/log/development.log +8618 -0
  46. data/spec/dummy/log/test.log +11306 -0
  47. data/spec/dummy/public/404.html +26 -0
  48. data/spec/dummy/public/422.html +26 -0
  49. data/spec/dummy/public/500.html +25 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/script/rails +6 -0
  52. data/spec/dummy/tmp/cache/assets/C5F/270/sprockets%2F32a6d17723de2976b8456753922862fc +0 -0
  53. data/spec/dummy/tmp/cache/assets/CA3/870/sprockets%2F703bc6444d2a153516ad9804dc24b467 +0 -0
  54. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  55. data/spec/dummy/tmp/cache/assets/D2F/510/sprockets%2F42e50ab0277768533b1cad2237fb5ade +0 -0
  56. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  57. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  58. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  59. data/spec/dummy/tmp/cache/assets/DAE/CC0/sprockets%2Fcf340221edaaed61b5821abd28052dbb +0 -0
  60. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  61. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  62. data/spec/models/providers/airbrake_spec.rb +63 -0
  63. data/spec/models/providers/provider_spec.rb +22 -0
  64. data/spec/models/providers/rollbar_spec.rb +75 -0
  65. data/spec/models/providers_spec.rb +83 -0
  66. data/spec/models/smoke_detector_spec.rb +35 -0
  67. data/spec/requests/aibrake_config_spec.rb +11 -0
  68. data/spec/requests/multi_provider_config_spec.rb +16 -0
  69. data/spec/requests/rollbar_config_spec.rb +13 -0
  70. data/spec/spec_helper.rb +26 -0
  71. data/spec/support/shared_examples_for_providers.rb +63 -0
  72. metadata +326 -0
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/404.html -->
21
+ <div class="dialog">
22
+ <h1>The page you were looking for doesn't exist.</h1>
23
+ <p>You may have mistyped the address or the page may have moved.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmokeDetector::Providers::Airbrake do
4
+ let(:provider) { SmokeDetector::Providers::Airbrake.new('api_key', settings) }
5
+ let(:settings) { {} }
6
+ let(:err) { mock('error', backtrace: [], message: 'bad news') }
7
+ let(:data) { {custom: :data} }
8
+
9
+ describe '#alert' do
10
+ it 'notifies Airbrake of the exception' do
11
+ Airbrake.should_receive(:notify).with(err)
12
+ provider.alert(err)
13
+ end
14
+
15
+ context 'when passed a controller option' do
16
+ it 'ignores the option' do
17
+ Airbrake.should_receive(:notify).with(err)
18
+ provider.alert(err, controller: mock('controller'))
19
+ end
20
+ end
21
+
22
+ context 'when passed a data option' do
23
+ it 'includes the data in the Airbrake parameters' do
24
+ Airbrake.should_receive(:notify).with(err, parameters: data)
25
+ provider.alert(err, data: data)
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ describe '#message' do
32
+ let(:message) { 'hello airbrake' }
33
+
34
+ it 'notifies Airbrake of the message' do
35
+ Airbrake.should_receive(:notify).with(message)
36
+ provider.message(message)
37
+ end
38
+
39
+ context 'when passed options' do
40
+ it 'includes the options in the Airbrake parameters' do
41
+ Airbrake.should_receive(:notify).with(message, parameters: data)
42
+ provider.message(message, data: data)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe 'ControllerMethods' do
48
+ let(:controller) do
49
+ ActionController::Base.new.tap do |c|
50
+ c.class.send(:include, SmokeDetector::Providers::Airbrake::ControllerMethods)
51
+ c.stub(:rollbar_request_data)
52
+ c.stub(:rollbar_person_data)
53
+ end
54
+ end
55
+
56
+ describe '#alert_smoke_detector' do
57
+ it 'notifies Airbrake of the exception' do
58
+ controller.should_receive(:notify_airbrake)
59
+ controller.alert_smoke_detector(err)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmokeDetector::Providers::Provider do
4
+ let(:provider) { SmokeDetector::Providers::Provider.new }
5
+
6
+ describe '#alert' do
7
+ subject { provider.alert(Exception.new) }
8
+
9
+ it 'raises an error' do
10
+ expect { subject }.to raise_error NotImplementedError
11
+ end
12
+ end
13
+
14
+ describe '#message' do
15
+ subject { provider.message(Exception.new) }
16
+
17
+ it 'raises an error' do
18
+ expect { subject }.to raise_error NotImplementedError
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmokeDetector::Providers::Rollbar do
4
+ let(:provider) { SmokeDetector::Providers::Rollbar.new('api_key', settings) }
5
+ let(:settings) { {} }
6
+ let(:err) { StandardError.new('error') }
7
+ let(:data) { {custom: :data} }
8
+
9
+ describe '#alert' do
10
+ it 'reports the exception to Rollbar' do
11
+ Rollbar.should_receive(:report_exception).with(err)
12
+ provider.alert(err)
13
+ end
14
+
15
+ context 'when passed a data option' do
16
+ it 'includes the data in the exception message' do
17
+ err.message.should_receive(:<<).with(data.to_s)
18
+ provider.alert(err, data: data)
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ describe '#message' do
25
+ let(:message) { 'Hello Rollbar' }
26
+ let(:level) { 'info' }
27
+ let(:options) { {} }
28
+
29
+ it 'reports the message to Rollbar' do
30
+ Rollbar.should_receive(:report_message).with(message, level, options)
31
+ provider.message(message)
32
+ end
33
+
34
+ context 'when passed options' do
35
+ let(:options) { {custom: :data} }
36
+
37
+ it 'passes the options along as the data param' do
38
+ Rollbar.should_receive(:report_message).with(message, level, options)
39
+ provider.message(message, options)
40
+ end
41
+
42
+ context 'including the level' do
43
+ let(:level) { 'debug' }
44
+ let(:options) { {custom: :data, level: level} }
45
+
46
+ it 'sets the message level' do
47
+ Rollbar.should_receive(:report_message).with(message, level, options)
48
+ provider.message(message, options)
49
+ end
50
+
51
+ it 'does not include the level in the data param' do
52
+ Rollbar.should_receive(:report_message).with(message, level, options)
53
+ provider.message(message, options)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'ControllerMethods' do
60
+ let(:controller) do
61
+ ActionController::Base.new.tap do |c|
62
+ c.class.send(:include, SmokeDetector::Providers::Rollbar::ControllerMethods)
63
+ end
64
+ end
65
+
66
+ describe '#alert_smoke_detector' do
67
+ it 'notifies Rollbar of the exception' do
68
+ Rollbar.should_receive(:report_exception)
69
+ controller.should_receive(:rollbar_request_data)
70
+ controller.should_receive(:rollbar_person_data)
71
+ controller.alert_smoke_detector(err)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmokeDetector do
4
+ let(:provider) { :rollbar }
5
+ let(:api_key) { 'some_key' }
6
+ let(:provider_class) { SmokeDetector::Providers::Rollbar }
7
+
8
+ describe '.register_provider' do
9
+ context 'with a supported provider' do
10
+ context 'that is unregistered' do
11
+ before do
12
+ SmokeDetector.stub(:registered_provider?).with(provider).and_return(false)
13
+ end
14
+
15
+ it 'adds the provider to the SmokeDetector providers' do
16
+ SmokeDetector.register_provider(provider, api_key)
17
+ SmokeDetector.providers.last.should be_a provider_class
18
+ end
19
+ end
20
+
21
+ context 'that is registered' do
22
+ before do
23
+ SmokeDetector.stub(:registered_provider?).with(provider).and_return(true)
24
+ end
25
+
26
+ it 'raises an error' do
27
+ expect { SmokeDetector.register_provider(provider, api_key) }.to raise_error SmokeDetector::ProviderRegistrationError
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ context 'with an unsupported provider' do
34
+ let(:provider) { :not_a_provider }
35
+
36
+ it 'raises an error' do
37
+ expect { SmokeDetector.register_provider(provider, api_key) }.to raise_error SmokeDetector::ProviderRegistrationError
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.registered_provider?' do
43
+ subject { SmokeDetector.registered_provider?(provider) }
44
+
45
+ context "with a supported provider" do
46
+ context 'that is registered' do
47
+ before do
48
+ SmokeDetector.register_provider(provider, api_key)
49
+ end
50
+
51
+ it { should == true }
52
+ end
53
+
54
+ context 'that is unregistered' do
55
+ it { should == false }
56
+ end
57
+ end
58
+
59
+ context "with an unsupported provider" do
60
+ let(:provider) { :not_a_provider }
61
+
62
+ it 'raises an error' do
63
+ expect { subject }.to raise_error SmokeDetector::ProviderRegistrationError
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '.classify_provider' do
69
+ subject { SmokeDetector.classify_provider(provider) }
70
+
71
+ context "with a supported provider" do
72
+ it { should == provider_class }
73
+ end
74
+
75
+ context "with an unsupported provider" do
76
+ let(:provider) { :not_a_provider }
77
+
78
+ it 'raises an error' do
79
+ expect { subject }.to raise_error SmokeDetector::ProviderRegistrationError
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmokeDetector do
4
+ describe '.alert' do
5
+ let(:err) { Exception.new }
6
+
7
+ before do
8
+ SmokeDetector.register_provider(:airbrake, 'key')
9
+ SmokeDetector.register_provider(:rollbar, 'key')
10
+ SmokeDetector.providers.size.should > 1
11
+ end
12
+
13
+ context 'given an exception' do
14
+ it 'notifies the provider of the exception' do
15
+ SmokeDetector.providers.each do |provider|
16
+ provider.should_receive(:alert).once.with(err, {})
17
+ end
18
+ SmokeDetector.alert(err)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe '.message' do
24
+ context 'given a message' do
25
+ let(:message) { "holy crap!" }
26
+
27
+ it 'notifies the provider of the message' do
28
+ SmokeDetector.providers.each do |provider|
29
+ provider.should_receive(:message).once.with(message, {})
30
+ end
31
+ SmokeDetector.message(message)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Airbrake config: An exception' do
4
+
5
+ before do
6
+ SmokeDetector.instance_variable_set(:@providers, [])
7
+ SmokeDetector.register_provider(:airbrake, 'key')
8
+ end
9
+
10
+ it_behaves_like 'Airbrake integrated error handler'
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Multi-provider config: An exception' do
4
+
5
+ before do
6
+ SmokeDetector.instance_variable_set(:@providers, [])
7
+
8
+ SmokeDetector.register_provider(:rollbar, 'key')
9
+ SmokeDetector.register_provider(:airbrake, 'key')
10
+ SmokeDetector.providers.size.should == 2
11
+ end
12
+
13
+ it_behaves_like 'Rollbar integrated error handler'
14
+ it_behaves_like 'Airbrake integrated error handler'
15
+
16
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Rollbar config: An exception' do
4
+
5
+ before do
6
+ SmokeDetector.instance_variable_set(:@providers, [])
7
+
8
+ SmokeDetector.register_provider(:rollbar, 'key')
9
+ end
10
+
11
+ it_behaves_like 'Rollbar integrated error handler'
12
+
13
+ end
@@ -0,0 +1,26 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+
7
+ Rails.backtrace_cleaner.remove_silencers!
8
+
9
+ # Load support files
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+
12
+ RSpec.configure do |config|
13
+ config.mock_with :rspec
14
+ config.use_transactional_fixtures = true
15
+ config.infer_base_class_for_anonymous_controllers = false
16
+ config.order = "random"
17
+
18
+ config.before(:each) do
19
+ SmokeDetector.instance_variable_set(:@providers, [])
20
+
21
+ # sandbox services
22
+ Airbrake.stub(:send_notice)
23
+ Rollbar.stub(:schedule_payload)
24
+ end
25
+
26
+ end