1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# frozen_string_literal: true
require 'minitest/global_expectations/autorun'
require 'rack/show_exceptions'
require 'rack/lint'
require 'rack/mock'
describe Rack::ShowExceptions do
def show_exceptions(app)
Rack::Lint.new Rack::ShowExceptions.new(app)
end
it "catches exceptions" do
res = nil
req = Rack::MockRequest.new(
show_exceptions(
lambda{|env| raise RuntimeError }
))
res = req.get("/", "HTTP_ACCEPT" => "text/html")
res.must_be :server_error?
res.status.must_equal 500
assert_match(res, /RuntimeError/)
assert_match(res, /ShowExceptions/)
end
it "works with binary data in the Rack environment" do
res = nil
# "\xCC" is not a valid UTF-8 string
req = Rack::MockRequest.new(
show_exceptions(
lambda{|env| env['foo'] = "\xCC"; raise RuntimeError }
))
res = req.get("/", "HTTP_ACCEPT" => "text/html")
res.must_be :server_error?
res.status.must_equal 500
assert_match(res, /RuntimeError/)
assert_match(res, /ShowExceptions/)
end
it "responds with HTML only to requests accepting HTML" do
res = nil
req = Rack::MockRequest.new(
show_exceptions(
lambda{|env| raise RuntimeError, "It was never supposed to work" }
))
[
# Serve text/html when the client accepts text/html
["text/html", ["/", { "HTTP_ACCEPT" => "text/html" }]],
["text/html", ["/", { "HTTP_ACCEPT" => "*/*" }]],
# Serve text/plain when the client does not accept text/html
["text/plain", ["/"]],
["text/plain", ["/", { "HTTP_ACCEPT" => "application/json" }]]
].each do |exmime, rargs|
res = req.get(*rargs)
res.must_be :server_error?
res.status.must_equal 500
res.content_type.must_equal exmime
res.body.must_include "RuntimeError"
res.body.must_include "It was never supposed to work"
if exmime == "text/html"
res.body.must_include '</html>'
else
res.body.wont_include '</html>'
end
end
end
it "handles exceptions without a backtrace" do
res = nil
req = Rack::MockRequest.new(
show_exceptions(
lambda{|env| raise RuntimeError, "", [] }
)
)
res = req.get("/", "HTTP_ACCEPT" => "text/html")
res.must_be :server_error?
res.status.must_equal 500
assert_match(res, /RuntimeError/)
assert_match(res, /ShowExceptions/)
assert_match(res, /unknown location/)
end
it "allows subclasses to override template" do
c = Class.new(Rack::ShowExceptions) do
TEMPLATE = ERB.new("foo")
def template
TEMPLATE
end
end
app = lambda { |env| raise RuntimeError, "", [] }
req = Rack::MockRequest.new(
Rack::Lint.new c.new(app)
)
res = req.get("/", "HTTP_ACCEPT" => "text/html")
res.must_be :server_error?
res.status.must_equal 500
res.body.must_equal "foo"
end
it "knows to prefer plaintext for non-html" do
# We don't need an app for this
exc = Rack::ShowExceptions.new(nil)
[
[{ "HTTP_ACCEPT" => "text/plain" }, true],
[{ "HTTP_ACCEPT" => "text/foo" }, true],
[{ "HTTP_ACCEPT" => "text/html" }, false]
].each do |env, expected|
assert_equal(expected, exc.prefers_plaintext?(env))
end
end
end
|