exceptron 0.0.2

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 (75) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/lib/exceptron.rb +38 -0
  4. data/lib/exceptron/dispatcher.rb +58 -0
  5. data/lib/exceptron/exception.rb +97 -0
  6. data/lib/exceptron/exceptions_controller.rb +19 -0
  7. data/lib/exceptron/helpers.rb +24 -0
  8. data/lib/exceptron/local_exceptions_controller.rb +17 -0
  9. data/lib/exceptron/local_helpers.rb +27 -0
  10. data/lib/exceptron/middleware.rb +27 -0
  11. data/lib/exceptron/railtie.rb +16 -0
  12. data/lib/exceptron/version.rb +3 -0
  13. data/lib/exceptron/views/exceptron/exceptions/internal_server_error.html.erb +26 -0
  14. data/lib/exceptron/views/exceptron/local_exceptions/_request_and_response.erb +27 -0
  15. data/lib/exceptron/views/exceptron/local_exceptions/_trace.erb +26 -0
  16. data/lib/exceptron/views/exceptron/local_exceptions/diagnostics.erb +10 -0
  17. data/lib/exceptron/views/exceptron/local_exceptions/missing_template.erb +2 -0
  18. data/lib/exceptron/views/exceptron/local_exceptions/routing_error.erb +10 -0
  19. data/lib/exceptron/views/exceptron/local_exceptions/template_error.erb +17 -0
  20. data/lib/exceptron/views/exceptron/local_exceptions/unknown_action.erb +2 -0
  21. data/lib/exceptron/views/layouts/exceptron/local_exceptions.erb +31 -0
  22. data/test/dummy/Rakefile +7 -0
  23. data/test/dummy/app/controllers/application_controller.rb +4 -0
  24. data/test/dummy/app/controllers/exceptions_controller.rb +24 -0
  25. data/test/dummy/app/controllers/home_controller.rb +4 -0
  26. data/test/dummy/app/helpers/application_helper.rb +2 -0
  27. data/test/dummy/app/views/app_exceptions/internal_server_error.html.erb +2 -0
  28. data/test/dummy/app/views/app_exceptions/not_found.html.erb +2 -0
  29. data/test/dummy/app/views/home/index.erb +1 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/test/dummy/app/views/layouts/exceptions.html.erb +12 -0
  32. data/test/dummy/config.ru +4 -0
  33. data/test/dummy/config/application.rb +49 -0
  34. data/test/dummy/config/boot.rb +10 -0
  35. data/test/dummy/config/database.yml +22 -0
  36. data/test/dummy/config/environment.rb +5 -0
  37. data/test/dummy/config/environments/development.rb +25 -0
  38. data/test/dummy/config/environments/production.rb +49 -0
  39. data/test/dummy/config/environments/test.rb +35 -0
  40. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/test/dummy/config/initializers/inflections.rb +10 -0
  42. data/test/dummy/config/initializers/mime_types.rb +5 -0
  43. data/test/dummy/config/initializers/secret_token.rb +7 -0
  44. data/test/dummy/config/initializers/session_store.rb +8 -0
  45. data/test/dummy/config/locales/en.yml +5 -0
  46. data/test/dummy/config/routes.rb +60 -0
  47. data/test/dummy/db/development.sqlite3 +0 -0
  48. data/test/dummy/db/production.sqlite3 +0 -0
  49. data/test/dummy/db/schema.rb +15 -0
  50. data/test/dummy/db/test.sqlite3 +0 -0
  51. data/test/dummy/log/test.log +40506 -0
  52. data/test/dummy/public/favicon.ico +0 -0
  53. data/test/dummy/public/javascripts/application.js +2 -0
  54. data/test/dummy/public/javascripts/controls.js +965 -0
  55. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  56. data/test/dummy/public/javascripts/effects.js +1123 -0
  57. data/test/dummy/public/javascripts/prototype.js +4874 -0
  58. data/test/dummy/public/javascripts/rails.js +118 -0
  59. data/test/dummy/public/stylesheets/exceptions.css +17 -0
  60. data/test/dummy/script/rails +6 -0
  61. data/test/exceptron_local_custom_test.rb +173 -0
  62. data/test/exceptron_local_test.rb +122 -0
  63. data/test/exceptron_public_custom_test.rb +128 -0
  64. data/test/exceptron_public_test.rb +72 -0
  65. data/test/test_helper.rb +48 -0
  66. data/test/views/exceptions_custom/internal_server_error.da.html.erb +1 -0
  67. data/test/views/exceptions_custom/internal_server_error.json +1 -0
  68. data/test/views/exceptions_custom/not_found.html +26 -0
  69. data/test/views/exceptions_custom/not_found.xml +5 -0
  70. data/test/views/exceptions_custom/not_implemented.html.erb +26 -0
  71. data/test/views/layouts/exception_test.html.erb +12 -0
  72. data/test/views/local_exceptions_custom/diagnostics.da.html.erb +1 -0
  73. data/test/views/local_exceptions_custom/not_implemented.html.erb +26 -0
  74. data/test/views/local_exceptions_custom/unknown_action.erb +2 -0
  75. metadata +197 -0
@@ -0,0 +1,118 @@
1
+ document.observe("dom:loaded", function() {
2
+ function handleRemote(element) {
3
+ var method, url, params;
4
+
5
+ if (element.tagName.toLowerCase() === 'form') {
6
+ method = element.readAttribute('method') || 'post';
7
+ url = element.readAttribute('action');
8
+ params = element.serialize(true);
9
+ } else {
10
+ method = element.readAttribute('data-method') || 'get';
11
+ url = element.readAttribute('href');
12
+ params = {};
13
+ }
14
+
15
+ var event = element.fire("ajax:before");
16
+ if (event.stopped) return false;
17
+
18
+ new Ajax.Request(url, {
19
+ method: method,
20
+ parameters: params,
21
+ asynchronous: true,
22
+ evalScripts: true,
23
+
24
+ onLoading: function(request) { element.fire("ajax:loading", {request: request}); },
25
+ onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); },
26
+ onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
27
+ onComplete: function(request) { element.fire("ajax:complete", {request: request}); },
28
+ onSuccess: function(request) { element.fire("ajax:success", {request: request}); },
29
+ onFailure: function(request) { element.fire("ajax:failure", {request: request}); }
30
+ });
31
+
32
+ element.fire("ajax:after");
33
+ }
34
+
35
+ function handleMethod(element) {
36
+ var method, url, token_name, token;
37
+
38
+ method = element.readAttribute('data-method');
39
+ url = element.readAttribute('href');
40
+ csrf_param = $$('meta[name=csrf-param]').first();
41
+ csrf_token = $$('meta[name=csrf-token]').first();
42
+
43
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
44
+ element.parentNode.appendChild(form);
45
+
46
+ if (method != 'post') {
47
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
48
+ form.appendChild(field);
49
+ }
50
+
51
+ if (csrf_param) {
52
+ var param = csrf_param.readAttribute('content');
53
+ var token = csrf_token.readAttribute('content');
54
+ var field = new Element('input', { type: 'hidden', name: param, value: token });
55
+ form.appendChild(field);
56
+ }
57
+
58
+ form.submit();
59
+ }
60
+
61
+ $(document.body).observe("click", function(event) {
62
+ var message = event.findElement().readAttribute('data-confirm');
63
+ if (message && !confirm(message)) {
64
+ event.stop();
65
+ return false;
66
+ }
67
+
68
+ var element = event.findElement("a[data-remote]");
69
+ if (element) {
70
+ handleRemote(element);
71
+ event.stop();
72
+ return true;
73
+ }
74
+
75
+ var element = event.findElement("a[data-method]");
76
+ if (element) {
77
+ handleMethod(element);
78
+ event.stop();
79
+ return true;
80
+ }
81
+ });
82
+
83
+ // TODO: I don't think submit bubbles in IE
84
+ $(document.body).observe("submit", function(event) {
85
+ var element = event.findElement(),
86
+ message = element.readAttribute('data-confirm');
87
+ if (message && !confirm(message)) {
88
+ event.stop();
89
+ return false;
90
+ }
91
+
92
+ var inputs = element.select("input[type=submit][data-disable-with]");
93
+ inputs.each(function(input) {
94
+ input.disabled = true;
95
+ input.writeAttribute('data-original-value', input.value);
96
+ input.value = input.readAttribute('data-disable-with');
97
+ });
98
+
99
+ var element = event.findElement("form[data-remote]");
100
+ if (element) {
101
+ handleRemote(element);
102
+ event.stop();
103
+ }
104
+ });
105
+
106
+ $(document.body).observe("ajax:after", function(event) {
107
+ var element = event.findElement();
108
+
109
+ if (element.tagName.toLowerCase() === 'form') {
110
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
111
+ inputs.each(function(input) {
112
+ input.value = input.readAttribute('data-original-value');
113
+ input.writeAttribute('data-original-value', null);
114
+ input.disabled = false;
115
+ });
116
+ }
117
+ });
118
+ });
@@ -0,0 +1,17 @@
1
+ body {
2
+ background-color: #fff;
3
+ color: #666;
4
+ text-align: center;
5
+ font-family: arial, sans-serif;
6
+ }
7
+
8
+ div.dialog {
9
+ width: 25em;
10
+ padding: 0 4em;
11
+ margin: 4em auto 0 auto;
12
+ border: 1px solid #ccc;
13
+ border-right-color: #999;
14
+ border-bottom-color: #999;
15
+ }
16
+
17
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
@@ -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,173 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptronLocalCustomTest < ActionDispatch::IntegrationTest
4
+ def setup
5
+ # Hack to test inherited hook
6
+ klass = Class.new(Exceptron::LocalExceptionsController) do
7
+ def self.name
8
+ 'LocalExceptionsCustomController'
9
+ end
10
+
11
+ prepend_view_path File.expand_path('../views', __FILE__)
12
+
13
+ def internal_server_error
14
+ respond_to do |format|
15
+ format.html { super }
16
+ format.json { render :json => exception_presenter.to_json }
17
+ end
18
+ end
19
+
20
+ def not_found
21
+ respond_to do |format|
22
+ format.html { render :action => Exceptron.rescue_templates[exception_presenter.original_exception.class.name] }
23
+ format.xml { render :xml => exception_presenter.to_xml }
24
+ end
25
+ end
26
+ end
27
+
28
+ Object.const_set klass.name, klass
29
+ end
30
+
31
+ def teardown
32
+ Object.send :remove_const, 'LocalExceptionsCustomController'
33
+ Exceptron.local_controller = Exceptron::LocalExceptionsController
34
+ end
35
+
36
+ test "rescue locally from a local request" do
37
+ @app = ProductionApp
38
+ ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
39
+ self.remote_addr = ip_address
40
+
41
+ get "/"
42
+ assert_response 500
43
+ assert_equal 'text/html', response.content_type.to_s
44
+ assert_select 'title', "Exceptron: Exception caught"
45
+ assert_select 'body' do
46
+ assert_select 'h1', "RuntimeError"
47
+ end
48
+ assert_match(/puke/, body)
49
+
50
+ get "/not_found"
51
+ assert_response 404
52
+ assert_equal 'text/html', response.content_type.to_s
53
+ assert_select 'title', "Exceptron: Exception caught"
54
+ assert_select 'body' do
55
+ assert_select 'h1', "[CUSTOM] Unknown action"
56
+ assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
57
+ end
58
+
59
+ get "/method_not_allowed"
60
+ assert_response 405
61
+ assert_equal 'text/html', response.content_type.to_s
62
+ assert_select 'title', "Exceptron: Exception caught"
63
+ assert_select 'body' do
64
+ assert_select 'h1', "ActionController::MethodNotAllowed"
65
+ end
66
+
67
+ get "/not_implemented"
68
+ assert_response 501
69
+ assert_equal 'text/html', response.content_type.to_s
70
+ assert_select 'title', "[CUSTOM] 501 Not Implemented"
71
+ assert_select 'body' do
72
+ assert_select 'h1', "[CUSTOM] 501 Not Implemented"
73
+ assert_select 'p', "[CUSTOM] 501 Not Implemented"
74
+ end
75
+ end
76
+ end
77
+
78
+ test "always rescue locally in development mode" do
79
+ @app = DevelopmentApp
80
+ self.remote_addr = '208.77.188.166'
81
+
82
+ get "/"
83
+ assert_response 500
84
+ assert_equal 'text/html', response.content_type.to_s
85
+ assert_select 'title', "Exceptron: Exception caught"
86
+ assert_select 'body' do
87
+ assert_select 'h1', "RuntimeError"
88
+ end
89
+ assert_match(/puke/, body)
90
+
91
+ get "/not_found"
92
+ assert_response 404
93
+ assert_equal 'text/html', response.content_type.to_s
94
+ assert_select 'title', "Exceptron: Exception caught"
95
+ assert_select 'body' do
96
+ assert_select 'h1', "[CUSTOM] Unknown action"
97
+ assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
98
+ end
99
+
100
+ get "/method_not_allowed"
101
+ assert_response 405
102
+ assert_equal 'text/html', response.content_type.to_s
103
+ assert_select 'title', "Exceptron: Exception caught"
104
+ assert_select 'body' do
105
+ assert_select 'h1', "ActionController::MethodNotAllowed"
106
+ end
107
+ end
108
+
109
+ test "localize public rescue message" do
110
+ old_locale, I18n.locale = I18n.locale, :da
111
+
112
+ begin
113
+ @app = DevelopmentApp
114
+
115
+ get "/"
116
+ assert_response 500
117
+ assert_equal 'text/html', response.content_type.to_s
118
+ assert_match /500 localized error fixture/, body
119
+
120
+ get "/not_found"
121
+ assert_response 404
122
+ assert_equal 'text/html', response.content_type.to_s
123
+ assert_select 'title', "Exceptron: Exception caught"
124
+ assert_select 'body' do
125
+ assert_select 'h1', "[CUSTOM] Unknown action"
126
+ assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
127
+ end
128
+ ensure
129
+ I18n.locale = old_locale
130
+ end
131
+ end
132
+
133
+ test "does not show filtered parameters" do
134
+ @app = DevelopmentApp
135
+
136
+ get "/", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
137
+ assert_response 500
138
+ assert_equal 'text/html', response.content_type.to_s
139
+ assert_match("&quot;foo&quot;=&gt;&quot;[FILTERED]&quot;", body)
140
+ end
141
+
142
+ test "show registered original exception for wrapped exceptions when consider_all_requests_local is true" do
143
+ @app = DevelopmentApp
144
+
145
+ get "/not_found_original_exception"
146
+ assert_response 404
147
+ assert_select 'title', "Exceptron: Exception caught"
148
+ assert_equal 'text/html', response.content_type.to_s
149
+ assert_select 'body' do
150
+ assert_select 'h1', "[CUSTOM] Unknown action"
151
+ assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
152
+ end
153
+ end
154
+
155
+ test "rescue other formats in public from a remote ip" do
156
+ @app = ProductionApp
157
+ ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
158
+ self.remote_addr = ip_address
159
+
160
+ get "/", {}, 'HTTP_ACCEPT' => 'application/json'
161
+ assert_response 500
162
+ assert_equal 'application/json', response.content_type.to_s
163
+ assert_match %r{"message":"Internal Server Error"}, response.body
164
+ assert_match %r{"status":500}, response.body
165
+
166
+ get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
167
+ assert_response 404
168
+ assert_equal 'application/xml', response.content_type.to_s
169
+ assert_match %r{<message>Not Found</message>}, response.body
170
+ assert_match %r{<status type="integer">404</status>}, response.body
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,122 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptronLocalTest < ActionDispatch::IntegrationTest
4
+ test "rescue locally from a local request" do
5
+ @app = ProductionApp
6
+ ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
7
+ self.remote_addr = ip_address
8
+
9
+ get "/"
10
+ assert_response 500
11
+ assert_equal 'text/html', response.content_type.to_s
12
+ assert_select 'title', "Exceptron: Exception caught"
13
+ assert_select 'body' do
14
+ assert_select 'h1', "RuntimeError"
15
+ end
16
+ assert_match(/puke/, body)
17
+
18
+ get "/not_found"
19
+ assert_response 404
20
+ assert_equal 'text/html', response.content_type.to_s
21
+ assert_select 'title', "Exceptron: Exception caught"
22
+ assert_select 'body' do
23
+ assert_select 'h1', "Unknown action"
24
+ assert_select 'p', "AbstractController::ActionNotFound"
25
+ end
26
+
27
+ get "/method_not_allowed"
28
+ assert_response 405
29
+ assert_equal 'text/html', response.content_type.to_s
30
+ assert_select 'title', "Exceptron: Exception caught"
31
+ assert_select 'body' do
32
+ assert_select 'h1', "ActionController::MethodNotAllowed"
33
+ end
34
+ end
35
+ end
36
+
37
+ test "always rescue locally in development mode" do
38
+ @app = DevelopmentApp
39
+ self.remote_addr = '208.77.188.166'
40
+
41
+ get "/"
42
+ assert_response 500
43
+ assert_equal 'text/html', response.content_type.to_s
44
+ assert_select 'title', "Exceptron: Exception caught"
45
+ assert_select 'body' do
46
+ assert_select 'h1', "RuntimeError"
47
+ end
48
+ assert_match(/puke/, body)
49
+
50
+ get "/not_found"
51
+ assert_response 404
52
+ assert_equal 'text/html', response.content_type.to_s
53
+ assert_select 'title', "Exceptron: Exception caught"
54
+ assert_select 'body' do
55
+ assert_select 'h1', "Unknown action"
56
+ assert_select 'p', "AbstractController::ActionNotFound"
57
+ end
58
+
59
+ get "/method_not_allowed"
60
+ assert_response 405
61
+ assert_equal 'text/html', response.content_type.to_s
62
+ assert_select 'title', "Exceptron: Exception caught"
63
+ assert_select 'body' do
64
+ assert_select 'h1', "ActionController::MethodNotAllowed"
65
+ end
66
+ end
67
+
68
+ test "does not show filtered parameters" do
69
+ @app = DevelopmentApp
70
+
71
+ get "/", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
72
+ assert_response 500
73
+ assert_equal 'text/html', response.content_type.to_s
74
+ assert_match("&quot;foo&quot;=&gt;&quot;[FILTERED]&quot;", body)
75
+ end
76
+
77
+ test "show registered original exception for wrapped exceptions when consider_all_requests_local is true" do
78
+ @app = DevelopmentApp
79
+
80
+ get "/not_found_original_exception"
81
+ assert_response 404
82
+ assert_select 'title', "Exceptron: Exception caught"
83
+ assert_equal 'text/html', response.content_type.to_s
84
+ assert_select 'body' do
85
+ assert_select 'h1', "Unknown action"
86
+ assert_select 'p', "AbstractController::ActionNotFound"
87
+ end
88
+ end
89
+
90
+ test "rescue locally other formats as html from a local request" do
91
+ @app = ProductionApp
92
+ ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
93
+ self.remote_addr = ip_address
94
+
95
+ get "/", {}, 'HTTP_ACCEPT' => 'application/json'
96
+ assert_response 500
97
+ assert_equal 'text/html', response.content_type.to_s
98
+ assert_select 'title', "Exceptron: Exception caught"
99
+ assert_select 'body' do
100
+ assert_select 'h1', "RuntimeError"
101
+ end
102
+ assert_match(/puke/, body)
103
+
104
+ get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
105
+ assert_response 404
106
+ assert_equal 'text/html', response.content_type.to_s
107
+ assert_select 'title', "Exceptron: Exception caught"
108
+ assert_select 'body' do
109
+ assert_select 'h1', "Unknown action"
110
+ assert_select 'p', "AbstractController::ActionNotFound"
111
+ end
112
+
113
+ get "/method_not_allowed", {}, 'HTTP_ACCEPT' => 'application/json'
114
+ assert_response 405
115
+ assert_equal 'text/html', response.content_type.to_s
116
+ assert_select 'title', "Exceptron: Exception caught"
117
+ assert_select 'body' do
118
+ assert_select 'h1', "ActionController::MethodNotAllowed"
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,128 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptronPublicCustomTest < ActionDispatch::IntegrationTest
4
+ def setup
5
+ # Hack to test inherited hook
6
+ klass = Class.new(Exceptron::ExceptionsController) do
7
+ def self.name
8
+ 'ExceptionsCustomController'
9
+ end
10
+
11
+ prepend_view_path File.expand_path('../views', __FILE__)
12
+ end
13
+
14
+ Object.const_set klass.name, klass
15
+ end
16
+
17
+ def teardown
18
+ Object.send :remove_const, 'ExceptionsCustomController'
19
+ Exceptron.controller = Exceptron::ExceptionsController
20
+ end
21
+
22
+ test "rescue in public from a remote ip" do
23
+ @app = ProductionApp
24
+ self.remote_addr = '208.77.188.166'
25
+
26
+ get "/"
27
+ assert_response 500
28
+ assert_equal 'text/html', response.content_type.to_s
29
+ assert_select 'title', "We're sorry, but something went wrong (500)"
30
+ assert_select 'body' do
31
+ assert_select 'h1', "We're sorry, but something went wrong."
32
+ assert_select 'p', "We've been notified about this issue and we'll take a look at it shortly."
33
+ end
34
+
35
+ get "/not_found"
36
+ assert_response 404
37
+ assert_equal 'text/html', response.content_type.to_s
38
+ assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
39
+ assert_select 'body' do
40
+ assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
41
+ assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
42
+ end
43
+
44
+ get "/method_not_allowed"
45
+ assert_response 405
46
+ assert_equal 'text/html', response.content_type.to_s
47
+ assert_select 'title', "We're sorry, but something went wrong (405)"
48
+ assert_select 'body' do
49
+ assert_select 'h1', "We're sorry, but something went wrong."
50
+ assert_select 'p', "We've been notified about this issue and we'll take a look at it shortly."
51
+ end
52
+
53
+ get "/not_implemented"
54
+ assert_response 501
55
+ assert_equal 'text/html', response.content_type.to_s
56
+ assert_select 'title', "[CUSTOM] 501 Not Implemented"
57
+ assert_select 'body' do
58
+ assert_select 'h1', "[CUSTOM] 501 Not Implemented"
59
+ assert_select 'p', "[CUSTOM] 501 Not Implemented"
60
+ end
61
+ end
62
+
63
+ test "localize public rescue message" do
64
+ old_locale, I18n.locale = I18n.locale, :da
65
+
66
+ begin
67
+ @app = ProductionApp
68
+ self.remote_addr = '208.77.188.166'
69
+
70
+ get "/"
71
+ assert_response 500
72
+ assert_equal 'text/html', response.content_type.to_s
73
+ assert_match /500 localized error fixture/, body
74
+
75
+ get "/not_found"
76
+ assert_response 404
77
+ assert_equal 'text/html', response.content_type.to_s
78
+ assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
79
+ assert_select 'body' do
80
+ assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
81
+ assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
82
+ end
83
+ ensure
84
+ I18n.locale = old_locale
85
+ end
86
+ end
87
+
88
+ test "does not show filtered parameters" do
89
+ @app = ProductionApp
90
+ self.remote_addr = '208.77.188.166'
91
+
92
+ get "/not_implemented", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
93
+ assert_response 501
94
+ assert_equal 'text/html', response.content_type.to_s
95
+ assert_match("&quot;foo&quot;=&gt;&quot;[FILTERED]&quot;", body)
96
+ end
97
+
98
+ test "show registered original exception for wrapped exceptions when consider_all_requests_local is false" do
99
+ @app = ProductionApp
100
+ self.remote_addr = '208.77.188.166'
101
+
102
+ get "/not_found_original_exception"
103
+ assert_response 404
104
+ assert_equal 'text/html', response.content_type.to_s
105
+ assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
106
+ assert_select 'body' do
107
+ assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
108
+ assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
109
+ end
110
+ end
111
+
112
+ test "rescue other formats in public from a remote ip" do
113
+ @app = ProductionApp
114
+ self.remote_addr = '208.77.188.166'
115
+
116
+ get "/", {}, 'HTTP_ACCEPT' => 'application/json'
117
+ assert_response 500
118
+ assert_equal 'application/json', response.content_type.to_s
119
+ assert_match %r{"message":"CUSTOM Internal Server Error"}, response.body
120
+ assert_match %r{"status":500}, response.body
121
+
122
+ get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
123
+ assert_response 404
124
+ assert_equal 'application/xml', response.content_type.to_s
125
+ assert_match %r{<message>CUSTOM Not Found</message>}, response.body
126
+ assert_match %r{<status type="integer">404</status>}, response.body
127
+ end
128
+ end