diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6f9c7652..5a4fcbb1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,7 @@ jobs: fail-fast: false matrix: ruby: + - "2.3" - "2.4" - "2.5" - "2.6" @@ -33,9 +34,6 @@ jobs: - "3.2" - "3.3" - "jruby-9.4" - rack: - - "2" - - "3" steps: - uses: actions/checkout@v3 @@ -55,7 +53,7 @@ jobs: ${GITHUB_WORKSPACE}/minio/minio server ${GITHUB_WORKSPACE}/minio/data --address localhost:9000 &>${GITHUB_WORKSPACE}/minio/data/server.log & - name: Install dependencies - run: bundle exec appraisal install + run: bundle install - name: Run tests run: bundle exec appraisal rack-${{ matrix.rack }} rake test diff --git a/Appraisals b/Appraisals deleted file mode 100644 index f5b330cf7..000000000 --- a/Appraisals +++ /dev/null @@ -1,7 +0,0 @@ -appraise "rack-2" do - gem "rack", "~> 2" -end - -appraise "rack-3" do - gem "rack", "~> 3" -end diff --git a/Gemfile b/Gemfile index 9b00365dd..bae8c28c9 100644 --- a/Gemfile +++ b/Gemfile @@ -7,4 +7,4 @@ gem "simplecov" gem "hanna", require: false -gem "activerecord-jdbcsqlite3-adapter", "~> 51.0", platform: :jruby if RUBY_ENGINE == "jruby" +gem "activerecord-jdbcsqlite3-adapter", "~> 70.0", platform: :jruby if RUBY_ENGINE == "jruby" diff --git a/gemfiles/rack_2.gemfile b/gemfiles/rack_2.gemfile deleted file mode 100644 index 0b47a3a30..000000000 --- a/gemfiles/rack_2.gemfile +++ /dev/null @@ -1,10 +0,0 @@ -# This file was generated by Appraisal - -source "https://rubygems.org" - -gem "pry" -gem "simplecov" -gem "hanna", require: false -gem "rack", "~> 2" - -gemspec path: "../" diff --git a/gemfiles/rack_3.gemfile b/gemfiles/rack_3.gemfile deleted file mode 100644 index c3394c647..000000000 --- a/gemfiles/rack_3.gemfile +++ /dev/null @@ -1,10 +0,0 @@ -# This file was generated by Appraisal - -source "https://rubygems.org" - -gem "pry" -gem "simplecov" -gem "hanna", require: false -gem "rack", "~> 3" - -gemspec path: "../" diff --git a/lib/shrine/plugins/derivation_endpoint.rb b/lib/shrine/plugins/derivation_endpoint.rb index 27fef576a..9febbb75b 100644 --- a/lib/shrine/plugins/derivation_endpoint.rb +++ b/lib/shrine/plugins/derivation_endpoint.rb @@ -365,16 +365,9 @@ def call(env) handle_request(request) end - headers ||= {} - - if Rack.release >= "3" - headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : - body.map(&:bytesize).inject(0, :+).to_s - else - headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s - end - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" + headers = Rack::Headers[headers] + headers["Content-Length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : + body.map(&:bytesize).inject(0, :+).to_s [status, headers, body] end @@ -420,8 +413,6 @@ def handle_request(request) headers["Cache-Control"] = derivation.option(:cache_control) end - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" - [status, headers, body] end @@ -455,11 +446,7 @@ def expires_in(request) # Halts the request with the error message. def error!(status, message) - headers = { "Content-Type" => "text/plain" } - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" - - throw :halt, [status, headers, [message]] + throw :halt, [status, { "Content-Type" => "text/plain" }, [message]] end def secret_key @@ -496,33 +483,20 @@ def local_response(env) # `Content-Type` and `Content-Disposition` response headers from derivation # options and file extension of the derivation result. def file_response(file, env) - response = rack_file_response(file.path, env) - - status = response[0] - - headers = if Rack.release >= "3" - { - "content-type" => type || response[1]["content-type"], - "content-length" => response[1]["content-length"], - "content-disposition" => content_disposition(file), - "content-range" => response[1]["content-range"], - "accept-ranges" => "bytes", - }.compact - else - { - "Content-Type" => type || response[1]["Content-Type"], - "Content-Length" => response[1]["Content-Length"], - "Content-Disposition" => content_disposition(file), - "Content-Range" => response[1]["Content-Range"], - "Accept-Ranges" => "bytes", - }.compact - end + status, headers, body = rack_file_response(file.path, env) - body = Rack::BodyProxy.new(response[2]) { File.delete(file.path) } + headers = Rack::Headers[headers] if Rack.release >= "3" + headers = { + "Content-Type" => type || headers["Content-Type"], + "Content-Length" => headers["Content-Length"], + "Content-Disposition" => content_disposition(file), + "Content-Range" => headers["Content-Range"], + "Accept-Ranges" => "bytes", + }.compact - file.close + body = Rack::BodyProxy.new(body) { File.delete(file.path) } - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" + file.close [status, headers, body] end @@ -541,8 +515,10 @@ def upload_response(env) if upload_redirect redirect_url = uploaded_file.url(**upload_redirect_url_options) + headers = { "Location" => redirect_url } + headers = Rack::Headers[headers] if Rack.release >= "3" - [302, { "Location" => redirect_url }, []] + [302, headers, []] else if derivative && File.exist?(derivative.path) file_response(derivative, env) diff --git a/lib/shrine/plugins/download_endpoint.rb b/lib/shrine/plugins/download_endpoint.rb index 768376209..b46f09322 100644 --- a/lib/shrine/plugins/download_endpoint.rb +++ b/lib/shrine/plugins/download_endpoint.rb @@ -113,14 +113,9 @@ def call(env) handle_request(request) end - if Rack.release >= "3" - headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : - body.map(&:bytesize).inject(0, :+).to_s - else - headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s - end - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" + headers = Rack::Headers[headers] if Rack.release >= "3" + headers["Content-Length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : + body.map(&:bytesize).inject(0, :+).to_s [status, headers, body] end @@ -204,11 +199,7 @@ def bad_request!(message) # Halts the request with the error message. def error!(status, message) - headers = { "Content-Type" => "text/plain" } - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" - - throw :halt, [status, headers, [message]] + throw :halt, [status, { "Content-Type" => "text/plain" }, [message]] end end end diff --git a/lib/shrine/plugins/presign_endpoint.rb b/lib/shrine/plugins/presign_endpoint.rb index c8330f96a..1ef58ecf2 100644 --- a/lib/shrine/plugins/presign_endpoint.rb +++ b/lib/shrine/plugins/presign_endpoint.rb @@ -91,14 +91,9 @@ def call(env) end end - if Rack.release >= "3" - headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : - body.map(&:bytesize).inject(0, :+).to_s - else - headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s - end - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" + headers = Rack::Headers[headers] if Rack.release >= "3" + headers["Content-Length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : + body.map(&:bytesize).inject(0, :+).to_s [status, headers, body] end @@ -165,25 +160,22 @@ def generate_presign(location, options, request) # headers, and a body enumerable. If `:rack_response` option is given, # calls that instead. def make_response(object, request) - if @rack_response - response = @rack_response.call(object, request) + status, headers, body = if @rack_response + @rack_response.call(object, request) else - response = [200, { "Content-Type" => CONTENT_TYPE_JSON }, [object.to_json]] + [200, { "Content-Type" => CONTENT_TYPE_JSON }, [object.to_json]] end + headers = Rack::Headers[headers] if Rack.release >= "3" # prevent browsers from caching the response - response[1]["Cache-Control"] = "no-store" unless response[1].key?("Cache-Control") + headers["Cache-Control"] = "no-store" unless headers.key?("Cache-Control") - response + [status, headers, body] end # Used for early returning an error response. def error!(status, message) - headers = { "Content-Type" => CONTENT_TYPE_TEXT } - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" - - throw :halt, [status, headers, [message]] + throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]] end # Returns the uploader around the specified storage. diff --git a/lib/shrine/plugins/rack_response.rb b/lib/shrine/plugins/rack_response.rb index c5eb47301..b0f54c7b6 100644 --- a/lib/shrine/plugins/rack_response.rb +++ b/lib/shrine/plugins/rack_response.rb @@ -32,11 +32,9 @@ def call(**options) headers = rack_headers(**options) body = rack_body(**options) - if Rack.release >= "3" - [status, headers.transform_keys(&:downcase), body] - else - [status, headers, body] - end + headers = Rack::Headers[headers] if Rack.release >= "3" + + [status, headers, body] end private diff --git a/lib/shrine/plugins/upload_endpoint.rb b/lib/shrine/plugins/upload_endpoint.rb index 8e271af80..aa143ca24 100644 --- a/lib/shrine/plugins/upload_endpoint.rb +++ b/lib/shrine/plugins/upload_endpoint.rb @@ -91,14 +91,9 @@ def call(env) handle_request(request) end - if Rack.release >= "3" - headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : - body.map(&:bytesize).inject(0, :+).to_s - else - headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s - end - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" + headers = Rack::Headers[headers] if Rack.release >= "3" + headers["Content-Length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s : + body.map(&:bytesize).inject(0, :+).to_s [status, headers, body] end @@ -217,11 +212,7 @@ def verify_checksum!(file, request) # Used for early returning an error response. def error!(status, message) - headers = { "Content-Type" => CONTENT_TYPE_TEXT } - - headers = headers.transform_keys(&:downcase) if Rack.release >= "3" - - throw :halt, [status, headers, [message]] + throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]] end # Returns the uploader around the specified storage. diff --git a/shrine.gemspec b/shrine.gemspec index 26912822d..0276f999e 100644 --- a/shrine.gemspec +++ b/shrine.gemspec @@ -37,7 +37,6 @@ direct uploads for fully asynchronous user experience. gem.add_dependency "content_disposition", "~> 1.0" # general testing helpers - gem.add_development_dependency "appraisal", "~> 2.5" gem.add_development_dependency "rake", ">= 11.1" gem.add_development_dependency "minitest", "~> 5.8" gem.add_development_dependency "mocha", "~> 1.11" @@ -45,7 +44,7 @@ direct uploads for fully asynchronous user experience. # for endpoint plugins gem.add_development_dependency "rack", ">= 2", "< 4" gem.add_development_dependency "http-form_data", "~> 2.2" - gem.add_development_dependency "rack-test_app" + gem.add_development_dependency "rack-test", "~> 2.1" # for determine_mime_type plugin gem.add_development_dependency "mimemagic", ">= 0.3.2" diff --git a/test/plugin/derivation_endpoint_test.rb b/test/plugin/derivation_endpoint_test.rb index 05cb77051..85b45675d 100644 --- a/test/plugin/derivation_endpoint_test.rb +++ b/test/plugin/derivation_endpoint_test.rb @@ -1,6 +1,7 @@ require "test_helper" require "shrine/plugins/derivation_endpoint" require "dry-monitor" +require "rack/test" require "tempfile" require "stringio" require "pathname" @@ -198,7 +199,7 @@ describe "Shrine.derivation_endpoint" do def app(*args, **options) - Rack::TestApp.wrap(Rack::Lint.new(endpoint(*args, **options)), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + Rack::Test::Session.new(Rack::Lint.new(endpoint(*args, **options))) end def endpoint(*args, **options) @@ -209,17 +210,17 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, "dark") response = app.get(derivation_url) assert_equal 200, response.status - assert_equal "gray dark content", response.body_binary - assert_equal "17", response.headers[CONTENT_LENGTH_HEADER] + assert_equal "gray dark content", response.body + assert_equal "17", response.headers["Content-Length"] end it "handles Range requests" do derivation_url = @uploaded_file.derivation_url(:gray) - response = app.get(derivation_url, headers: { "Range" => "bytes=0-3" }) + response = app.get(derivation_url, {}, { "HTTP_RANGE" => "bytes=0-3" }) assert_equal 206, response.status - assert_equal "gray", response.body_binary - assert_equal "4", response.headers[CONTENT_LENGTH_HEADER] - assert_equal "bytes 0-3/12", response.headers[CONTENT_RANGE_HEADER] + assert_equal "gray", response.body + assert_equal "4", response.headers["Content-Length"] + assert_equal "bytes 0-3/12", response.headers["Content-Range"] end it "applies plugin options" do @@ -227,7 +228,7 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray) response = app.get(derivation_url) assert_equal 200, response.status - assert_match "attachment", response.headers[CONTENT_DISPOSITION_HEADER] + assert_match "attachment", response.headers["Content-Disposition"] end it "applies app options" do @@ -235,7 +236,7 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray) response = app(disposition: "attachment").get(derivation_url) assert_equal 200, response.status - assert_match "attachment", response.headers[CONTENT_DISPOSITION_HEADER] + assert_match "attachment", response.headers["Content-Disposition"] end it "applies 'type' param" do @@ -243,7 +244,7 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, type: "text/csv") response = app(type: "text/plain").get(derivation_url) assert_equal 200, response.status - assert_equal "text/csv", response.headers[CONTENT_TYPE_HEADER] + assert_equal "text/csv", response.headers["Content-Type"] end it "applies 'disposition' param" do @@ -251,7 +252,7 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, disposition: "attachment") response = app(disposition: "inline").get(derivation_url) assert_equal 200, response.status - assert_match "attachment", response.headers[CONTENT_DISPOSITION_HEADER] + assert_match "attachment", response.headers["Content-Disposition"] end it "applies 'filename' param" do @@ -259,7 +260,7 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, filename: "custom") response = app(filename: "default").get(derivation_url) assert_equal 200, response.status - assert_match "filename=\"custom\"", response.headers[CONTENT_DISPOSITION_HEADER] + assert_match "filename=\"custom\"", response.headers["Content-Disposition"] end it "applies 'version' param" do @@ -267,68 +268,68 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, version: 2) response = app(version: 1).get(derivation_url) assert_equal 200, response.status - assert_match "filename=\"2\"", response.headers[CONTENT_DISPOSITION_HEADER] + assert_match "filename=\"2\"", response.headers["Content-Disposition"] end it "returns Cache-Control header on 2xx response" do derivation_url = @uploaded_file.derivation_url(:gray) response = app.get(derivation_url) assert_equal 200, response.status - assert_equal "public, max-age=31536000", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=31536000", response.headers["Cache-Control"] derivation_url = @uploaded_file.derivation_url(:gray) - response = app.get(derivation_url, headers: { "Range" => "bytes=0-3" }) + response = app.get(derivation_url, {}, { "HTTP_RANGE" => "bytes=0-3" }) assert_equal 206, response.status - assert_equal "public, max-age=31536000", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=31536000", response.headers["Cache-Control"] derivation_url = @uploaded_file.derivation_url(:gray) response = app(upload: true, upload_redirect: true).get(derivation_url) assert_equal 302, response.status - refute response.headers.key?(CACHE_CONTROL_HEADER) + refute response.headers.key?("Cache-Control") end it "applies :cache_control" do @shrine.plugin :derivation_endpoint, cache_control: "public, max-age=10" derivation_url = @uploaded_file.derivation_url(:gray) response = app.get(derivation_url) - assert_equal "public, max-age=10", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=10", response.headers["Cache-Control"] response = app(cache_control: "public, max-age=20").get(derivation_url) - assert_equal "public, max-age=20", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=20", response.headers["Cache-Control"] response = app(cache_control: -> { "public, max-age=20" }).get(derivation_url) - assert_equal "public, max-age=20", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=20", response.headers["Cache-Control"] derivation_url = @uploaded_file.derivation_url(:gray, expires_in: 100) response = app.get(derivation_url) - assert_equal "public, max-age=10", response.headers[CACHE_CONTROL_HEADER] + assert_equal "public, max-age=10", response.headers["Cache-Control"] end it "returns 404 on unknown derivation" do derivation_url = @uploaded_file.derivation_url(:nonexistent) response = app.get(derivation_url) - assert_equal 404, response.status - assert_match "Unknown derivation", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] + assert_equal 404, response.status + assert_match "Unknown derivation", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] end it "returns 404 when source was not found" do @uploaded_file.delete derivation_url = @uploaded_file.derivation_url(:gray) response = app.get(derivation_url) - assert_equal 404, response.status - assert_match "Source file not found", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] + assert_equal 404, response.status + assert_match "Source file not found", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] end it "successfully handles expiring links that have not yet expired" do derivation_url = @uploaded_file.derivation_url(:gray, expires_in: 100) response = app.get(derivation_url) assert_equal 200, response.status - assert_equal "12", response.headers[CONTENT_LENGTH_HEADER] + assert_equal "12", response.headers["Content-Length"] # caching duration is limited by the expiration date - max_age = Integer(response.headers[CACHE_CONTROL_HEADER][/max-age=(\d+)/, 1]) + max_age = Integer(response.headers["Cache-Control"][/max-age=(\d+)/, 1]) assert_operator max_age, :<=, 100 assert_operator 0, :<, max_age end @@ -337,38 +338,38 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray, expires_in: -1) @shrine.derivation(:gray) { fail "this should not be called" } response = app.get(derivation_url) - assert_equal 403, response.status - assert_match "Request has expired", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] - refute response.headers.key?(CACHE_CONTROL_HEADER) + assert_equal 403, response.status + assert_match "Request has expired", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] + refute response.headers.key?("Cache-Control") end it "returns 403 on invalid signature" do derivation_url = @uploaded_file.derivation_url(:gray).sub(/\w+$/, "foo") @shrine.derivation(:gray) { fail "this should not be called" } response = app.get(derivation_url) - assert_equal 403, response.status - assert_match "signature does not match", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] - refute response.headers.key?(CACHE_CONTROL_HEADER) + assert_equal 403, response.status + assert_match "signature does not match", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] + refute response.headers.key?("Cache-Control") end it "returns 403 on missing signature" do derivation_url = @uploaded_file.derivation_url(:gray).sub(/signature=\w+$/, "") @shrine.derivation(:gray) { fail "this should not be called" } response = app.get(derivation_url) - assert_equal 403, response.status - assert_match "Missing \"signature\" param", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] - refute response.headers.key?(CACHE_CONTROL_HEADER) + assert_equal 403, response.status + assert_match "Missing \"signature\" param", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] + refute response.headers.key?("Cache-Control") end it "includes request params when calculating signature" do derivation_url = @uploaded_file.derivation_url(:gray) + "&foo=bar" response = app.get(derivation_url) assert_equal 403, response.status - assert_match "signature does not match", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] + assert_match "signature does not match", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] end it "skips signature verifcation when secret_key is nil" do @@ -378,22 +379,22 @@ def endpoint(*args, **options) derivation_url = @uploaded_file.derivation_url(:gray).sub(/signature=\w+$/, "") response = app.get(derivation_url) assert_equal 200, response.status - assert_equal "12", response.headers[CONTENT_LENGTH_HEADER] + assert_equal "12", response.headers["Content-Length"] end it "accepts HEAD requests" do derivation_url = @uploaded_file.derivation_url(:gray) response = app.head(derivation_url) assert_equal 200, response.status - assert_equal "12", response.headers[CONTENT_LENGTH_HEADER] + assert_equal "12", response.headers["Content-Length"] end it "returns 405 on invalid request method" do derivation_url = @uploaded_file.derivation_url(:gray) response = app.post(derivation_url) - assert_equal 405, response.status - assert_equal "Method not allowed", response.body_binary - assert_equal response.body_binary.length.to_s, response.headers[CONTENT_LENGTH_HEADER] + assert_equal 405, response.status + assert_equal "Method not allowed", response.body + assert_equal response.body.length.to_s, response.headers["Content-Length"] end it "defines #inspect and #to_s" do @@ -419,7 +420,7 @@ def endpoint(*args, **options) status, headers, body = @shrine.derivation_response(env) assert_equal 200, status - assert_equal "12", headers[CONTENT_LENGTH_HEADER] + assert_equal "12", headers["Content-Length"] assert_equal "gray content", body.enum_for(:each).to_a.join assert_equal "", env["SCRIPT_NAME"] @@ -461,7 +462,7 @@ def endpoint(*args, **options) status, headers, body = @shrine.derivation_response(env, type: "text/plain") assert_equal 200, status - assert_equal "text/plain", headers[CONTENT_TYPE_HEADER] + assert_equal "text/plain", headers["Content-Type"] end it "fails when request path doesn't start with prefix" do @@ -489,26 +490,26 @@ def endpoint(*args, **options) response = @uploaded_file.derivation_response(:gray, env: {}) assert_equal 200, response[0] - assert_equal "12", response[1][CONTENT_LENGTH_HEADER] + assert_equal "12", response[1]["Content-Length"] assert_equal "gray content", response[2].enum_for(:each).to_a.join end it "returns Content-Disposition" do response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal ContentDisposition.inline("gray-#{@uploaded_file.id}"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("gray-#{@uploaded_file.id}"), response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, "dark", env: {}) - assert_equal ContentDisposition.inline("gray-dark-#{@uploaded_file.id}"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("gray-dark-#{@uploaded_file.id}"), response[1]["Content-Disposition"] @shrine.derivation(:gray) { |file| Tempfile.new(["derivation", ".txt"]) } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal ContentDisposition.inline("gray-#{@uploaded_file.id}.txt"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("gray-#{@uploaded_file.id}.txt"), response[1]["Content-Disposition"] end it "returns Content-Type" do @shrine.derivation(:gray) { |file| Tempfile.new(["derivation", ".jpg"]) } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal "image/jpeg", response[1][CONTENT_TYPE_HEADER] + assert_equal "image/jpeg", response[1]["Content-Type"] @shrine.derivation(:gray) { |file| Tempfile.new(["derivation"]) } response = @uploaded_file.derivation_response(:gray, env: {}) @@ -520,33 +521,33 @@ def endpoint(*args, **options) @shrine.plugin :derivation_endpoint, type: "text/plain" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] @shrine.plugin :derivation_endpoint, type: -> { "text/plain" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] response = @uploaded_file.derivation_response(:gray, env: {}, type: "text/csv") - assert_equal "text/csv", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/csv", response[1]["Content-Type"] response = @uploaded_file.derivation_response(:gray, env: {}, type: -> { "text/csv" }) - assert_equal "text/csv", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/csv", response[1]["Content-Type"] end it "applies :disposition" do @shrine.plugin :derivation_endpoint, disposition: "attachment" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "attachment; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "attachment; ", response[1]["Content-Disposition"] @shrine.plugin :derivation_endpoint, disposition: -> { "attachment" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "attachment; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "attachment; ", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, disposition: "inline") - assert_match "inline; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; ", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, disposition: -> { "inline" }) - assert_match "inline; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; ", response[1]["Content-Disposition"] end it "applies :filename" do @@ -554,30 +555,30 @@ def endpoint(*args, **options) @shrine.plugin :derivation_endpoint, filename: "one" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "inline; filename=\"one.txt\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"one.txt\"", response[1]["Content-Disposition"] @shrine.plugin :derivation_endpoint, filename: -> { "one" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "inline; filename=\"one.txt\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"one.txt\"", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, filename: "two.csv") - assert_match "inline; filename=\"two.csv\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"two.csv\"", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, filename: -> { "two.csv" }) - assert_match "inline; filename=\"two.csv\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"two.csv\"", response[1]["Content-Disposition"] end it "handles Range requests" do response = @uploaded_file.derivation_response(:gray, env: { "HTTP_RANGE" => "bytes=0-3" }) assert_equal 206, response[0] - assert_equal "bytes 0-3/12", response[1][CONTENT_RANGE_HEADER] - assert_equal "bytes", response[1][ACCEPT_RANGES_HEADER] + assert_equal "bytes 0-3/12", response[1]["Content-Range"] + assert_equal "bytes", response[1]["Accept-Ranges"] assert_equal "gray", response[2].enum_for(:each).to_a.join response = @uploaded_file.derivation_response(:gray, env: {}) assert_equal 200, response[0] - assert_equal "bytes", response[1][ACCEPT_RANGES_HEADER] - refute response[1].key?(CONTENT_RANGE_HEADER) + assert_equal "bytes", response[1]["Accept-Ranges"] + refute response[1].key?("Content-Range") end it "closes and deletes derivation result" do @@ -605,7 +606,7 @@ def endpoint(*args, **options) response = @uploaded_file.derivation_response(:gray, env: {}) assert_equal 200, response[0] - assert_equal "12", response[1][CONTENT_LENGTH_HEADER] + assert_equal "12", response[1]["Content-Length"] assert_equal "gray content", response[2].enum_for(:each).to_a.join refute_instance_of Shrine::Plugins::RackResponse::FileBody, response[2] @@ -618,7 +619,7 @@ def endpoint(*args, **options) response = @uploaded_file.derivation_response(:gray, env: {}) assert_equal 200, response[0] - assert_equal "12", response[1][CONTENT_LENGTH_HEADER] + assert_equal "12", response[1]["Content-Length"] assert_equal "gray content", response[2].enum_for(:each).to_a.join end @@ -627,17 +628,17 @@ def endpoint(*args, **options) @shrine.plugin :derivation_endpoint, type: "text/plain" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] @shrine.plugin :derivation_endpoint, type: -> { "text/plain" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] response = @uploaded_file.derivation_response(:gray, env: {}, type: "text/csv") - assert_equal "text/csv", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/csv", response[1]["Content-Type"] response = @uploaded_file.derivation_response(:gray, env: {}, type: -> { "text/csv" }) - assert_equal "text/csv", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/csv", response[1]["Content-Type"] end it "applies :disposition" do @@ -645,17 +646,17 @@ def endpoint(*args, **options) @shrine.plugin :derivation_endpoint, disposition: "attachment" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "attachment; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "attachment; ", response[1]["Content-Disposition"] @shrine.plugin :derivation_endpoint, disposition: -> { "attachment" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "attachment; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "attachment; ", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, disposition: "inline") - assert_match "inline; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; ", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, disposition: -> { "inline" }) - assert_match "inline; ", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; ", response[1]["Content-Disposition"] end it "applies :filename" do @@ -663,33 +664,33 @@ def endpoint(*args, **options) @shrine.plugin :derivation_endpoint, filename: "one" response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "inline; filename=\"one\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"one\"", response[1]["Content-Disposition"] @shrine.plugin :derivation_endpoint, filename: -> { "one" } response = @uploaded_file.derivation_response(:gray, env: {}) - assert_match "inline; filename=\"one\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"one\"", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, filename: "two") - assert_match "inline; filename=\"two\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"two\"", response[1]["Content-Disposition"] response = @uploaded_file.derivation_response(:gray, env: {}, filename: -> { "two" }) - assert_match "inline; filename=\"two\"", response[1][CONTENT_DISPOSITION_HEADER] + assert_match "inline; filename=\"two\"", response[1]["Content-Disposition"] end it "handles Range requests" do @uploaded_file.derivation_response(:gray, env: {}) response = @uploaded_file.derivation_response(:gray, env: { "HTTP_RANGE" => "bytes=0-3" }) assert_equal 206, response[0] - assert_equal "bytes 0-3/12", response[1][CONTENT_RANGE_HEADER] - assert_equal "bytes", response[1][ACCEPT_RANGES_HEADER] + assert_equal "bytes 0-3/12", response[1]["Content-Range"] + assert_equal "bytes", response[1]["Accept-Ranges"] assert_equal "gray", response[2].enum_for(:each).to_a.join end it "returns ETag" do @uploaded_file.derivation_response(:gray, env: {}) response = @uploaded_file.derivation_response(:gray, env: {}) - assert_instance_of String, response[1][ETAG_HEADER] - assert_match /^W\/"\w{32}"$/, response[1][ETAG_HEADER] + assert_instance_of String, response[1]["ETag"] + assert_match /^W\/"\w{32}"$/, response[1]["ETag"] end it "applies :upload_open_options" do @@ -739,7 +740,7 @@ def upload(io, id, **options) response = @uploaded_file.derivation_response(:gray, env: {}) assert_equal 200, response[0] - assert_equal "12", response[1][CONTENT_LENGTH_HEADER] + assert_equal "12", response[1]["Content-Length"] assert_equal "gray content", response[2].enum_for(:each).to_a.join end diff --git a/test/plugin/download_endpoint_test.rb b/test/plugin/download_endpoint_test.rb index 05cecc969..43f9c52e9 100644 --- a/test/plugin/download_endpoint_test.rb +++ b/test/plugin/download_endpoint_test.rb @@ -1,10 +1,11 @@ require "test_helper" require "shrine/plugins/download_endpoint" +require "rack/test" require "uri" describe Shrine::Plugins::DownloadEndpoint do def app - Rack::TestApp.wrap(Rack::Lint.new(endpoint), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + Rack::Test::Session.new(Rack::Lint.new(endpoint)) end def endpoint @@ -22,76 +23,76 @@ def endpoint @uploaded_file = @uploader.upload(io) response = app.get(@uploaded_file.download_url) assert_equal 200, response.status - assert_equal @uploaded_file.read, response.body_binary - assert_equal @uploaded_file.size.to_s, response.headers[CONTENT_LENGTH_HEADER] - assert_equal @uploaded_file.mime_type, response.headers[CONTENT_TYPE_HEADER] - assert_equal ContentDisposition.inline(@uploaded_file.original_filename), response.headers[CONTENT_DISPOSITION_HEADER] + assert_equal @uploaded_file.read, response.body + assert_equal @uploaded_file.size.to_s, response.headers["Content-Length"] + assert_equal @uploaded_file.mime_type, response.headers["COntent-Type"] + assert_equal ContentDisposition.inline(@uploaded_file.original_filename), response.headers["Content-Disposition"] end it "applies :download_options hash" do @shrine.plugin :download_endpoint, download_options: { foo: "bar" } @uploaded_file.storage.expects(:open).with(@uploaded_file.id, foo: "bar").returns(StringIO.new("options")) response = app.get(@uploaded_file.download_url) - assert_equal "options", response.body_binary + assert_equal "options", response.body end it "applies :download_options proc" do @shrine.plugin :download_endpoint, download_options: -> (uploaded_file, request) { { foo: "bar" } } @uploaded_file.storage.expects(:open).with(@uploaded_file.id, foo: "bar").returns(StringIO.new("options")) response = app.get(@uploaded_file.download_url) - assert_equal "options", response.body_binary + assert_equal "options", response.body end it "applies :disposition to response" do @shrine.plugin :download_endpoint, disposition: "attachment" response = app.get(@uploaded_file.download_url) - assert_equal ContentDisposition.attachment(@uploaded_file.id), response.headers[CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.attachment(@uploaded_file.id), response.headers["Content-Disposition"] end it "returns Cache-Control" do response = app.get(@uploaded_file.download_url) - assert_equal "max-age=31536000", response.headers[CACHE_CONTROL_HEADER] + assert_equal "max-age=31536000", response.headers["Cache-Control"] end it "accepts :redirect with true" do @shrine.plugin :download_endpoint, redirect: true response = app.get(@uploaded_file.download_url) assert_equal 302, response.status - assert_match %r{^memory://\w+$}, response.headers[LOCATION_HEADER] + assert_match %r{^memory://\w+$}, response.headers["Location"] end it "accepts :redirect with proc" do @shrine.plugin :download_endpoint, redirect: -> (uploaded_file, request) { "/foo" } response = app.get(@uploaded_file.download_url) assert_equal 302, response.status - assert_equal "/foo", response.headers[LOCATION_HEADER] + assert_equal "/foo", response.headers["Location"] end it "returns Accept-Ranges" do response = app.get(@uploaded_file.download_url) - assert_equal "bytes", response.headers[ACCEPT_RANGES_HEADER] + assert_equal "bytes", response.headers["Accept-Ranges"] end it "supports ranged requests" do @uploaded_file = @uploader.upload(fakeio("content")) - response = app.get(@uploaded_file.download_url, headers: { "Range" => "bytes=2-4" }) + response = app.get(@uploaded_file.download_url, nil, { "HTTP_RANGE" => "bytes=2-4" }) assert_equal 206, response.status - assert_equal "bytes 2-4/7", response.headers[CONTENT_RANGE_HEADER] - assert_equal "3", response.headers[CONTENT_LENGTH_HEADER] - assert_equal "nte", response.body_binary + assert_equal "bytes 2-4/7", response.headers["Content-Range"] + assert_equal "3", response.headers["Content-Length"] + assert_equal "nte", response.body end it "returns ETag" do response = app.get(@uploaded_file.download_url) - assert_instance_of String, response.headers[ETAG_HEADER] - assert_match /^W\/"\w{32}"$/, response.headers[ETAG_HEADER] + assert_instance_of String, response.headers["ETag"] + assert_match /^W\/"\w{32}"$/, response.headers["ETag"] end it "returns 404 for nonexisting file" do @uploaded_file.delete response = app.get(@uploaded_file.download_url) assert_equal 404, response.status - assert_equal "File Not Found", response.body_binary + assert_equal "File Not Found", response.body assert_equal "text/plain", response.content_type end @@ -100,7 +101,7 @@ def endpoint @shrine.storages.delete(@uploaded_file.storage_key) response = app.get(url) assert_equal 404, response.status - assert_equal "File Not Found", response.body_binary + assert_equal "File Not Found", response.body assert_equal "text/plain", response.content_type end @@ -125,9 +126,9 @@ def endpoint end it "accepts ad-hoc options" do - app = Rack::TestApp.wrap(@shrine.download_endpoint(disposition: "attachment"), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + app = Rack::Test::Session.new(@shrine.download_endpoint(disposition: "attachment")) response = app.get(@uploaded_file.download_url) - assert_match /^attachment; /, response.headers[CONTENT_DISPOSITION_HEADER] + assert_match /^attachment; /, response.headers["Content-Disposition"] end it "returns same URL regardless of metadata order" do @@ -141,11 +142,11 @@ def endpoint it "returns 400 on invalid serialized file" do response = app.get("/dontwork") assert_equal 400, response.status - assert_equal "Invalid serialized file", response.body_binary + assert_equal "Invalid serialized file", response.body response = app.get("/dont%20work") assert_equal 400, response.status - assert_equal "Invalid serialized file", response.body_binary + assert_equal "Invalid serialized file", response.body end describe "Shrine.download_response" do @@ -165,7 +166,7 @@ def endpoint status, headers, body = @shrine.download_response(env) assert_equal 200, status - assert_equal @uploaded_file.size.to_s, headers[CONTENT_LENGTH_HEADER] + assert_equal @uploaded_file.size.to_s, headers["Content-Length"] assert_equal @uploaded_file.read, body.enum_for(:each).to_a.join assert_equal "", env["SCRIPT_NAME"] @@ -207,7 +208,7 @@ def endpoint status, headers, body = @shrine.download_response(env, disposition: "attachment") assert_equal 200, status - assert_match /^attachment; /, headers[CONTENT_DISPOSITION_HEADER] + assert_match /^attachment; /, headers["Content-Disposition"] end it "fails when request path doesn't start with prefix" do diff --git a/test/plugin/presign_endpoint_test.rb b/test/plugin/presign_endpoint_test.rb index 248c3ce1a..eefbc0257 100644 --- a/test/plugin/presign_endpoint_test.rb +++ b/test/plugin/presign_endpoint_test.rb @@ -1,11 +1,12 @@ require "test_helper" require "shrine/plugins/presign_endpoint" require "shrine/storage/s3" +require "rack/test" require "json" describe Shrine::Plugins::PresignEndpoint do def app - Rack::TestApp.wrap(Rack::Lint.new(endpoint), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + Rack::Test::Session.new(Rack::Lint.new(endpoint)) end def endpoint @@ -23,35 +24,37 @@ def endpoint assert_equal 200, response.status - assert_equal "application/json; charset=utf-8", response.headers[CONTENT_TYPE_HEADER] - assert_equal response.body_binary.bytesize.to_s, response.headers[CONTENT_LENGTH_HEADER] - assert_equal "no-store", response.headers[CACHE_CONTROL_HEADER] + assert_equal "application/json; charset=utf-8", response.headers["Content-Type"] + assert_equal response.body.bytesize.to_s, response.headers["Content-Length"] + assert_equal "no-store", response.headers["Cache-Control"] - assert_instance_of String, response.body_json["method"] - assert_instance_of String, response.body_json["url"] - assert_instance_of Hash, response.body_json["fields"] - assert_instance_of Hash, response.body_json["headers"] + result = JSON.parse(response.body) + + assert_instance_of String, result["method"] + assert_instance_of String, result["url"] + assert_instance_of Hash, result["fields"] + assert_instance_of Hash, result["headers"] end it "uses extension from given filename" do response = app.get "/?filename=nature.jpg" - assert_match /\.jpg$/, response.body_json["fields"]["key"] + assert_match /\.jpg$/, JSON.parse(response.body)["fields"]["key"] end it "accepts presign location" do @shrine.plugin :presign_endpoint, presign_location: -> (r) { "${filename}" } response = app.get "/" - assert_match "${filename}", response.body_json["fields"]["key"] + assert_match "${filename}", JSON.parse(response.body)["fields"]["key"] end it "accepts presign options" do @shrine.plugin :presign_endpoint, presign_options: { content_type: "image/jpeg" } response = app.get "/" - assert_equal "image/jpeg", response.body_json["fields"]["Content-Type"] + assert_equal "image/jpeg", JSON.parse(response.body)["fields"]["Content-Type"] @shrine.plugin :presign_endpoint, presign_options: -> (r) { {content_type: "image/jpeg"} } response = app.get "/" - assert_equal "image/jpeg", response.body_json["fields"]["Content-Type"] + assert_equal "image/jpeg", JSON.parse(response.body)["fields"]["Content-Type"] end it "accepts presign proc" do @@ -59,9 +62,9 @@ def endpoint presign_options: { content_type: "image/jpeg" }, presign: -> (i, o, r) { {url: "foo", fields: o, headers: {"foo" => "bar"}} } response = app.get "/" - assert_match "foo", response.body_json["url"] - assert_equal "image/jpeg", response.body_json["fields"]["content_type"] - assert_equal "bar", response.body_json["headers"]["foo"] + assert_match "foo", JSON.parse(response.body)["url"] + assert_equal "image/jpeg", JSON.parse(response.body)["fields"]["content_type"] + assert_equal "bar", JSON.parse(response.body)["headers"]["foo"] end it "sets default fields and headers for presign" do @@ -69,9 +72,9 @@ def endpoint presign_options: { content_type: "image/jpeg" }, presign: -> (i, o, r) { {url: "foo"} } response = app.get "/" - assert_match "foo", response.body_json["url"] - assert_equal Hash.new, response.body_json["fields"] - assert_equal Hash.new, response.body_json["headers"] + assert_match "foo", JSON.parse(response.body)["url"] + assert_equal Hash.new, JSON.parse(response.body)["fields"] + assert_equal Hash.new, JSON.parse(response.body)["headers"] end it "supports presign as an object that responds to #to_h" do @@ -79,40 +82,40 @@ def endpoint presign_options: { content_type: "image/jpeg" }, presign: -> (i, o, r) { Struct.new(:url, :fields).new("foo", o) } response = app.get "/" - assert_match "foo", response.body_json["url"] - assert_equal "image/jpeg", response.body_json["fields"]["content_type"] - assert_equal Hash.new, response.body_json["headers"] + assert_match "foo", JSON.parse(response.body)["url"] + assert_equal "image/jpeg", JSON.parse(response.body)["fields"]["content_type"] + assert_equal Hash.new, JSON.parse(response.body)["headers"] end it "accepts response proc" do @shrine.plugin :presign_endpoint, rack_response: -> (o, r) do - [200, {CONTENT_TYPE_HEADER => "application/vnd.api+json"}, [{data: o}.to_json]] + [200, { "Content-Type" => "application/vnd.api+json" }, [{data: o}.to_json]] end response = app.get "/" - assert_equal ["fields", "headers", "method", "url"], JSON.parse(response.body_binary)["data"].keys.sort - assert_equal "application/vnd.api+json", response.headers[CONTENT_TYPE_HEADER] + assert_equal ["fields", "headers", "method", "url"], JSON.parse(response.body)["data"].keys.sort + assert_equal "application/vnd.api+json", response.headers["Content-Type"] end it "allows overriding Cache-Control" do @shrine.plugin :presign_endpoint, rack_response: -> (o, r) do - [200, {CONTENT_TYPE_HEADER => "application/json", "Cache-Control" => "no-cache"}, [o.to_json]] + [200, { "Content-Type" => "application/json", "Cache-Control" => "no-cache"}, [o.to_json]] end response = app.get "/" - assert_equal "no-cache", response.headers[CACHE_CONTROL_HEADER] + assert_equal "no-cache", response.headers["Cache-Control"] end it "allows overriding options when instantiating the endpoint" do - app = Rack::TestApp.wrap(@shrine.presign_endpoint(:cache, presign_options: { content_type: "image/jpeg" }), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + app = Rack::Test::Session.new(@shrine.presign_endpoint(:cache, presign_options: { content_type: "image/jpeg" })) response = app.get "/" - assert_equal "image/jpeg", response.body_json["fields"]["Content-Type"] + assert_equal "image/jpeg", JSON.parse(response.body)["fields"]["Content-Type"] end it "accepts OPTIONS request" do response = app.options "/" - assert_equal 200, response.status - assert_equal Hash[CONTENT_LENGTH_HEADER => "0"], response.headers - assert_equal "", response.body_binary + assert_equal 200, response.status + assert_equal "0", response.headers["Content-Length"] + assert_equal "", response.body end it "accepts only root requests" do @@ -123,8 +126,8 @@ def endpoint it "doesn't accept verbs other than GET or OPTIONS" do response = app.put "/" assert_equal 405, response.status - assert_equal "text/plain", response.headers[CONTENT_TYPE_HEADER] - assert_equal "Method Not Allowed", response.body_binary + assert_equal "text/plain", response.headers["Content-Type"] + assert_equal "Method Not Allowed", response.body end describe "Shrine.presign_response" do @@ -140,7 +143,7 @@ def endpoint response = @shrine.presign_response(:cache, env) assert_equal 200, response[0] - assert_equal "application/json; charset=utf-8", response[1][CONTENT_TYPE_HEADER] + assert_equal "application/json; charset=utf-8", response[1]["Content-Type"] assert_match /\.txt$/, JSON.parse(response[2].first)["fields"]["key"] end @@ -156,7 +159,7 @@ def endpoint response = @shrine.presign_response(:cache, env, presign_options: { content_type: "foo/bar" }) assert_equal 200, response[0] - assert_equal "application/json; charset=utf-8", response[1][CONTENT_TYPE_HEADER] + assert_equal "application/json; charset=utf-8", response[1]["Content-Type"] assert_equal "foo/bar", JSON.parse(response[2].first)["fields"]["Content-Type"] end end diff --git a/test/plugin/rack_response_test.rb b/test/plugin/rack_response_test.rb index f89e672a4..a0cdb4492 100644 --- a/test/plugin/rack_response_test.rb +++ b/test/plugin/rack_response_test.rb @@ -18,71 +18,71 @@ uploaded_file = @uploader.upload(fakeio("content")) uploaded_file.metadata.delete("size") response = uploaded_file.to_rack_response - assert_equal "7", response[1][CONTENT_LENGTH_HEADER] + assert_equal "7", response[1]["Content-Length"] end it "returns Content-Type header with mime_type metadata" do uploaded_file = @uploader.upload(fakeio(content_type: "text/plain")) response = uploaded_file.to_rack_response - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] end it "returns Content-Type header from extension if mime_type metadata is missing" do uploaded_file = @uploader.upload(fakeio(filename: "document.txt")) response = uploaded_file.to_rack_response - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] end it "doesn't return Content-Type header if MIME type is unknown" do uploaded_file = @uploader.upload(fakeio(filename: "foo.foo")) response = uploaded_file.to_rack_response - refute response[1].key?(CONTENT_TYPE_HEADER) + refute response[1].key?("Content-Type") end it "doesn't Content-Type header if MIME type is missing" do uploaded_file = @uploader.upload(fakeio) response = uploaded_file.to_rack_response - refute response[1].key?(CONTENT_TYPE_HEADER) + refute response[1].key?("Content-Type") end it "returns Content-Type header from :type" do uploaded_file = @uploader.upload(fakeio(content_type: "text/plain")) response = uploaded_file.to_rack_response(type: "text/plain; charset=utf-8") - assert_equal "text/plain; charset=utf-8", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain; charset=utf-8", response[1]["Content-Type"] end it "it allows setting Content-Type to application/octet-stream" do uploaded_file = @uploader.upload(fakeio(content_type: "application/octet-stream")) response = uploaded_file.to_rack_response - assert_equal "application/octet-stream", response[1][CONTENT_TYPE_HEADER] + assert_equal "application/octet-stream", response[1]["Content-Type"] uploaded_file = @uploader.upload(fakeio) response = uploaded_file.to_rack_response(type: "application/octet-stream") - assert_equal "application/octet-stream", response[1][CONTENT_TYPE_HEADER] + assert_equal "application/octet-stream", response[1]["Content-Type"] end it "returns Content-Disposition filename from metadata" do uploaded_file = @uploader.upload(fakeio(filename: "plain.txt")) response = uploaded_file.to_rack_response - assert_equal ContentDisposition.inline("plain.txt"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("plain.txt"), response[1]["Content-Disposition"] end it "returns Content-Disposition filename from :filename" do uploaded_file = @uploader.upload(fakeio(filename: "plain.txt")) response = uploaded_file.to_rack_response(filename: "custom.txt") - assert_equal ContentDisposition.inline("custom.txt"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("custom.txt"), response[1]["Content-Disposition"] end it "returns Content-Disposition filename with id if metadata is missing" do uploaded_file = @uploader.upload(fakeio, location: "foo/bar/baz") response = uploaded_file.to_rack_response - assert_equal ContentDisposition.inline("baz"), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.inline("baz"), response[1]["Content-Disposition"] end it "returns Content-Disposition disposition from :disposition" do uploaded_file = @uploader.upload(fakeio) response = uploaded_file.to_rack_response(disposition: "attachment") - assert_equal ContentDisposition.attachment(uploaded_file.id), response[1][CONTENT_DISPOSITION_HEADER] + assert_equal ContentDisposition.attachment(uploaded_file.id), response[1]["Content-Disposition"] end it "returns body which yields contents of the file" do @@ -114,69 +114,69 @@ uploaded_file = @uploader.upload(fakeio("content")) response = uploaded_file.to_rack_response(range: "bytes=0-6") assert_equal 206, response[0] - assert_equal "bytes 0-6/7", response[1][CONTENT_RANGE_HEADER] - assert_equal "7", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 0-6/7", response[1]["Content-Range"] + assert_equal "7", response[1]["Content-Length"] assert_equal "content", response[2].each { |chunk| break chunk } uploaded_file = @uploader.upload(fakeio("content")) response = uploaded_file.to_rack_response(range: "bytes=0-2") assert_equal 206, response[0] - assert_equal "bytes 0-2/7", response[1][CONTENT_RANGE_HEADER] - assert_equal "3", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 0-2/7", response[1]["Content-Range"] + assert_equal "3", response[1]["Content-Length"] assert_equal "con", response[2].each { |chunk| break chunk } uploaded_file = @uploader.upload(fakeio("content")) response = uploaded_file.to_rack_response(range: "bytes=2-4") assert_equal 206, response[0] - assert_equal "bytes 2-4/7", response[1][CONTENT_RANGE_HEADER] - assert_equal "3", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 2-4/7", response[1]["Content-Range"] + assert_equal "3", response[1]["Content-Length"] assert_equal "nte", response[2].each { |chunk| break chunk } uploaded_file = @uploader.upload(fakeio("content")) response = uploaded_file.to_rack_response(range: "bytes=4-6") assert_equal 206, response[0] - assert_equal "bytes 4-6/7", response[1][CONTENT_RANGE_HEADER] - assert_equal "3", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 4-6/7", response[1]["Content-Range"] + assert_equal "3", response[1]["Content-Length"] assert_equal "ent", response[2].each { |chunk| break chunk } end it "returns ranged responses across multiple chunks" do uploaded_file = @uploader.upload(fakeio("a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024)) response = uploaded_file.to_rack_response(range: "bytes=0-36863") - assert_equal "bytes 0-36863/36864", response[1][CONTENT_RANGE_HEADER] - assert_equal "36864", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 0-36863/36864", response[1]["Content-Range"] + assert_equal "36864", response[1]["Content-Length"] yielded_content = "" response[2].each { |chunk| yielded_content << chunk } assert_equal "a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024, yielded_content uploaded_file = @uploader.upload(fakeio("a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024)) response = uploaded_file.to_rack_response(range: "bytes=0-20479") - assert_equal "bytes 0-20479/36864", response[1][CONTENT_RANGE_HEADER] - assert_equal "20480", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 0-20479/36864", response[1]["Content-Range"] + assert_equal "20480", response[1]["Content-Length"] yielded_content = "" response[2].each { |chunk| yielded_content << chunk } assert_equal "a" * 16*1024 + "b" * 4*1024, yielded_content uploaded_file = @uploader.upload(fakeio("a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024)) response = uploaded_file.to_rack_response(range: "bytes=12288-20479") - assert_equal "bytes 12288-20479/36864", response[1][CONTENT_RANGE_HEADER] - assert_equal "8192", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 12288-20479/36864", response[1]["Content-Range"] + assert_equal "8192", response[1]["Content-Length"] yielded_content = "" response[2].each { |chunk| yielded_content << chunk } assert_equal "a" * 4*1024 + "b" * 4*1024, yielded_content uploaded_file = @uploader.upload(fakeio("a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024)) response = uploaded_file.to_rack_response(range: "bytes=12288-33791") - assert_equal "bytes 12288-33791/36864", response[1][CONTENT_RANGE_HEADER] - assert_equal "21504", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 12288-33791/36864", response[1]["Content-Range"] + assert_equal "21504", response[1]["Content-Length"] yielded_content = "" response[2].each { |chunk| yielded_content << chunk } assert_equal "a" * 4*1024 + "b" * 16*1024 + "c" * 1*1024, yielded_content uploaded_file = @uploader.upload(fakeio("a" * 16*1024 + "b" * 16*1024 + "c" * 4*1024)) response = uploaded_file.to_rack_response(range: "bytes=35840-36863") - assert_equal "bytes 35840-36863/36864", response[1][CONTENT_RANGE_HEADER] - assert_equal "1024", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 35840-36863/36864", response[1]["Content-Range"] + assert_equal "1024", response[1]["Content-Length"] yielded_content = "" response[2].each { |chunk| yielded_content << chunk } assert_equal "c" * 1*1024, yielded_content @@ -187,24 +187,24 @@ uploaded_file.metadata.delete("size") response = uploaded_file.to_rack_response(range: "bytes=0-6") assert_equal 206, response[0] - assert_equal "bytes 0-6/7", response[1][CONTENT_RANGE_HEADER] - assert_equal "7", response[1][CONTENT_LENGTH_HEADER] + assert_equal "bytes 0-6/7", response[1]["Content-Range"] + assert_equal "7", response[1]["Content-Length"] assert_equal "content", response[2].each { |chunk| break chunk } end it "returns Accept-Ranges when :range is given" do uploaded_file = @uploader.upload(fakeio) response = uploaded_file.to_rack_response - refute response[1].key?(ACCEPT_RANGES_HEADER) + refute response[1].key?("Accept-Ranges") response = uploaded_file.to_rack_response(range: nil) - assert_equal "bytes", response[1][ACCEPT_RANGES_HEADER] + assert_equal "bytes", response[1]["Accept-Ranges"] end it "returns ETag" do uploaded_file = @uploader.upload(fakeio) response = uploaded_file.to_rack_response - assert_instance_of String, response[1][ETAG_HEADER] - assert_match /^W\/"\w{32}"$/, response[1][ETAG_HEADER] + assert_instance_of String, response[1]["ETag"] + assert_match /^W\/"\w{32}"$/, response[1]["ETag"] end it "makes ETag as unique as possible" do @@ -212,19 +212,19 @@ etags << @uploader.class.new(:cache) .upload(fakeio, location: "foo") - .to_rack_response[1][ETAG_HEADER] + .to_rack_response[1]["ETag"] etags << @uploader.class.new(:cache) .upload(fakeio, location: "bar") - .to_rack_response[1][ETAG_HEADER] + .to_rack_response[1]["ETag"] etags << @uploader.class.new(:store) .upload(fakeio, location: "foo") - .to_rack_response[1][ETAG_HEADER] + .to_rack_response[1]["ETag"] etags << uploader { plugin :rack_response } .upload(fakeio, location: "foo") - .to_rack_response[1][ETAG_HEADER] + .to_rack_response[1]["ETag"] assert_equal etags, etags.uniq end diff --git a/test/plugin/upload_endpoint_test.rb b/test/plugin/upload_endpoint_test.rb index 91750987f..044f8d56c 100644 --- a/test/plugin/upload_endpoint_test.rb +++ b/test/plugin/upload_endpoint_test.rb @@ -1,183 +1,186 @@ require "test_helper" require "shrine/plugins/upload_endpoint" require "http/form_data" +require "rack/test" require "json" describe Shrine::Plugins::UploadEndpoint do def app - Rack::TestApp.wrap(Rack::Lint.new(endpoint), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) + Rack::Test::Session.new(Rack::Lint.new(endpoint)) end def endpoint @shrine.upload_endpoint(:cache) end + def rack_file(filename: nil) + Rack::Test::UploadedFile.new(image.path, "image/jpeg", original_filename: filename) + end + before do @uploader = uploader { plugin :upload_endpoint } @shrine = @uploader.class end it "returns a JSON response" do - response = app.post "/", multipart: { file: image } + response = app.post "/", { file: rack_file } assert_equal 200, response.status - assert_equal "application/json; charset=utf-8", response.headers[CONTENT_TYPE_HEADER] + assert_equal "application/json; charset=utf-8", response.headers["Content-Type"] + + result = JSON.parse(response.body) - assert_match /^\w+\.jpg$/, response.body_json["id"] - assert_equal "cache", response.body_json["storage"] - assert_equal image.size, response.body_json["metadata"]["size"] - assert_equal "image.jpg", response.body_json["metadata"]["filename"] - assert_equal "image/jpeg", response.body_json["metadata"]["mime_type"] + assert_match /^\w+\.jpg$/, result["id"] + assert_equal "cache", result["storage"] + assert_equal image.size, result["metadata"]["size"] + assert_equal "image.jpg", result["metadata"]["filename"] + assert_equal "image/jpeg", result["metadata"]["mime_type"] end it "uploads the file" do - response = app.post "/", multipart: { file: image } - uploaded_file = @shrine.uploaded_file(response.body_json) + response = app.post "/", { file: rack_file } + uploaded_file = @shrine.uploaded_file(response.body) assert_equal image.read, uploaded_file.read end it "finds the file in Uppy's default files[] format" do - response = app.post "/", multipart: {"files[]": image} - uploaded_file = @shrine.uploaded_file(response.body_json) + response = app.post "/", { "files[]": rack_file } + uploaded_file = @shrine.uploaded_file(JSON.parse(response.body)) assert_equal image.read, uploaded_file.read end it "doesn't accept more than one file" do - response = app.post "/", multipart: HTTP::FormData.create({ "files[]": [ - HTTP::FormData::File.new(image.path), - HTTP::FormData::File.new(image.path), - ] }) + response = app.post "/", { "files[]": [rack_file, rack_file] } assert_equal 400, response.status - assert_equal "Too Many Files", response.body_binary + assert_equal "Too Many Files", response.body end it "accepts already wrapped uploaded file (Rails)" do Rack::Request.any_instance.stubs(:params).returns({ "file" => fakeio("file") }) - response = app.post "/", multipart: { file: image } + response = app.post "/", { file: rack_file } assert_equal 200, response.status - assert_equal "file", @shrine.uploaded_file(response.body_json).read + assert_equal "file", @shrine.uploaded_file(JSON.parse(response.body)).read end it "validates maximum size" do @shrine.plugin :upload_endpoint, max_size: 10 - response = app.post "/", multipart: { file: image } + response = app.post "/", { file: rack_file } assert_equal 413, response.status - assert_equal "text/plain", response.headers[CONTENT_TYPE_HEADER] - assert_equal "Upload Too Large", response.body_binary + assert_equal "text/plain", response.headers["Content-Type"] + assert_equal "Upload Too Large", response.body end it "validates that param is a file" do - response = app.post "/", multipart: { file: "image" } + response = app.post "/", { file: "image" }, multipart: true assert_equal 400, response.status - assert_equal "text/plain", response.headers[CONTENT_TYPE_HEADER] - assert_equal "Upload Not Valid", response.body_binary + assert_equal "text/plain", response.headers["Content-Type"] + assert_equal "Upload Not Valid", response.body end it "validates that param is present" do - response = app.post "/", multipart: { image: "image" } + response = app.post "/", { image: "image" }, multipart: true assert_equal 400, response.status - assert_equal "text/plain", response.headers[CONTENT_TYPE_HEADER] - assert_equal "Upload Not Found", response.body_binary + assert_equal "text/plain", response.headers["Content-Type"] + assert_equal "Upload Not Found", response.body end it "handles filenames with UTF-8 characters" do filename = "über_pdf_with_1337%_leetness.pdf" - form = HTTP::FormData.create({ file: HTTP::FormData::Part.new("", filename: filename) }) - response = app.post "/", multipart: { input: form.to_s }, headers: {CONTENT_TYPE_HEADER => form.content_type} + response = app.post "/", { file: rack_file(filename: filename) } assert_equal 200, response.status - uploaded_file = @shrine.uploaded_file(response.body_json) + uploaded_file = @shrine.uploaded_file(response.body) assert_equal filename, uploaded_file.original_filename end it "adds the :action parameter to context" do @shrine.class_eval { def extract_metadata(io, context); { "action" => context[:action] }; end } - response = app.post "/", multipart: { file: image } - assert_equal "upload", response.body_json["metadata"]["action"] + response = app.post "/", { file: rack_file } + assert_equal "upload", JSON.parse(response.body)["metadata"]["action"] end it "accepts upload context" do @shrine.plugin :upload_endpoint, upload_context: -> (r) { { location: "foo" } } - response = app.post "/", multipart: { file: image } - assert_equal "foo", response.body_json["id"] - uploaded_file = @shrine.uploaded_file(response.body_json) + response = app.post "/", { file: rack_file } + assert_equal "foo", JSON.parse(response.body)["id"] + uploaded_file = @shrine.uploaded_file(response.body) assert_equal image.read, uploaded_file.read end it "accepts upload proc" do @shrine.plugin :upload_endpoint, upload: -> (i, c, r) { @uploader.upload(i, **c, location: "foo") } - response = app.post "/", multipart: { file: image } - assert_equal "foo", response.body_json["id"] - uploaded_file = @shrine.uploaded_file(response.body_json) + response = app.post "/", { file: rack_file } + assert_equal "foo", JSON.parse(response.body)["id"] + uploaded_file = @shrine.uploaded_file(response.body) assert_equal image.read, uploaded_file.read end it "accepts :url parameter" do @shrine.plugin :upload_endpoint, url: true - response = app.post "/", multipart: { file: image } - uploaded_file = @shrine.uploaded_file(response.body_json["data"]) - assert_equal uploaded_file.url, response.body_json["url"] + response = app.post "/", { file: rack_file } + uploaded_file = @shrine.uploaded_file(JSON.parse(response.body)["data"]) + assert_equal uploaded_file.url, JSON.parse(response.body)["url"] @shrine.plugin :upload_endpoint, url: { foo: "bar" }, upload_context: -> (r) { { location: "foo" } } @shrine.storages[:cache].expects(:url).with("foo", { foo: "bar" }).returns("my-url") - response = app.post "/", multipart: { file: image } - assert_equal "my-url", response.body_json["url"] + response = app.post "/", { file: rack_file } + assert_equal "my-url", JSON.parse(response.body)["url"] @shrine.plugin :upload_endpoint, url: -> (f, r) { "my-url" } - response = app.post "/", multipart: { file: image } - assert_equal "my-url", response.body_json["url"] + response = app.post "/", { file: rack_file } + assert_equal "my-url", JSON.parse(response.body)["url"] end it "verifies provided checksum" do - response = app.post "/", multipart: { file: image }, headers: { "Content-MD5" => Digest::MD5.base64digest(image.read) } + response = app.post "/", { file: rack_file }, { "HTTP_CONTENT_MD5" => Digest::MD5.base64digest(image.read) } assert_equal 200, response.status - response = app.post "/", multipart: { file: image }, headers: { "Content-MD5" => Digest::MD5.base64digest("") } + response = app.post "/", { file: rack_file }, { "HTTP_CONTENT_MD5" => Digest::MD5.base64digest("") } assert_equal 460, response.status - assert_equal "The Content-MD5 you specified did not match what was recieved", response.body_binary + assert_equal "The Content-MD5 you specified did not match what was recieved", response.body - response = app.post "/", multipart: { file: image }, headers: { "Content-MD5" => "foo" } + response = app.post "/", { file: rack_file }, { "HTTP_CONTENT_MD5" => "foo" } assert_equal 400, response.status - assert_equal "The Content-MD5 you specified was invalid", response.body_binary + assert_equal "The Content-MD5 you specified was invalid", response.body end it "accepts response proc" do @shrine.plugin :upload_endpoint, rack_response: -> (o, r) do - [200, {CONTENT_TYPE_HEADER => "application/vnd.api+json"}, [{data: o}.to_json]] + [200, {"Content-Type" => "application/vnd.api+json"}, [{data: o}.to_json]] end - response = app.post "/", multipart: { file: image } - assert_equal ["id", "storage", "metadata"], JSON.parse(response.body_binary)["data"].keys - assert_equal "application/vnd.api+json", response.headers[CONTENT_TYPE_HEADER] + response = app.post "/", { file: rack_file } + assert_equal ["id", "storage", "metadata"], JSON.parse(response.body)["data"].keys + assert_equal "application/vnd.api+json", response.headers["Content-Type"] end it "allows overriding options when instantiating the endpoint" do - app = Rack::TestApp.wrap(@shrine.upload_endpoint(:cache, max_size: 10), { Rack::SERVER_PROTOCOL => "HTTP/1.1" }) - response = app.post "/", multipart: { file: image } + app = Rack::Test::Session.new(@shrine.upload_endpoint(:cache, max_size: 10)) + response = app.post "/", { file: rack_file } assert_equal 413, response.status end it "doesn't react to parseable Content-Type" do - response = app.post "/", headers: { CONTENT_TYPE_HEADER => "application/x-www-form-urlencoded" } + response = app.post "/", {}, { "CONTENT_TYPE" => "application/x-www-form-urlencoded" } assert_equal 400, response.status - assert_equal "Upload Not Found", response.body_binary + assert_equal "Upload Not Found", response.body end it "doesn't react to blank Content-Type" do - response = app.post "/", headers: { CONTENT_TYPE_HEADER => "" } + response = app.post "/", {}, { "CONTENT_TYPE" => "" } assert_equal 400, response.status - assert_equal "Upload Not Found", response.body_binary + assert_equal "Upload Not Found", response.body end it "accepts only POST requests" do - response = app.put "/", multipart: { file: image } + response = app.put "/", { file: rack_file } assert_equal 405, response.status - assert_equal "text/plain", response.headers[CONTENT_TYPE_HEADER] - assert_equal "Method Not Allowed", response.body_binary + assert_equal "text/plain", response.headers["Content-Type"] + assert_equal "Method Not Allowed", response.body end it "accepts only root requests" do - response = app.post "/upload", multipart: { file: image } + response = app.post "/upload", { file: rack_file } assert_equal 404, response.status end @@ -199,7 +202,7 @@ def endpoint response = @shrine.upload_response(:cache, env) assert_equal 200, response[0] - assert_equal "application/json; charset=utf-8", response[1][CONTENT_TYPE_HEADER] + assert_equal "application/json; charset=utf-8", response[1]["Content-Type"] assert_equal "content", @shrine.uploaded_file(response[2].first).read end @@ -220,7 +223,7 @@ def endpoint response = @shrine.upload_response(:cache, env, max_size: 1) assert_equal 413, response[0] - assert_equal "text/plain", response[1][CONTENT_TYPE_HEADER] + assert_equal "text/plain", response[1]["Content-Type"] assert_equal "Upload Too Large", response[2].first end end diff --git a/test/storage/file_system_test.rb b/test/storage/file_system_test.rb index e6f29aca9..9fffcc02d 100644 --- a/test/storage/file_system_test.rb +++ b/test/storage/file_system_test.rb @@ -350,6 +350,10 @@ def root_symlink assert_equal "#{root}/uploads/foo.jpg", @storage.open("foo.jpg").path end + it "forbids traversal" do + # assertions + end + def assert_permissions(expected, path) assert_equal expected, File.lstat(path).mode & 0777 end diff --git a/test/support/ext.rb b/test/support/ext.rb deleted file mode 100644 index af1dbe286..000000000 --- a/test/support/ext.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "rack/test_app" - -class Rack::TestApp::Wrapper - %w[get post put delete head patch options trace].each do |verb| - undef_method verb.upcase - define_method(verb.upcase) { |path, **kwargs| request(verb.upcase.to_sym, path, **kwargs) } - - undef_method verb - alias_method verb, verb.upcase - end -end - -module RackTestAppResultPatch - def body_binary - @body_binary ||= super - end - - def body_text - @body_text ||= super - end - - def body_json - @body_json ||= super - end -end - -Rack::TestApp::Result.send(:prepend, RackTestAppResultPatch) diff --git a/test/test_helper.rb b/test/test_helper.rb index 5d3789cf1..6170a4618 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -28,7 +28,6 @@ require "./test/support/shrine_helper" require "./test/support/file_helper" require "./test/support/logging_helper" -require "./test/support/ext" class RubySerializer def self.dump(data) @@ -39,12 +38,3 @@ def self.load(data) eval(data) end end - -ACCEPT_RANGES_HEADER = Rack.release >= "3" ? "accept-ranges" : "Accept-Ranges" -CACHE_CONTROL_HEADER = Rack.release >= "3" ? "cache-control" : "Cache-Control" -CONTENT_DISPOSITION_HEADER = Rack.release >= "3" ? "content-disposition" : "Content-Disposition" -CONTENT_LENGTH_HEADER = Rack.release >= "3" ? "content-length" : "Content-Length" -CONTENT_RANGE_HEADER = Rack.release >= "3" ? "content-range" : "Content-Range" -CONTENT_TYPE_HEADER = Rack.release >= "3" ? "content-type" : "Content-Type" -ETAG_HEADER = Rack.release >= "3" ? "etag" : "ETag" -LOCATION_HEADER = Rack.release >= "3" ? "location" : "Location"