require File.expand_path(File.dirname(__FILE__) + '/spec_helper') describe "Rack::AcceptOnly" do before(:each) do @app = lambda{ |env| [111, {'foo' => 'bar', 'Content-Type' => @return_type}, ["Something"]] } end context "if not supplied a permitted content type" do before(:each) do @accept_only = Rack::AcceptOnly.new(@app) end context "and the Accept header is not present in the request" do before(:each) do @request = Rack::MockRequest.env_for("/") end it "should not modify the downstream response" do @return_type = "foo" @accept_only.call(@request).should == @app.call(@request) end end context "and the Accept header is present in the request" do before(:each) do @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "acceptable") end context "and the Content-Type of the downstream reply is not acceptable" do it "should reject the request" do @return_type = "not_acceptable" @accept_only.call(@request)[0].should == 406 end it "should include the downstream Content-Type in the reply" do @return_type = "not_acceptable" @accept_only.call(@request)[1]['Content-Type'].should == "not_acceptable" end end context "and the Content-Type of the downstream reply is acceptable" do it "should not modify the downstream response" do @return_type = "acceptable" @accept_only.call(@request).should == @app.call(@request) end end end end context "if supplied a (single) permitted content type" do before(:each) do @accept_only = Rack::AcceptOnly.new(@app, "permitted") end context "and the Accept header is not present in the request" do before(:each) do @request = Rack::MockRequest.env_for("/") end it "should signal server error if the Content-Type of the downstream reply is not permitted" do @return_type = "not_permitted" @accept_only.call(@request)[0].should == 500 end it "should not modify the downstream response if the Content-Type of the downstream reply is permitted" do @return_type = "permitted" @accept_only.call(@request).should == @app.call(@request) end end context "and the Accept header is present in the request" do context "if the acceptable types do not include the permitted type" do before(:each) do @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "not_permitted, also_not_permitted") @return_type = "shouldnt_see_this" end it "should reject the request" do @accept_only.call(@request)[0].should == 406 end it "should include the permitted type in the reply" do @accept_only.call(@request)[1]['Content-Type'].should == "permitted" end it "should not call downstream middleware" do @app.should_not_receive(:call) @accept_only.call(@request) end end context "if the acceptable types do include the permitted type" do before(:each) do @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "not_permitted, permitted") end it "should signal server error if the Content-Type of the downstream reply is not permitted" do @return_type = "not_permitted" @accept_only.call(@request)[0].should == 500 end it "should not modify the downstream response if the Content-Type of the downstream reply is permitted" do @return_type = "permitted" @accept_only.call(@request).should == @app.call(@request) end end end end it "should reject non-simple permitted types" do lambda{Rack::AcceptOnly.new(@app, "audio/*")}.should raise_error lambda{Rack::AcceptOnly.new(@app, "*/*")}.should raise_error lambda{Rack::AcceptOnly.new(@app, "image/gif; q=0.8")}.should raise_error end it "should handle more complex accept headers in the request when given a permitted type" do @accept_only = Rack::AcceptOnly.new(@app, "image/jpeg") @return_type = "image/jpeg" @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "image/gif, image/*; q=0.8") @accept_only.call(@request).should == @app.call(@request) @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "*/*") @accept_only.call(@request).should == @app.call(@request) end it "should handle more complex accept headers in the request when not given a permitted type" do @accept_only = Rack::AcceptOnly.new(@app) @return_type = "image/jpeg" @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "image/gif, image/*; q=0.8") @accept_only.call(@request).should == @app.call(@request) @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "*/*") @accept_only.call(@request).should == @app.call(@request) end it "should signal server error if the reply has no content-type when given a permitted type" do @app = lambda{ |env| [111, {'foo' => 'bar'}, ["Something"]] } @accept_only = Rack::AcceptOnly.new(@app, "image/jpeg") @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "image/jpeg") @accept_only.call(@request)[0].should == 500 end it "should signal server error if the reply has no content-type when not given a permitted type" do @app = lambda{ |env| [111, {'foo' => 'bar'}, ["Something"]] } @accept_only = Rack::AcceptOnly.new(@app) @request = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "image/jpeg") @accept_only.call(@request)[0].should == 500 end end