# This specifies the extended behavior of the SiteController which includes
# serving up the stylesheets and javascripts to the public.
require File.dirname(__FILE__) + '/../spec_helper'
describe SiteController, "(Extended)" do
integrate_views
# Pages scenario is used for two reasons. First, we test for conditions where
# pages urls may conflict with stylesheet_ or javascript_directory urls.
# Secondly, at least one page must exist when SiteController goes to find an
# uncached page or else it redirects the user to the login screen.
scenario :javascripts, :stylesheets, :pages
before(:each) do
# make sure the css_ and js_directories are the default ones
Sns::Config.restore_defaults
# don't bork results with stale cache items
controller.text_asset_cache.clear
end
it "should be a SiteController" do
controller.should be_kind_of(SiteController)
end
it "should offer a #text_asset_cache method to access TextAssetResponseCache" do
controller.text_asset_cache.should be_kind_of(TextAssetResponseCache)
end
[ { :class => Stylesheet,
:name => 'stylesheet',
:default_directory => "css" },
{ :class => Javascript,
:name => 'javascript',
:default_directory => "js" }
].each do |current_asset|
describe ",when routing #{current_asset[:name].pluralize}," do
it "should send default #{current_asset[:name]}_directory urls (setting isn't customized) to #show_page action" do
params_from(:get, "/#{current_asset[:default_directory]}/main").should ==
{ :controller => "site",
:action => "show_page",
:url => current_asset[:default_directory].split("/") << "main" }
end
it "should send customized #{current_asset[:name]}_directory urls to #show_page action" do
Sns::Config["#{current_asset[:name]}_directory"] = "foo"
params_from(:get, "/foo/main").should ==
{ :controller => "site",
:action => "show_page",
:url => ["foo", "main"] }
end
it "should send multi-level, customized #{current_asset[:name]}_directory urls to #show_page action" do
Sns::Config[current_asset[:name] + '_directory'] = 'foo/bar/baz'
params_from(:get, "/foo/bar/baz/main").should ==
{ :controller => "site",
:action => "show_page",
:url => ["foo", "bar", "baz", "main"] }
end
end
describe "valid GET requests" do
it "should render the content for existing #{current_asset[:name].pluralize}" do
get :show_page,
:url => current_asset[:default_directory].split("/") << "main"
response.should be_success
response.body.should == "Main #{current_asset[:name]} content"
end
it "should find and render an existing #{current_asset[:name]} on the default dev site" do
request.host = "dev.site.com"
get :show_page,
:url => current_asset[:default_directory].split("/") << "main"
response.should be_success
response.body.should == "Main #{current_asset[:name]} content"
end
it "should render a 404 page for a non-existing #{current_asset[:name]}" do
get :show_page,
:url => current_asset[:default_directory].split("/") << "non-existent.file"
response.should render_template('site/not_found')
response.headers["Status"].should == "404 Not Found"
end
it "should render a 404 page for #{current_asset[:name]}_directory (/#{current_asset[:default_directory]}/)" do
get :show_page,
:url => current_asset[:default_directory].split("/")
response.should render_template('site/not_found')
response.headers["Status"].should == "404 Not Found"
end
it "should render a 404 page if url includes a deeper path than :#{current_asset[:name]}_directory" do
get :show_page,
:url => current_asset[:default_directory].split("/") << 'bogus' << 'extra' << 'path' << 'main'
response.headers["Status"].should == "404 Not Found"
response.should render_template('site/not_found')
end
# This is sort of dumb. Really, users should not go anywhere near creating
# a page with the same name as the css directory. If they do, here's what
# should happen.
describe "with URLs that overlap Page namespaces" do
it "should render a page that is competing with :#{current_asset[:name]}_directory (the directory)" do
create_page current_asset[:default_directory]
get :show_page,
:url => current_asset[:default_directory].split("/")
response.should be_success
response.body.should == "#{current_asset[:default_directory]} body."
end
it "should render a page inside: #{current_asset[:name]}_directory (immediate child of /#{current_asset[:default_directory]}/)" do
create_page current_asset[:default_directory] do
create_page 'page-inside'
end
get :show_page,
:url => current_asset[:default_directory].split("/") << 'page-inside'
response.should be_success
response.body.should == 'page-inside body.'
end
it "should render a page inside: #{current_asset[:name]}_directory (grandchild of /#{current_asset[:default_directory]}/)" do
create_page current_asset[:default_directory] do
create_page 'page-inside' do
create_page 'another-page'
end
end
get :show_page,
:url => current_asset[:default_directory].split("/") << 'page-inside' << 'another-page'
response.should be_success
response.body.should == 'another-page body.'
end
it "should render the #{current_asset[:name]} and not the page if both have the same url" do
create_page current_asset[:default_directory] do
create_page 'abc.123'
end
send("create_#{current_asset[:name]}", 'abc.123')
get :show_page,
:url => current_asset[:default_directory].split("/") << 'abc.123'
response.should be_success
response.body.should == "#{current_asset[:name]} content for abc.123"
end
end
describe "with regard to Last-Modified date" do
before :each do
@dependant = current_asset[:class].new(:filename => 'dependant')
@dependency = current_asset[:class].new(:filename => 'dependency')
save_asset_at(@dependant, 1990)
end
it "should be a string" do
get :show_page,
:url => current_asset[:default_directory].split("/") << 'dependant'
response.headers['Last-Modified'].should be_kind_of(String)
end
it "should use a valid HTTP header date format" do
get :show_page,
:url => current_asset[:default_directory].split("/") << 'dependant'
response.headers['Last-Modified'].should == "Mon, 01 Jan 1990 00:00:00 GMT"
end
it "should reflect the #{current_asset[:name]}'s updated_at date/time if the file has no dependencies" do
get :show_page,
:url => current_asset[:default_directory].split("/") << 'dependant'
response.headers['Last-Modified'].should == Time.gm(1990).httpdate
end
it "should reflect the #{current_asset[:name]}'s updated_at date/time if its dependencies are older" do
@dependant.content = %{}
save_asset_at(@dependency, 1991)
save_asset_at(@dependant, 1992)
get :show_page,
:url => current_asset[:default_directory].split("/") << 'dependant'
response.headers['Last-Modified'].should == Time.gm(1992).httpdate
end
it "should reflect the #{current_asset[:name]}'s dependency's updated_at date/time if its dependencies are newer" do
@dependant.content = %{}
save_asset_at(@dependant, 1993)
save_asset_at(@dependency, 1994)
get :show_page,
:url => current_asset[:default_directory].split("/") << 'dependant'
response.headers['Last-Modified'].should == Time.gm(1994).httpdate
end
end
end
end
end
private
def save_asset_at(text_asset, year)
Time.stub!(:now).and_return(Time.gm(year))
text_asset.save!
end