tartarus 1.0.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +104 -0
  5. data/README.rdoc +30 -4
  6. data/Rakefile +10 -28
  7. data/{generators → lib/generators}/tartarus/USAGE +4 -3
  8. data/lib/generators/tartarus/tartarus_generator.rb +36 -0
  9. data/{generators → lib/generators}/tartarus/templates/app/controllers/exceptions_controller.rb +0 -0
  10. data/{generators → lib/generators}/tartarus/templates/app/models/logged_exception.rb +0 -0
  11. data/{generators → lib/generators}/tartarus/templates/app/views/exceptions/_exception.html.erb +0 -0
  12. data/{generators → lib/generators}/tartarus/templates/app/views/exceptions/details.html.erb +0 -0
  13. data/{generators → lib/generators}/tartarus/templates/app/views/exceptions/index.html.erb +0 -0
  14. data/{generators → lib/generators}/tartarus/templates/config/exceptions.yml +0 -0
  15. data/{generators → lib/generators}/tartarus/templates/db/migrate/add_logged_exceptions.rb +0 -0
  16. data/{generators → lib/generators}/tartarus/templates/public/javascripts/tartarus.jquery.js +0 -0
  17. data/{generators → lib/generators}/tartarus/templates/public/stylesheets/tartarus.css +0 -0
  18. data/{generators → lib/generators}/tartarus/templates/spec/controllers/exceptions_controller_spec.rb +1 -1
  19. data/{generators → lib/generators}/tartarus/templates/spec/models/logged_exception_spec.rb +0 -0
  20. data/lib/tartarus.rb +7 -3
  21. data/lib/tartarus/logger.rb +50 -14
  22. data/lib/tartarus/notifiers/mail.rb +25 -0
  23. data/lib/tartarus/rack.rb +23 -0
  24. data/lib/tartarus/railtie.rb +9 -0
  25. data/lib/tartarus/version.rb +3 -0
  26. data/spec/rails_app/.gitignore +4 -0
  27. data/spec/rails_app/.rspec +1 -0
  28. data/spec/rails_app/Gemfile +13 -0
  29. data/spec/rails_app/Gemfile.lock +99 -0
  30. data/spec/rails_app/README +256 -0
  31. data/spec/rails_app/Rakefile +7 -0
  32. data/spec/rails_app/app/controllers/application_controller.rb +3 -0
  33. data/spec/rails_app/app/controllers/logged_exceptions_controller.rb +31 -0
  34. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  35. data/spec/{rails → rails_app}/app/models/logged_exception.rb +2 -1
  36. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  37. data/spec/rails_app/app/views/logged_exceptions/_exception.html.erb +14 -0
  38. data/spec/rails_app/app/views/logged_exceptions/details.html.erb +86 -0
  39. data/spec/rails_app/app/views/logged_exceptions/index.html.erb +28 -0
  40. data/spec/rails_app/config.ru +4 -0
  41. data/spec/rails_app/config/application.rb +42 -0
  42. data/spec/rails_app/config/boot.rb +13 -0
  43. data/spec/rails_app/config/database.yml +22 -0
  44. data/spec/rails_app/config/environment.rb +5 -0
  45. data/spec/rails_app/config/environments/development.rb +26 -0
  46. data/spec/rails_app/config/environments/production.rb +49 -0
  47. data/spec/rails_app/config/environments/test.rb +35 -0
  48. data/spec/rails_app/config/exceptions.yml +18 -0
  49. data/spec/{rails → rails_app}/config/initializers/backtrace_silencers.rb +2 -2
  50. data/spec/{rails → rails_app}/config/initializers/inflections.rb +1 -1
  51. data/spec/{rails → rails_app}/config/initializers/mime_types.rb +0 -0
  52. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  53. data/spec/rails_app/config/initializers/session_store.rb +8 -0
  54. data/spec/{rails → rails_app}/config/locales/en.yml +1 -1
  55. data/spec/rails_app/config/routes.rb +58 -0
  56. data/spec/rails_app/db/migrate/20101230191040_add_logged_exception_table.rb +19 -0
  57. data/spec/rails_app/db/schema.rb +28 -0
  58. data/spec/rails_app/db/seeds.rb +7 -0
  59. data/spec/rails_app/doc/README_FOR_APP +2 -0
  60. data/spec/rails_app/lib/tasks/.gitkeep +0 -0
  61. data/spec/rails_app/public/404.html +26 -0
  62. data/spec/rails_app/public/422.html +26 -0
  63. data/spec/rails_app/public/500.html +26 -0
  64. data/spec/rails_app/public/favicon.ico +0 -0
  65. data/spec/rails_app/public/images/rails.png +0 -0
  66. data/spec/rails_app/public/javascripts/application.js +2 -0
  67. data/spec/rails_app/public/javascripts/controls.js +965 -0
  68. data/spec/rails_app/public/javascripts/dragdrop.js +974 -0
  69. data/spec/rails_app/public/javascripts/effects.js +1123 -0
  70. data/spec/rails_app/public/javascripts/prototype.js +6001 -0
  71. data/spec/rails_app/public/javascripts/rails.js +175 -0
  72. data/spec/rails_app/public/javascripts/tartarus.jquery.js +8 -0
  73. data/spec/rails_app/public/robots.txt +5 -0
  74. data/spec/rails_app/public/stylesheets/.gitkeep +0 -0
  75. data/spec/rails_app/public/stylesheets/tartarus.css +26 -0
  76. data/spec/rails_app/script/rails +6 -0
  77. data/spec/rails_app/spec/controllers/logged_exceptions_controller_spec.rb +83 -0
  78. data/spec/rails_app/spec/models/logged_exception_spec.rb +7 -0
  79. data/spec/rails_app/spec/spec_helper.rb +27 -0
  80. data/spec/rails_app/vendor/plugins/.gitkeep +0 -0
  81. data/spec/spec_helper.rb +14 -7
  82. data/spec/tartarus/logger_spec.rb +51 -23
  83. data/spec/tartarus_spec.rb +5 -8
  84. data/tartarus.gemspec +11 -103
  85. metadata +148 -94
  86. data/VERSION +0 -1
  87. data/generators/tartarus/tartarus_generator.rb +0 -50
  88. data/lib/tartarus/notifier.rb +0 -11
  89. data/lib/tartarus/rescue.rb +0 -39
  90. data/rails/init.rb +0 -3
  91. data/spec/rails/app/controllers/application_controller.rb +0 -10
  92. data/spec/rails/config/boot.rb +0 -110
  93. data/spec/rails/config/database.yml +0 -5
  94. data/spec/rails/config/environment.rb +0 -41
  95. data/spec/rails/config/environments/development.rb +0 -17
  96. data/spec/rails/config/environments/production.rb +0 -28
  97. data/spec/rails/config/environments/test.rb +0 -28
  98. data/spec/rails/config/exceptions.yml +0 -9
  99. data/spec/rails/config/initializers/new_rails_defaults.rb +0 -21
  100. data/spec/rails/config/initializers/session_store.rb +0 -15
  101. data/spec/rails/config/routes.rb +0 -43
  102. data/spec/rails/db/test.sqlite3 +0 -0
  103. data/spec/rcov.opts +0 -3
  104. data/spec/spec.opts +0 -4
  105. data/spec/tartarus/rescue_spec.rb +0 -86
  106. data/views/tartarus_notifier/notification.html.erb +0 -9
@@ -0,0 +1,175 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+ })();
@@ -0,0 +1,8 @@
1
+ (function($) {
2
+ $(function() {
3
+ $('.togglable').each(function() {
4
+ var toggle_data = $(this).find('.toggle_data');
5
+ $(this).find('.toggle_link').click(function() { toggle_data.toggle(); })
6
+ });
7
+ });
8
+ })(jQuery);
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
File without changes
@@ -0,0 +1,26 @@
1
+ #tartarus { margin: 0px 20px }
2
+
3
+ #tartarus_cap { padding-bottom: 10px; border-bottom: 1px solid #777; margin: 20px 0px; }
4
+ #tartarus h2 { margin: 10px 0px; }
5
+
6
+ #tartarus_nav { float: right }
7
+ .tartarus_pagination { margin-top: 20px; }
8
+
9
+ #tartarus table { border-collapse: collapse; width: 100%; }
10
+ #tartarus table tr { border-bottom: 1px solid #E0DFE0; }
11
+ #tartarus table th, #tartarus table td { padding: 5px; }
12
+ #tartarus table th { text-align: left; }
13
+
14
+ #tartarus th#exception_location { width: 150px; }
15
+ #tartarus th#exception_date { width: 150px; }
16
+ #tartarus th#exception_count { text-align: center; }
17
+
18
+ #tartarus pre { -webkit-border-radius: 5px; -moz-border-radius: 5px; font-size: 10px; color: #fff; background-color: #222; padding: 10px; font-family: Consolas, Monaco, 'Courier New', Courier,monospace; }
19
+ #tartarus a, #tartarus a:visited { text-decoration: underline; #bdf; }
20
+ #tartarus a:hover { #09f }
21
+
22
+ #tartarus #exception { clear: both; }
23
+ #tartarus #exception_actions { float: right; }
24
+
25
+ #tartarus .toggle_data { display: none }
26
+ #tartarus #backtrace_information .toggle_data { display: block; }
@@ -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,83 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe LoggedExceptionsController do
4
+ before(:each) do
5
+ @exception = LoggedException.new
6
+ end
7
+
8
+ describe "#index" do
9
+ it 'should set an assigns of exceptions with the collection of all exception groups' do
10
+ LoggedException.should_receive(:all).with(:select => '*, COUNT(*) as count', :group => 'group_id', :order => 'created_at DESC').and_return([@exception])
11
+
12
+ get :index
13
+ assigns[:exceptions].should == [@exception]
14
+ end
15
+ end
16
+
17
+ describe "#details" do
18
+ before(:each) do
19
+ @exception2 = LoggedException.new
20
+ LoggedException.stub!(:paginate).and_return([@exception, @exception2])
21
+ end
22
+
23
+ it 'should set an assigns of exceptions with a paginated collection' do
24
+ LoggedException.should_receive(:paginate).with(:all, :conditions => { :group_id => '89hasd98ashdasas98dhsda' },
25
+ :order => 'created_at DESC', :page => '1', :per_page => 1).and_return([@exception, @exception2])
26
+
27
+ get :details, :id => '89hasd98ashdasas98dhsda', :page => '1'
28
+ assigns[:exceptions].should == [@exception, @exception2]
29
+ end
30
+
31
+ it 'should set an assigns of exception with the first exception from the paginated collection' do
32
+ get :details, :id => '89hasd98ashdasas98dhsda'
33
+ assigns[:exception].should == @exception
34
+ end
35
+ end
36
+
37
+ describe "#remove_all" do
38
+ it 'should delete all exceptions' do
39
+ LoggedException.should_receive(:delete_all)
40
+ get :remove_all
41
+ end
42
+
43
+ it 'should redirect to exceptions#index' do
44
+ get :remove_all
45
+ response.should redirect_to(:action => :index)
46
+ end
47
+ end
48
+
49
+ describe "#remove_group" do
50
+ it 'should delete all exceptions in a specific group' do
51
+ LoggedException.should_receive(:delete_all).with(:group_id => '892h39fds')
52
+ get :remove_group, :id => '892h39fds'
53
+ end
54
+
55
+ it 'should redirect to exceptions#index' do
56
+ get :remove_group, :id => '892h39fds'
57
+ response.should redirect_to(:action => :index)
58
+ end
59
+ end
60
+
61
+ describe "#remove_individual" do
62
+ before(:each) do
63
+ LoggedException.stub!(:find_by_id).and_return(@exception)
64
+ end
65
+
66
+ it 'should remove a single exception' do
67
+ @exception.should_receive(:destroy)
68
+ get :remove_individual, :id => 1
69
+ end
70
+
71
+ it 'should redirect to exceptions#index if the exception group contains no more exceptions' do
72
+ LoggedException.stub!(:count).and_return(0)
73
+ get :remove_individual, :id => 1
74
+ response.should redirect_to(:action => :index)
75
+ end
76
+
77
+ it 'should redirect to exceptions#details if the exception group contains more exceptions' do
78
+ LoggedException.stub!(:count).and_return(1)
79
+ get :remove_individual, :id => 1
80
+ response.should redirect_to(:action => :details)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe LoggedException do
4
+ it "should include the Tartarus::Logger module" do
5
+ LoggedException.included_modules.include?(Tartarus::Logger)
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require File.expand_path("../../config/environment", __FILE__)
4
+ require 'rspec/rails'
5
+
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ # == Mock Framework
12
+ #
13
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
14
+ #
15
+ # config.mock_with :mocha
16
+ # config.mock_with :flexmock
17
+ # config.mock_with :rr
18
+ config.mock_with :rspec
19
+
20
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
21
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
22
+
23
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
24
+ # examples within a transaction, remove the following line or assign false
25
+ # instead of true.
26
+ config.use_transactional_fixtures = true
27
+ end
File without changes
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,17 @@
1
- ENV["RAILS_ENV"] = "test"
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require File.expand_path(File.dirname(__FILE__) + "/rails_app/config/environment", __FILE__)
4
+ require 'rspec/rails'
2
5
 
3
- require File.expand_path(File.dirname(__FILE__) + "/rails/config/environment")
4
- require "#{File.expand_path(File.dirname(__FILE__))}/../rails/init"
5
- require 'spec'
6
- require 'spec/rails'
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
7
9
 
10
+ RSpec.configure do |config|
11
+ config.mock_with :rspec
12
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
13
+ config.use_transactional_fixtures = true
14
+ end
8
15
 
9
16
  def fake_controller_request
10
17
  stub('request',
@@ -17,10 +24,10 @@ def fake_controller_request
17
24
  'rack.request.cookie_hash' => {}
18
25
  },
19
26
  :method => 'post',
20
- :parameters => 'params',
27
+ :filtered_parameters => 'params',
21
28
  :format => 'html',
22
29
  :protocol => 'http://',
23
- :request_uri => '/my/uri')
30
+ :fullpath => '/my/uri')
24
31
  end
25
32
 
26
33
  class LoggedException < ActiveRecord::Base
@@ -1,14 +1,11 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Tartarus::Logger do
4
- it 'should serialize the request attribute' do
5
- LoggedException.serialized_attributes.include?('request').should be_true
6
- end
7
-
8
4
  describe "#log" do
9
5
  before(:each) do
6
+ Tartarus.stub(:configuration).and_return({ 'test' => { :enabled => true, "logger_class"=>"LoggedException" } })
10
7
  LoggedException.stub!(:normalize_request_data).and_return({})
11
- @controller = mock('controller', :controller_path => 'home', :normalize_request_data_for_tartarus => 'params', :action_name => 'index', :request => fake_controller_request)
8
+ @controller = { 'action_controller.instance' => mock('controller', :controller_path => 'home', :action_name => 'index', :request => fake_controller_request) }
12
9
  @exception = StandardError.new('An error has occured!')
13
10
  @exception.stub!(:backtrace).and_return(['one', 'two', 'three'])
14
11
  end
@@ -25,7 +22,7 @@ describe Tartarus::Logger do
25
22
  end
26
23
 
27
24
  it "should normalize the controller request data" do
28
- @controller.should_receive(:normalize_request_data_for_tartarus)
25
+ LoggedException.should_receive(:normalize_request_data).with(@controller)
29
26
  @logged_exception = LoggedException.log(@controller, @exception)
30
27
  end
31
28
 
@@ -36,41 +33,72 @@ describe Tartarus::Logger do
36
33
  end
37
34
 
38
35
  it 'should return the group count' do
39
- e = LoggedException.create( :group_id => "hash" )
36
+ e = LoggedException.create( :group_id => "hash", :request => {})
40
37
  LoggedException.should_receive( :count ).with( :conditions => ["group_id = ?", 'hash'] ).and_return( 42 )
41
38
  e.group_count.should == 42
42
39
  end
43
40
 
44
41
  describe '#handle_notifications' do
45
42
  before(:each) do
46
- @e = LoggedException.create
47
- Tartarus.configuration['notification_threshold'] = 10
48
- Tartarus.configuration['notification_address'] = 'test@example.com'
43
+ @logged_exception = LoggedException.create(:request => {})
44
+ Tartarus.stub(:configuration).and_return({ 'notification_threshold' => 10, 'notification_address' => 'test@example.com', 'enabled' => true, "logger_class"=>"LoggedException" })
49
45
  end
50
46
 
51
- it 'should return and not deliver notification if there is no address present' do
52
- Tartarus::Notifier.should_receive( :deliver_notification ).never
53
- Tartarus.configuration['notification_address'] = nil
47
+ it 'should return and not deliver notification if there is no address present' do
48
+ Tartarus.should_receive(:configuration).and_return({ 'enabled' => true, "logger_class"=>"LoggedException" })
49
+ Tartarus::Notifiers::Mail.should_receive( :deliver_notification ).never
54
50
 
55
- @e.handle_notifications
51
+ @logged_exception.handle_notifications
56
52
  end
57
53
 
58
54
  it 'should send email if there is an address present and the count matches the threshold' do
59
- Tartarus::Notifier.should_receive( :deliver_notification ).with( 'test@example.com', @e )
60
- @e.stub( :group_count ).and_return( 20 )
61
- @e.handle_notifications
55
+ Tartarus::Notifiers::Mail.should_receive( :deliver_notification ).with( 'test@example.com', @logged_exception )
56
+ @logged_exception.stub( :group_count ).and_return( 20 )
57
+ @logged_exception.handle_notifications
62
58
  end
63
59
 
64
60
  it 'should send email if there is an address present and it is the first exception in a group' do
65
- Tartarus::Notifier.should_receive( :deliver_notification ).with( 'test@example.com', @e )
66
- @e.stub( :group_count ).and_return( 1 )
67
- @e.handle_notifications
61
+ Tartarus::Notifiers::Mail.should_receive( :deliver_notification ).with( 'test@example.com', @logged_exception )
62
+ @logged_exception.stub( :group_count ).and_return( 1 )
63
+ @logged_exception.handle_notifications
68
64
  end
69
65
 
70
66
  it 'should not send email if there is an address present and the count does not match the threshold' do
71
- Tartarus::Notifier.should_receive( :deliver_notification ).never
72
- @e.stub( :group_count ).and_return( 22 )
73
- @e.handle_notifications
67
+ Tartarus::Notifiers::Mail.should_receive( :deliver_notification ).never
68
+ @logged_exception.stub( :group_count ).and_return( 22 )
69
+ @logged_exception.handle_notifications
70
+ end
71
+ end
72
+
73
+ describe 'when normalizing request data for tartarus' do
74
+ before(:each) do
75
+ @mock_env = { 'action_controller.instance' => stub('controller_instance', :request => fake_controller_request) }
76
+ @logged_exception = LoggedException.create(:request => {})
77
+ Tartarus.stub(:configuration).and_return({ 'notification_threshold' => 10, 'notification_address' => 'test@example.com', 'enabled' => true, "logger_class"=>"LoggedException" })
78
+ end
79
+
80
+ it 'should have the session hash' do
81
+ params = LoggedException.normalize_request_data(@mock_env)
82
+ params[:session].should_not be_blank
83
+ params[:session].should be_an_instance_of(Hash)
84
+ params[:session].should == { :cookie => {}, :variables => { :id=>"123123" } }
85
+ end
86
+
87
+ it 'should have a enviroment hash that contains a hash of only the uppercase keys of the original controller request hash' do
88
+ params = LoggedException.normalize_request_data(@mock_env)
89
+ params[:enviroment].should_not be_blank
90
+ params[:enviroment].should == { "http_host" => "test_host", "loooooooong_key_two" => "key_two_value", "key_one" => "key_one_value", :server => `hostname -s`.chomp, :process => $$ }
91
+ end
92
+
93
+ it 'should have a http details hash' do
94
+ params = LoggedException.normalize_request_data(@mock_env)
95
+ params[:http_details].should_not be_blank
96
+ params[:http_details].should == { :parameters => "params", :format => "html", :method => "POST", :url => "http://test_host/my/uri" }
97
+ end
98
+
99
+ it "should return a hash of request data" do
100
+ params = LoggedException.normalize_request_data(@mock_env)
101
+ params.should be_an_instance_of(Hash)
74
102
  end
75
103
  end
76
104