diff --git a/lib/rack/pact_broker/accepts_html_filter.rb b/lib/rack/pact_broker/accepts_html_filter.rb index d0ff21e8c..88b06f301 100644 --- a/lib/rack/pact_broker/accepts_html_filter.rb +++ b/lib/rack/pact_broker/accepts_html_filter.rb @@ -1,4 +1,5 @@ -# Decides whether this is a browser request or a request for the API +# Decides whether this is a request for the UI or a request for the API + module Rack module PactBroker class AcceptsHtmlFilter @@ -7,24 +8,29 @@ def initialize app end def call env - if accepts_web_content_types_and_not_api_media env + if request_for_ui_resource? env @app.call(env) else [404, {},[]] end end - def accepts_web_content_types_and_not_api_media env - accept = env['HTTP_ACCEPT'] || '' - accepts_web_content_types(accept) && !accepts_api_content_types(accept) + private + + def request_for_ui_resource? env + request_for_file?(env) || accepts_html?(env) end - def accepts_web_content_types(accept) - accept.include?("*/*") || accept.include?("html") || accept.include?("text/css") || accept.include?("text/javascript") + def request_for_file?(env) + if last_segment = env['PATH_INFO'].split("/").last + last_segment.include?(".") + else + false + end end - def accepts_api_content_types accept - accept.include?("json") || accept.include?("csv") + def accepts_html?(env) + (env['HTTP_ACCEPT'] || '').include?("text/html") end end end diff --git a/spec/lib/rack/pact_broker/accepts_html_filter_spec.rb b/spec/lib/rack/pact_broker/accepts_html_filter_spec.rb new file mode 100644 index 000000000..39c1dc0fa --- /dev/null +++ b/spec/lib/rack/pact_broker/accepts_html_filter_spec.rb @@ -0,0 +1,43 @@ +require 'rack/pact_broker/accepts_html_filter' +require 'rack/test' + +module Rack + module PactBroker + describe AcceptsHtmlFilter do + include Rack::Test::Methods + + describe "#call" do + let(:target_app) { double('target_app', call: [200, {}, []]) } + let(:app) { AcceptsHtmlFilter.new(target_app) } + let(:path) { "/" } + let(:accept) { "text/html" } + + subject { get path, nil, { "HTTP_ACCEPT" => accept } } + + context "when the Accept header includes text/html" do + it "forwards the request to the target app" do + expect(target_app).to receive(:call) + subject + end + end + + context "when the request is for a file" do + let(:path) { "/blah/foo.css" } + + it "forwards the request to the target app" do + expect(target_app).to receive(:call) + subject + end + end + + context "when the request is not for a file, and the Accept header does not include text/html" do + let(:accept) { "application/hal+json, */*" } + + it "returns a 404" do + expect(subject.status).to eq 404 + end + end + end + end + end +end