tartarus 1.0.3 → 2.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.
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