summaryrefslogtreecommitdiff
path: root/test/spec_method_override.rb
blob: f3b8ad729f790441098b6d5081ca40fcfc627192 (plain)
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
# frozen_string_literal: true

require_relative 'helper'

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

describe Rack::MethodOverride do
  def app
    Rack::Lint.new(Rack::MethodOverride.new(lambda {|e|
      [200, { "content-type" => "text/plain" }, []]
    }))
  end

  it "not affect GET requests" do
    env = Rack::MockRequest.env_for("/?_method=delete", method: "GET")
    app.call env

    env["REQUEST_METHOD"].must_equal "GET"
  end

  it "sets rack.errors for invalid UTF8 _method values" do
    errors = StringIO.new
    env = Rack::MockRequest.env_for("/",
      :method => "POST",
      :input => "_method=\xBF".b,
      Rack::RACK_ERRORS => errors)

    app.call env

    errors.rewind
    errors.read.must_equal "Invalid string for method\n"
    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "modify REQUEST_METHOD for POST requests when _method parameter is set" do
    env = Rack::MockRequest.env_for("/", method: "POST", input: "_method=put")
    app.call env

    env["REQUEST_METHOD"].must_equal "PUT"
  end

  it "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
    env = Rack::MockRequest.env_for("/",
            :method => "POST",
            "HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
          )
    app.call env

    env["REQUEST_METHOD"].must_equal "PATCH"
  end

  it "not modify REQUEST_METHOD if the method is unknown" do
    env = Rack::MockRequest.env_for("/", method: "POST", input: "_method=foo")
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "not modify REQUEST_METHOD when _method is nil" do
    env = Rack::MockRequest.env_for("/", method: "POST", input: "foo=bar")
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "store the original REQUEST_METHOD prior to overriding" do
    env = Rack::MockRequest.env_for("/",
            method: "POST",
            input: "_method=options")
    app.call env

    env["rack.methodoverride.original_method"].must_equal "POST"
  end

  it "not modify REQUEST_METHOD when given invalid multipart form data" do
    input = <<EOF
--AaB03x\r
content-disposition: form-data; name="huge"; filename="huge"\r
EOF
    env = Rack::MockRequest.env_for("/",
                      "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
                      "CONTENT_LENGTH" => input.size.to_s,
                      :method => "POST", :input => input)
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "writes error to RACK_ERRORS when given invalid multipart form data" do
    input = <<EOF
--AaB03x\r
content-disposition: form-data; name="huge"; filename="huge"\r
EOF
    env = Rack::MockRequest.env_for("/",
                      "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
                      "CONTENT_LENGTH" => input.size.to_s,
                      Rack::RACK_ERRORS => StringIO.new,
                      :method => "POST", :input => input)
    Rack::MethodOverride.new(proc { [200, { "content-type" => "text/plain" }, []] }).call env

    env[Rack::RACK_ERRORS].rewind
    env[Rack::RACK_ERRORS].read.must_include 'Bad request content body'
  end

  it "not modify REQUEST_METHOD for POST requests when the params are unparseable because too deep" do
    env = Rack::MockRequest.env_for("/", method: "POST", input: ("[a]" * 36) + "=1")
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "not modify REQUEST_METHOD for POST requests when the params are unparseable" do
    env = Rack::MockRequest.env_for("/", method: "POST", input: "(%bad-params%)")
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
  end

  it "not set form input when the content type is JSON" do
    env = Rack::MockRequest.env_for("/",
      "CONTENT_TYPE" => "application/json",
      method: "POST",
      input: '{"_method":"options"}')
    app.call env

    env["REQUEST_METHOD"].must_equal "POST"
    env["rack.request.form_input"].must_be_nil
  end
end