rack.git  about / heads / tags
a modular Ruby webserver interface
blob 14c3da45a58d0212de9bd6e908a184d5e56fdfcf 3849 bytes (raw)
$ git show chunk:test/spec_show_status.rb	# shows this blob on the CLI

  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
136
137
138
139
140
141
142
 
# frozen_string_literal: true

require_relative 'helper'

separate_testing do
  require_relative '../lib/rack/show_status'
  require_relative '../lib/rack/lint'
  require_relative '../lib/rack/mock_request'
end

describe Rack::ShowStatus do
  def show_status(app)
    Rack::Lint.new Rack::ShowStatus.new(app)
  end

  it "provide a default status message" do
    req = Rack::MockRequest.new(
      show_status(lambda{|env|
        [404, { "content-type" => "text/plain", "content-length" => "0" }, []]
    }))

    res = req.get("/", lint: true)
    res.must_be :not_found?
    res.wont_be_empty

    res["content-type"].must_equal "text/html"
    assert_match(res, /404/)
    assert_match(res, /Not Found/)
  end

  it "let the app provide additional information" do
    req = Rack::MockRequest.new(
      show_status(
        lambda{|env|
          env["rack.showstatus.detail"] = "gone too meta."
          [404, { "content-type" => "text/plain", "content-length" => "0" }, []]
    }))

    res = req.get("/", lint: true)
    res.must_be :not_found?
    res.wont_be_empty

    res["content-type"].must_equal "text/html"
    assert_match(res, /404/)
    assert_match(res, /Not Found/)
    assert_match(res, /too meta/)
  end

  it "let the app provide additional information with non-String details" do
    req = Rack::MockRequest.new(
      show_status(
        lambda{|env|
          env["rack.showstatus.detail"] = ['gone too meta.']
          [404, { "content-type" => "text/plain", "content-length" => "0" }, []]
    }))

    res = req.get("/", lint: true)
    res.must_be :not_found?
    res.wont_be_empty

    res["content-type"].must_equal "text/html"
    assert_includes(res.body, '404')
    assert_includes(res.body, 'Not Found')
    assert_includes(res.body, '["gone too meta."]')
  end

  it "escape error" do
    detail = "<script>alert('hi \"')</script>"
    req = Rack::MockRequest.new(
      show_status(
        lambda{|env|
          env["rack.showstatus.detail"] = detail
          [500, { "content-type" => "text/plain", "content-length" => "0" }, []]
    }))

    res = req.get("/", lint: true)
    res.wont_be_empty

    res["content-type"].must_equal "text/html"
    assert_match(res, /500/)
    res.wont_include detail
    res.body.must_include Rack::Utils.escape_html(detail)
  end

  it "not replace existing messages" do
    req = Rack::MockRequest.new(
      show_status(
        lambda{|env|
          [404, { "content-type" => "text/plain", "content-length" => "4" }, ["foo!"]]
    }))

    res = req.get("/", lint: true)
    res.must_be :not_found?

    res.body.must_equal "foo!"
  end

  it "pass on original headers" do
    headers = { "www-authenticate" => "Basic blah" }

    req = Rack::MockRequest.new(
      show_status(lambda{|env| [401, headers, []] }))
    res = req.get("/", lint: true)

    res["www-authenticate"].must_equal "Basic blah"
  end

  it "replace existing messages if there is detail" do
    req = Rack::MockRequest.new(
      show_status(
        lambda{|env|
          env["rack.showstatus.detail"] = "gone too meta."
          [404, { "content-type" => "text/plain", "content-length" => "4" }, ["foo!"]]
    }))

    res = req.get("/", lint: true)
    res.must_be :not_found?
    res.wont_be_empty

    res["content-type"].must_equal "text/html"
    res["content-length"].wont_equal "4"
    assert_match(res, /404/)
    assert_match(res, /too meta/)
    res.body.wont_match(/foo/)
  end

  it "close the original body" do
    closed = false

    body = Object.new
    def body.each; yield 's' end
    body.define_singleton_method(:close) { closed = true }

    req = Rack::MockRequest.new(
      show_status(lambda{|env|
        [404, { "content-type" => "text/plain", "content-length" => "0" }, body]
    }))

    req.get("/", lint: true)
    closed.must_equal true
  end
end

git clone https://yhbt.net/rack.git