require File.join(File.dirname(__FILE__), "spec_helper") describe Merb::Controller, " responds" do before do Merb.push_path(:layout, File.dirname(__FILE__) / "controllers" / "views" / "layouts") Merb::Router.prepare do |r| r.default_routes end end it "should default the mime-type to HTML" do dispatch_to(Merb::Test::Fixtures::Controllers::HtmlDefault, :index).body.should == "HTML: Default" end it "should use other mime-types if they are provided on the controller-level" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassProvides, :index, {}, :http_accept => "application/xml") controller.body.should == "" end it "should fail if none of the acceptable mime-types are available" do calling { dispatch_to(Merb::Test::Fixtures::Controllers::ClassProvides, :index, {}, :http_accept => "application/json") }. should raise_error(Merb::ControllerExceptions::NotAcceptable) end it "should use mime-types that are provided at the action-level" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::LocalProvides, :index, {}, :http_accept => "application/xml") controller.body.should == "" end it "should use mime-types that are provided at the controller-level as well as the action-level (controller)" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassAndLocalProvides, :index, {}, :http_accept => "text/html") controller.class_provided_formats.should == [:html] controller._provided_formats.should == [:html, :xml] controller.body.should == "HTML: Class and Local" end it "should use mime-types that are provided at the controller-level as well as the action-level (action)" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassAndLocalProvides, :index, {}, :http_accept => "application/xml") controller.class_provided_formats.should == [:html] controller._provided_formats.should == [:html, :xml] controller.body.should == "" end it "should use the first mime-type when accepting anything */*" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::MultiProvides, :index, {}, :http_accept => "*/*") controller.body.should == "HTML: Multi" end it "should pick application/xhtml+xml when both application/xml and application/xhtml+xml are available" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassProvides, :index, {}, :http_accept => "application/xml,application/xhtml+xml") controller.body.should == "HTML: Wins Over XML If Both Are Specified" end it "should use the first mime-type when accepting anything */*, even if something unprovidable comes first" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::HtmlDefault, :index, {}, :http_accept => "application/json, */*") controller.body.should == "HTML: Default" end it "should use the pick the first mime-type from the list not the */*" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::MultiProvides, :index, {}, :http_accept => "text/javascript, */*") controller.body.should == "JS: Multi" end it "should pick the first mime-type if no specific supported content-type matches are *available*" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::MultiProvides, :index, {}, :http_accept => "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*") controller.body.should == "HTML: Multi" end it "should pick the first mime-type if no specific supported content-type matches are actually *provided*" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::MultiProvides, :index, {}, :http_accept => "application/json, */*") controller.body.should == "HTML: Multi" end it "should select the format based on params supplied to it with controller-level provides" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassProvides, :index, :format => "xml") controller.content_type.should == :xml end it "should select the format based on params supplied to it with action-level provides" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::LocalProvides, :index, :format => "xml") controller.content_type.should == :xml end it "should select the format based on params supplied to it with controller and action provides (controller)" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassAndLocalProvides, :index, :format => "html") controller.content_type.should == :html end it "should select the format based on params supplied to it with controller and action provides (action)" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassAndLocalProvides, :index, :format => "xml") controller.content_type.should == :xml end it "should properly add formats when only_provides is called in action" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::OnlyProvides, :index, {}, :http_accept => "application/xml") controller._provided_formats.should == [:text, :xml] controller.content_type.should == :xml end it "should properly remove formats when only_provides is called in action" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::OnlyProvides, :index, {}, :http_accept => "text/html") lambda { controller.content_type }.should raise_error(Merb::ControllerExceptions::NotAcceptable) end it "should properly add formats when only_provides is called in controller" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassOnlyProvides, :index, {}, :http_accept => "application/xml") controller._provided_formats.should == [:text, :xml] controller.content_type.should == :xml end it "should properly remove formats when only_provides is called in controller" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassOnlyProvides, :index, {}, :http_accept => "text/html") lambda { controller.content_type }.should raise_error(Merb::ControllerExceptions::NotAcceptable) end it "should properly remove formats when does_not_provide is called in controller" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassDoesntProvides, :index, {}, :http_accept => "text/html") controller._provided_formats.should == [:xml] lambda { controller.content_type }.should raise_error(Merb::ControllerExceptions::NotAcceptable) end it "should properly remove formats when does_not_provide is called in action" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::DoesntProvide, :index, {}, :http_accept => "text/html") controller._provided_formats.should == [:xml] lambda { controller.content_type }.should raise_error(Merb::ControllerExceptions::NotAcceptable) end it "should return the correct default HTTP headers for a format" do controller = dispatch_to(Merb::Test::Fixtures::Controllers::ClassProvides, :index, :format => "xml") controller.headers.keys.sort.should == ["Content-Type"] controller.headers["Content-Type"].should == "application/xml; charset=utf-8" end it "should append the correct charset which was set when the format was added" do Merb.add_mime_type(:foo, nil, %w[application/foo], :charset => "iso-8859-1") controller = dispatch_to(Merb::Test::Fixtures::Controllers::FooFormatProvides, :index, :format => "foo") controller.headers["Content-Type"].should == "application/foo; charset=iso-8859-1" end it "should return the correct HTTP headers which were set when the format was added" do Merb.add_mime_type(:foo, nil, %w[application/foo], "Foo" => 'bar', "Content-Language" => "en", :charset => "utf-8") controller = dispatch_to(Merb::Test::Fixtures::Controllers::FooFormatProvides, :index, :format => "foo") controller.headers.keys.should_not include(:charset) controller.headers["Content-Type"].should == "application/foo; charset=utf-8" controller.headers["Content-Language"].should == "en" controller.headers["Foo"] = "bar" end it "should return the correct HTTP headers using the block given when the format was added" do Merb.add_mime_type(:foo, nil, %w[application/foo], "Foo" => "bar") do |controller| controller.headers["Action-Name"] = controller.action_name end controller = dispatch_to(Merb::Test::Fixtures::Controllers::FooFormatProvides, :index, :format => "foo") controller.headers["Content-Type"].should == "application/foo" controller.headers["Action-Name"].should == "index" controller.headers["Foo"] = "bar" end it "should not overwrite runtime-set headers with default format response headers" do Merb.add_mime_type(:foo, nil, %w[application/foo], "Foo" => "bar", "Content-Language" => "en") controller = dispatch_to(Merb::Test::Fixtures::Controllers::FooFormatProvides, :show, :format => "foo") controller.headers["Content-Language"].should == "nl" controller.headers["Biz"] = "buzz" controller.headers["Foo"] = "bar" end end