Vendoring Rails 2.3.5

This commit is contained in:
Eric Allen 2009-12-07 12:42:42 -05:00
parent 3e83d19299
commit f8779795ce
943 changed files with 56503 additions and 61351 deletions

View file

@ -1,39 +1,61 @@
$:.unshift(File.dirname(__FILE__) + '/../lib')
$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
require 'rubygems'
require 'yaml'
require 'stringio'
require 'test/unit'
gem 'mocha', '>= 0.9.7'
require 'mocha'
begin
require 'ruby-debug'
Debugger.settings[:autoeval] = true
Debugger.start
rescue LoadError
# Debugging disabled. `gem install ruby-debug` to enable.
end
require 'action_controller'
require 'action_controller/cgi_ext'
require 'action_controller/test_process'
require 'action_view/test_case'
begin
require 'ruby-debug'
rescue LoadError
# Debugging disabled. `gem install ruby-debug` to enable.
end
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
ActionController::Base.logger = nil
ActionController::Routing::Routes.reload rescue nil
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
ActionView::PathSet::Path.eager_load_templates!
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
ActionController::Base.session_store = nil
# Wrap tests that use Mocha and skip if unavailable.
def uses_mocha(test_name)
unless Object.const_defined?(:Mocha)
require 'mocha'
require 'stubba'
# Register danish language for testing
I18n.backend.store_translations 'da', {}
I18n.backend.store_translations 'pt-BR', {}
ORIGINAL_LOCALES = I18n.available_locales.map(&:to_s).sort
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
ActionView::Base.cache_template_loading = true
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
CACHED_VIEW_PATHS = ActionView::Base.cache_template_loading? ?
ActionController::Base.view_paths :
ActionController::Base.view_paths.map {|path| ActionView::Template::EagerPath.new(path.to_s)}
class DummyMutex
def lock
@locked = true
end
def unlock
@locked = false
end
def locked?
@locked
end
yield
rescue LoadError => load_error
raise unless load_error.message =~ /mocha/i
$stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
end
ActionController::Reloader.default_lock = DummyMutex.new

View file

@ -51,7 +51,8 @@ class ActiveRecordTestConnector
if Object.const_defined?(:ActiveRecord)
defaults = { :database => ':memory:' }
begin
options = defaults.merge :adapter => 'sqlite3', :timeout => 500
adapter = defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'
options = defaults.merge :adapter => adapter, :timeout => 500
ActiveRecord::Base.establish_connection(options)
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
ActiveRecord::Base.connection
@ -82,7 +83,9 @@ class ActiveRecordTestConnector
end
end
class ActiveRecordTestCase < ActiveSupport::TestCase
class ActiveRecordTestCase < ActionController::TestCase
include ActiveRecord::TestFixtures
# Set our fixture path
if ActiveRecordTestConnector.able_to_connect
self.fixture_path = [FIXTURE_LOAD_PATH]
@ -96,8 +99,6 @@ class ActiveRecordTestCase < ActiveSupport::TestCase
def run(*args)
super if ActiveRecordTestConnector.connected
end
def default_test; end
end
ActiveRecordTestConnector.setup

View file

@ -1,141 +1,174 @@
# These tests exercise CGI::Session::ActiveRecordStore, so you're going to
# need AR in a sibling directory to AP and have SQLite installed.
require 'active_record_unit'
require 'action_controller/session/active_record_store'
module CommonActiveRecordStoreTests
def test_basics
s = session_class.new(:session_id => '1234', :data => { 'foo' => 'bar' })
assert_equal 'bar', s.data['foo']
assert s.save
assert_equal 'bar', s.data['foo']
class ActiveRecordStoreTest < ActionController::IntegrationTest
DispatcherApp = ActionController::Dispatcher.new
SessionApp = ActiveRecord::SessionStore.new(DispatcherApp,
:key => '_session_id')
SessionAppWithFixation = ActiveRecord::SessionStore.new(DispatcherApp,
:key => '_session_id', :cookie_only => false)
assert_not_nil t = session_class.find_by_session_id('1234')
assert_not_nil t.data
assert_equal 'bar', t.data['foo']
class TestController < ActionController::Base
def no_session_access
head :ok
end
def set_session_value
session[:foo] = params[:foo] || "bar"
head :ok
end
def get_session_value
render :text => "foo: #{session[:foo].inspect}"
end
def get_session_id
session[:foo]
render :text => "#{request.session_options[:id]}"
end
def call_reset_session
session[:foo]
reset_session
session[:foo] = "baz"
head :ok
end
def rescue_action(e) raise end
end
def test_reload_same_session
@new_session.update
reloaded = CGI::Session.new(CGI.new, 'session_id' => @new_session.session_id, 'database_manager' => CGI::Session::ActiveRecordStore)
assert_equal 'bar', reloaded['foo']
def setup
ActiveRecord::SessionStore.session_class.create_table!
@integration_session = open_session(SessionApp)
end
def test_tolerates_close_close
assert_nothing_raised do
@new_session.close
@new_session.close
def teardown
ActiveRecord::SessionStore.session_class.drop_table!
end
def test_setting_and_getting_session_value
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "bar"', response.body
get '/set_session_value', :foo => "baz"
assert_response :success
assert cookies['_session_id']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "baz"', response.body
end
end
end
class ActiveRecordStoreTest < ActiveRecordTestCase
include CommonActiveRecordStoreTests
def session_class
CGI::Session::ActiveRecordStore::Session
end
def session_id_column
"session_id"
end
def setup
session_class.create_table!
ENV['REQUEST_METHOD'] = 'GET'
ENV['REQUEST_URI'] = '/'
CGI::Session::ActiveRecordStore.session_class = session_class
@cgi = CGI.new
@new_session = CGI::Session.new(@cgi, 'database_manager' => CGI::Session::ActiveRecordStore, 'new_session' => true)
@new_session['foo'] = 'bar'
end
# this test only applies for eager session saving
# def test_another_instance
# @another = CGI::Session.new(@cgi, 'session_id' => @new_session.session_id, 'database_manager' => CGI::Session::ActiveRecordStore)
# assert_equal @new_session.session_id, @another.session_id
# end
def test_model_attribute
assert_kind_of CGI::Session::ActiveRecordStore::Session, @new_session.model
assert_equal({ 'foo' => 'bar' }, @new_session.model.data)
end
def test_save_unloaded_session
c = session_class.connection
bogus_class = c.quote(ActiveSupport::Base64.encode64("\004\010o:\vBlammo\000"))
c.insert("INSERT INTO #{session_class.table_name} ('#{session_id_column}', 'data') VALUES ('abcdefghijklmnop', #{bogus_class})")
sess = session_class.find_by_session_id('abcdefghijklmnop')
assert_not_nil sess
assert !sess.loaded?
# because the session is not loaded, the save should be a no-op. If it
# isn't, this'll try and unmarshall the bogus class, and should get an error.
assert_nothing_raised { sess.save }
end
def teardown
session_class.drop_table!
end
end
class ColumnLimitTest < ActiveRecordTestCase
def setup
@session_class = CGI::Session::ActiveRecordStore::Session
@session_class.create_table!
end
def teardown
@session_class.drop_table!
end
def test_protection_from_data_larger_than_column
# Can't test this unless there is a limit
return unless limit = @session_class.data_column_size_limit
too_big = ':(' * limit
s = @session_class.new(:session_id => '666', :data => {'foo' => too_big})
s.data
assert_raise(ActionController::SessionOverflowError) { s.save }
end
end
class DeprecatedActiveRecordStoreTest < ActiveRecordStoreTest
def session_id_column
"sessid"
end
def setup
session_class.connection.execute 'create table old_sessions (id integer primary key, sessid text unique, data text)'
session_class.table_name = 'old_sessions'
session_class.send :setup_sessid_compatibility!
ENV['REQUEST_METHOD'] = 'GET'
CGI::Session::ActiveRecordStore.session_class = session_class
@new_session = CGI::Session.new(CGI.new, 'database_manager' => CGI::Session::ActiveRecordStore, 'new_session' => true)
@new_session['foo'] = 'bar'
end
def teardown
session_class.connection.execute 'drop table old_sessions'
session_class.table_name = 'sessions'
end
end
class SqlBypassActiveRecordStoreTest < ActiveRecordStoreTest
def session_class
unless defined? @session_class
@session_class = CGI::Session::ActiveRecordStore::SqlBypass
@session_class.connection = CGI::Session::ActiveRecordStore::Session.connection
def test_getting_nil_session_value
with_test_route_set do
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
end
@session_class
end
def test_model_attribute
assert_kind_of CGI::Session::ActiveRecordStore::SqlBypass, @new_session.model
assert_equal({ 'foo' => 'bar' }, @new_session.model.data)
def test_setting_session_value_after_session_reset
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
session_id = cookies['_session_id']
get '/call_reset_session'
assert_response :success
assert_not_equal [], headers['Set-Cookie']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "baz"', response.body
get '/get_session_id'
assert_response :success
assert_not_equal session_id, response.body
end
end
def test_getting_session_id
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
session_id = cookies['_session_id']
get '/get_session_id'
assert_response :success
assert_equal session_id, response.body
end
end
def test_prevents_session_fixation
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "bar"', response.body
session_id = cookies['_session_id']
assert session_id
reset!
get '/set_session_value', :_session_id => session_id, :foo => "baz"
assert_response :success
assert_equal nil, cookies['_session_id']
get '/get_session_value', :_session_id => session_id
assert_response :success
assert_equal 'foo: nil', response.body
assert_equal nil, cookies['_session_id']
end
end
def test_allows_session_fixation
@integration_session = open_session(SessionAppWithFixation)
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "bar"', response.body
session_id = cookies['_session_id']
assert session_id
reset!
@integration_session = open_session(SessionAppWithFixation)
get '/set_session_value', :_session_id => session_id, :foo => "baz"
assert_response :success
assert_equal session_id, cookies['_session_id']
get '/get_session_value', :_session_id => session_id
assert_response :success
assert_equal 'foo: "baz"', response.body
assert_equal session_id, cookies['_session_id']
end
end
private
def with_test_route_set
with_routing do |set|
set.draw do |map|
map.with_options :controller => "active_record_store_test/test" do |c|
c.connect "/:action"
end
end
yield
end
end
end

View file

@ -47,19 +47,13 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base
end
class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
tests RenderPartialWithRecordIdentificationController
fixtures :developers, :projects, :developers_projects, :topics, :replies, :companies, :mascots
def setup
@controller = RenderPartialWithRecordIdentificationController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
super
end
def test_rendering_partial_with_has_many_and_belongs_to_association
get :render_with_has_many_and_belongs_to_association
assert_template 'projects/_project'
assert_equal 'Active RecordActive Controller', @response.body
assert_equal assigns(:developer).projects.map(&:name).join, @response.body
end
def test_rendering_partial_with_has_many_association
@ -88,7 +82,7 @@ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
def test_render_with_record_collection_and_spacer_template
get :render_with_record_collection_and_spacer_template
assert_equal 'Active Recordonly partialActive Controller', @response.body
assert_equal assigns(:developer).projects.map(&:name).join('only partial'), @response.body
end
def test_rendering_partial_with_has_one_association
@ -162,12 +156,7 @@ module Fun
end
class RenderPartialWithRecordIdentificationAndNestedControllersTest < ActiveRecordTestCase
def setup
@controller = Fun::NestedController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
super
end
tests Fun::NestedController
def test_render_with_record_in_nested_controller
get :render_with_record_in_nested_controller
@ -183,12 +172,7 @@ class RenderPartialWithRecordIdentificationAndNestedControllersTest < ActiveReco
end
class RenderPartialWithRecordIdentificationAndNestedDeeperControllersTest < ActiveRecordTestCase
def setup
@controller = Fun::Serious::NestedDeeperController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
super
end
tests Fun::Serious::NestedDeeperController
def test_render_with_record_in_deeper_nested_controller
get :render_with_record_in_deeper_nested_controller

View file

@ -11,6 +11,9 @@ class ActionPackAssertionsController < ActionController::Base
# a standard template
def hello_xml_world() render :template => "test/hello_xml_world"; end
# a standard partial
def partial() render :partial => 'test/partial'; end
# a redirect to an internal location
def redirect_internal() redirect_to "/nothing"; end
@ -165,13 +168,11 @@ module Admin
end
# a test case to exercise the new capabilities TestRequest & TestResponse
class ActionPackAssertionsControllerTest < Test::Unit::TestCase
class ActionPackAssertionsControllerTest < ActionController::TestCase
# let's get this party started
def setup
ActionController::Routing::Routes.reload
ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module user content admin/user))
@controller = ActionPackAssertionsController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
def teardown
@ -235,13 +236,13 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
map.connect ':controller/:action/:id'
end
process :redirect_to_named_route
assert_raise(Test::Unit::AssertionFailedError) do
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to 'http://test.host/route_two'
end
assert_raise(Test::Unit::AssertionFailedError) do
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
end
assert_raise(Test::Unit::AssertionFailedError) do
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to route_two_url
end
end
@ -328,11 +329,35 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
# check if we were rendered by a file-based template?
def test_rendered_action
process :nothing
assert_nil @response.rendered_template
assert_nil @response.rendered[:template]
process :hello_world
assert @response.rendered_template
assert 'hello_world', @response.rendered_template.to_s
assert @response.rendered[:template]
assert 'hello_world', @response.rendered[:template].to_s
end
def test_assert_template_with_partial
get :partial
assert_template :partial => '_partial'
end
def test_assert_template_with_nil
get :nothing
assert_template nil
end
def test_assert_template_with_string
get :hello_world
assert_template 'hello_world'
end
def test_assert_template_with_symbol
get :hello_world
assert_template :hello_world
end
def test_assert_template_with_bad_argument
assert_raise(ArgumentError) { assert_template 1 }
end
# check the redirection location
@ -368,6 +393,12 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
assert @response.missing?
end
# check client errors
def test_client_error_response_code
process :response404
assert @response.client_error?
end
# check to see if our redirection matches a pattern
def test_redirect_url_match
process :redirect_external
@ -410,7 +441,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
def test_assert_redirection_fails_with_incorrect_controller
process :redirect_to_controller
assert_raise(Test::Unit::AssertionFailedError) do
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to :controller => "action_pack_assertions", :action => "flash_me"
end
end
@ -457,16 +488,16 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
def test_assert_valid
get :get_valid_record
assert_valid assigns('record')
assert_deprecated { assert_valid assigns('record') }
end
def test_assert_valid_failing
get :get_invalid_record
begin
assert_valid assigns('record')
assert_deprecated { assert_valid assigns('record') }
assert false
rescue Test::Unit::AssertionFailedError => e
rescue ActiveSupport::TestCase::Assertion => e
end
end
@ -475,7 +506,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
get :index
assert_response :success
flunk 'Expected non-success response'
rescue Test::Unit::AssertionFailedError => e
rescue ActiveSupport::TestCase::Assertion => e
assert e.message.include?('FAIL')
end
@ -484,31 +515,29 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
get :show
assert_response :success
flunk 'Expected non-success response'
rescue Test::Unit::AssertionFailedError
rescue ActiveSupport::TestCase::Assertion
# success
rescue
flunk "assert_response failed to handle failure response with missing, but optional, exception."
end
end
class ActionPackHeaderTest < Test::Unit::TestCase
def setup
@controller = ActionPackAssertionsController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
class ActionPackHeaderTest < ActionController::TestCase
tests ActionPackAssertionsController
def test_rendering_xml_sets_content_type
process :hello_xml_world
assert_equal('application/xml; charset=utf-8', @response.headers['type'])
assert_equal('application/xml; charset=utf-8', @response.headers['Content-Type'])
end
def test_rendering_xml_respects_content_type
@response.headers['type'] = 'application/pdf'
process :hello_xml_world
assert_equal('application/pdf; charset=utf-8', @response.headers['type'])
assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
end
def test_render_text_with_custom_content_type
get :render_text_with_custom_content_type
assert_equal 'application/rss+xml; charset=utf-8', @response.headers['type']
assert_equal 'application/rss+xml; charset=utf-8', @response.headers['Content-Type']
end
end

View file

@ -19,17 +19,14 @@ class AddressesTestController < ActionController::Base
def self.controller_path; "addresses"; end
end
class AddressesTest < Test::Unit::TestCase
def setup
@controller = AddressesTestController.new
class AddressesTest < ActionController::TestCase
tests AddressesTestController
def setup
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
# a more accurate simulation of what happens in "real life".
@controller.logger = Logger.new(nil)
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = "www.nextangle.com"
end

View file

@ -9,9 +9,10 @@ require 'controller/fake_controllers'
unless defined?(ActionMailer)
begin
$:.unshift(File.dirname(__FILE__) + "/../../../actionmailer/lib")
$:.unshift("#{File.dirname(__FILE__)}/../../../actionmailer/lib")
require 'action_mailer'
rescue LoadError
rescue LoadError => e
raise unless e.message =~ /action_mailer/
require 'rubygems'
gem 'actionmailer'
end
@ -19,7 +20,18 @@ end
ActionMailer::Base.template_root = FIXTURE_LOAD_PATH
class AssertSelectTest < Test::Unit::TestCase
class AssertSelectTest < ActionController::TestCase
Assertion = ActiveSupport::TestCase::Assertion
class AssertSelectMailer < ActionMailer::Base
def test(html)
recipients "test <test@test.host>"
from "test@test.host"
subject "Test e-mail"
part :content_type=>"text/html", :body=>html
end
end
class AssertSelectController < ActionController::Base
def response_with=(content)
@content = content
@ -51,21 +63,9 @@ class AssertSelectTest < Test::Unit::TestCase
end
end
class AssertSelectMailer < ActionMailer::Base
def test(html)
recipients "test <test@test.host>"
from "test@test.host"
subject "Test e-mail"
part :content_type=>"text/html", :body=>html
end
end
AssertionFailedError = Test::Unit::AssertionFailedError
tests AssertSelectController
def setup
@controller = AssertSelectController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
@ -76,7 +76,7 @@ class AssertSelectTest < Test::Unit::TestCase
end
def assert_failure(message, &block)
e = assert_raises(AssertionFailedError, &block)
e = assert_raise(Assertion, &block)
assert_match(message, e.message) if Regexp === message
assert_equal(message, e.message) if String === message
end
@ -94,43 +94,43 @@ class AssertSelectTest < Test::Unit::TestCase
def test_equality_true_false
render_html %Q{<div id="1"></div><div id="2"></div>}
assert_nothing_raised { assert_select "div" }
assert_raises(AssertionFailedError) { assert_select "p" }
assert_nothing_raised { assert_select "div", true }
assert_raises(AssertionFailedError) { assert_select "p", true }
assert_raises(AssertionFailedError) { assert_select "div", false }
assert_nothing_raised { assert_select "p", false }
assert_nothing_raised { assert_select "div" }
assert_raise(Assertion) { assert_select "p" }
assert_nothing_raised { assert_select "div", true }
assert_raise(Assertion) { assert_select "p", true }
assert_raise(Assertion) { assert_select "div", false }
assert_nothing_raised { assert_select "p", false }
end
def test_equality_string_and_regexp
render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
assert_nothing_raised { assert_select "div", "foo" }
assert_raises(AssertionFailedError) { assert_select "div", "bar" }
assert_nothing_raised { assert_select "div", :text=>"foo" }
assert_raises(AssertionFailedError) { assert_select "div", :text=>"bar" }
assert_nothing_raised { assert_select "div", /(foo|bar)/ }
assert_raises(AssertionFailedError) { assert_select "div", /foobar/ }
assert_nothing_raised { assert_select "div", :text=>/(foo|bar)/ }
assert_raises(AssertionFailedError) { assert_select "div", :text=>/foobar/ }
assert_raises(AssertionFailedError) { assert_select "p", :text=>/foobar/ }
assert_nothing_raised { assert_select "div", "foo" }
assert_raise(Assertion) { assert_select "div", "bar" }
assert_nothing_raised { assert_select "div", :text=>"foo" }
assert_raise(Assertion) { assert_select "div", :text=>"bar" }
assert_nothing_raised { assert_select "div", /(foo|bar)/ }
assert_raise(Assertion) { assert_select "div", /foobar/ }
assert_nothing_raised { assert_select "div", :text=>/(foo|bar)/ }
assert_raise(Assertion) { assert_select "div", :text=>/foobar/ }
assert_raise(Assertion) { assert_select "p", :text=>/foobar/ }
end
def test_equality_of_html
render_html %Q{<p>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</p>}
text = "\"This is not a big problem,\" he said."
html = "<em>\"This is <strong>not</strong> a big problem,\"</em> he said."
assert_nothing_raised { assert_select "p", text }
assert_raises(AssertionFailedError) { assert_select "p", html }
assert_nothing_raised { assert_select "p", :html=>html }
assert_raises(AssertionFailedError) { assert_select "p", :html=>text }
assert_nothing_raised { assert_select "p", text }
assert_raise(Assertion) { assert_select "p", html }
assert_nothing_raised { assert_select "p", :html=>html }
assert_raise(Assertion) { assert_select "p", :html=>text }
# No stripping for pre.
render_html %Q{<pre>\n<em>"This is <strong>not</strong> a big problem,"</em> he said.\n</pre>}
text = "\n\"This is not a big problem,\" he said.\n"
html = "\n<em>\"This is <strong>not</strong> a big problem,\"</em> he said.\n"
assert_nothing_raised { assert_select "pre", text }
assert_raises(AssertionFailedError) { assert_select "pre", html }
assert_nothing_raised { assert_select "pre", :html=>html }
assert_raises(AssertionFailedError) { assert_select "pre", :html=>text }
assert_nothing_raised { assert_select "pre", text }
assert_raise(Assertion) { assert_select "pre", html }
assert_nothing_raised { assert_select "pre", :html=>html }
assert_raise(Assertion) { assert_select "pre", :html=>text }
end
def test_counts
@ -206,16 +206,16 @@ class AssertSelectTest < Test::Unit::TestCase
def test_assert_select_text_match
render_html %Q{<div id="1"><span>foo</span></div><div id="2"><span>bar</span></div>}
assert_select "div" do
assert_nothing_raised { assert_select "div", "foo" }
assert_nothing_raised { assert_select "div", "bar" }
assert_nothing_raised { assert_select "div", /\w*/ }
assert_nothing_raised { assert_select "div", /\w*/, :count=>2 }
assert_raises(AssertionFailedError) { assert_select "div", :text=>"foo", :count=>2 }
assert_nothing_raised { assert_select "div", :html=>"<span>bar</span>" }
assert_nothing_raised { assert_select "div", :html=>"<span>bar</span>" }
assert_nothing_raised { assert_select "div", :html=>/\w*/ }
assert_nothing_raised { assert_select "div", :html=>/\w*/, :count=>2 }
assert_raises(AssertionFailedError) { assert_select "div", :html=>"<span>foo</span>", :count=>2 }
assert_nothing_raised { assert_select "div", "foo" }
assert_nothing_raised { assert_select "div", "bar" }
assert_nothing_raised { assert_select "div", /\w*/ }
assert_nothing_raised { assert_select "div", /\w*/, :count=>2 }
assert_raise(Assertion) { assert_select "div", :text=>"foo", :count=>2 }
assert_nothing_raised { assert_select "div", :html=>"<span>bar</span>" }
assert_nothing_raised { assert_select "div", :html=>"<span>bar</span>" }
assert_nothing_raised { assert_select "div", :html=>/\w*/ }
assert_nothing_raised { assert_select "div", :html=>/\w*/, :count=>2 }
assert_raise(Assertion) { assert_select "div", :html=>"<span>foo</span>", :count=>2 }
end
end
@ -248,6 +248,19 @@ class AssertSelectTest < Test::Unit::TestCase
end
end
def test_assert_select_rjs_for_positioned_insert_should_fail_when_mixing_arguments
render_rjs do |page|
page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>"
end
assert_raise(Assertion) {assert_select_rjs :insert, :top, "test2"}
end
def test_elect_with_xml_namespace_attributes
render_html %Q{<link xlink:href="http://nowhere.com"></link>}
assert_nothing_raised { assert_select "link[xlink:href=http://nowhere.com]" }
end
#
# Test css_select.
#
@ -323,7 +336,7 @@ class AssertSelectTest < Test::Unit::TestCase
# Test that we fail if there is nothing to pick.
def test_assert_select_rjs_fails_if_nothing_to_pick
render_rjs { }
assert_raises(AssertionFailedError) { assert_select_rjs }
assert_raise(Assertion) { assert_select_rjs }
end
def test_assert_select_rjs_with_unicode
@ -338,10 +351,10 @@ class AssertSelectTest < Test::Unit::TestCase
if str.respond_to?(:force_encoding)
str.force_encoding(Encoding::UTF_8)
assert_select str, /\343\203\201..\343\203\210/u
assert_raises(AssertionFailedError) { assert_select str, /\343\203\201.\343\203\210/u }
assert_raise(Assertion) { assert_select str, /\343\203\201.\343\203\210/u }
else
assert_select str, Regexp.new("\343\203\201..\343\203\210",0,'U')
assert_raises(AssertionFailedError) { assert_select str, Regexp.new("\343\203\201.\343\203\210",0,'U') }
assert_raise(Assertion) { assert_select str, Regexp.new("\343\203\201.\343\203\210",0,'U') }
end
end
end
@ -365,7 +378,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#3"
end
assert_raises(AssertionFailedError) { assert_select_rjs "test4" }
assert_raise(Assertion) { assert_select_rjs "test4" }
end
def test_assert_select_rjs_for_replace
@ -383,7 +396,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#1"
end
assert_raises(AssertionFailedError) { assert_select_rjs :replace, "test2" }
assert_raise(Assertion) { assert_select_rjs :replace, "test2" }
# Replace HTML.
assert_select_rjs :replace_html do
assert_select "div", 1
@ -393,7 +406,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#2"
end
assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" }
end
def test_assert_select_rjs_for_chained_replace
@ -411,7 +424,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#1"
end
assert_raises(AssertionFailedError) { assert_select_rjs :chained_replace, "test2" }
assert_raise(Assertion) { assert_select_rjs :chained_replace, "test2" }
# Replace HTML.
assert_select_rjs :chained_replace_html do
assert_select "div", 1
@ -421,7 +434,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#2"
end
assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" }
end
# Simple remove
@ -440,8 +453,8 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select_rjs :remove, "test1"
rescue Test::Unit::AssertionFailedError
assert_equal "No RJS statement that removes 'test1' was rendered.", $!.message
rescue Assertion
assert_equal "No RJS statement that removes 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_remove_ignores_block
@ -472,8 +485,8 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select_rjs :show, "test1"
rescue Test::Unit::AssertionFailedError
assert_equal "No RJS statement that shows 'test1' was rendered.", $!.message
rescue Assertion
assert_equal "No RJS statement that shows 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_show_ignores_block
@ -504,8 +517,8 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select_rjs :hide, "test1"
rescue Test::Unit::AssertionFailedError
assert_equal "No RJS statement that hides 'test1' was rendered.", $!.message
rescue Assertion
assert_equal "No RJS statement that hides 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_hide_ignores_block
@ -536,8 +549,8 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select_rjs :toggle, "test1"
rescue Test::Unit::AssertionFailedError
assert_equal "No RJS statement that toggles 'test1' was rendered.", $!.message
rescue Assertion
assert_equal "No RJS statement that toggles 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_toggle_ignores_block
@ -567,7 +580,7 @@ class AssertSelectTest < Test::Unit::TestCase
assert_select "div", 1
assert_select "#3"
end
assert_raises(AssertionFailedError) { assert_select_rjs :insert_html, "test1" }
assert_raise(Assertion) { assert_select_rjs :insert_html, "test1" }
end
# Positioned insert.
@ -600,8 +613,8 @@ class AssertSelectTest < Test::Unit::TestCase
end
def test_assert_select_rjs_raise_errors
assert_raises(ArgumentError) { assert_select_rjs(:destroy) }
assert_raises(ArgumentError) { assert_select_rjs(:insert, :left) }
assert_raise(ArgumentError) { assert_select_rjs(:destroy) }
assert_raise(ArgumentError) { assert_select_rjs(:insert, :left) }
end
# Simple selection from a single result.
@ -693,7 +706,7 @@ EOF
#
def test_assert_select_email
assert_raises(AssertionFailedError) { assert_select_email {} }
assert_raise(Assertion) { assert_select_email {} }
AssertSelectMailer.deliver_test "<div><p>foo</p><p>bar</p></div>"
assert_select_email do
assert_select "div:root" do

View file

@ -105,7 +105,7 @@ class ControllerInstanceTests < Test::Unit::TestCase
end
class PerformActionTest < Test::Unit::TestCase
class PerformActionTest < ActionController::TestCase
class MockLogger
attr_reader :logged
@ -129,6 +129,8 @@ class PerformActionTest < Test::Unit::TestCase
@response = ActionController::TestResponse.new
@request.host = "www.nextangle.com"
rescue_action_in_public!
end
def test_get_on_priv_should_show_selector
@ -164,14 +166,12 @@ class PerformActionTest < Test::Unit::TestCase
end
end
class DefaultUrlOptionsTest < Test::Unit::TestCase
class DefaultUrlOptionsTest < ActionController::TestCase
tests DefaultUrlOptionsController
def setup
@controller = DefaultUrlOptionsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = 'www.example.com'
rescue_action_in_public!
end
def test_default_url_options_are_used_if_set
@ -189,14 +189,12 @@ class DefaultUrlOptionsTest < Test::Unit::TestCase
end
end
class EmptyUrlOptionsTest < Test::Unit::TestCase
class EmptyUrlOptionsTest < ActionController::TestCase
tests NonEmptyController
def setup
@controller = NonEmptyController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = 'www.example.com'
rescue_action_in_public!
end
def test_ensure_url_for_works_as_expected_when_called_with_no_options_if_default_url_options_is_not_set

View file

@ -11,17 +11,17 @@ class BenchmarkedController < ActionController::Base
end
end
class BenchmarkTest < Test::Unit::TestCase
class BenchmarkTest < ActionController::TestCase
tests BenchmarkedController
class MockLogger
def method_missing(*args)
end
end
def setup
@controller = BenchmarkedController.new
# benchmark doesn't do anything unless a logger is set
@controller.logger = MockLogger.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
@request.host = "test.actioncontroller.i"
end

View file

@ -1,5 +1,6 @@
require 'fileutils'
require 'abstract_unit'
require 'active_record_unit'
CACHE_DIR = 'test_cache'
# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
@ -7,6 +8,10 @@ FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
ActionController::Base.page_cache_directory = FILE_STORE_PATH
ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
# Force sweeper classes to load
ActionController::Caching::Sweeper
ActionController::Caching::Sweeping
class PageCachingTestController < ActionController::Base
caches_page :ok, :no_content, :if => Proc.new { |c| !c.request.format.json? }
caches_page :found, :not_found
@ -42,12 +47,13 @@ class PageCachingTestController < ActionController::Base
end
end
class PageCachingTest < Test::Unit::TestCase
class PageCachingTest < ActionController::TestCase
def setup
ActionController::Base.perform_caching = true
ActionController::Routing::Routes.draw do |map|
map.main '', :controller => 'posts'
map.main '', :controller => 'posts', :format => nil
map.formatted_posts 'posts.:format', :controller => 'posts'
map.resources :posts
map.connect ':controller/:action/:id'
end
@ -67,7 +73,7 @@ class PageCachingTest < Test::Unit::TestCase
def teardown
FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
ActionController::Routing::Routes.clear!
ActionController::Base.perform_caching = false
end
@ -107,21 +113,18 @@ class PageCachingTest < Test::Unit::TestCase
assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
end
uses_mocha("should_cache_ok_at_custom_path") do
def test_should_cache_ok_at_custom_path
@request.stubs(:path).returns("/index.html")
get :ok
assert_response :ok
assert File.exist?("#{FILE_STORE_PATH}/index.html")
end
def test_should_cache_ok_at_custom_path
@request.stubs(:path).returns("/index.html")
get :ok
assert_response :ok
assert File.exist?("#{FILE_STORE_PATH}/index.html")
end
[:ok, :no_content, :found, :not_found].each do |status|
[:get, :post, :put, :delete].each do |method|
unless method == :get and status == :ok
define_method "test_shouldnt_cache_#{method}_with_#{status}_status" do
@request.env['REQUEST_METHOD'] = method.to_s.upcase
process status
send(method, status)
assert_response status
assert_page_not_cached status, "#{method} with #{status} status shouldn't have been cached"
end
@ -154,6 +157,7 @@ class ActionCachingTestController < ActionController::Base
caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
caches_action :with_layout
caches_action :layout_false, :layout => false
caches_action :record_not_found, :four_oh_four, :simple_runtime_error
layout 'talk_from_action.erb'
@ -168,7 +172,7 @@ class ActionCachingTestController < ActionController::Base
def forbidden
render :text => "Forbidden"
headers["Status"] = "403 Forbidden"
response.status = "403 Forbidden"
end
def with_layout
@ -176,6 +180,18 @@ class ActionCachingTestController < ActionController::Base
render :text => @cache_this, :layout => true
end
def record_not_found
raise ActiveRecord::RecordNotFound, "oops!"
end
def four_oh_four
render :text => "404'd!", :status => 404
end
def simple_runtime_error
raise "oops!"
end
alias_method :show, :index
alias_method :edit, :index
alias_method :destroy, :index
@ -222,7 +238,7 @@ class ActionCachingMockController
end
end
class ActionCacheTest < Test::Unit::TestCase
class ActionCacheTest < ActionController::TestCase
def setup
reset!
FileUtils.mkdir_p(FILE_STORE_PATH)
@ -291,13 +307,11 @@ class ActionCacheTest < Test::Unit::TestCase
ActionController::Base.use_accept_header = old_use_accept_header
end
uses_mocha 'test action cache' do
def test_action_cache_with_store_options
MockTime.expects(:now).returns(12345).once
@controller.expects(:read_fragment).with('hostname.com/action_caching_test', :expires_in => 1.hour).once
@controller.expects(:write_fragment).with('hostname.com/action_caching_test', '12345.0', :expires_in => 1.hour).once
get :index
end
def test_action_cache_with_store_options
MockTime.expects(:now).returns(12345).once
@controller.expects(:read_fragment).with('hostname.com/action_caching_test', :expires_in => 1.hour).once
@controller.expects(:write_fragment).with('hostname.com/action_caching_test', '12345.0', :expires_in => 1.hour).once
get :index
end
def test_action_cache_with_custom_cache_path
@ -401,7 +415,7 @@ class ActionCacheTest < Test::Unit::TestCase
def test_xml_version_of_resource_is_treated_as_different_cache
with_routing do |set|
ActionController::Routing::Routes.draw do |map|
set.draw do |map|
map.connect ':controller/:action.:format'
map.connect ':controller/:action'
end
@ -432,6 +446,20 @@ class ActionCacheTest < Test::Unit::TestCase
assert_equal 'application/xml', @response.content_type
end
def test_correct_content_type_is_returned_for_cache_hit_on_action_with_string_key
# run it twice to cache it the first time
get :show, :format => 'xml'
get :show, :format => 'xml'
assert_equal 'application/xml', @response.content_type
end
def test_correct_content_type_is_returned_for_cache_hit_on_action_with_string_key_from_proc
# run it twice to cache it the first time
get :edit, :id => 1, :format => 'xml'
get :edit, :id => 1, :format => 'xml'
assert_equal 'application/xml', @response.content_type
end
def test_empty_path_is_normalized
@mock_controller.mock_url_for = 'http://example.org/'
@mock_controller.mock_path = '/'
@ -446,6 +474,27 @@ class ActionCacheTest < Test::Unit::TestCase
assert_response :success
end
def test_record_not_found_returns_404_for_multiple_requests
get :record_not_found
assert_response 404
get :record_not_found
assert_response 404
end
def test_four_oh_four_returns_404_for_multiple_requests
get :four_oh_four
assert_response 404
get :four_oh_four
assert_response 404
end
def test_simple_runtime_error_returns_500_for_multiple_requests
get :simple_runtime_error
assert_response 500
get :simple_runtime_error
assert_response 500
end
private
def content_to_cache
assigns(:cache_this)
@ -471,7 +520,7 @@ class FragmentCachingTestController < ActionController::Base
def some_action; end;
end
class FragmentCachingTest < Test::Unit::TestCase
class FragmentCachingTest < ActionController::TestCase
def setup
ActionController::Base.perform_caching = true
@store = ActiveSupport::Cache::MemoryStore.new
@ -527,7 +576,7 @@ class FragmentCachingTest < Test::Unit::TestCase
def test_write_fragment_with_caching_disabled
assert_nil @store.read('views/name')
ActionController::Base.perform_caching = false
assert_equal nil, @controller.write_fragment('name', 'value')
assert_equal 'value', @controller.write_fragment('name', 'value')
assert_nil @store.read('views/name')
end
@ -603,7 +652,7 @@ class FunctionalCachingController < ActionController::Base
end
end
class FunctionalFragmentCachingTest < Test::Unit::TestCase
class FunctionalFragmentCachingTest < ActionController::TestCase
def setup
ActionController::Base.perform_caching = true
@store = ActiveSupport::Cache::MemoryStore.new

View file

@ -23,17 +23,14 @@ class CaptureController < ActionController::Base
def rescue_action(e) raise end
end
class CaptureTest < Test::Unit::TestCase
def setup
@controller = CaptureController.new
class CaptureTest < ActionController::TestCase
tests CaptureController
def setup
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
# a more accurate simulation of what happens in "real life".
@controller.logger = Logger.new(nil)
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = "www.nextangle.com"
end

View file

@ -1,263 +0,0 @@
require 'abstract_unit'
require 'action_controller/cgi_process'
class BaseCgiTest < Test::Unit::TestCase
def setup
@request_hash = {
"HTTP_MAX_FORWARDS" => "10",
"SERVER_NAME" => "glu.ttono.us:8007",
"FCGI_ROLE" => "RESPONDER",
"AUTH_TYPE" => "Basic",
"HTTP_X_FORWARDED_HOST" => "glu.ttono.us",
"HTTP_ACCEPT_CHARSET" => "UTF-8",
"HTTP_ACCEPT_ENCODING" => "gzip, deflate",
"HTTP_CACHE_CONTROL" => "no-cache, max-age=0",
"HTTP_PRAGMA" => "no-cache",
"HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)",
"PATH_INFO" => "/homepage/",
"HTTP_ACCEPT_LANGUAGE" => "en",
"HTTP_NEGOTIATE" => "trans",
"HTTP_HOST" => "glu.ttono.us:8007",
"HTTP_REFERER" => "http://www.google.com/search?q=glu.ttono.us",
"HTTP_FROM" => "googlebot",
"SERVER_PROTOCOL" => "HTTP/1.1",
"REDIRECT_URI" => "/dispatch.fcgi",
"SCRIPT_NAME" => "/dispatch.fcgi",
"SERVER_ADDR" => "207.7.108.53",
"REMOTE_ADDR" => "207.7.108.53",
"REMOTE_HOST" => "google.com",
"REMOTE_IDENT" => "kevin",
"REMOTE_USER" => "kevin",
"SERVER_SOFTWARE" => "lighttpd/1.4.5",
"HTTP_COOKIE" => "_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes",
"HTTP_X_FORWARDED_SERVER" => "glu.ttono.us",
"REQUEST_URI" => "/admin",
"DOCUMENT_ROOT" => "/home/kevinc/sites/typo/public",
"PATH_TRANSLATED" => "/home/kevinc/sites/typo/public/homepage/",
"SERVER_PORT" => "8007",
"QUERY_STRING" => "",
"REMOTE_PORT" => "63137",
"GATEWAY_INTERFACE" => "CGI/1.1",
"HTTP_X_FORWARDED_FOR" => "65.88.180.234",
"HTTP_ACCEPT" => "*/*",
"SCRIPT_FILENAME" => "/home/kevinc/sites/typo/public/dispatch.fcgi",
"REDIRECT_STATUS" => "200",
"REQUEST_METHOD" => "GET"
}
# some Nokia phone browsers omit the space after the semicolon separator.
# some developers have grown accustomed to using comma in cookie values.
@alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}
@cgi = CGI.new
class << @cgi; attr_accessor :env_table end
@cgi.env_table = @request_hash
@request = ActionController::CgiRequest.new(@cgi)
end
def default_test; end
private
def set_content_data(data)
@request.env['REQUEST_METHOD'] = 'POST'
@request.env['CONTENT_LENGTH'] = data.length
@request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
@request.env['RAW_POST_DATA'] = data
end
end
class CgiRequestTest < BaseCgiTest
def test_proxy_request
assert_equal 'glu.ttono.us', @request.host_with_port
end
def test_http_host
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash['HTTP_HOST'] = "rubyonrails.org:8080"
assert_equal "rubyonrails.org:8080", @request.host_with_port
@request_hash['HTTP_X_FORWARDED_HOST'] = "www.firsthost.org, www.secondhost.org"
assert_equal "www.secondhost.org", @request.host(true)
end
def test_http_host_with_default_port_overrides_server_port
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash['HTTP_HOST'] = "rubyonrails.org"
assert_equal "rubyonrails.org", @request.host_with_port
end
def test_host_with_port_defaults_to_server_name_if_no_host_headers
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash.delete "HTTP_HOST"
assert_equal "glu.ttono.us:8007", @request.host_with_port
end
def test_host_with_port_falls_back_to_server_addr_if_necessary
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash.delete "HTTP_HOST"
@request_hash.delete "SERVER_NAME"
assert_equal "207.7.108.53:8007", @request.host_with_port
end
def test_host_with_port_if_http_standard_port_is_specified
@request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:80"
assert_equal "glu.ttono.us", @request.host_with_port
end
def test_host_with_port_if_https_standard_port_is_specified
@request_hash['HTTP_X_FORWARDED_PROTO'] = "https"
@request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:443"
assert_equal "glu.ttono.us", @request.host_with_port
end
def test_host_if_ipv6_reference
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
end
def test_host_if_ipv6_reference_with_port
@request_hash.delete "HTTP_X_FORWARDED_HOST"
@request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]:8008"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
end
def test_cgi_environment_variables
assert_equal "Basic", @request.auth_type
assert_equal 0, @request.content_length
assert_equal nil, @request.content_type
assert_equal "CGI/1.1", @request.gateway_interface
assert_equal "*/*", @request.accept
assert_equal "UTF-8", @request.accept_charset
assert_equal "gzip, deflate", @request.accept_encoding
assert_equal "en", @request.accept_language
assert_equal "no-cache, max-age=0", @request.cache_control
assert_equal "googlebot", @request.from
assert_equal "glu.ttono.us", @request.host
assert_equal "trans", @request.negotiate
assert_equal "no-cache", @request.pragma
assert_equal "http://www.google.com/search?q=glu.ttono.us", @request.referer
assert_equal "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)", @request.user_agent
assert_equal "/homepage/", @request.path_info
assert_equal "/home/kevinc/sites/typo/public/homepage/", @request.path_translated
assert_equal "", @request.query_string
assert_equal "207.7.108.53", @request.remote_addr
assert_equal "google.com", @request.remote_host
assert_equal "kevin", @request.remote_ident
assert_equal "kevin", @request.remote_user
assert_equal :get, @request.request_method
assert_equal "/dispatch.fcgi", @request.script_name
assert_equal "glu.ttono.us:8007", @request.server_name
assert_equal 8007, @request.server_port
assert_equal "HTTP/1.1", @request.server_protocol
assert_equal "lighttpd", @request.server_software
end
def test_cookie_syntax_resilience
cookies = CGI::Cookie::parse(@request_hash["HTTP_COOKIE"]);
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"], cookies.inspect
assert_equal ["yes"], cookies["is_admin"], cookies.inspect
alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]);
assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect
assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect
end
end
class CgiRequestParamsParsingTest < BaseCgiTest
def test_doesnt_break_when_content_type_has_charset
set_content_data 'flamenco=love'
assert_equal({"flamenco"=> "love"}, @request.request_parameters)
end
def test_doesnt_interpret_request_uri_as_query_string_when_missing
@request.env['REQUEST_URI'] = 'foo'
assert_equal({}, @request.query_parameters)
end
end
class CgiRequestContentTypeTest < BaseCgiTest
def test_html_content_type_verification
@request.env['CONTENT_TYPE'] = Mime::HTML.to_s
assert @request.content_type.verify_request?
end
def test_xml_content_type_verification
@request.env['CONTENT_TYPE'] = Mime::XML.to_s
assert !@request.content_type.verify_request?
end
end
class CgiRequestMethodTest < BaseCgiTest
def test_get
assert_equal :get, @request.request_method
end
def test_post
@request.env['REQUEST_METHOD'] = 'POST'
assert_equal :post, @request.request_method
end
def test_put
set_content_data '_method=put'
assert_equal :put, @request.request_method
end
def test_delete
set_content_data '_method=delete'
assert_equal :delete, @request.request_method
end
end
class CgiRequestNeedsRewoundTest < BaseCgiTest
def test_body_should_be_rewound
data = 'foo'
fake_cgi = Struct.new(:env_table, :query_string, :stdinput).new(@request_hash, '', StringIO.new(data))
fake_cgi.env_table['CONTENT_LENGTH'] = data.length
fake_cgi.env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
# Read the request body by parsing params.
request = ActionController::CgiRequest.new(fake_cgi)
request.request_parameters
# Should have rewound the body.
assert_equal 0, request.body.pos
end
end
uses_mocha 'CGI Response' do
class CgiResponseTest < BaseCgiTest
def setup
super
@cgi.expects(:header).returns("HTTP/1.0 200 OK\nContent-Type: text/html\n")
@response = ActionController::CgiResponse.new(@cgi)
@output = StringIO.new('')
end
def test_simple_output
@response.body = "Hello, World!"
@response.out(@output)
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\nHello, World!", @output.string
end
def test_head_request
@cgi.env_table['REQUEST_METHOD'] = 'HEAD'
@response.body = "Hello, World!"
@response.out(@output)
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n", @output.string
end
def test_streaming_block
@response.body = Proc.new do |response, output|
5.times { |n| output.write(n) }
end
@response.out(@output)
assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n01234", @output.string
end
end
end

View file

@ -1,156 +0,0 @@
require 'abstract_unit'
class CallerController < ActionController::Base
def calling_from_controller
render_component(:controller => "callee", :action => "being_called")
end
def calling_from_controller_with_params
render_component(:controller => "callee", :action => "being_called", :params => { "name" => "David" })
end
def calling_from_controller_with_different_status_code
render_component(:controller => "callee", :action => "blowing_up")
end
def calling_from_template
render :inline => "Ring, ring: <%= render_component(:controller => 'callee', :action => 'being_called') %>"
end
def internal_caller
render :inline => "Are you there? <%= render_component(:action => 'internal_callee') %>"
end
def internal_callee
render :text => "Yes, ma'am"
end
def set_flash
render_component(:controller => "callee", :action => "set_flash")
end
def use_flash
render_component(:controller => "callee", :action => "use_flash")
end
def calling_redirected
render_component(:controller => "callee", :action => "redirected")
end
def calling_redirected_as_string
render :inline => "<%= render_component(:controller => 'callee', :action => 'redirected') %>"
end
def rescue_action(e) raise end
end
class CalleeController < ActionController::Base
def being_called
render :text => "#{params[:name] || "Lady"} of the House, speaking"
end
def blowing_up
render :text => "It's game over, man, just game over, man!", :status => 500
end
def set_flash
flash[:notice] = 'My stoney baby'
render :text => 'flash is set'
end
def use_flash
render :text => flash[:notice] || 'no flash'
end
def redirected
redirect_to :controller => "callee", :action => "being_called"
end
def rescue_action(e) raise end
end
class ComponentsTest < Test::Unit::TestCase
def setup
@controller = CallerController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_calling_from_controller
assert_deprecated do
get :calling_from_controller
assert_equal "Lady of the House, speaking", @response.body
end
end
def test_calling_from_controller_with_params
assert_deprecated do
get :calling_from_controller_with_params
assert_equal "David of the House, speaking", @response.body
end
end
def test_calling_from_controller_with_different_status_code
assert_deprecated do
get :calling_from_controller_with_different_status_code
assert_equal 500, @response.response_code
end
end
def test_calling_from_template
assert_deprecated do
get :calling_from_template
assert_equal "Ring, ring: Lady of the House, speaking", @response.body
end
end
def test_etag_is_set_for_parent_template_when_calling_from_template
assert_deprecated do
get :calling_from_template
expected_etag = etag_for("Ring, ring: Lady of the House, speaking")
assert_equal expected_etag, @response.headers['ETag']
end
end
def test_internal_calling
assert_deprecated do
get :internal_caller
assert_equal "Are you there? Yes, ma'am", @response.body
end
end
def test_flash
assert_deprecated do
get :set_flash
assert_equal 'My stoney baby', flash[:notice]
get :use_flash
assert_equal 'My stoney baby', @response.body
get :use_flash
assert_equal 'no flash', @response.body
end
end
def test_component_redirect_redirects
assert_deprecated do
get :calling_redirected
assert_redirected_to :controller=>"callee", :action => "being_called"
end
end
def test_component_multiple_redirect_redirects
test_component_redirect_redirects
test_internal_calling
end
def test_component_as_string_redirect_renders_redirected_action
assert_deprecated do
get :calling_redirected_as_string
assert_equal "Lady of the House, speaking", @response.body
end
end
protected
def etag_for(text)
%("#{Digest::MD5.hexdigest(text)}")
end
end

View file

@ -50,16 +50,13 @@ class ContentTypeController < ActionController::Base
def rescue_action(e) raise end
end
class ContentTypeTest < Test::Unit::TestCase
def setup
@controller = ContentTypeController.new
class ContentTypeTest < ActionController::TestCase
tests ContentTypeController
def setup
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
# a more accurate simulation of what happens in "real life".
@controller.logger = Logger.new(nil)
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_render_defaults

View file

@ -1,24 +1,28 @@
require 'abstract_unit'
class CookieTest < Test::Unit::TestCase
class CookieTest < ActionController::TestCase
class TestController < ActionController::Base
def authenticate
cookies["user_name"] = "david"
end
def set_with_with_escapable_characters
cookies["that & guy"] = "foo & bar => baz"
end
def authenticate_for_fourteen_days
cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
end
def authenticate_for_fourteen_days_with_symbols
cookies[:user_name] = { :value => "david", :expires => Time.local(2005, 10, 10) }
cookies[:user_name] = { :value => "david", :expires => Time.utc(2005, 10, 10,5) }
end
def set_multiple_cookies
cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
cookies["login"] = "XJ-122"
end
def access_frozen_cookies
cookies["will"] = "work"
end
@ -33,60 +37,70 @@ class CookieTest < Test::Unit::TestCase
end
def authenticate_with_http_only
cookies["user_name"] = { :value => "david", :http_only => true }
cookies["user_name"] = { :value => "david", :httponly => true }
end
def rescue_action(e)
raise unless ActionView::MissingTemplate # No templates here, and we don't care about the output
def rescue_action(e)
raise unless ActionView::MissingTemplate # No templates here, and we don't care about the output
end
end
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
tests TestController
@controller = TestController.new
def setup
@request.host = "www.nextangle.com"
end
def test_setting_cookie
get :authenticate
assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david") ], @response.headers["cookie"]
assert_equal ["user_name=david; path=/"], @response.headers["Set-Cookie"]
assert_equal({"user_name" => "david"}, @response.cookies)
end
def test_setting_with_escapable_characters
get :set_with_with_escapable_characters
assert_equal ["that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"], @response.headers["Set-Cookie"]
assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
end
def test_setting_cookie_for_fourteen_days
get :authenticate_for_fourteen_days
assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"]
assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
assert_equal({"user_name" => "david"}, @response.cookies)
end
def test_setting_cookie_for_fourteen_days_with_symbols
get :authenticate_for_fourteen_days_with_symbols
assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"]
assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
assert_equal({"user_name" => "david"}, @response.cookies)
end
def test_setting_cookie_with_http_only
get :authenticate_with_http_only
assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "http_only" => true) ], @response.headers["cookie"]
assert_equal CGI::Cookie::new("name" => "user_name", "value" => "david", "path" => "/", "http_only" => true).to_s, @response.headers["cookie"][0].to_s
assert_equal ["user_name=david; path=/; HttpOnly"], @response.headers["Set-Cookie"]
assert_equal({"user_name" => "david"}, @response.cookies)
end
def test_multiple_cookies
get :set_multiple_cookies
assert_equal 2, @response.cookies.size
assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"][0]
assert_equal "login=XJ-122; path=/", @response.headers["Set-Cookie"][1]
assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies)
end
def test_setting_test_cookie
assert_nothing_raised { get :access_frozen_cookies }
end
def test_expiring_cookie
get :logout
assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "", "expires" => Time.at(0)) ], @response.headers["cookie"]
assert_equal CGI::Cookie::new("name" => "user_name", "value" => "", "expires" => Time.at(0)).value, []
end
assert_equal ["user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"], @response.headers["Set-Cookie"]
assert_equal({"user_name" => nil}, @response.cookies)
end
def test_cookiejar_accessor
@request.cookies["user_name"] = CGI::Cookie.new("name" => "user_name", "value" => "david", "expires" => Time.local(2025, 10, 10))
@request.cookies["user_name"] = "david"
@controller.request = @request
jar = ActionController::CookieJar.new(@controller)
assert_equal "david", jar["user_name"]
@ -94,53 +108,27 @@ class CookieTest < Test::Unit::TestCase
end
def test_cookiejar_accessor_with_array_value
a = %w{1 2 3}
@request.cookies["pages"] = CGI::Cookie.new("name" => "pages", "value" => a, "expires" => Time.local(2025, 10, 10))
@request.cookies["pages"] = %w{1 2 3}
@controller.request = @request
jar = ActionController::CookieJar.new(@controller)
assert_equal a, jar["pages"]
assert_equal %w{1 2 3}, jar["pages"]
end
def test_cookiejar_delete_removes_item_and_returns_its_value
@request.cookies["user_name"] = "david"
@controller.response = @response
jar = ActionController::CookieJar.new(@controller)
assert_equal "david", jar.delete("user_name")
end
def test_delete_cookie_with_path
get :delete_cookie_with_path
assert_equal "/beaten", @response.headers["cookie"].first.path
assert_not_equal "/", @response.headers["cookie"].first.path
assert_equal ["user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT"], @response.headers["Set-Cookie"]
end
def test_cookie_to_s_simple_values
assert_equal 'myname=myvalue; path=', CGI::Cookie.new('myname', 'myvalue').to_s
end
def test_cookie_to_s_hash
cookie_str = CGI::Cookie.new(
'name' => 'myname',
'value' => 'myvalue',
'domain' => 'mydomain',
'path' => 'mypath',
'expires' => Time.utc(2007, 10, 20),
'secure' => true,
'http_only' => true).to_s
assert_equal 'myname=myvalue; domain=mydomain; path=mypath; expires=Sat, 20 Oct 2007 00:00:00 GMT; secure; HttpOnly', cookie_str
end
def test_cookie_to_s_hash_default_not_secure_not_http_only
cookie_str = CGI::Cookie.new(
'name' => 'myname',
'value' => 'myvalue',
'domain' => 'mydomain',
'path' => 'mypath',
'expires' => Time.utc(2007, 10, 20))
assert cookie_str !~ /secure/
assert cookie_str !~ /HttpOnly/
end
def test_cookies_should_not_be_split_on_ampersand_values
cookies = CGI::Cookie.parse('return_to=http://rubyonrails.org/search?term=api&scope=all&global=true')
assert_equal({"return_to" => ["http://rubyonrails.org/search?term=api&scope=all&global=true"]}, cookies)
end
def test_cookies_should_not_be_split_on_values_with_newlines
cookies = CGI::Cookie.new("name" => "val", "value" => "this\nis\na\ntest")
assert cookies.size == 1
def test_cookies_persist_throughout_request
get :authenticate
cookies = @controller.send(:cookies)
assert_equal 'david', cookies['user_name']
end
end

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
class DeprecatedBaseMethodsTest < Test::Unit::TestCase
class DeprecatedBaseMethodsTest < ActionController::TestCase
class Target < ActionController::Base
def home_url(greeting)
"http://example.com/#{greeting}"
@ -13,11 +13,7 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase
def rescue_action(e) raise e end
end
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = Target.new
end
tests Target
def test_log_error_silences_deprecation_warnings
get :raises_name_error
@ -25,10 +21,12 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase
assert_not_deprecated { @controller.send :log_error, e }
end
def test_assertion_failed_error_silences_deprecation_warnings
get :raises_name_error
rescue => e
error = Test::Unit::Error.new('testing ur doodz', e)
assert_not_deprecated { error.message }
if defined? Test::Unit::Error
def test_assertion_failed_error_silences_deprecation_warnings
get :raises_name_error
rescue => e
error = Test::Unit::Error.new('testing ur doodz', e)
assert_not_deprecated { error.message }
end
end
end

View file

@ -1,43 +1,29 @@
require 'abstract_unit'
uses_mocha 'dispatcher tests' do
require 'action_controller/dispatcher'
class DispatcherTest < Test::Unit::TestCase
Dispatcher = ActionController::Dispatcher
Reloader = ActionController::Reloader
def setup
@output = StringIO.new
ENV['REQUEST_METHOD'] = 'GET'
# Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
reset_dispatcher
Dispatcher.stubs(:require_dependency)
@dispatcher = Dispatcher.new(@output)
end
def teardown
ENV.delete 'REQUEST_METHOD'
reset_dispatcher
end
def test_clears_dependencies_after_dispatch_if_in_loading_mode
ActiveSupport::Dependencies.expects(:clear).once
dispatch(@output, false)
# Close the response so dependencies kicks in
dispatch(false).last.close
end
def test_reloads_routes_before_dispatch_if_in_loading_mode
ActionController::Routing::Routes.expects(:reload).once
dispatch(@output, false)
end
def test_clears_asset_tag_cache_before_dispatch_if_in_loading_mode
ActionView::Helpers::AssetTagHelper::AssetTag::Cache.expects(:clear).once
dispatch(@output, false)
dispatch(false)
end
def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
@ -47,18 +33,51 @@ class DispatcherTest < Test::Unit::TestCase
dispatch
end
def test_builds_middleware_stack_only_during_initialization_if_not_in_loading_mode
dispatcher = create_dispatcher
assert_not_nil dispatcher.instance_variable_get(:"@app")
dispatcher.instance_variable_set(:"@app", lambda { |env| })
dispatcher.expects(:build_middleware_stack).never
dispatcher.call(nil)
dispatcher.call(nil)
end
def test_rebuilds_middleware_stack_on_every_request_if_in_loading_mode
dispatcher = create_dispatcher(false)
dispatcher.instance_variable_set(:"@app", lambda { |env| })
dispatcher.expects(:build_middleware_stack).twice
dispatcher.call(nil)
Reloader.default_lock.unlock
dispatcher.call(nil)
end
def test_doesnt_wrap_call_in_reloader_if_not_in_loading_mode
Reloader.expects(:run).never
dispatch
end
def test_wraps_call_in_reloader_if_in_loading_mode
Reloader.expects(:run).once
dispatch(false)
end
# Stub out dispatch error logger
class << Dispatcher
def log_failsafe_exception(status, exception); end
end
def test_failsafe_response
CGI.expects(:new).raises('some multipart parsing failure')
Dispatcher.expects(:log_failsafe_exception)
Dispatcher.any_instance.expects(:dispatch).raises('b00m')
ActionController::Failsafe.any_instance.expects(:log_failsafe_exception)
assert_nothing_raised { dispatch }
assert_equal "Status: 400 Bad Request\r\nContent-Type: text/html\r\n\r\n<html><body><h1>400 Bad Request</h1></body></html>", @output.string
response = nil
assert_nothing_raised do
response = dispatch
end
assert_equal 3, response.size
assert_equal 500, response[0]
assert_equal({"Content-Type" => "text/html"}, response[1])
assert_match /500 Internal Server Error/, response[2].join
end
def test_prepare_callbacks
@ -71,7 +90,7 @@ class DispatcherTest < Test::Unit::TestCase
assert_nil a || b || c
# Run callbacks
@dispatcher.send :run_callbacks, :prepare_dispatch
Dispatcher.run_prepare_callbacks
assert_equal 1, a
assert_equal 2, b
@ -79,7 +98,7 @@ class DispatcherTest < Test::Unit::TestCase
# Make sure they are only run once
a = b = c = nil
@dispatcher.send :dispatch
dispatch
assert_nil a || b || c
end
@ -88,26 +107,38 @@ class DispatcherTest < Test::Unit::TestCase
Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
@dispatcher.send :run_callbacks, :prepare_dispatch
Dispatcher.run_prepare_callbacks
assert_equal 2, a
assert_equal nil, b
end
private
def dispatch(output = @output, cache_classes = true)
controller = mock
controller.stubs(:process).returns(controller)
controller.stubs(:out).with(output).returns('response')
ActionController::Routing::Routes.stubs(:recognize).returns(controller)
def dispatch(cache_classes = true)
ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
Dispatcher.define_dispatcher_callbacks(cache_classes)
Dispatcher.dispatch(nil, {}, output)
Dispatcher.new.call({'rack.input' => StringIO.new('')})
end
def create_dispatcher(cache_classes = true)
Dispatcher.define_dispatcher_callbacks(cache_classes)
Dispatcher.new
end
def reset_dispatcher
Dispatcher.middleware = ActionController::MiddlewareStack.new do |middleware|
middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/middlewares.rb"))
middleware.instance_eval(File.read(middlewares))
end
# Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
Dispatcher.define_dispatcher_callbacks(true)
end
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
assert_equal howmany, klass.subclasses.size, message
end
end
end

View file

@ -0,0 +1,53 @@
require 'abstract_unit'
class DomAssertionsTest < ActionView::TestCase
def setup
super
@html_only = '<ul><li>foo</li><li>bar</li></ul>'
@html_with_meaningless_whitespace = %{
<ul>
<li>\tfoo </li>
<li>
bar
</li>
</ul>
}
@more_html_with_meaningless_whitespace = %{<ul>
<li>foo</li>
<li>bar</li></ul>}
end
test "assert_dom_equal strips meaningless whitespace from expected string" do
assert_dom_equal @html_with_meaningless_whitespace, @html_only
end
test "assert_dom_equal strips meaningless whitespace from actual string" do
assert_dom_equal @html_only, @html_with_meaningless_whitespace
end
test "assert_dom_equal strips meaningless whitespace from both expected and actual strings" do
assert_dom_equal @more_html_with_meaningless_whitespace, @html_with_meaningless_whitespace
end
test "assert_dom_not_equal strips meaningless whitespace from expected string" do
assert_assertion_fails { assert_dom_not_equal @html_with_meaningless_whitespace, @html_only }
end
test "assert_dom_not_equal strips meaningless whitespace from actual string" do
assert_assertion_fails { assert_dom_not_equal @html_only, @html_with_meaningless_whitespace }
end
test "assert_dom_not_equal strips meaningless whitespace from both expected and actual strings" do
assert_assertion_fails do
assert_dom_not_equal @more_html_with_meaningless_whitespace, @html_with_meaningless_whitespace
end
end
private
def assert_assertion_fails
assert_raise(ActiveSupport::TestCase::Assertion) { yield }
end
end

View file

@ -0,0 +1,60 @@
require 'abstract_unit'
require 'stringio'
require 'logger'
class FailsafeTest < ActionController::TestCase
FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures/failsafe".freeze
def setup
@old_error_file_path = ActionController::Failsafe.error_file_path
ActionController::Failsafe.error_file_path = FIXTURE_PUBLIC
@app = mock
@log_io = StringIO.new
@logger = Logger.new(@log_io)
@failsafe = ActionController::Failsafe.new(@app)
@failsafe.stubs(:failsafe_logger).returns(@logger)
end
def teardown
ActionController::Failsafe.error_file_path = @old_error_file_path
end
def app_will_raise_error!
@app.expects(:call).then.raises(RuntimeError.new("Printer on fire"))
end
def test_calls_app_and_returns_its_return_value
@app.expects(:call).returns([200, { "Content-Type" => "text/html" }, "ok"])
assert_equal [200, { "Content-Type" => "text/html" }, "ok"], @failsafe.call({})
end
def test_writes_to_log_file_on_exception
app_will_raise_error!
@failsafe.call({})
assert_match /Printer on fire/, @log_io.string # Logs exception message.
assert_match /failsafe_test\.rb/, @log_io.string # Logs backtrace.
end
def test_returns_500_internal_server_error_on_exception
app_will_raise_error!
response = @failsafe.call({})
assert_equal 3, response.size # It is a valid Rack response.
assert_equal 500, response[0] # Status is 500.
end
def test_renders_error_page_file_with_erb
app_will_raise_error!
response = @failsafe.call({})
assert_equal 500, response[0]
assert_equal "hello my world", response[2].join
end
def test_returns_a_default_message_if_erb_rendering_failed
app_will_raise_error!
@failsafe.expects(:render_template).raises(RuntimeError.new("Harddisk is crashing"))
response = @failsafe.call({})
assert_equal 500, response[0]
assert_match /500 Internal Server Error/, response[2].join
assert_match %r(please read this web application's log file), response[2].join
end
end

View file

@ -9,3 +9,11 @@ end
class GoodCustomer < Customer
end
module Quiz
class Question < Struct.new(:name, :id)
def to_param
id.to_s
end
end
end

View file

@ -18,12 +18,15 @@ class FilterParamTest < Test::Unit::TestCase
test_hashes = [[{},{},[]],
[{'foo'=>nil},{'foo'=>nil},[]],
[{'foo'=>'bar'},{'foo'=>'bar'},[]],
[{'foo'=>1},{'foo'=>1},[]],
[{'foo'=>'bar'},{'foo'=>'bar'},%w'food'],
[{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'],
[{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
[{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
[{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
[{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']]
[{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
[{'baz'=>[{'foo'=>'baz'}]}, {'baz'=>[{'foo'=>'[FILTERED]'}]}, %w(foo)],
[{'baz'=>[{'foo'=>'baz'}, 1, 2, 3]}, {'baz'=>[{'foo'=>'[FILTERED]'}, 1, 2, 3]}, %w(foo)]]
test_hashes.each do |before_filter, after_filter, filter_words|
FilterParamController.filter_parameter_logging(*filter_words)

View file

@ -634,9 +634,11 @@ class FilterTest < Test::Unit::TestCase
private
def test_process(controller, action = "show")
ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest
request = ActionController::TestRequest.new
request.action = action
controller.process(request, ActionController::TestResponse.new)
controller = controller.new if controller.is_a?(Class)
controller.process_with_test(request, ActionController::TestResponse.new)
end
end
@ -874,8 +876,10 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase
protected
def test_process(controller, action = "show")
ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest
request = ActionController::TestRequest.new
request.action = action
controller.process(request, ActionController::TestResponse.new)
controller = controller.new if controller.is_a?(Class)
controller.process_with_test(request, ActionController::TestResponse.new)
end
end

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
class FlashTest < Test::Unit::TestCase
class FlashTest < ActionController::TestCase
class TestController < ActionController::Base
def set_flash
flash["that"] = "hello"
@ -73,11 +73,7 @@ class FlashTest < Test::Unit::TestCase
end
end
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = TestController.new
end
tests TestController
def test_flash
get :set_flash
@ -125,7 +121,7 @@ class FlashTest < Test::Unit::TestCase
assert_nil @response.template.assigns["flash_copy"]["that"], "On second flash"
assert_equal "hello again", @response.template.assigns["flash_copy"]["this"], "On second flash"
end
def test_flash_after_reset_session
get :use_flash_after_reset_session
assert_equal "hello", @response.template.assigns["flashy_that"]
@ -143,4 +139,9 @@ class FlashTest < Test::Unit::TestCase
get :std_action
assert_nil @response.template.assigns["flash_copy"]["foo"]
end
def test_does_not_set_the_session_if_the_flash_is_empty
get :std_action
assert_nil session["flash"]
end
end

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
ActionController::Helpers::HELPERS_DIR.replace File.dirname(__FILE__) + '/../fixtures/helpers'
ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers'
class TestController < ActionController::Base
attr_accessor :delegate_attr
@ -130,6 +130,20 @@ class HelperTest < Test::Unit::TestCase
assert methods.include?('foobar')
end
def test_all_helpers_with_alternate_helper_dir
@controller_class.helpers_dir = File.dirname(__FILE__) + '/../fixtures/alternate_helpers'
# Reload helpers
@controller_class.master_helper_module = Module.new
@controller_class.helper :all
# helpers/abc_helper.rb should not be included
assert !master_helper_methods.include?('bare_a')
# alternate_helpers/foo_helper.rb
assert master_helper_methods.include?('baz')
end
def test_helper_proxy
methods = ApplicationController.helpers.methods.map(&:to_s)

View file

@ -134,7 +134,7 @@ HTML
end
def test_invalid_document_raises_exception_when_strict
assert_raises RuntimeError do
assert_raise RuntimeError do
doc = HTML::Document.new("<html>
<table>
<tr>

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
class SanitizerTest < Test::Unit::TestCase
class SanitizerTest < ActionController::TestCase
def setup
@sanitizer = nil # used by assert_sanitizer
end
@ -19,6 +19,7 @@ class SanitizerTest < Test::Unit::TestCase
assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
assert_equal "non printable char is a tag", sanitizer.sanitize("<\x07a href='/hello'>non printable char is a tag</a>")
[nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
end

View file

@ -1,54 +0,0 @@
require 'abstract_unit'
class HttpBasicAuthenticationTest < Test::Unit::TestCase
include ActionController::HttpAuthentication::Basic
class DummyController
attr_accessor :headers, :renders, :request
def initialize
@headers, @renders = {}, []
@request = ActionController::TestRequest.new
end
def render(options)
self.renders << options
end
end
def setup
@controller = DummyController.new
@credentials = ActionController::HttpAuthentication::Basic.encode_credentials("dhh", "secret")
end
def test_successful_authentication
login = Proc.new { |user_name, password| user_name == "dhh" && password == "secret" }
set_headers
assert authenticate(@controller, &login)
set_headers ''
assert_nothing_raised do
assert !authenticate(@controller, &login)
end
set_headers nil
set_headers @credentials, 'REDIRECT_X_HTTP_AUTHORIZATION'
assert authenticate(@controller, &login)
end
def test_failing_authentication
set_headers
assert !authenticate(@controller) { |user_name, password| user_name == "dhh" && password == "incorrect" }
end
def test_authentication_request
authentication_request(@controller, "Megaglobalapp")
assert_equal 'Basic realm="Megaglobalapp"', @controller.headers["WWW-Authenticate"]
assert_equal :unauthorized, @controller.renders.first[:status]
end
private
def set_headers(value = @credentials, name = 'HTTP_AUTHORIZATION')
@controller.request.env[name] = value
end
end

View file

@ -0,0 +1,113 @@
require 'abstract_unit'
class HttpBasicAuthenticationTest < ActionController::TestCase
class DummyController < ActionController::Base
before_filter :authenticate, :only => :index
before_filter :authenticate_with_request, :only => :display
before_filter :authenticate_long_credentials, :only => :show
def index
render :text => "Hello Secret"
end
def display
render :text => 'Definitely Maybe'
end
def show
render :text => 'Only for loooooong credentials'
end
private
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == 'lifo' && password == 'world'
end
end
def authenticate_with_request
if authenticate_with_http_basic { |username, password| username == 'pretty' && password == 'please' }
@logged_in = true
else
request_http_basic_authentication("SuperSecret")
end
end
def authenticate_long_credentials
authenticate_or_request_with_http_basic do |username, password|
username == '1234567890123456789012345678901234567890' && password == '1234567890123456789012345678901234567890'
end
end
end
AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
tests DummyController
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials('lifo', 'world')
get :index
assert_response :success
assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
end
test "successful authentication with #{header.downcase} and long credentials" do
@request.env[header] = encode_credentials('1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890')
get :show
assert_response :success
assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials('h4x0r', 'world')
get :index
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
end
test "unsuccessful authentication with #{header.downcase} and long credentials" do
@request.env[header] = encode_credentials('h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r', 'worldworldworldworldworldworldworldworld')
get :show
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header} and long credentials"
end
end
test "authentication request without credential" do
get :display
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body
assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
end
test "authentication request with invalid credential" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'foo')
get :display
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body
assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
end
test "authentication request with valid credential" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'please')
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
private
def encode_credentials(username, password)
"Basic #{ActiveSupport::Base64.encode64("#{username}:#{password}")}"
end
end

View file

@ -0,0 +1,254 @@
require 'abstract_unit'
class HttpDigestAuthenticationTest < ActionController::TestCase
class DummyDigestController < ActionController::Base
before_filter :authenticate, :only => :index
before_filter :authenticate_with_request, :only => :display
USERS = { 'lifo' => 'world', 'pretty' => 'please',
'dhh' => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":"))}
def index
render :text => "Hello Secret"
end
def display
render :text => 'Definitely Maybe'
end
private
def authenticate
authenticate_or_request_with_http_digest("SuperSecret") do |username|
# Return the password
USERS[username]
end
end
def authenticate_with_request
if authenticate_with_http_digest("SuperSecret") { |username| USERS[username] }
@logged_in = true
else
request_http_digest_authentication("SuperSecret", "Authentication Failed")
end
end
end
AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
tests DummyDigestController
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials(:username => 'lifo', :password => 'world')
get :index
assert_response :success
assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
@request.env[header] = encode_credentials(:username => 'h4x0r', :password => 'world')
get :index
assert_response :unauthorized
assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
end
end
test "authentication request without credential" do
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
credentials = decode_credentials(@response.headers['WWW-Authenticate'])
assert_equal 'SuperSecret', credentials[:realm]
end
test "authentication request with nil credentials" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
get :index
assert_response :unauthorized
assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request"
assert_not_equal 'Hello Secret', @response.body, "Authentication didn't fail for request"
end
test "authentication request with invalid password" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo')
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with invalid nonce" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :nonce => "xxyyzz")
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with missing nonce should return 401" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :remove_nonce => true)
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with Basic auth credentials should return 401" do
ActionController::Base.session_options[:secret] = "session_options_secret"
@request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials('pretty', 'please')
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with invalid opaque" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :opaque => "xxyyzz")
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with invalid realm" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :realm => "NotSecret")
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with valid credential" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with valid credential and nil session" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
# session_id = "" in functional test, but is +nil+ in real life
@request.session.session_id = nil
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with request-uri that doesn't match credentials digest-uri" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
@request.env['REQUEST_URI'] = "/http_digest_authentication_test/dummy_digest/altered/uri"
get :display
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
end
test "authentication request with absolute request uri (as in webrick)" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
@request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with absolute uri in credentials (as in IE)" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
:username => 'pretty', :password => 'please')
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with absolute uri in both request and credentials (as in Webrick with IE)" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
:username => 'pretty', :password => 'please')
@request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with password stored as ha1 digest hash" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'dhh',
:password => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":")),
:password_is_ha1 => true)
get :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with _method" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :method => :post)
@request.env['rack.methodoverride.original_method'] = 'POST'
put :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
test "validate_digest_response should fail with nil returning password_procedure" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
end
private
def encode_credentials(options)
options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b", :password_is_ha1 => false)
password = options.delete(:password)
# Set in /initializers/session_store.rb. Used as secret in generating nonce
# to prevent tampering of timestamp
ActionController::Base.session_options[:secret] = "session_options_secret"
# Perform unauthenticated request to retrieve digest parameters to use on subsequent request
method = options.delete(:method) || 'GET'
case method.to_s.upcase
when 'GET'
get :index
when 'POST'
post :index
end
assert_response :unauthorized
remove_nonce = options.delete(:remove_nonce)
credentials = decode_credentials(@response.headers['WWW-Authenticate'])
credentials.merge!(options)
credentials.merge!(:uri => @request.env['REQUEST_URI'].to_s)
credentials.delete(:nonce) if remove_nonce
ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
end
def decode_credentials(header)
ActionController::HttpAuthentication::Digest.decode_credentials(@response.headers['WWW-Authenticate'])
end
end

View file

@ -1,22 +1,12 @@
require 'abstract_unit'
require 'action_controller/integration'
require 'action_controller/routing'
uses_mocha 'integration' do
module IntegrationSessionStubbing
def stub_integration_session(session)
session.stubs(:process)
session.stubs(:generic_url_rewriter)
end
end
class SessionTest < Test::Unit::TestCase
include IntegrationSessionStubbing
StubApp = lambda { |env|
[200, {"Content-Type" => "text/html", "Content-Length" => "13"}, ["Hello, World!"]]
}
def setup
@session = ActionController::Integration::Session.new
stub_integration_session(@session)
@session = ActionController::Integration::Session.new(StubApp)
end
def test_https_bang_works_and_sets_truth_by_default
@ -38,14 +28,6 @@ class SessionTest < Test::Unit::TestCase
assert_raise(RuntimeError) { @session.follow_redirect! }
end
def test_follow_redirect_calls_get_and_returns_status
@session.stubs(:redirect?).returns(true)
@session.stubs(:headers).returns({"location" => ["www.google.com"]})
@session.stubs(:status).returns(200)
@session.expects(:get)
assert_equal 200, @session.follow_redirect!
end
def test_request_via_redirect_uses_given_method
path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
@session.expects(:put).with(path, args, headers)
@ -209,13 +191,10 @@ class SessionTest < Test::Unit::TestCase
end
class IntegrationTestTest < Test::Unit::TestCase
include IntegrationSessionStubbing
def setup
@test = ::ActionController::IntegrationTest.new(:default_test)
@test.class.stubs(:fixture_table_names).returns([])
@session = @test.open_session
stub_integration_session(@session)
end
def test_opens_new_session
@ -228,20 +207,38 @@ class IntegrationTestTest < Test::Unit::TestCase
assert_equal ::ActionController::Integration::Session, session2.class
assert_not_equal session1, session2
end
# RSpec mixes Matchers (which has a #method_missing) into
# IntegrationTest's superclass. Make sure IntegrationTest does not
# try to delegate these methods to the session object.
def test_does_not_prevent_method_missing_passing_up_to_ancestors
mixin = Module.new do
def method_missing(name, *args)
name.to_s == 'foo' ? 'pass' : super
end
end
@test.class.superclass.__send__(:include, mixin)
begin
assert_equal 'pass', @test.foo
ensure
# leave other tests as unaffected as possible
mixin.__send__(:remove_method, :method_missing)
end
end
end
# Tests that integration tests don't call Controller test methods for processing.
# Integration tests have their own setup and teardown.
class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest
include IntegrationSessionStubbing
def self.fixture_table_names
[]
end
def test_integration_methods_called
reset!
stub_integration_session(@integration_session)
@integration_session.stubs(:generic_url_rewriter)
@integration_session.stubs(:process)
%w( get post head put delete ).each do |verb|
assert_nothing_raised("'#{verb}' should use integration test methods") { __send__(verb, '/') }
end
@ -250,8 +247,6 @@ end
class IntegrationProcessTest < ActionController::IntegrationTest
class IntegrationController < ActionController::Base
session :off
def get
respond_to do |format|
format.html { render :text => "OK", :status => 200 }
@ -263,6 +258,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest
render :text => "foo: #{params[:foo]}", :status => 200
end
def post_with_multiparameter_params
render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}", :status => 200
end
def multipart_post_with_multiparameter_params
render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, filesize: #{params[:file].size}", :status => 200
end
def post
render :text => "Created", :status => 201
end
@ -278,19 +281,18 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
def test_get
with_test_route_set do
get '/get'
assert_equal 200, status
assert_equal "OK", status_message
assert_equal "200 OK", response.headers["Status"]
assert_equal ["200 OK"], headers["status"]
assert_response 200
assert_response :success
assert_response :ok
assert_equal [], response.headers["cookie"]
assert_equal [], headers["cookie"]
assert_equal({}, cookies)
assert_equal "OK", body
assert_equal "OK", response.body
assert_kind_of HTML::Document, html_document
assert_equal 1, request_count
@ -302,14 +304,11 @@ class IntegrationProcessTest < ActionController::IntegrationTest
post '/post'
assert_equal 201, status
assert_equal "Created", status_message
assert_equal "201 Created", response.headers["Status"]
assert_equal ["201 Created"], headers["status"]
assert_response 201
assert_response :success
assert_response :created
assert_equal [], response.headers["cookie"]
assert_equal [], headers["cookie"]
assert_equal({}, cookies)
assert_equal "Created", body
assert_equal "Created", response.body
assert_kind_of HTML::Document, html_document
assert_equal 1, request_count
@ -323,17 +322,9 @@ class IntegrationProcessTest < ActionController::IntegrationTest
get '/cookie_monster'
assert_equal 410, status
assert_equal "Gone", status_message
assert_equal "410 Gone", response.headers["Status"]
assert_equal ["410 Gone"], headers["status"]
assert_response 410
assert_response :gone
assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], response.headers["Set-Cookie"]
assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], headers['set-cookie']
assert_equal [
CGI::Cookie::new("name" => "cookie_1", "value" => ""),
CGI::Cookie::new("name" => "cookie_3", "value" => "chocolate")
], response.headers["cookie"]
assert_equal [], headers["cookie"]
assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"]
assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies)
assert_equal "Gone", response.body
end
@ -344,14 +335,16 @@ class IntegrationProcessTest < ActionController::IntegrationTest
get '/redirect'
assert_equal 302, status
assert_equal "Found", status_message
assert_equal "302 Found", response.headers["Status"]
assert_equal ["302 Found"], headers["status"]
assert_response 302
assert_response :redirect
assert_response :found
assert_equal "<html><body>You are being <a href=\"http://www.example.com/get\">redirected</a>.</body></html>", response.body
assert_kind_of HTML::Document, html_document
assert_equal 1, request_count
follow_redirect!
assert_response :success
assert_equal "/get", path
end
end
@ -360,8 +353,6 @@ class IntegrationProcessTest < ActionController::IntegrationTest
xhr :get, '/get'
assert_equal 200, status
assert_equal "OK", status_message
assert_equal "200 OK", response.headers["Status"]
assert_equal ["200 OK"], headers["status"]
assert_response 200
assert_response :success
assert_response :ok
@ -374,7 +365,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest
get '/get_with_params?foo=bar'
assert_equal '/get_with_params?foo=bar', request.env["REQUEST_URI"]
assert_equal '/get_with_params?foo=bar', request.request_uri
assert_equal nil, request.env["QUERY_STRING"]
assert_equal "", request.env["QUERY_STRING"]
assert_equal 'foo=bar', request.query_string
assert_equal 'bar', request.parameters['foo']
@ -397,6 +388,36 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
def test_post_with_multiparameter_attribute_parameters
with_test_route_set do
post '/post_with_multiparameter_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz"
assert_equal 200, status
assert_equal "foo(1i): bar, foo(2i): baz", response.body
end
end
def test_multipart_post_with_multiparameter_attribute_parameters
with_test_route_set do
post '/multipart_post_with_multiparameter_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz", :file => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
assert_equal 200, status
assert_equal "foo(1i): bar, foo(2i): baz, filesize: 159528", response.body
end
end
def test_head
with_test_route_set do
head '/get'
assert_equal 200, status
assert_equal "", body
head '/post'
assert_equal 201, status
assert_equal "", body
end
end
private
def with_test_route_set
with_routing do |set|
@ -410,4 +431,53 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
class MetalTest < ActionController::IntegrationTest
class Poller
def self.call(env)
if env["PATH_INFO"] =~ /^\/success/
[200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, ["Hello World!"]]
else
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
end
end
end
def setup
@integration_session = ActionController::Integration::Session.new(Poller)
end
def test_successful_get
get "/success"
assert_response 200
assert_response :success
assert_response :ok
assert_equal "Hello World!", response.body
end
def test_failed_get
get "/failure"
assert_response 404
assert_response :not_found
assert_equal '', response.body
end
end
class StringSubclassBodyTest < ActionController::IntegrationTest
class SafeString < String
end
class SafeStringMiddleware
def self.call(env)
[200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, [SafeString.new("Hello World!")]]
end
end
def setup
@integration_session = ActionController::Integration::Session.new(SafeStringMiddleware)
end
def test_string_subclass_body
get '/'
assert_equal 'Hello World!', response.body
end
end

View file

@ -1,43 +0,0 @@
require 'abstract_unit'
require 'action_controller/integration'
require 'action_controller/routing'
unless defined? ApplicationController
class ApplicationController < ActionController::Base
end
end
class UploadTestController < ActionController::Base
session :off
def update
SessionUploadTest.last_request_type = ActionController::Base.param_parsers[request.content_type]
render :text => "got here"
end
end
class SessionUploadTest < ActionController::IntegrationTest
FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
class << self
attr_accessor :last_request_type
end
# def setup
# @session = ActionController::Integration::Session.new
# end
def test_post_with_upload
uses_mocha "test_post_with_upload" do
ActiveSupport::Dependencies.stubs(:load?).returns(false)
with_routing do |set|
set.draw do |map|
map.update 'update', :controller => "upload_test", :action => "update", :method => :post
end
params = { :uploaded_data => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg") }
post '/update', params, :location => 'blah'
assert_equal(:multipart_form, SessionUploadTest.last_request_type)
end
end
end
end

View file

@ -3,6 +3,10 @@ require 'abstract_unit'
# The view_paths array must be set on Base and not LayoutTest so that LayoutTest's inherited
# method has access to the view_paths array when looking for a layout to automatically assign.
old_load_paths = ActionController::Base.view_paths
ActionView::Template::register_template_handler :mab,
lambda { |template| template.source.inspect }
ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ]
class LayoutTest < ActionController::Base
@ -31,14 +35,8 @@ end
class MultipleExtensions < LayoutTest
end
ActionView::Template::register_template_handler :mab,
lambda { |template| template.source.inspect }
class LayoutAutoDiscoveryTest < Test::Unit::TestCase
class LayoutAutoDiscoveryTest < ActionController::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = "www.nextangle.com"
end
@ -55,10 +53,9 @@ class LayoutAutoDiscoveryTest < Test::Unit::TestCase
end
def test_third_party_template_library_auto_discovers_layout
ThirdPartyTemplateLibraryController.view_paths.reload!
@controller = ThirdPartyTemplateLibraryController.new
get :hello
assert_equal 'layouts/third_party_template_library', @controller.active_layout
assert_equal 'layouts/third_party_template_library.mab', @controller.active_layout.to_s
assert_equal 'layouts/third_party_template_library', @response.layout
assert_response :success
assert_equal 'Mab', @response.body
@ -67,14 +64,14 @@ class LayoutAutoDiscoveryTest < Test::Unit::TestCase
def test_namespaced_controllers_auto_detect_layouts
@controller = ControllerNameSpace::NestedController.new
get :hello
assert_equal 'layouts/controller_name_space/nested', @controller.active_layout
assert_equal 'layouts/controller_name_space/nested', @controller.active_layout.to_s
assert_equal 'controller_name_space/nested.rhtml hello.rhtml', @response.body
end
def test_namespaced_controllers_auto_detect_layouts
@controller = MultipleExtensions.new
get :hello
assert_equal 'layouts/multiple_extensions', @controller.active_layout
assert_equal 'layouts/multiple_extensions.html.erb', @controller.active_layout.to_s
assert_equal 'multiple_extensions.html.erb hello.rhtml', @response.body.strip
end
end
@ -82,10 +79,26 @@ end
class DefaultLayoutController < LayoutTest
end
class AbsolutePathLayoutController < LayoutTest
layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test.rhtml')
end
class AbsolutePathWithoutLayoutsController < LayoutTest
# Absolute layout path without 'layouts' in it.
layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/abs_path_layout.rhtml')
end
class HasOwnLayoutController < LayoutTest
layout 'item'
end
class PrependsViewPathController < LayoutTest
def hello
prepend_view_path File.dirname(__FILE__) + '/../fixtures/layout_tests/alt/'
render :layout => 'alt'
end
end
class SetsLayoutInRenderController < LayoutTest
def hello
render :layout => 'third_party_template_library'
@ -98,12 +111,7 @@ class RendersNoLayoutController < LayoutTest
end
end
class LayoutSetInResponseTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
class LayoutSetInResponseTest < ActionController::TestCase
def test_layout_set_when_using_default_layout
@controller = DefaultLayoutController.new
get :hello
@ -138,6 +146,24 @@ class LayoutSetInResponseTest < Test::Unit::TestCase
ensure
ActionController::Base.exempt_from_layout.delete(/\.rhtml$/)
end
def test_layout_is_picked_from_the_controller_instances_view_path
@controller = PrependsViewPathController.new
get :hello
assert_equal 'layouts/alt', @response.layout
end
def test_absolute_pathed_layout
@controller = AbsolutePathLayoutController.new
get :hello
assert_equal "layout_test.rhtml hello.rhtml", @response.body.strip
end
def test_absolute_pathed_layout_without_layouts_in_path
@controller = AbsolutePathWithoutLayoutsController.new
get :hello
assert_equal "abs_path_layout.rhtml hello.rhtml", @response.body.strip
end
end
class RenderWithTemplateOptionController < LayoutTest
@ -150,17 +176,11 @@ class SetsNonExistentLayoutFile < LayoutTest
layout "nofile.rhtml"
end
class LayoutExceptionRaised < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
class LayoutExceptionRaised < ActionController::TestCase
def test_exception_raised_when_layout_file_not_found
@controller = SetsNonExistentLayoutFile.new
get :hello
@response.template.class.module_eval { attr_accessor :exception }
assert_equal ActionView::MissingTemplate, @response.template.exception.class
assert_kind_of ActionView::MissingTemplate, @response.template.instance_eval { @exception }
end
end
@ -170,12 +190,7 @@ class LayoutStatusIsRendered < LayoutTest
end
end
class LayoutStatusIsRenderedTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
class LayoutStatusIsRenderedTest < ActionController::TestCase
def test_layout_status_is_rendered
@controller = LayoutStatusIsRendered.new
get :hello
@ -183,20 +198,18 @@ class LayoutStatusIsRenderedTest < Test::Unit::TestCase
end
end
class LayoutSymlinkedTest < LayoutTest
layout "symlinked/symlinked_layout"
end
class LayoutSymlinkedIsRenderedTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
unless RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
class LayoutSymlinkedTest < LayoutTest
layout "symlinked/symlinked_layout"
end
def test_symlinked_layout_is_rendered
@controller = LayoutSymlinkedTest.new
get :hello
assert_response 200
assert_equal "layouts/symlinked/symlinked_layout", @response.layout
class LayoutSymlinkedIsRenderedTest < ActionController::TestCase
def test_symlinked_layout_is_rendered
@controller = LayoutSymlinkedTest.new
get :hello
assert_response 200
assert_equal "layouts/symlinked/symlinked_layout", @response.layout
end
end
end

View file

@ -0,0 +1,90 @@
require 'abstract_unit'
class MiddlewareStackTest < ActiveSupport::TestCase
class FooMiddleware; end
class BarMiddleware; end
class BazMiddleware; end
def setup
@stack = ActionController::MiddlewareStack.new
@stack.use FooMiddleware
@stack.use BarMiddleware
end
test "use should push middleware as class onto the stack" do
assert_difference "@stack.size" do
@stack.use BazMiddleware
end
assert_equal BazMiddleware, @stack.last.klass
end
test "use should push middleware as a string onto the stack" do
assert_difference "@stack.size" do
@stack.use "MiddlewareStackTest::BazMiddleware"
end
assert_equal BazMiddleware, @stack.last.klass
end
test "use should push middleware as a symbol onto the stack" do
assert_difference "@stack.size" do
@stack.use :"MiddlewareStackTest::BazMiddleware"
end
assert_equal BazMiddleware, @stack.last.klass
end
test "use should push middleware class with arguments onto the stack" do
assert_difference "@stack.size" do
@stack.use BazMiddleware, true, :foo => "bar"
end
assert_equal BazMiddleware, @stack.last.klass
assert_equal([true, {:foo => "bar"}], @stack.last.args)
end
test "insert inserts middleware at the integer index" do
@stack.insert(1, BazMiddleware)
assert_equal BazMiddleware, @stack[1].klass
end
test "insert_after inserts middleware after the integer index" do
@stack.insert_after(1, BazMiddleware)
assert_equal BazMiddleware, @stack[2].klass
end
test "insert_before inserts middleware before another middleware class" do
@stack.insert_before(BarMiddleware, BazMiddleware)
assert_equal BazMiddleware, @stack[1].klass
end
test "insert_after inserts middleware after another middleware class" do
@stack.insert_after(BarMiddleware, BazMiddleware)
assert_equal BazMiddleware, @stack[2].klass
end
test "swaps one middleware out for another" do
assert_equal FooMiddleware, @stack[0].klass
@stack.swap(FooMiddleware, BazMiddleware)
assert_equal BazMiddleware, @stack[0].klass
end
test "active returns all only enabled middleware" do
assert_no_difference "@stack.active.size" do
assert_difference "@stack.size" do
@stack.use BazMiddleware, :if => lambda { false }
end
end
end
test "lazy evaluates middleware class" do
assert_difference "@stack.size" do
@stack.use lambda { BazMiddleware }
end
assert_equal BazMiddleware, @stack.last.klass
end
test "lazy evaluates middleware arguments" do
assert_difference "@stack.size" do
@stack.use BazMiddleware, lambda { :foo }
end
assert_equal [:foo], @stack.last.send(:build_args)
end
end

View file

@ -162,13 +162,11 @@ class RespondToController < ActionController::Base
end
end
class MimeControllerTest < Test::Unit::TestCase
class MimeControllerTest < ActionController::TestCase
tests RespondToController
def setup
ActionController::Base.use_accept_header = true
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = RespondToController.new
@request.host = "www.example.com"
end
@ -471,7 +469,7 @@ class MimeControllerTest < Test::Unit::TestCase
assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body
@request.accept = "text/iphone"
assert_raises(ActionView::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
assert_raise(ActionView::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
end
end
@ -509,12 +507,10 @@ class SuperPostController < PostController
end
end
class MimeControllerLayoutsTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
class MimeControllerLayoutsTest < ActionController::TestCase
tests PostController
@controller = PostController.new
def setup
@request.host = "www.example.com"
end

View file

@ -81,4 +81,13 @@ class MimeTypeTest < Test::Unit::TestCase
assert verified.each { |type| assert Mime.const_get(type.to_s.upcase).verify_request?, "Verifiable Mime Type is not verified: #{type.inspect}" }
assert unverified.each { |type| assert !Mime.const_get(type.to_s.upcase).verify_request?, "Nonverifiable Mime Type is verified: #{type.inspect}" }
end
def test_regexp_matcher
assert Mime::JS =~ "text/javascript"
assert Mime::JS =~ "application/javascript"
assert Mime::JS !~ "text/html"
assert !(Mime::JS !~ "text/javascript")
assert !(Mime::JS !~ "application/javascript")
assert Mime::HTML =~ 'application/xhtml+xml'
end
end

View file

@ -18,192 +18,280 @@ class Tag < Article
def response_id; 1 end
end
class Tax
attr_reader :id
def save; @id = 1 end
def new_record?; @id.nil? end
def name
model = self.class.name.downcase
@id.nil? ? "new #{model}" : "#{model} ##{@id}"
end
end
class Fax < Tax
def store_id; 1 end
end
# TODO: test nested models
class Response::Nested < Response; end
uses_mocha 'polymorphic URL helpers' do
class PolymorphicRoutesTest < Test::Unit::TestCase
class PolymorphicRoutesTest < ActiveSupport::TestCase
include ActionController::PolymorphicRoutes
include ActionController::PolymorphicRoutes
def setup
@article = Article.new
@response = Response.new
@tax = Tax.new
@fax = Fax.new
end
def setup
@article = Article.new
@response = Response.new
end
def test_with_record
@article.save
expects(:article_url).with(@article)
polymorphic_url(@article)
end
def test_with_record
@article.save
expects(:article_url).with(@article)
polymorphic_url(@article)
end
def test_with_new_record
expects(:articles_url).with()
@article.expects(:new_record?).returns(true)
polymorphic_url(@article)
end
def test_with_new_record
expects(:articles_url).with()
@article.expects(:new_record?).returns(true)
polymorphic_url(@article)
end
def test_with_record_and_action
expects(:new_article_url).with()
@article.expects(:new_record?).never
polymorphic_url(@article, :action => 'new')
end
def test_with_record_and_action
expects(:new_article_url).with()
@article.expects(:new_record?).never
polymorphic_url(@article, :action => 'new')
end
def test_url_helper_prefixed_with_new
expects(:new_article_url).with()
new_polymorphic_url(@article)
end
def test_url_helper_prefixed_with_new
expects(:new_article_url).with()
new_polymorphic_url(@article)
end
def test_url_helper_prefixed_with_edit
@article.save
expects(:edit_article_url).with(@article)
edit_polymorphic_url(@article)
end
def test_url_helper_prefixed_with_edit
@article.save
expects(:edit_article_url).with(@article)
edit_polymorphic_url(@article)
end
def test_url_helper_prefixed_with_edit_with_url_options
@article.save
expects(:edit_article_url).with(@article, :param1 => '10')
edit_polymorphic_url(@article, :param1 => '10')
end
def test_url_helper_prefixed_with_edit_with_url_options
@article.save
expects(:edit_article_url).with(@article, :param1 => '10')
edit_polymorphic_url(@article, :param1 => '10')
end
def test_url_helper_with_url_options
@article.save
expects(:article_url).with(@article, :param1 => '10')
polymorphic_url(@article, :param1 => '10')
end
def test_url_helper_with_url_options
@article.save
expects(:article_url).with(@article, :param1 => '10')
polymorphic_url(@article, :param1 => '10')
end
def test_formatted_url_helper
expects(:formatted_article_url).with(@article, :pdf)
def test_formatted_url_helper_is_deprecated
expects(:articles_url).with(:format => :pdf)
assert_deprecated do
formatted_polymorphic_url([@article, :pdf])
end
end
def test_format_option
@article.save
expects(:formatted_article_url).with(@article, :pdf)
polymorphic_url(@article, :format => :pdf)
end
def test_format_option
@article.save
expects(:article_url).with(@article, :format => :pdf)
polymorphic_url(@article, :format => :pdf)
end
def test_format_option_with_url_options
@article.save
expects(:formatted_article_url).with(@article, :pdf, :param1 => '10')
polymorphic_url(@article, :format => :pdf, :param1 => '10')
end
def test_format_option_with_url_options
@article.save
expects(:article_url).with(@article, :format => :pdf, :param1 => '10')
polymorphic_url(@article, :format => :pdf, :param1 => '10')
end
def test_id_and_format_option
@article.save
expects(:article_url).with(:id => @article, :format => :pdf)
polymorphic_url(:id => @article, :format => :pdf)
end
def test_id_and_format_option
@article.save
expects(:article_url).with(:id => @article, :format => :pdf)
polymorphic_url(:id => @article, :format => :pdf)
end
def test_with_nested
@response.save
expects(:article_response_url).with(@article, @response)
polymorphic_url([@article, @response])
end
def test_with_nested
@response.save
expects(:article_response_url).with(@article, @response)
polymorphic_url([@article, @response])
end
def test_with_nested_unsaved
expects(:article_responses_url).with(@article)
polymorphic_url([@article, @response])
end
def test_with_nested_unsaved
expects(:article_responses_url).with(@article)
polymorphic_url([@article, @response])
end
def test_new_with_array_and_namespace
expects(:new_admin_article_url).with()
polymorphic_url([:admin, @article], :action => 'new')
end
def test_new_with_array_and_namespace
expects(:new_admin_article_url).with()
polymorphic_url([:admin, @article], :action => 'new')
end
def test_unsaved_with_array_and_namespace
expects(:admin_articles_url).with()
polymorphic_url([:admin, @article])
end
def test_unsaved_with_array_and_namespace
expects(:admin_articles_url).with()
polymorphic_url([:admin, @article])
end
def test_nested_unsaved_with_array_and_namespace
@article.save
expects(:admin_article_url).with(@article)
polymorphic_url([:admin, @article])
expects(:admin_article_responses_url).with(@article)
polymorphic_url([:admin, @article, @response])
end
def test_nested_unsaved_with_array_and_namespace
@article.save
expects(:admin_article_url).with(@article)
polymorphic_url([:admin, @article])
expects(:admin_article_responses_url).with(@article)
polymorphic_url([:admin, @article, @response])
end
def test_nested_with_array_and_namespace
@response.save
expects(:admin_article_response_url).with(@article, @response)
polymorphic_url([:admin, @article, @response])
def test_nested_with_array_and_namespace
@response.save
expects(:admin_article_response_url).with(@article, @response)
polymorphic_url([:admin, @article, @response])
# a ridiculously long named route tests correct ordering of namespaces and nesting:
@tag = Tag.new
@tag.save
expects(:site_admin_article_response_tag_url).with(@article, @response, @tag)
polymorphic_url([:site, :admin, @article, @response, @tag])
end
# a ridiculously long named route tests correct ordering of namespaces and nesting:
@tag = Tag.new
@tag.save
expects(:site_admin_article_response_tag_url).with(@article, @response, @tag)
polymorphic_url([:site, :admin, @article, @response, @tag])
end
def test_nesting_with_array_ending_in_singleton_resource
expects(:article_response_url).with(@article)
polymorphic_url([@article, :response])
end
def test_nesting_with_array_ending_in_singleton_resource
expects(:article_response_url).with(@article)
polymorphic_url([@article, :response])
end
def test_nesting_with_array_containing_singleton_resource
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag)
polymorphic_url([@article, :response, @tag])
end
def test_nesting_with_array_containing_singleton_resource
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag)
polymorphic_url([@article, :response, @tag])
end
def test_nesting_with_array_containing_namespace_and_singleton_resource
@tag = Tag.new
@tag.save
expects(:admin_article_response_tag_url).with(@article, @tag)
polymorphic_url([:admin, @article, :response, @tag])
end
def test_nesting_with_array_containing_namespace_and_singleton_resource
@tag = Tag.new
@tag.save
expects(:admin_article_response_tag_url).with(@article, @tag)
polymorphic_url([:admin, @article, :response, @tag])
end
def test_nesting_with_array_containing_singleton_resource_and_format
@tag = Tag.new
@tag.save
expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf)
formatted_polymorphic_url([@article, :response, @tag, :pdf])
end
def test_nesting_with_array_containing_singleton_resource_and_format
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag, :format => :pdf)
polymorphic_url([@article, :response, @tag], :format => :pdf)
end
def test_nesting_with_array_containing_singleton_resource_and_format_option
@tag = Tag.new
@tag.save
expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf)
polymorphic_url([@article, :response, @tag], :format => :pdf)
end
def test_nesting_with_array_containing_singleton_resource_and_format_option
@tag = Tag.new
@tag.save
expects(:article_response_tag_url).with(@article, @tag, :format => :pdf)
polymorphic_url([@article, :response, @tag], :format => :pdf)
end
def test_nesting_with_array_containing_nil
expects(:article_response_url).with(@article)
polymorphic_url([@article, nil, :response])
end
def test_nesting_with_array_containing_nil
expects(:article_response_url).with(@article)
polymorphic_url([@article, nil, :response])
end
def test_with_array_containing_single_object
@article.save
expects(:article_url).with(@article)
polymorphic_url([nil, @article])
end
def test_with_array_containing_single_object
@article.save
expects(:article_url).with(@article)
polymorphic_url([nil, @article])
end
def test_with_array_containing_single_name
@article.save
expects(:articles_url)
polymorphic_url([:articles])
end
def test_with_array_containing_single_name
@article.save
expects(:articles_url)
polymorphic_url([:articles])
end
# TODO: Needs to be updated to correctly know about whether the object is in a hash or not
def xtest_with_hash
expects(:article_url).with(@article)
@article.save
polymorphic_url(:id => @article)
end
# TODO: Needs to be updated to correctly know about whether the object is in a hash or not
def xtest_with_hash
expects(:article_url).with(@article)
@article.save
polymorphic_url(:id => @article)
end
def test_polymorphic_path_accepts_options
expects(:new_article_path).with()
polymorphic_path(@article, :action => :new)
end
def test_polymorphic_path_accepts_options
expects(:new_article_path).with()
polymorphic_path(@article, :action => :new)
end
def test_polymorphic_path_does_not_modify_arguments
expects(:admin_article_responses_url).with(@article)
path = [:admin, @article, @response]
assert_no_difference 'path.size' do
polymorphic_url(path)
end
def test_polymorphic_path_does_not_modify_arguments
expects(:admin_article_responses_url).with(@article)
path = [:admin, @article, @response]
assert_no_difference 'path.size' do
polymorphic_url(path)
end
end
# Tests for names where .plural.singular doesn't round-trip
def test_with_irregular_plural_record
@tax.save
expects(:taxis_url).with(@tax)
polymorphic_url(@tax)
end
def test_with_irregular_plural_new_record
expects(:taxes_url).with()
@tax.expects(:new_record?).returns(true)
polymorphic_url(@tax)
end
def test_with_irregular_plural_record_and_action
expects(:new_taxis_url).with()
@tax.expects(:new_record?).never
polymorphic_url(@tax, :action => 'new')
end
def test_irregular_plural_url_helper_prefixed_with_new
expects(:new_taxis_url).with()
new_polymorphic_url(@tax)
end
def test_irregular_plural_url_helper_prefixed_with_edit
@tax.save
expects(:edit_taxis_url).with(@tax)
edit_polymorphic_url(@tax)
end
def test_with_nested_irregular_plurals
@fax.save
expects(:taxis_faxis_url).with(@tax, @fax)
polymorphic_url([@tax, @fax])
end
def test_with_nested_unsaved_irregular_plurals
expects(:taxis_faxes_url).with(@tax)
polymorphic_url([@tax, @fax])
end
def test_new_with_irregular_plural_array_and_namespace
expects(:new_admin_taxis_url).with()
polymorphic_url([:admin, @tax], :action => 'new')
end
def test_unsaved_with_irregular_plural_array_and_namespace
expects(:admin_taxes_url).with()
polymorphic_url([:admin, @tax])
end
def test_nesting_with_irregular_plurals_and_array_ending_in_singleton_resource
expects(:taxis_faxis_url).with(@tax)
polymorphic_url([@tax, :faxis])
end
def test_with_array_containing_single_irregular_plural_object
@tax.save
expects(:taxis_url).with(@tax)
polymorphic_url([nil, @tax])
end
def test_with_array_containing_single_name_irregular_plural
@tax.save
expects(:taxes_url)
polymorphic_url([:taxes])
end
def test_with_array_containing_symbols
expects(:new_article_url).with()
polymorphic_url([:new, :article])
end
end

View file

@ -1,11 +1,10 @@
require 'abstract_unit'
require 'action_controller/rack_process'
class BaseRackTest < Test::Unit::TestCase
class BaseRackTest < ActiveSupport::TestCase
def setup
@env = {
"HTTP_MAX_FORWARDS" => "10",
"SERVER_NAME" => "glu.ttono.us:8007",
"SERVER_NAME" => "glu.ttono.us",
"FCGI_ROLE" => "RESPONDER",
"AUTH_TYPE" => "Basic",
"HTTP_X_FORWARDED_HOST" => "glu.ttono.us",
@ -44,10 +43,10 @@ class BaseRackTest < Test::Unit::TestCase
"REDIRECT_STATUS" => "200",
"REQUEST_METHOD" => "GET"
}
@request = ActionController::RackRequest.new(@env)
@request = ActionController::Request.new(@env)
# some Nokia phone browsers omit the space after the semicolon separator.
# some developers have grown accustomed to using comma in cookie values.
@alt_cookie_fmt_request = ActionController::RackRequest.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}))
@alt_cookie_fmt_request = ActionController::Request.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}))
end
def default_test; end
@ -58,67 +57,67 @@ class BaseRackTest < Test::Unit::TestCase
@request.env['REQUEST_METHOD'] = 'POST'
@request.env['CONTENT_LENGTH'] = data.length
@request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
@request.env['RAW_POST_DATA'] = data
@request.env['rack.input'] = StringIO.new(data)
end
end
class RackRequestTest < BaseRackTest
def test_proxy_request
assert_equal 'glu.ttono.us', @request.host_with_port(true)
assert_equal 'glu.ttono.us', @request.host_with_port
end
def test_http_host
@env.delete "HTTP_X_FORWARDED_HOST"
@env['HTTP_HOST'] = "rubyonrails.org:8080"
assert_equal "rubyonrails.org", @request.host(true)
assert_equal "rubyonrails.org:8080", @request.host_with_port(true)
assert_equal "rubyonrails.org", @request.host
assert_equal "rubyonrails.org:8080", @request.host_with_port
@env['HTTP_X_FORWARDED_HOST'] = "www.firsthost.org, www.secondhost.org"
assert_equal "www.secondhost.org", @request.host(true)
assert_equal "www.secondhost.org", @request.host
end
def test_http_host_with_default_port_overrides_server_port
@env.delete "HTTP_X_FORWARDED_HOST"
@env['HTTP_HOST'] = "rubyonrails.org"
assert_equal "rubyonrails.org", @request.host_with_port(true)
assert_equal "rubyonrails.org", @request.host_with_port
end
def test_host_with_port_defaults_to_server_name_if_no_host_headers
@env.delete "HTTP_X_FORWARDED_HOST"
@env.delete "HTTP_HOST"
assert_equal "glu.ttono.us:8007", @request.host_with_port(true)
assert_equal "glu.ttono.us:8007", @request.host_with_port
end
def test_host_with_port_falls_back_to_server_addr_if_necessary
@env.delete "HTTP_X_FORWARDED_HOST"
@env.delete "HTTP_HOST"
@env.delete "SERVER_NAME"
assert_equal "207.7.108.53", @request.host(true)
assert_equal 8007, @request.port(true)
assert_equal "207.7.108.53:8007", @request.host_with_port(true)
assert_equal "207.7.108.53", @request.host
assert_equal 8007, @request.port
assert_equal "207.7.108.53:8007", @request.host_with_port
end
def test_host_with_port_if_http_standard_port_is_specified
@env['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:80"
assert_equal "glu.ttono.us", @request.host_with_port(true)
assert_equal "glu.ttono.us", @request.host_with_port
end
def test_host_with_port_if_https_standard_port_is_specified
@env['HTTP_X_FORWARDED_PROTO'] = "https"
@env['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:443"
assert_equal "glu.ttono.us", @request.host_with_port(true)
assert_equal "glu.ttono.us", @request.host_with_port
end
def test_host_if_ipv6_reference
@env.delete "HTTP_X_FORWARDED_HOST"
@env['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host(true)
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
end
def test_host_if_ipv6_reference_with_port
@env.delete "HTTP_X_FORWARDED_HOST"
@env['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]:8008"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host(true)
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
end
def test_cgi_environment_variables
@ -146,7 +145,7 @@ class RackRequestTest < BaseRackTest
assert_equal "kevin", @request.remote_user
assert_equal :get, @request.request_method
assert_equal "/dispatch.fcgi", @request.script_name
assert_equal "glu.ttono.us:8007", @request.server_name
assert_equal "glu.ttono.us", @request.server_name
assert_equal 8007, @request.server_port
assert_equal "HTTP/1.1", @request.server_protocol
assert_equal "lighttpd", @request.server_software
@ -154,12 +153,12 @@ class RackRequestTest < BaseRackTest
def test_cookie_syntax_resilience
cookies = @request.cookies
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"], cookies.inspect
assert_equal ["yes"], cookies["is_admin"], cookies.inspect
assert_equal "c84ace84796670c052c6ceb2451fb0f2", cookies["_session_id"], cookies.inspect
assert_equal "yes", cookies["is_admin"], cookies.inspect
alt_cookies = @alt_cookie_fmt_request.cookies
assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect
assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect
#assert_equal "c84ace847,96670c052c6ceb2451fb0f2", alt_cookies["_session_id"], alt_cookies.inspect
assert_equal "yes", alt_cookies["is_admin"], alt_cookies.inspect
end
end
@ -188,29 +187,6 @@ class RackRequestContentTypeTest < BaseRackTest
end
end
class RackRequestMethodTest < BaseRackTest
def test_get
assert_equal :get, @request.request_method
end
def test_post
@request.env['REQUEST_METHOD'] = 'POST'
assert_equal :post, @request.request_method
end
def test_put
set_content_data '_method=put'
assert_equal :put, @request.request_method
end
def test_delete
set_content_data '_method=delete'
assert_equal :delete, @request.request_method
end
end
class RackRequestNeedsRewoundTest < BaseRackTest
def test_body_should_be_rewound
data = 'foo'
@ -219,7 +195,7 @@ class RackRequestNeedsRewoundTest < BaseRackTest
@env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
# Read the request body by parsing params.
request = ActionController::RackRequest.new(@env)
request = ActionController::Request.new(@env)
request.request_parameters
# Should have rewound the body.
@ -230,21 +206,20 @@ end
class RackResponseTest < BaseRackTest
def setup
super
@response = ActionController::RackResponse.new(@request)
@output = StringIO.new('')
@response = ActionController::Response.new
end
def test_simple_output
@response.body = "Hello, World!"
@response.prepare!
status, headers, body = @response.out(@output)
assert_equal "200 OK", status
status, headers, body = @response.to_a
assert_equal 200, status
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "private, max-age=0, must-revalidate",
"ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"',
"Set-Cookie" => [],
"Set-Cookie" => "",
"Content-Length" => "13"
}, headers)
@ -253,60 +228,73 @@ class RackResponseTest < BaseRackTest
assert_equal ["Hello, World!"], parts
end
def test_utf8_output
@response.body = [1090, 1077, 1089, 1090].pack("U*")
@response.prepare!
status, headers, body = @response.to_a
assert_equal 200, status
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "private, max-age=0, must-revalidate",
"ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"',
"Set-Cookie" => "",
"Content-Length" => "8"
}, headers)
end
def test_streaming_block
@response.body = Proc.new do |response, output|
5.times { |n| output.write(n) }
end
@response.prepare!
status, headers, body = @response.out(@output)
assert_equal "200 OK", status
assert_equal({"Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers)
status, headers, body = @response.to_a
assert_equal 200, status
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "no-cache",
"Set-Cookie" => ""
}, headers)
parts = []
body.each { |part| parts << part }
assert_equal ["0", "1", "2", "3", "4"], parts
end
def test_set_session_cookie
cookie = CGI::Cookie.new({"name" => "name", "value" => "Josh"})
@request.cgi.send :instance_variable_set, '@output_cookies', [cookie]
def test_streaming_block_with_flush_is_deprecated
@response.body = Proc.new do |response, output|
5.times do |n|
output.write(n)
output.flush
end
end
@response.body = "Hello, World!"
@response.prepare!
assert_deprecated(/output.flush is no longer needed/) do
@response.prepare!
status, headers, body = @response.to_a
status, headers, body = @response.out(@output)
assert_equal "200 OK", status
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "private, max-age=0, must-revalidate",
"ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"',
"Set-Cookie" => ["name=Josh; path="],
"Content-Length" => "13"
}, headers)
parts = []
body.each { |part| parts << part }
assert_equal ["Hello, World!"], parts
parts = []
body.each { |part| parts << part }
end
end
end
class RackResponseHeadersTest < BaseRackTest
def setup
super
@response = ActionController::RackResponse.new(@request)
@output = StringIO.new('')
@response.headers['Status'] = "200 OK"
@response = ActionController::Response.new
@response.status = "200 OK"
end
def test_content_type
[204, 304].each do |c|
@response.headers['Status'] = c.to_s
@response.status = c.to_s
assert !response_headers.has_key?("Content-Type"), "#{c} should not have Content-Type header"
end
[200, 302, 404, 500].each do |c|
@response.headers['Status'] = c.to_s
@response.status = c.to_s
assert response_headers.has_key?("Content-Type"), "#{c} did not have Content-Type header"
end
end
@ -318,6 +306,6 @@ class RackResponseHeadersTest < BaseRackTest
private
def response_headers
@response.prepare!
@response.out(@output)[1]
@response.to_a[1]
end
end

View file

@ -103,12 +103,8 @@ class RedirectController < ActionController::Base
end
end
class RedirectTest < Test::Unit::TestCase
def setup
@controller = RedirectController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
class RedirectTest < ActionController::TestCase
tests RedirectController
def test_simple_redirect
get :simple_redirect
@ -216,7 +212,7 @@ class RedirectTest < Test::Unit::TestCase
end
def test_redirect_to_back_with_no_referer
assert_raises(ActionController::RedirectBackError) {
assert_raise(ActionController::RedirectBackError) {
@request.env["HTTP_REFERER"] = nil
get :redirect_to_back
}
@ -239,11 +235,14 @@ class RedirectTest < Test::Unit::TestCase
def test_redirect_with_partial_params
get :module_redirect
assert_redirected_to :action => 'hello_world'
assert_deprecated(/test_redirect_with_partial_params/) do
assert_redirected_to :action => 'hello_world'
end
end
def test_redirect_to_nil
assert_raises(ActionController::ActionControllerError) do
assert_raise(ActionController::ActionControllerError) do
get :redirect_to_nil
end
end
@ -256,12 +255,8 @@ module ModuleTest
end
end
class ModuleRedirectTest < Test::Unit::TestCase
def setup
@controller = ModuleRedirectController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
class ModuleRedirectTest < ActionController::TestCase
tests ModuleRedirectController
def test_simple_redirect
get :simple_redirect

View file

@ -0,0 +1,124 @@
require 'abstract_unit'
class ReloaderTests < ActiveSupport::TestCase
Reloader = ActionController::Reloader
Dispatcher = ActionController::Dispatcher
class MyBody < Array
def initialize(&block)
@on_close = block
end
def foo
"foo"
end
def bar
"bar"
end
def close
@on_close.call if @on_close
end
end
def setup
@lock = Mutex.new
end
def test_it_reloads_the_application_before_yielding
Dispatcher.expects(:reload_application)
Reloader.run(@lock) do
[200, { "Content-Type" => "text/html" }, [""]]
end
end
def test_it_locks_before_yielding
lock = DummyMutex.new
Dispatcher.expects(:reload_application)
Reloader.run(lock) do
assert lock.locked?
[200, { "Content-Type" => "text/html" }, [""]]
end
assert lock.locked?
end
def test_it_unlocks_upon_calling_close_on_body
lock = DummyMutex.new
Dispatcher.expects(:reload_application)
headers, status, body = Reloader.run(lock) do
[200, { "Content-Type" => "text/html" }, [""]]
end
body.close
assert !lock.locked?
end
def test_it_unlocks_if_app_object_raises_exception
lock = DummyMutex.new
Dispatcher.expects(:reload_application)
assert_raise(RuntimeError) do
Reloader.run(lock) do
raise "oh no!"
end
end
assert !lock.locked?
end
def test_returned_body_object_always_responds_to_close
status, headers, body = Reloader.run(@lock) do
[200, { "Content-Type" => "text/html" }, [""]]
end
assert body.respond_to?(:close)
end
def test_returned_body_object_behaves_like_underlying_object
status, headers, body = Reloader.run(@lock) do
b = MyBody.new
b << "hello"
b << "world"
[200, { "Content-Type" => "text/html" }, b]
end
assert_equal 2, body.size
assert_equal "hello", body[0]
assert_equal "world", body[1]
assert_equal "foo", body.foo
assert_equal "bar", body.bar
end
def test_it_calls_close_on_underlying_object_when_close_is_called_on_body
close_called = false
status, headers, body = Reloader.run(@lock) do
b = MyBody.new do
close_called = true
end
[200, { "Content-Type" => "text/html" }, b]
end
body.close
assert close_called
end
def test_returned_body_object_responds_to_all_methods_supported_by_underlying_object
status, headers, body = Reloader.run(@lock) do
[200, { "Content-Type" => "text/html" }, MyBody.new]
end
assert body.respond_to?(:size)
assert body.respond_to?(:each)
assert body.respond_to?(:foo)
assert body.respond_to?(:bar)
end
def test_it_doesnt_clean_up_the_application_after_call
Dispatcher.expects(:cleanup_application).never
status, headers, body = Reloader.run(@lock) do
[200, { "Content-Type" => "text/html" }, MyBody.new]
end
end
def test_it_cleans_up_the_application_when_close_is_called_on_body
Dispatcher.expects(:cleanup_application)
status, headers, body = Reloader.run(@lock) do
[200, { "Content-Type" => "text/html" }, MyBody.new]
end
body.close
end
end

View file

@ -21,6 +21,8 @@ class MockLogger
end
class TestController < ActionController::Base
protect_from_forgery
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
end
@ -34,6 +36,39 @@ class TestController < ActionController::Base
render :action => 'hello_world'
end
end
def conditional_hello_with_public_header
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true)
render :action => 'hello_world'
end
end
def conditional_hello_with_public_header_and_expires_at
expires_in 1.minute
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true)
render :action => 'hello_world'
end
end
def conditional_hello_with_expires_in
expires_in 1.minute
render :action => 'hello_world'
end
def conditional_hello_with_expires_in_with_public
expires_in 1.minute, :public => true
render :action => 'hello_world'
end
def conditional_hello_with_expires_in_with_public_with_more_keys
expires_in 1.minute, :public => true, 'max-stale' => 5.hours
render :action => 'hello_world'
end
def conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
expires_in 1.minute, :public => true, :private => nil, 'max-stale' => 5.hours
render :action => 'hello_world'
end
def conditional_hello_with_bangs
render :action => 'hello_world'
@ -79,6 +114,10 @@ class TestController < ActionController::Base
render :action => "hello_world"
end
def render_action_hello_world_as_string
render "hello_world"
end
def render_action_hello_world_with_symbol
render :action => :hello_world
end
@ -102,6 +141,12 @@ class TestController < ActionController::Base
render :file => path
end
def render_file_as_string_with_instance_variables
@secret = 'in the sauce'
path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
render path
end
def render_file_not_using_full_path
@secret = 'in the sauce'
render :file => 'test/render_file_with_ivar'
@ -112,6 +157,11 @@ class TestController < ActionController::Base
render :file => 'test/dot.directory/render_file_with_ivar'
end
def render_file_using_pathname
@secret = 'in the sauce'
render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar.erb')
end
def render_file_from_template
@secret = 'in the sauce'
@path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
@ -122,6 +172,11 @@ class TestController < ActionController::Base
render :file => path, :locals => {:secret => 'in the sauce'}
end
def render_file_as_string_with_locals
path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb'))
render path, :locals => {:secret => 'in the sauce'}
end
def accessing_request_in_template
render :inline => "Hello: <%= request.host %>"
end
@ -138,20 +193,24 @@ class TestController < ActionController::Base
render :inline => "<%= controller_name %>"
end
def render_json_nil
render :json => nil
end
def render_json_hello_world
render :json => {:hello => 'world'}.to_json
render :json => ActiveSupport::JSON.encode(:hello => 'world')
end
def render_json_hello_world_with_callback
render :json => {:hello => 'world'}.to_json, :callback => 'alert'
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
end
def render_json_with_custom_content_type
render :json => {:hello => 'world'}.to_json, :content_type => 'text/javascript'
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
end
def render_symbol_json
render :json => {:hello => 'world'}.to_json
render :json => ActiveSupport::JSON.encode(:hello => 'world')
end
def render_json_with_render_to_string
@ -180,10 +239,6 @@ class TestController < ActionController::Base
render :text => "appended"
end
def render_invalid_args
render("test/hello")
end
def render_vanilla_js_hello
render :js => "alert('hello')"
end
@ -193,6 +248,11 @@ class TestController < ActionController::Base
render :template => "test/hello"
end
def render_xml_hello_as_string_template
@name = "David"
render "test/hello"
end
def render_xml_with_custom_content_type
render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
end
@ -209,6 +269,10 @@ class TestController < ActionController::Base
# let's just rely on the template
end
def blank_response
render :text => ' '
end
def layout_test
render :action => "hello_world"
end
@ -246,13 +310,20 @@ class TestController < ActionController::Base
:locals => { :local_name => name }
end
def helper_method_to_render_to_string(*args)
render_to_string(*args)
def render_implicit_html_template
end
helper_method :helper_method_to_render_to_string
def render_html_only_partial_within_inline
render :inline => "Hello world <%= helper_method_to_render_to_string :partial => 'test/partial_with_only_html_version' %>"
def render_explicit_html_template
end
def render_implicit_html_template_from_xhr_request
end
def render_implicit_js_template_without_layout
end
def render_html_explicit_template_and_layout
render :template => 'test/render_implicit_html_template_from_xhr_request', :layout => 'layouts/default_html'
end
def formatted_html_erb
@ -281,6 +352,14 @@ class TestController < ActionController::Base
render :action => "hello_world", :layout => "standard"
end
def layout_test_with_different_layout_and_string_action
render "hello_world", :layout => "standard"
end
def layout_test_with_different_layout_and_symbol_action
render :hello_world, :layout => "standard"
end
def rendering_without_layout
render :action => "hello_world", :layout => false
end
@ -322,6 +401,10 @@ class TestController < ActionController::Base
render :template => "test/hello_world"
end
def render_with_explicit_string_template
render "test/hello_world"
end
def render_with_explicit_template_with_locals
render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' }
end
@ -608,6 +691,14 @@ class TestController < ActionController::Base
render :partial => "hash_object", :object => {:first_name => "Sam"}
end
def partial_with_nested_object
render :partial => "quiz/questions/question", :object => Quiz::Question.new("first")
end
def partial_with_nested_object_shorthand
render Quiz::Question.new("first")
end
def partial_hash_collection
render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
end
@ -644,23 +735,26 @@ class TestController < ActionController::Base
"accessing_params_in_template",
"accessing_params_in_template_with_layout",
"render_with_explicit_template",
"render_with_explicit_string_template",
"render_js_with_explicit_template",
"render_js_with_explicit_action_template",
"delete_with_js", "update_page", "update_page_with_instance_variables"
"layouts/standard"
when "render_implicit_js_template_without_layout"
"layouts/default_html"
when "action_talk_to_layout", "layout_overriding_layout"
"layouts/talk_from_action"
when "render_implicit_html_template_from_xhr_request"
(request.xhr? ? 'layouts/xhr' : 'layouts/standard')
end
end
end
class RenderTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = TestController.new
class RenderTest < ActionController::TestCase
tests TestController
def setup
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
# a more accurate simulation of what happens in "real life".
@controller.logger = Logger.new(nil)
@ -725,6 +819,12 @@ class RenderTest < Test::Unit::TestCase
assert_template "test/hello_world"
end
def test_render_action_hello_world_as_string
get :render_action_hello_world_as_string
assert_equal "Hello world!", @response.body
assert_template "test/hello_world"
end
def test_render_action_with_symbol
get :render_action_hello_world_with_symbol
assert_template "test/hello_world"
@ -740,6 +840,11 @@ class RenderTest < Test::Unit::TestCase
assert_equal "<html>hello world, I'm here!</html>", @response.body
end
def test_xhr_with_render_text_and_layout
xhr :get, :render_text_hello_world_with_layout
assert_equal "<html>hello world, I'm here!</html>", @response.body
end
def test_do_with_render_action_and_layout_false
get :hello_world_with_layout_false
assert_equal 'Hello world!', @response.body
@ -750,6 +855,11 @@ class RenderTest < Test::Unit::TestCase
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_as_string_with_instance_variables
get :render_file_as_string_with_instance_variables
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_not_using_full_path
get :render_file_not_using_full_path
assert_equal "The secret is in the sauce\n", @response.body
@ -760,43 +870,59 @@ class RenderTest < Test::Unit::TestCase
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_using_pathname
get :render_file_using_pathname
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_with_locals
get :render_file_with_locals
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_as_string_with_locals
get :render_file_as_string_with_locals
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file_from_template
get :render_file_from_template
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_json_nil
get :render_json_nil
assert_equal 'null', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json
get :render_json_hello_world
assert_equal '{"hello": "world"}', @response.body
assert_equal '{"hello":"world"}', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_callback
get :render_json_hello_world_with_callback
assert_equal 'alert({"hello": "world"})', @response.body
assert_equal 'alert({"hello":"world"})', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_custom_content_type
get :render_json_with_custom_content_type
assert_equal '{"hello": "world"}', @response.body
assert_equal '{"hello":"world"}', @response.body
assert_equal 'text/javascript', @response.content_type
end
def test_render_symbol_json
get :render_symbol_json
assert_equal '{"hello": "world"}', @response.body
assert_equal '{"hello":"world"}', @response.body
assert_equal 'application/json', @response.content_type
end
def test_render_json_with_render_to_string
get :render_json_with_render_to_string
assert_equal '{"hello": "partial html"}', @response.body
assert_equal '{"hello":"partial html"}', @response.body
assert_equal 'application/json', @response.content_type
end
@ -830,16 +956,12 @@ class RenderTest < Test::Unit::TestCase
assert_equal 'appended', @response.body
end
def test_attempt_to_render_with_invalid_arguments
assert_raises(ActionController::RenderError) { get :render_invalid_args }
end
def test_attempt_to_access_object_method
assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
assert_raise(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
end
def test_private_methods
assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
assert_raise(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
end
def test_access_to_request_in_view
@ -869,10 +991,13 @@ class RenderTest < Test::Unit::TestCase
end
def test_render_xml
assert_deprecated do
get :render_xml_hello
end
get :render_xml_hello
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
assert_equal "application/xml", @response.content_type
end
def test_render_xml_as_string_template
get :render_xml_hello_as_string_template
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
assert_equal "application/xml", @response.content_type
end
@ -888,12 +1013,13 @@ class RenderTest < Test::Unit::TestCase
end
def test_enum_rjs_test
ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
get :enum_rjs_test
body = %{
$$(".product").each(function(value, index) {
new Effect.Highlight(element,{});
new Effect.Highlight(value,{});
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value)})}});
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
new Draggable(value, {});
});
}.gsub(/^ /, '').strip
@ -906,10 +1032,7 @@ class RenderTest < Test::Unit::TestCase
end
def test_render_xml_with_layouts
assert_deprecated do
get :builder_layout_test
end
get :builder_layout_test
assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
end
@ -949,9 +1072,37 @@ class RenderTest < Test::Unit::TestCase
assert_equal "Goodbye, Local David", @response.body
end
def test_rendering_html_only_partial_within_inline_with_js
get :render_html_only_partial_within_inline, :format => :js
assert_equal "Hello world partial with only html version", @response.body
def test_render_in_an_rjs_template_should_pick_html_templates_when_available
[:js, "js"].each do |format|
assert_nothing_raised do
get :render_implicit_html_template, :format => format
assert_equal %(document.write("Hello world\\n");), @response.body
end
end
end
def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
[:js, "js"].each do |format|
assert_nothing_raised do
get :render_explicit_html_template, :format => format
assert_equal %(document.write("Hello world\\n");), @response.body
end
end
end
def test_should_implicitly_render_html_template_from_xhr_request
xhr :get, :render_implicit_html_template_from_xhr_request
assert_equal "XHR!\nHello HTML!", @response.body
end
def test_should_render_explicit_html_template_with_html_layout
xhr :get, :render_html_explicit_template_and_layout
assert_equal "<html>Hello HTML!</html>\n", @response.body
end
def test_should_implicitly_render_js_template_without_layout
get :render_implicit_js_template_without_layout, :format => :js
assert_no_match /<html>/, @response.body
end
def test_should_render_formatted_template
@ -1005,6 +1156,16 @@ class RenderTest < Test::Unit::TestCase
assert_equal "<html>Hello world!</html>", @response.body
end
def test_layout_test_with_different_layout_and_string_action
get :layout_test_with_different_layout_and_string_action
assert_equal "<html>Hello world!</html>", @response.body
end
def test_layout_test_with_different_layout_and_symbol_action
get :layout_test_with_different_layout_and_symbol_action
assert_equal "<html>Hello world!</html>", @response.body
end
def test_rendering_without_layout
get :rendering_without_layout
assert_equal "Hello world!", @response.body
@ -1032,7 +1193,7 @@ class RenderTest < Test::Unit::TestCase
end
def test_bad_render_to_string_still_throws_exception
assert_raises(ActionView::MissingTemplate) { get :render_to_string_with_exception }
assert_raise(ActionView::MissingTemplate) { get :render_to_string_with_exception }
end
def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
@ -1051,16 +1212,21 @@ class RenderTest < Test::Unit::TestCase
assert_response :success
end
def test_render_with_explicit_string_template
get :render_with_explicit_string_template
assert_equal "<html>Hello world!</html>", @response.body
end
def test_double_render
assert_raises(ActionController::DoubleRenderError) { get :double_render }
assert_raise(ActionController::DoubleRenderError) { get :double_render }
end
def test_double_redirect
assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
assert_raise(ActionController::DoubleRenderError) { get :double_redirect }
end
def test_render_and_redirect
assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
assert_raise(ActionController::DoubleRenderError) { get :render_and_redirect }
end
# specify the one exception to double render rule - render_to_string followed by render
@ -1092,14 +1258,14 @@ class RenderTest < Test::Unit::TestCase
def test_update_page
get :update_page
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
assert_equal 2, @response.body.split($/).length
end
def test_update_page_with_instance_variables
get :update_page_with_instance_variables
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
assert_match /balance/, @response.body
assert_match /\$37/, @response.body
end
@ -1107,7 +1273,7 @@ class RenderTest < Test::Unit::TestCase
def test_update_page_with_view_method
get :update_page_with_view_method
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
assert_match /2 people/, @response.body
end
@ -1140,13 +1306,18 @@ class RenderTest < Test::Unit::TestCase
def test_head_with_symbolic_status
get :head_with_symbolic_status, :status => "ok"
assert_equal "200 OK", @response.headers["Status"]
assert_equal "200 OK", @response.status
assert_response :ok
get :head_with_symbolic_status, :status => "not_found"
assert_equal "404 Not Found", @response.headers["Status"]
assert_equal "404 Not Found", @response.status
assert_response :not_found
get :head_with_symbolic_status, :status => "no_content"
assert_equal "204 No Content", @response.status
assert !@response.headers.include?('Content-Length')
assert_response :no_content
ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code|
get :head_with_symbolic_status, :status => status.to_s
assert_equal code, @response.response_code
@ -1307,21 +1478,28 @@ class RenderTest < Test::Unit::TestCase
def test_partial_collection_with_spacer
get :partial_collection_with_spacer
assert_equal "Hello: davidonly partialHello: mary", @response.body
assert_template :partial => 'test/_partial_only'
assert_template :partial => '_customer'
end
def test_partial_collection_shorthand_with_locals
get :partial_collection_shorthand_with_locals
assert_equal "Bonjour: davidBonjour: mary", @response.body
assert_template :partial => 'customers/_customer', :count => 2
assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0
end
def test_partial_collection_shorthand_with_different_types_of_records
get :partial_collection_shorthand_with_different_types_of_records
assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
assert_template :partial => 'good_customers/_good_customer', :count => 3
assert_template :partial => 'bad_customers/_bad_customer', :count => 3
end
def test_empty_partial_collection
get :empty_partial_collection
assert_equal " ", @response.body
assert_template :partial => false
end
def test_partial_with_hash_object
@ -1329,6 +1507,16 @@ class RenderTest < Test::Unit::TestCase
assert_equal "Sam\nmaS\n", @response.body
end
def test_partial_with_nested_object
get :partial_with_nested_object
assert_equal "first", @response.body
end
def test_partial_with_nested_object_shorthand
get :partial_with_nested_object_shorthand
assert_equal "first", @response.body
end
def test_hash_partial_collection
get :partial_hash_collection
assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
@ -1347,7 +1535,7 @@ class RenderTest < Test::Unit::TestCase
end
def test_render_missing_partial_template
assert_raises(ActionView::MissingTemplate) do
assert_raise(ActionView::MissingTemplate) do
get :missing_partial
end
end
@ -1363,16 +1551,48 @@ class RenderTest < Test::Unit::TestCase
end
end
class EtagRenderTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = TestController.new
class ExpiresInRenderTest < ActionController::TestCase
tests TestController
def setup
@request.host = "www.nextangle.com"
end
def test_expires_in_header
get :conditional_hello_with_expires_in
assert_equal "max-age=60, private", @response.headers["Cache-Control"]
end
def test_expires_in_header_with_public
get :conditional_hello_with_expires_in_with_public
assert_equal "max-age=60, public", @response.headers["Cache-Control"]
end
def test_expires_in_header_with_additional_headers
get :conditional_hello_with_expires_in_with_public_with_more_keys
assert_equal "max-age=60, public, max-stale=18000", @response.headers["Cache-Control"]
end
def test_expires_in_old_syntax
get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
assert_equal "max-age=60, public, max-stale=18000", @response.headers["Cache-Control"]
end
end
class EtagRenderTest < ActionController::TestCase
tests TestController
def setup
@request.host = "www.nextangle.com"
@expected_bang_etag = etag_for(expand_key([:foo, 123]))
end
def test_render_blank_body_shouldnt_set_etag
get :blank_response
assert !@response.etag?
end
def test_render_200_should_set_etag
get :render_hello_world_from_variable
assert_equal etag_for("hello david"), @response.headers['ETag']
@ -1389,7 +1609,7 @@ class EtagRenderTest < Test::Unit::TestCase
def test_render_against_etag_request_should_have_no_content_length_when_match
@request.if_none_match = etag_for("hello david")
get :render_hello_world_from_variable
assert !@response.headers.has_key?("Content-Length")
assert !@response.headers.has_key?("Content-Length"), @response.headers['Content-Length']
end
def test_render_against_etag_request_should_200_when_no_match
@ -1433,10 +1653,7 @@ class EtagRenderTest < Test::Unit::TestCase
end
def test_etag_should_govern_renders_with_layouts_too
assert_deprecated do
get :builder_layout_test
end
get :builder_layout_test
assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
assert_equal etag_for("<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n"), @response.headers['ETag']
end
@ -1452,6 +1669,16 @@ class EtagRenderTest < Test::Unit::TestCase
get :conditional_hello_with_bangs
assert_response :not_modified
end
def test_etag_with_public_true_should_set_header
get :conditional_hello_with_public_header
assert_equal "public", @response.headers['Cache-Control']
end
def test_etag_with_public_true_should_set_header_and_retain_other_headers
get :conditional_hello_with_public_header_and_expires_at
assert_equal "max-age=60, public", @response.headers['Cache-Control']
end
protected
def etag_for(text)
@ -1463,12 +1690,10 @@ class EtagRenderTest < Test::Unit::TestCase
end
end
class LastModifiedRenderTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = TestController.new
class LastModifiedRenderTest < ActionController::TestCase
tests TestController
def setup
@request.host = "www.nextangle.com"
@last_modified = Time.now.utc.beginning_of_day.httpdate
end
@ -1520,12 +1745,10 @@ class LastModifiedRenderTest < Test::Unit::TestCase
end
end
class RenderingLoggingTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = TestController.new
class RenderingLoggingTest < ActionController::TestCase
tests TestController
def setup
@request.host = "www.nextangle.com"
end

View file

@ -0,0 +1,65 @@
require 'abstract_unit'
class JsonParamsParsingTest < ActionController::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_request_parameters
end
def parse
self.class.last_request_parameters = request.request_parameters
head :ok
end
end
def teardown
TestController.last_request_parameters = nil
end
test "parses json params for application json" do
assert_parses(
{"person" => {"name" => "David"}},
"{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/json' }
)
end
test "parses json params for application jsonrequest" do
assert_parses(
{"person" => {"name" => "David"}},
"{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/jsonrequest' }
)
end
test "logs error if parsing unsuccessful" do
with_test_routing do
begin
$stderr = StringIO.new
json = "[\"person]\": {\"name\": \"David\"}}"
post "/parse", json, {'CONTENT_TYPE' => 'application/json'}
assert_response :error
$stderr.rewind && err = $stderr.read
assert err =~ /Error occurred while parsing request parameters/
ensure
$stderr = STDERR
end
end
end
private
def assert_parses(expected, actual, headers = {})
with_test_routing do
post "/parse", actual, headers
assert_response :ok
assert_equal(expected, TestController.last_request_parameters)
end
end
def with_test_routing
with_routing do |set|
set.draw do |map|
map.connect ':action', :controller => "json_params_parsing_test/test"
end
yield
end
end
end

View file

@ -0,0 +1,162 @@
require 'abstract_unit'
class MultipartParamsParsingTest < ActionController::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_request_parameters
end
def parse
self.class.last_request_parameters = request.request_parameters
head :ok
end
def read
render :text => "File: #{params[:uploaded_data].read}"
end
end
FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/multipart'
def teardown
TestController.last_request_parameters = nil
end
test "parses single parameter" do
assert_equal({ 'foo' => 'bar' }, parse_multipart('single_parameter'))
end
test "parses bracketed parameters" do
assert_equal({ 'foo' => { 'baz' => 'bar'}}, parse_multipart('bracketed_param'))
end
test "parses text file" do
params = parse_multipart('text_file')
assert_equal %w(file foo), params.keys.sort
assert_equal 'bar', params['foo']
file = params['file']
assert_kind_of Tempfile, file
assert_equal 'file.txt', file.original_filename
assert_equal "text/plain", file.content_type
assert_equal 'contents', file.read
end
test "parses boundary problem file" do
params = parse_multipart('boundary_problem_file')
assert_equal %w(file foo), params.keys.sort
file = params['file']
foo = params['foo']
assert_kind_of Tempfile, file
assert_equal 'file.txt', file.original_filename
assert_equal "text/plain", file.content_type
assert_equal 'bar', foo
end
test "parses large text file" do
params = parse_multipart('large_text_file')
assert_equal %w(file foo), params.keys.sort
assert_equal 'bar', params['foo']
file = params['file']
assert_kind_of Tempfile, file
assert_equal 'file.txt', file.original_filename
assert_equal "text/plain", file.content_type
assert ('a' * 20480) == file.read
end
test "parses binary file" do
params = parse_multipart('binary_file')
assert_equal %w(file flowers foo), params.keys.sort
assert_equal 'bar', params['foo']
file = params['file']
assert_kind_of Tempfile, file
assert_equal 'file.csv', file.original_filename
assert_nil file.content_type
assert_equal 'contents', file.read
file = params['flowers']
assert_kind_of Tempfile, file
assert_equal 'flowers.jpg', file.original_filename
assert_equal "image/jpeg", file.content_type
assert_equal 19512, file.size
end
test "parses mixed files" do
params = parse_multipart('mixed_files')
assert_equal %w(files foo), params.keys.sort
assert_equal 'bar', params['foo']
# Ruby CGI doesn't handle multipart/mixed for us.
files = params['files']
assert_kind_of Tempfile, files
files.force_encoding('ASCII-8BIT') if files.respond_to?(:force_encoding)
assert_equal 19756, files.size
end
test "does not create tempfile if no file has been selected" do
params = parse_multipart('none')
assert_equal %w(submit-name), params.keys.sort
assert_equal 'Larry', params['submit-name']
assert_equal nil, params['files']
end
test "parses empty upload file" do
params = parse_multipart('empty')
assert_equal %w(files submit-name), params.keys.sort
assert_equal 'Larry', params['submit-name']
assert params['files']
assert_equal "", params['files'].read
end
test "uploads and reads binary file" do
with_test_routing do
fixture = FIXTURE_PATH + "/mona_lisa.jpg"
params = { :uploaded_data => fixture_file_upload(fixture, "image/jpg") }
post '/read', params
expected_length = 'File: '.length + File.size(fixture)
assert_equal expected_length, response.content_length
end
end
test "uploads and reads file" do
with_test_routing do
post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
assert_equal "File: Hello", response.body
end
end
private
def fixture(name)
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
{ "rack.input" => file.read,
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
"CONTENT_LENGTH" => file.stat.size.to_s }
end
end
def parse_multipart(name)
with_test_routing do
headers = fixture(name)
post "/parse", headers.delete("rack.input"), headers
assert_response :ok
TestController.last_request_parameters
end
end
def with_test_routing
with_routing do |set|
set.draw do |map|
map.connect ':action', :controller => "multipart_params_parsing_test/test"
end
yield
end
end
end

View file

@ -0,0 +1,120 @@
require 'abstract_unit'
class QueryStringParsingTest < ActionController::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_query_parameters
end
def parse
self.class.last_query_parameters = request.query_parameters
head :ok
end
end
def teardown
TestController.last_query_parameters = nil
end
test "query string" do
assert_parses(
{"action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
"action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
)
end
test "deep query string" do
assert_parses(
{'x' => {'y' => {'z' => '10'}}},
"x[y][z]=10"
)
end
test "deep query string with array" do
assert_parses({'x' => {'y' => {'z' => ['10']}}}, 'x[y][z][]=10')
assert_parses({'x' => {'y' => {'z' => ['10', '5']}}}, 'x[y][z][]=10&x[y][z][]=5')
end
test "deep query string with array of hash" do
assert_parses({'x' => {'y' => [{'z' => '10'}]}}, 'x[y][][z]=10')
assert_parses({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, 'x[y][][z]=10&x[y][][w]=10')
assert_parses({'x' => {'y' => [{'z' => '10', 'v' => {'w' => '10'}}]}}, 'x[y][][z]=10&x[y][][v][w]=10')
end
test "deep query string with array of hashes with one pair" do
assert_parses({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, 'x[y][][z]=10&x[y][][z]=20')
end
test "deep query string with array of hashes with multiple pairs" do
assert_parses(
{'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
'x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b'
)
end
test "query string with nil" do
assert_parses(
{ "action" => "create_customer", "full_name" => ''},
"action=create_customer&full_name="
)
end
test "query string with array" do
assert_parses(
{ "action" => "create_customer", "selected" => ["1", "2", "3"]},
"action=create_customer&selected[]=1&selected[]=2&selected[]=3"
)
end
test "query string with amps" do
assert_parses(
{ "action" => "create_customer", "name" => "Don't & Does"},
"action=create_customer&name=Don%27t+%26+Does"
)
end
test "query string with many equal" do
assert_parses(
{ "action" => "create_customer", "full_name" => "abc=def=ghi"},
"action=create_customer&full_name=abc=def=ghi"
)
end
test "query string without equal" do
assert_parses({ "action" => nil }, "action")
end
test "query string with empty key" do
assert_parses(
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
"action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
)
end
test "query string with many ampersands" do
assert_parses(
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
)
end
test "unbalanced query string with array" do
assert_parses(
{'location' => ["1", "2"], 'age_group' => ["2"]},
"location[]=1&location[]=2&age_group[]=2"
)
end
private
def assert_parses(expected, actual)
with_routing do |set|
set.draw do |map|
map.connect ':action', :controller => "query_string_parsing_test/test"
end
get "/parse", actual
assert_response :ok
assert_equal(expected, TestController.last_query_parameters)
end
end
end

View file

@ -0,0 +1,35 @@
require 'abstract_unit'
require 'stringio'
class ActionController::TestRequestTest < ActiveSupport::TestCase
def setup
@request = ActionController::TestRequest.new
end
def test_test_request_has_session_options_initialized
assert @request.session_options
end
Rack::Session::Abstract::ID::DEFAULT_OPTIONS.each_key do |option|
test "test_rack_default_session_options_#{option}_exists_in_session_options_and_is_default" do
assert_equal(Rack::Session::Abstract::ID::DEFAULT_OPTIONS[option],
@request.session_options[option],
"Missing rack session default option #{option} in request.session_options")
end
test "test_rack_default_session_options_#{option}_exists_in_session_options" do
assert(@request.session_options.has_key?(option),
"Missing rack session option #{option} in request.session_options")
end
end
def test_session_id_exists_by_default
assert_not_nil(@request.session_options[:id])
end
def test_session_id_different_on_each_call
prev_id =
assert_not_equal(@request.session_options[:id], ActionController::TestRequest.new.session_options[:id])
end
end

View file

@ -0,0 +1,146 @@
require 'abstract_unit'
class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_request_parameters, :last_request_type
end
def parse
self.class.last_request_parameters = request.request_parameters
head :ok
end
end
def teardown
TestController.last_request_parameters = nil
end
test "parses unbalanced query string with array" do
assert_parses(
{'location' => ["1", "2"], 'age_group' => ["2"]},
"location[]=1&location[]=2&age_group[]=2"
)
end
test "parses nested hash" do
query = [
"note[viewers][viewer][][type]=User",
"note[viewers][viewer][][id]=1",
"note[viewers][viewer][][type]=Group",
"note[viewers][viewer][][id]=2"
].join("&")
expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
assert_parses(expected, query)
end
test "parses more complex nesting" do
query = [
"customers[boston][first][name]=David",
"customers[boston][first][url]=http://David",
"customers[boston][second][name]=Allan",
"customers[boston][second][url]=http://Allan",
"something_else=blah",
"something_nil=",
"something_empty=",
"products[first]=Apple Computer",
"products[second]=Pc",
"=Save"
].join("&")
expected = {
"customers" => {
"boston" => {
"first" => {
"name" => "David",
"url" => "http://David"
},
"second" => {
"name" => "Allan",
"url" => "http://Allan"
}
}
},
"something_else" => "blah",
"something_empty" => "",
"something_nil" => "",
"products" => {
"first" => "Apple Computer",
"second" => "Pc"
}
}
assert_parses expected, query
end
test "parses params with array" do
query = "selected[]=1&selected[]=2&selected[]=3"
expected = { "selected" => [ "1", "2", "3" ] }
assert_parses expected, query
end
test "parses params with nil key" do
query = "=&test2=value1"
expected = { "test2" => "value1" }
assert_parses expected, query
end
test "parses params with array prefix and hashes" do
query = "a[][b][c]=d"
expected = {"a" => [{"b" => {"c" => "d"}}]}
assert_parses expected, query
end
test "parses params with complex nesting" do
query = "a[][b][c][][d][]=e"
expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
assert_parses expected, query
end
test "parses params with file path" do
query = [
"customers[boston][first][name]=David",
"something_else=blah",
"logo=#{File.expand_path(__FILE__)}"
].join("&")
expected = {
"customers" => {
"boston" => {
"first" => {
"name" => "David"
}
}
},
"something_else" => "blah",
"logo" => File.expand_path(__FILE__),
}
assert_parses expected, query
end
test "parses params with Safari 2 trailing null character" do
query = "selected[]=1&selected[]=2&selected[]=3\0"
expected = { "selected" => [ "1", "2", "3" ] }
assert_parses expected, query
end
private
def with_test_routing
with_routing do |set|
set.draw do |map|
map.connect ':action', :controller => "url_encoded_params_parsing_test/test"
end
yield
end
end
def assert_parses(expected, actual)
with_test_routing do
post "/parse", actual
assert_response :ok
assert_equal(expected, TestController.last_request_parameters)
end
end
end

View file

@ -0,0 +1,103 @@
require 'abstract_unit'
class XmlParamsParsingTest < ActionController::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_request_parameters
end
def parse
self.class.last_request_parameters = request.request_parameters
head :ok
end
end
def teardown
TestController.last_request_parameters = nil
end
test "parses hash params" do
with_test_routing do
xml = "<person><name>David</name></person>"
post "/parse", xml, default_headers
assert_response :ok
assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters)
end
end
test "parses single file" do
with_test_routing do
xml = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>"
post "/parse", xml, default_headers
assert_response :ok
person = TestController.last_request_parameters
assert_equal "image/jpg", person['person']['avatar'].content_type
assert_equal "me.jpg", person['person']['avatar'].original_filename
assert_equal "ABC", person['person']['avatar'].read
end
end
test "logs error if parsing unsuccessful" do
with_test_routing do
begin
$stderr = StringIO.new
xml = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></pineapple>"
post "/parse", xml, default_headers
assert_response :error
$stderr.rewind && err = $stderr.read
assert err =~ /Error occurred while parsing request parameters/
ensure
$stderr = STDERR
end
end
end
test "parses multiple files" do
xml = <<-end_body
<person>
<name>David</name>
<avatars>
<avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
<avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
</avatars>
</person>
end_body
with_test_routing do
post "/parse", xml, default_headers
assert_response :ok
end
person = TestController.last_request_parameters
assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
assert_equal "ABC", person['person']['avatars']['avatar'].first.read
assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
assert_equal "DEF", person['person']['avatars']['avatar'].last.read
end
private
def with_test_routing
with_routing do |set|
set.draw do |map|
map.connect ':action', :controller => "xml_params_parsing_test/test"
end
yield
end
end
def default_headers
{'CONTENT_TYPE' => 'application/xml'}
end
end
class LegacyXmlParamsParsingTest < XmlParamsParsingTest
private
def default_headers
{'HTTP_X_POST_DATA_FORMAT' => 'xml'}
end
end

View file

@ -5,13 +5,6 @@ ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id'
end
# simulates cookie session store
class FakeSessionDbMan
def self.generate_digest(data)
Digest::SHA1.hexdigest("secure")
end
end
# common controller actions
module RequestForgeryProtectionActions
def index
@ -29,36 +22,17 @@ module RequestForgeryProtectionActions
def unsafe
render :text => 'pwn'
end
def rescue_action(e) raise e end
end
# sample controllers
class RequestForgeryProtectionController < ActionController::Base
include RequestForgeryProtectionActions
protect_from_forgery :only => :index, :secret => 'abc'
end
class RequestForgeryProtectionWithoutSecretController < ActionController::Base
include RequestForgeryProtectionActions
protect_from_forgery
end
# no token is given, assume the cookie store is used
class CsrfCookieMonsterController < ActionController::Base
include RequestForgeryProtectionActions
protect_from_forgery :only => :index
end
# sessions are turned off
class SessionOffController < ActionController::Base
protect_from_forgery :secret => 'foobar'
session :off
def rescue_action(e) raise e end
include RequestForgeryProtectionActions
end
class FreeCookieController < CsrfCookieMonsterController
class FreeCookieController < RequestForgeryProtectionController
self.allow_forgery_protection = false
def index
@ -70,6 +44,13 @@ class FreeCookieController < CsrfCookieMonsterController
end
end
class CustomAuthenticityParamController < RequestForgeryProtectionController
def form_authenticity_param
'foobar'
end
end
# common test methods
module RequestForgeryProtectionTests
@ -105,17 +86,17 @@ module RequestForgeryProtectionTests
def test_should_not_allow_html_post_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raises(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
end
def test_should_not_allow_html_put_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raises(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
end
def test_should_not_allow_html_delete_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raises(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
end
def test_should_allow_api_formatted_post_without_token
@ -137,54 +118,50 @@ module RequestForgeryProtectionTests
end
def test_should_not_allow_api_formatted_post_sent_as_url_encoded_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
post :index, :format => 'xml'
end
end
def test_should_not_allow_api_formatted_put_sent_as_url_encoded_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
put :index, :format => 'xml'
end
end
def test_should_not_allow_api_formatted_delete_sent_as_url_encoded_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
delete :index, :format => 'xml'
end
end
def test_should_not_allow_api_formatted_post_sent_as_multipart_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
post :index, :format => 'xml'
end
end
def test_should_not_allow_api_formatted_put_sent_as_multipart_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
put :index, :format => 'xml'
end
end
def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_token
assert_raises(ActionController::InvalidAuthenticityToken) do
assert_raise(ActionController::InvalidAuthenticityToken) do
@request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
delete :index, :format => 'xml'
end
end
def test_should_allow_xhr_post_without_token
assert_nothing_raised { xhr :post, :index }
end
def test_should_not_allow_xhr_post_with_html_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raise(ActionController::InvalidAuthenticityToken) { xhr :post, :index }
end
def test_should_allow_xhr_put_without_token
assert_nothing_raised { xhr :put, :index }
@ -194,6 +171,11 @@ module RequestForgeryProtectionTests
assert_nothing_raised { xhr :delete, :index }
end
def test_should_allow_xhr_post_with_encoded_form_content_type_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_nothing_raised { xhr :post, :index }
end
def test_should_allow_post_with_token
post :index, :authenticity_token => @token
assert_response :success
@ -230,62 +212,28 @@ end
# OK let's get our test on
class RequestForgeryProtectionControllerTest < Test::Unit::TestCase
class RequestForgeryProtectionControllerTest < ActionController::TestCase
include RequestForgeryProtectionTests
def setup
@controller = RequestForgeryProtectionController.new
@request = ActionController::TestRequest.new
@request.format = :html
@response = ActionController::TestResponse.new
class << @request.session
def session_id() '123' end
end
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
@token = "cf50faa3fe97702ca1ae"
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
ActionController::Base.request_forgery_protection_token = :authenticity_token
end
end
class RequestForgeryProtectionWithoutSecretControllerTest < Test::Unit::TestCase
def setup
@controller = RequestForgeryProtectionWithoutSecretController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
class << @request.session
def session_id() '123' end
end
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
ActionController::Base.request_forgery_protection_token = :authenticity_token
end
# def test_should_raise_error_without_secret
# assert_raises ActionController::InvalidAuthenticityToken do
# get :index
# end
# end
end
class CsrfCookieMonsterControllerTest < Test::Unit::TestCase
include RequestForgeryProtectionTests
def setup
@controller = CsrfCookieMonsterController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
class << @request.session
attr_accessor :dbman
end
# simulate a cookie session store
@request.session.dbman = FakeSessionDbMan
@token = Digest::SHA1.hexdigest("secure")
ActionController::Base.request_forgery_protection_token = :authenticity_token
end
end
class FreeCookieControllerTest < Test::Unit::TestCase
class FreeCookieControllerTest < ActionController::TestCase
def setup
@controller = FreeCookieController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
@token = "cf50faa3fe97702ca1ae"
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
end
def test_should_not_render_form_with_token_tag
@ -305,23 +253,13 @@ class FreeCookieControllerTest < Test::Unit::TestCase
end
end
class SessionOffControllerTest < Test::Unit::TestCase
class CustomAuthenticityParamControllerTest < ActionController::TestCase
def setup
@controller = SessionOffController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
ActionController::Base.request_forgery_protection_token = :authenticity_token
end
# TODO: Rewrite this test.
# This test was passing but for the wrong reason.
# Sessions aren't really being turned off, so an exception was raised
# because sessions weren't on - not because the token didn't match.
#
# def test_should_raise_correct_exception
# @request.session = {} # session(:off) doesn't appear to work with controller tests
# assert_raises(ActionController::InvalidAuthenticityToken) do
# post :index, :authenticity_token => @token, :format => :html
# end
# end
def test_should_allow_custom_token
post :index, :authenticity_token => 'foobar'
assert_response :ok
end
end

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,5 @@
require 'abstract_unit'
uses_mocha 'rescue' do
class RescueController < ActionController::Base
class NotAuthorized < StandardError
end
@ -67,6 +65,11 @@ class RescueController < ActionController::Base
render :text => 'no way'
end
before_filter(:only => :before_filter_raises) { raise 'umm nice' }
def before_filter_raises
end
def raises
render :text => 'already rendered'
raise "don't panic!"
@ -154,6 +157,16 @@ class RescueControllerTest < ActionController::TestCase
end
end
def test_rescue_exceptions_raised_by_filters
with_rails_root FIXTURE_PUBLIC do
with_all_requests_local false do
get :before_filter_raises
end
end
assert_response :internal_server_error
end
def test_rescue_action_locally_if_all_requests_local
@controller.expects(:local_request?).never
@controller.expects(:rescue_action_locally).with(@exception)
@ -184,6 +197,24 @@ class RescueControllerTest < ActionController::TestCase
end
end
def test_rescue_action_in_public_with_localized_error_file
# Change locale
old_locale = I18n.locale
I18n.locale = :da
with_rails_root FIXTURE_PUBLIC do
with_all_requests_local false do
get :raises
end
end
assert_response :internal_server_error
body = File.read("#{FIXTURE_PUBLIC}/public/500.da.html")
assert_equal body, @response.body
ensure
I18n.locale = old_locale
end
def test_rescue_action_in_public_with_error_file
with_rails_root FIXTURE_PUBLIC do
with_all_requests_local false do
@ -291,24 +322,6 @@ class RescueControllerTest < ActionController::TestCase
assert_equal 'template_error', templates[ActionView::TemplateError.name]
end
def test_clean_backtrace
with_rails_root nil do
# No action if RAILS_ROOT isn't set.
cleaned = @controller.send(:clean_backtrace, @exception)
assert_equal @exception.backtrace, cleaned
end
with_rails_root Dir.pwd do
# RAILS_ROOT is removed from backtrace.
cleaned = @controller.send(:clean_backtrace, @exception)
expected = @exception.backtrace.map { |line| line.sub(RAILS_ROOT, '') }
assert_equal expected, cleaned
# No action if backtrace is nil.
assert_nil @controller.send(:clean_backtrace, Exception.new)
end
end
def test_not_implemented
with_all_requests_local false do
with_rails_public_path(".") do
@ -385,10 +398,21 @@ class RescueControllerTest < ActionController::TestCase
end
def test_rescue_dispatcher_exceptions
RescueController.process_with_exception(@request, @response, ActionController::RoutingError.new("Route not found"))
env = @request.env
env["action_controller.rescue.request"] = @request
env["action_controller.rescue.response"] = @response
RescueController.call_with_exception(env, ActionController::RoutingError.new("Route not found"))
assert_equal "no way", @response.body
end
def test_rescue_dispatcher_exceptions_without_request_set
@request.env['REQUEST_URI'] = '/no_way'
response = RescueController.call_with_exception(@request.env, ActionController::RoutingError.new("Route not found"))
assert_kind_of ActionController::Response, response
assert_equal "no way", response.body
end
protected
def with_all_requests_local(local = true)
old_local, ActionController::Base.consider_all_requests_local =
@ -510,4 +534,3 @@ class ControllerInheritanceRescueControllerTest < ActionController::TestCase
assert_response :created
end
end
end # uses_mocha

View file

@ -29,7 +29,7 @@ module Backoffice
end
end
class ResourcesTest < Test::Unit::TestCase
class ResourcesTest < ActionController::TestCase
# The assertions in these tests are incompatible with the hash method
# optimisation. This could indicate user level problems
def setup
@ -76,6 +76,50 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_override_paths_for_member_and_collection_methods
collection_methods = { 'rss' => :get, 'reorder' => :post, 'csv' => :post }
member_methods = { 'rss' => :get, :atom => :get, :upload => :post, :fix => :post }
path_names = {:new => 'nuevo', 'rss' => 'canal', :fix => 'corrigir' }
with_restful_routing :messages,
:collection => collection_methods,
:member => member_methods,
:path_names => path_names do
assert_restful_routes_for :messages,
:collection => collection_methods,
:member => member_methods,
:path_names => path_names do |options|
member_methods.each do |action, method|
assert_recognizes(options.merge(:action => action.to_s, :id => '1'),
:path => "/messages/1/#{path_names[action] || action}",
:method => method)
end
collection_methods.each do |action, method|
assert_recognizes(options.merge(:action => action),
:path => "/messages/#{path_names[action] || action}",
:method => method)
end
end
assert_restful_named_routes_for :messages,
:collection => collection_methods,
:member => member_methods,
:path_names => path_names do |options|
collection_methods.keys.each do |action|
assert_named_route "/messages/#{path_names[action] || action}", "#{action}_messages_path", :action => action
end
member_methods.keys.each do |action|
assert_named_route "/messages/1/#{path_names[action] || action}", "#{action}_message_path", :action => action, :id => "1"
end
end
end
end
def test_override_paths_for_default_restful_actions
resource = ActionController::Resources::Resource.new(:messages,
:path_names => {:new => 'nuevo', :edit => 'editar'})
@ -99,7 +143,7 @@ class ResourcesTest < Test::Unit::TestCase
expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'}
with_restful_routing :messages do
assert_raises(ActionController::RoutingError) do
assert_raise(ActionController::RoutingError) do
assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get)
end
end
@ -120,6 +164,14 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_irregular_id_requirements_should_get_passed_to_member_actions
expected_options = {:controller => 'messages', :action => 'custom', :id => '1.1.1'}
with_restful_routing(:messages, :member => {:custom => :get}, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}) do
assert_recognizes(expected_options, :path => 'messages/1.1.1/custom', :method => :get)
end
end
def test_with_path_prefix
with_restful_routing :messages, :path_prefix => '/thread/:thread_id' do
assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
@ -175,6 +227,24 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_with_collection_actions_and_name_prefix_and_member_action_with_same_name
actions = { 'a' => :get }
with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => actions, :member => actions do
assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
actions.each do |action, method|
assert_recognizes(options.merge(:action => action), :path => "/threads/1/messages/#{action}", :method => method)
end
end
assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
actions.keys.each do |action|
assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", :action => action
end
end
end
end
def test_with_collection_action_and_name_prefix_and_formatted
actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete }
@ -187,7 +257,7 @@ class ResourcesTest < Test::Unit::TestCase
assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
actions.keys.each do |action|
assert_named_route "/threads/1/messages/#{action}.xml", "formatted_#{action}_thread_messages_path", :action => action, :format => 'xml'
assert_named_route "/threads/1/messages/#{action}.xml", "#{action}_thread_messages_path", :action => action, :format => 'xml'
end
end
end
@ -209,6 +279,14 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_with_member_action_and_requirement
expected_options = {:controller => 'messages', :action => 'mark', :id => '1.1.1'}
with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}, :member => { :mark => :get }) do
assert_recognizes(expected_options, :path => 'messages/1.1.1/mark', :method => :get)
end
end
def test_member_when_override_paths_for_default_restful_actions_with
[:put, :post].each do |method|
with_restful_routing :messages, :member => { :mark => method }, :path_names => {:new => 'nuevo'} do
@ -316,7 +394,7 @@ class ResourcesTest < Test::Unit::TestCase
end
assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
assert_named_route preview_path, :formatted_preview_new_thread_message_path, preview_options
assert_named_route preview_path, :preview_new_thread_message_path, preview_options
end
end
end
@ -325,7 +403,7 @@ class ResourcesTest < Test::Unit::TestCase
with_restful_routing :messages do
assert_restful_routes_for :messages do |options|
assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get)
assert_raises(ActionController::MethodNotAllowed) do
assert_raise(ActionController::MethodNotAllowed) do
ActionController::Routing::Routes.recognize_path("/messages/new", :method => :post)
end
end
@ -406,6 +484,34 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_shallow_nested_restful_routes_with_namespaces
with_routing do |set|
set.draw do |map|
map.namespace :backoffice do |map|
map.namespace :admin do |map|
map.resources :products, :shallow => true do |map|
map.resources :images
end
end
end
end
assert_simply_restful_for :products,
:controller => 'backoffice/admin/products',
:namespace => 'backoffice/admin/',
:name_prefix => 'backoffice_admin_',
:path_prefix => 'backoffice/admin/',
:shallow => true
assert_simply_restful_for :images,
:controller => 'backoffice/admin/images',
:namespace => 'backoffice/admin/',
:name_prefix => 'backoffice_admin_product_',
:path_prefix => 'backoffice/admin/products/1/',
:shallow => true,
:options => { :product_id => '1' }
end
end
def test_restful_routes_dont_generate_duplicates
with_restful_routing :messages do
routes = ActionController::Routing::Routes.routes
@ -583,11 +689,11 @@ class ResourcesTest < Test::Unit::TestCase
options = { :controller => controller_name.to_s }
collection_path = "/#{controller_name}"
assert_raises(ActionController::MethodNotAllowed) do
assert_raise(ActionController::MethodNotAllowed) do
assert_recognizes(options.merge(:action => 'update'), :path => collection_path, :method => :put)
end
assert_raises(ActionController::MethodNotAllowed) do
assert_raise(ActionController::MethodNotAllowed) do
assert_recognizes(options.merge(:action => 'destroy'), :path => collection_path, :method => :delete)
end
end
@ -596,7 +702,7 @@ class ResourcesTest < Test::Unit::TestCase
def test_should_not_allow_invalid_head_method_for_member_routes
with_routing do |set|
set.draw do |map|
assert_raises(ArgumentError) do
assert_raise(ArgumentError) do
map.resources :messages, :member => {:something => :head}
end
end
@ -606,7 +712,7 @@ class ResourcesTest < Test::Unit::TestCase
def test_should_not_allow_invalid_http_methods_for_member_routes
with_routing do |set|
set.draw do |map|
assert_raises(ArgumentError) do
assert_raise(ArgumentError) do
map.resources :messages, :member => {:something => :invalid}
end
end
@ -750,9 +856,17 @@ class ResourcesTest < Test::Unit::TestCase
end
def test_with_path_segment
with_restful_routing :messages, :as => 'reviews' do
assert_simply_restful_for :messages, :as => 'reviews'
with_restful_routing :messages do
assert_simply_restful_for :messages
assert_recognizes({:controller => "messages", :action => "index"}, "/messages")
assert_recognizes({:controller => "messages", :action => "index"}, "/messages/")
end
with_restful_routing :messages, :as => 'reviews' do
assert_simply_restful_for :messages, :as => 'reviews'
assert_recognizes({:controller => "messages", :action => "index"}, "/reviews")
assert_recognizes({:controller => "messages", :action => "index"}, "/reviews/")
end
end
def test_multiple_with_path_segment_and_controller
@ -942,19 +1056,6 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_nested_resource_inherits_only_show_action
with_routing do |set|
set.draw do |map|
map.resources :products, :only => :show do |product|
product.resources :images
end
end
assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
end
end
def test_nested_resource_has_only_show_and_member_action
with_routing do |set|
set.draw do |map|
@ -971,7 +1072,7 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_nested_resource_ignores_only_option
def test_nested_resource_does_not_inherit_only_option
with_routing do |set|
set.draw do |map|
map.resources :products, :only => :show do |product|
@ -984,7 +1085,20 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_nested_resource_ignores_except_option
def test_nested_resource_does_not_inherit_only_option_by_default
with_routing do |set|
set.draw do |map|
map.resources :products, :only => :show do |product|
product.resources :images
end
end
assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destory], [], 'products/1/images')
assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
end
end
def test_nested_resource_does_not_inherit_except_option
with_routing do |set|
set.draw do |map|
map.resources :products, :except => :show do |product|
@ -997,6 +1111,29 @@ class ResourcesTest < Test::Unit::TestCase
end
end
def test_nested_resource_does_not_inherit_except_option_by_default
with_routing do |set|
set.draw do |map|
map.resources :products, :except => :show do |product|
product.resources :images
end
end
assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
end
end
def test_default_singleton_restful_route_uses_get
with_routing do |set|
set.draw do |map|
map.resource :product
end
assert_equal :get, set.named_routes.routes[:product].conditions[:method]
end
end
protected
def with_restful_routing(*args)
with_routing do |set|
@ -1043,7 +1180,7 @@ class ResourcesTest < Test::Unit::TestCase
path = "#{options[:as] || controller_name}"
collection_path = "/#{options[:path_prefix]}#{path}"
shallow_path = "/#{options[:path_prefix] unless options[:shallow]}#{path}"
shallow_path = "/#{options[:shallow] ? options[:namespace] : options[:path_prefix]}#{path}"
member_path = "#{shallow_path}/1"
new_path = "#{collection_path}/#{new_action}"
edit_member_path = "#{member_path}/#{edit_action}"
@ -1107,10 +1244,10 @@ class ResourcesTest < Test::Unit::TestCase
options[:options].delete :action
path = "#{options[:as] || controller_name}"
shallow_path = "/#{options[:path_prefix] unless options[:shallow]}#{path}"
shallow_path = "/#{options[:shallow] ? options[:namespace] : options[:path_prefix]}#{path}"
full_path = "/#{options[:path_prefix]}#{path}"
name_prefix = options[:name_prefix]
shallow_prefix = "#{options[:name_prefix] unless options[:shallow]}"
shallow_prefix = options[:shallow] ? options[:namespace].try(:gsub, /\//, '_') : options[:name_prefix]
new_action = "new"
edit_action = "edit"
@ -1120,14 +1257,14 @@ class ResourcesTest < Test::Unit::TestCase
end
assert_named_route "#{full_path}", "#{name_prefix}#{controller_name}_path", options[:options]
assert_named_route "#{full_path}.xml", "formatted_#{name_prefix}#{controller_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}.xml", "#{name_prefix}#{controller_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{shallow_path}/1", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1')
assert_named_route "#{shallow_path}/1.xml", "formatted_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
assert_named_route "#{shallow_path}/1.xml", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
assert_named_route "#{full_path}/#{new_action}", "new_#{name_prefix}#{singular_name}_path", options[:options]
assert_named_route "#{full_path}/#{new_action}.xml", "formatted_new_#{name_prefix}#{singular_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}/#{new_action}.xml", "new_#{name_prefix}#{singular_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{shallow_path}/1/#{edit_action}", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1')
assert_named_route "#{shallow_path}/1/#{edit_action}.xml", "formatted_edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
assert_named_route "#{shallow_path}/1/#{edit_action}.xml", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
yield options[:options] if block_given?
end
@ -1179,12 +1316,12 @@ class ResourcesTest < Test::Unit::TestCase
name_prefix = options[:name_prefix]
assert_named_route "#{full_path}", "#{name_prefix}#{singleton_name}_path", options[:options]
assert_named_route "#{full_path}.xml", "formatted_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}.xml", "#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}/new", "new_#{name_prefix}#{singleton_name}_path", options[:options]
assert_named_route "#{full_path}/new.xml", "formatted_new_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}/new.xml", "new_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}/edit", "edit_#{name_prefix}#{singleton_name}_path", options[:options]
assert_named_route "#{full_path}/edit.xml", "formatted_edit_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
assert_named_route "#{full_path}/edit.xml", "edit_#{name_prefix}#{singleton_name}_path", options[:options].merge(:format => 'xml')
end
def assert_named_route(expected, route, options)
@ -1240,7 +1377,7 @@ class ResourcesTest < Test::Unit::TestCase
end
def assert_not_recognizes(expected_options, path)
assert_raise ActionController::RoutingError, ActionController::MethodNotAllowed, Test::Unit::AssertionFailedError do
assert_raise ActionController::RoutingError, ActionController::MethodNotAllowed, Assertion do
assert_recognizes(expected_options, path)
end
end

File diff suppressed because it is too large Load diff

View file

@ -303,7 +303,7 @@ class SelectorTest < Test::Unit::TestCase
assert_equal 1, @matches.size
assert_equal "2", @matches[0].attributes["id"]
# Before first and past last returns nothing.:
assert_raises(ArgumentError) { select("tr:nth-child(-1)") }
assert_raise(ArgumentError) { select("tr:nth-child(-1)") }
select("tr:nth-child(0)")
assert_equal 0, @matches.size
select("tr:nth-child(5)")
@ -597,8 +597,8 @@ class SelectorTest < Test::Unit::TestCase
def test_negation_details
parse(%Q{<p id="1"></p><p id="2"></p><p id="3"></p>})
assert_raises(ArgumentError) { select(":not(") }
assert_raises(ArgumentError) { select(":not(:not())") }
assert_raise(ArgumentError) { select(":not(") }
assert_raise(ArgumentError) { select(":not(:not())") }
select("p:not(#1):not(#3)")
assert_equal 1, @matches.size
assert_equal "2", @matches[0].attributes["id"]

View file

@ -1,9 +1,10 @@
# encoding: utf-8
require 'abstract_unit'
module TestFileUtils
def file_name() File.basename(__FILE__) end
def file_path() File.expand_path(__FILE__) end
def file_data() File.open(file_path, 'rb') { |f| f.read } end
def file_data() @data ||= File.open(file_path, 'rb') { |f| f.read } end
end
class SendFileController < ActionController::Base
@ -15,11 +16,13 @@ class SendFileController < ActionController::Base
def file() send_file(file_path, options) end
def data() send_data(file_data, options) end
def multibyte_text_data() send_data("Кирилица\n祝您好運", options) end
def rescue_action(e) raise end
end
class SendFileTest < Test::Unit::TestCase
class SendFileTest < ActionController::TestCase
tests SendFileController
include TestFileUtils
Mime::Type.register "image/png", :png unless defined? Mime::PNG
@ -48,6 +51,7 @@ class SendFileTest < Test::Unit::TestCase
require 'stringio'
output = StringIO.new
output.binmode
output.string.force_encoding(file_data.encoding) if output.string.respond_to?(:force_encoding)
assert_nothing_raised { response.body.call(response, output) }
assert_equal file_data, output.string
end
@ -69,6 +73,7 @@ class SendFileTest < Test::Unit::TestCase
assert_equal @controller.file_path, response.headers['X-Sendfile']
assert response.body.blank?
assert !response.etag?
end
def test_data
@ -106,7 +111,7 @@ class SendFileTest < Test::Unit::TestCase
@controller.send(:send_file_headers!, options)
h = @controller.headers
assert_equal 1, h['Content-Length']
assert_equal '1', h['Content-Length']
assert_equal 'image/png', h['Content-Type']
assert_equal 'disposition; filename="filename"', h['Content-Disposition']
assert_equal 'binary', h['Content-Transfer-Encoding']
@ -118,17 +123,49 @@ class SendFileTest < Test::Unit::TestCase
assert_equal 'private', h['Cache-Control']
end
def test_send_file_headers_with_mime_lookup_with_symbol
options = {
:length => 1,
:type => :png
}
@controller.headers = {}
@controller.send(:send_file_headers!, options)
headers = @controller.headers
assert_equal 'image/png', headers['Content-Type']
end
def test_send_file_headers_with_bad_symbol
options = {
:length => 1,
:type => :this_type_is_not_registered
}
@controller.headers = {}
assert_raise(ArgumentError){ @controller.send(:send_file_headers!, options) }
end
%w(file data).each do |method|
define_method "test_send_#{method}_status" do
@controller.options = { :stream => false, :status => 500 }
assert_nothing_raised { assert_not_nil process(method) }
assert_equal '500 Internal Server Error', @response.headers['Status']
assert_equal '500 Internal Server Error', @response.status
end
define_method "test_default_send_#{method}_status" do
@controller.options = { :stream => false }
assert_nothing_raised { assert_not_nil process(method) }
assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @response.headers['Status']
assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @response.status
end
end
def test_send_data_content_length_header
@controller.headers = {}
@controller.options = { :type => :text, :filename => 'file_with_utf8_text' }
process('multibyte_text_data')
assert_equal '29', @controller.headers['Content-Length']
end
end

View file

@ -1,310 +1,216 @@
require 'abstract_unit'
require 'action_controller/cgi_process'
require 'action_controller/cgi_ext'
require 'stringio'
class CookieStoreTest < ActionController::IntegrationTest
SessionKey = '_myapp_session'
SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33'
class CGI::Session::CookieStore
def ensure_secret_secure_with_test_hax(secret)
if secret == CookieStoreTest.default_session_options['secret']
return true
else
ensure_secret_secure_without_test_hax(secret)
DispatcherApp = ActionController::Dispatcher.new
CookieStoreApp = ActionController::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret)
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
SignedBar = "BAh7BjoIZm9vIghiYXI%3D--fef868465920f415f2c0652d6910d3af288a0367"
class TestController < ActionController::Base
def no_session_access
head :ok
end
end
alias_method_chain :ensure_secret_secure, :test_hax
end
# Expose for tests.
class CGI
attr_reader :output_cookies, :output_hidden
class Session
attr_reader :dbman
class CookieStore
attr_reader :data, :original, :cookie_options
def persistent_session_id
render :text => session[:session_id]
end
end
end
class CookieStoreTest < Test::Unit::TestCase
def self.default_session_options
{ 'database_manager' => CGI::Session::CookieStore,
'session_key' => '_myapp_session',
'secret' => 'Keep it secret; keep it safe.',
'no_cookies' => true,
'no_hidden' => true,
'session_http_only' => true
}
end
def set_session_value
session[:foo] = "bar"
render :text => Rack::Utils.escape(Verifier.generate(session.to_hash))
end
def self.cookies
{ :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
:a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA==--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }],
:double_escaped => [CGI.escape('BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf'), { 'user_id' => 123, 'flash' => {} }] }
def get_session_value
render :text => "foo: #{session[:foo].inspect}"
end
def get_session_id
render :text => "foo: #{session[:foo].inspect}; id: #{request.session_options[:id]}"
end
def call_reset_session
reset_session
head :ok
end
def raise_data_overflow
session[:foo] = 'bye!' * 1024
head :ok
end
def rescue_action(e) raise end
end
def setup
ENV.delete('HTTP_COOKIE')
@integration_session = open_session(CookieStoreApp)
end
def test_raises_argument_error_if_missing_session_key
[nil, ''].each do |blank|
assert_raise(ArgumentError, blank.inspect) { new_session 'session_key' => blank }
end
assert_raise(ArgumentError, nil.inspect) {
ActionController::Session::CookieStore.new(nil,
:key => nil, :secret => SessionSecret)
}
assert_raise(ArgumentError, ''.inspect) {
ActionController::Session::CookieStore.new(nil,
:key => '', :secret => SessionSecret)
}
end
def test_raises_argument_error_if_missing_secret
[nil, ''].each do |blank|
assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
end
assert_raise(ArgumentError, nil.inspect) {
ActionController::Session::CookieStore.new(nil,
:key => SessionKey, :secret => nil)
}
assert_raise(ArgumentError, ''.inspect) {
ActionController::Session::CookieStore.new(nil,
:key => SessionKey, :secret => '')
}
end
def test_raises_argument_error_if_secret_is_probably_insecure
["password", "secret", "12345678901234567890123456789"].each do |blank|
assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
assert_raise(ArgumentError, "password".inspect) {
ActionController::Session::CookieStore.new(nil,
:key => SessionKey, :secret => "password")
}
assert_raise(ArgumentError, "secret".inspect) {
ActionController::Session::CookieStore.new(nil,
:key => SessionKey, :secret => "secret")
}
assert_raise(ArgumentError, "12345678901234567890123456789".inspect) {
ActionController::Session::CookieStore.new(nil,
:key => SessionKey, :secret => "12345678901234567890123456789")
}
end
def test_setting_session_value
with_test_route_set do
get '/set_session_value'
assert_response :success
assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
headers['Set-Cookie']
end
end
def test_getting_session_value
with_test_route_set do
cookies[SessionKey] = SignedBar
get '/get_session_value'
assert_response :success
assert_equal 'foo: "bar"', response.body
end
end
def test_getting_session_id
with_test_route_set do
cookies[SessionKey] = SignedBar
get '/persistent_session_id'
assert_response :success
assert_equal response.body.size, 32
session_id = response.body
get '/get_session_id'
assert_response :success
assert_equal "foo: \"bar\"; id: #{session_id}", response.body
end
end
def test_reconfigures_session_to_omit_id_cookie_and_hidden_field
new_session do |session|
assert_equal true, @options['no_hidden']
assert_equal true, @options['no_cookies']
end
end
def test_restore_unmarshals_missing_cookie_as_empty_hash
new_session do |session|
assert_nil session.dbman.data
assert_nil session['test']
assert_equal Hash.new, session.dbman.data
end
end
def test_restore_unmarshals_good_cookies
cookies(:empty, :a_one, :typical).each do |value, expected|
set_cookie! value
new_session do |session|
assert_nil session['lazy loads the data hash']
assert_equal expected, session.dbman.data
end
end
end
def test_restore_deletes_tampered_cookies
set_cookie! 'a--b'
new_session do |session|
assert_raise(CGI::Session::CookieStore::TamperedWithCookie) { session['fail'] }
assert_cookie_deleted session
end
end
def test_restores_double_encoded_cookies
set_cookie! cookie_value(:double_escaped)
new_session do |session|
session.dbman.restore
assert_equal session["user_id"], 123
assert_equal session["flash"], {}
end
end
def test_close_doesnt_write_cookie_if_data_is_blank
new_session do |session|
assert_no_cookies session
session.close
assert_no_cookies session
end
end
def test_close_doesnt_write_cookie_if_data_is_unchanged
set_cookie! cookie_value(:typical)
new_session do |session|
assert_no_cookies session
session['user_id'] = session['user_id']
session.close
assert_no_cookies session
def test_disregards_tampered_sessions
with_test_route_set do
cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--123456780"
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
end
end
def test_close_raises_when_data_overflows
set_cookie! cookie_value(:empty)
new_session do |session|
session['overflow'] = 'bye!' * 1024
assert_raise(CGI::Session::CookieStore::CookieOverflow) { session.close }
assert_no_cookies session
with_test_route_set do
assert_raise(ActionController::Session::CookieStore::CookieOverflow) {
get '/raise_data_overflow'
}
end
end
def test_close_marshals_and_writes_cookie
set_cookie! cookie_value(:typical)
new_session do |session|
assert_no_cookies session
session['flash'] = {}
assert_no_cookies session
session.close
assert_equal 1, session.cgi.output_cookies.size
cookie = session.cgi.output_cookies.first
assert_cookie cookie, cookie_value(:flashed)
assert_http_only_cookie cookie
assert_secure_cookie cookie, false
def test_doesnt_write_session_cookie_if_session_is_not_accessed
with_test_route_set do
get '/no_session_access'
assert_response :success
assert_equal "", headers['Set-Cookie']
end
end
def test_writes_non_secure_cookie_by_default
set_cookie! cookie_value(:typical)
new_session do |session|
session['flash'] = {}
session.close
cookie = session.cgi.output_cookies.first
assert_secure_cookie cookie,false
def test_doesnt_write_session_cookie_if_session_is_unchanged
with_test_route_set do
cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" +
"fef868465920f415f2c0652d6910d3af288a0367"
get '/no_session_access'
assert_response :success
assert_equal "", headers['Set-Cookie']
end
end
def test_writes_secure_cookie
set_cookie! cookie_value(:typical)
new_session('session_secure'=>true) do |session|
session['flash'] = {}
session.close
cookie = session.cgi.output_cookies.first
assert_secure_cookie cookie
def test_setting_session_value_after_session_reset
with_test_route_set do
get '/set_session_value'
assert_response :success
session_payload = response.body
assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
headers['Set-Cookie']
get '/call_reset_session'
assert_response :success
assert_not_equal [], headers['Set-Cookie']
assert_not_equal session_payload, cookies[SessionKey]
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
end
end
def test_http_only_cookie_by_default
set_cookie! cookie_value(:typical)
new_session do |session|
session['flash'] = {}
session.close
cookie = session.cgi.output_cookies.first
assert_http_only_cookie cookie
end
end
def test_overides_http_only_cookie
set_cookie! cookie_value(:typical)
new_session('session_http_only'=>false) do |session|
session['flash'] = {}
session.close
cookie = session.cgi.output_cookies.first
assert_http_only_cookie cookie, false
end
end
def test_delete_writes_expired_empty_cookie_and_sets_data_to_nil
set_cookie! cookie_value(:typical)
new_session do |session|
assert_no_cookies session
session.delete
assert_cookie_deleted session
# @data is set to nil so #close doesn't send another cookie.
session.close
assert_cookie_deleted session
end
end
def test_new_session_doesnt_reuse_deleted_cookie_data
set_cookie! cookie_value(:typical)
new_session do |session|
assert_not_nil session['user_id']
session.delete
# Start a new session using the same CGI instance.
post_delete_session = CGI::Session.new(session.cgi, self.class.default_session_options)
assert_nil post_delete_session['user_id']
def test_persistent_session_id
with_test_route_set do
cookies[SessionKey] = SignedBar
get '/persistent_session_id'
assert_response :success
assert_equal response.body.size, 32
session_id = response.body
get '/persistent_session_id'
assert_equal session_id, response.body
reset!
get '/persistent_session_id'
assert_not_equal session_id, response.body
end
end
private
def assert_no_cookies(session)
assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
end
def assert_cookie_deleted(session, message = 'Expected session deletion cookie to be set')
assert_equal 1, session.cgi.output_cookies.size
cookie = session.cgi.output_cookies.first
assert_cookie cookie, nil, 1.year.ago.to_date, "#{message}: #{cookie.name} => #{cookie.value}"
end
def assert_cookie(cookie, value = nil, expires = nil, message = nil)
assert_equal '_myapp_session', cookie.name, message
assert_equal [value].compact, cookie.value, message
assert_equal expires, cookie.expires ? cookie.expires.to_date : cookie.expires, message
end
def assert_secure_cookie(cookie,value=true)
assert cookie.secure==value
end
def assert_http_only_cookie(cookie,value=true)
assert cookie.http_only==value
end
def cookies(*which)
self.class.cookies.values_at(*which)
end
def cookie_value(which)
self.class.cookies[which].first
end
def set_cookie!(value)
ENV['HTTP_COOKIE'] = "_myapp_session=#{value}"
end
def new_session(options = {})
with_cgi do |cgi|
assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
@options = self.class.default_session_options.merge(options)
session = CGI::Session.new(cgi, @options)
ObjectSpace.undefine_finalizer(session)
assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
yield session if block_given?
session
def with_test_route_set
with_routing do |set|
set.draw do |map|
map.with_options :controller => "cookie_store_test/test" do |c|
c.connect "/:action"
end
end
yield
end
end
def with_cgi
ENV['REQUEST_METHOD'] = 'GET'
ENV['HTTP_HOST'] = 'example.com'
ENV['QUERY_STRING'] = ''
cgi = CGI.new('query', StringIO.new(''))
yield cgi if block_given?
cgi
def unmarshal_session(cookie_string)
session = Rack::Utils.parse_query(cookie_string, ';,').inject({}) {|h,(k,v)|
h[k] = Array === v ? v.first : v
h
}[SessionKey]
verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
verifier.verify(session)
end
end
class CookieStoreWithBlockAsSecretTest < CookieStoreTest
def self.default_session_options
CookieStoreTest.default_session_options.merge 'secret' => Proc.new { 'Keep it secret; keep it safe.' }
end
end
class CookieStoreWithMD5DigestTest < CookieStoreTest
def self.default_session_options
CookieStoreTest.default_session_options.merge 'digest' => 'MD5'
end
def self.cookies
{ :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
:a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA==--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }],
:double_escaped => [CGI.escape('BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51'), { 'user_id' => 123, 'flash' => {} }] }
end
end

View file

@ -1,181 +1,127 @@
require 'abstract_unit'
require 'action_controller/cgi_process'
require 'action_controller/cgi_ext'
class CGI::Session
def cache
dbman.instance_variable_get(:@cache)
end
end
uses_mocha 'MemCacheStore tests' do
if defined? MemCache::MemCacheError
class MemCacheStoreTest < Test::Unit::TestCase
SESSION_KEY_RE = /^session:[0-9a-z]+/
CONN_TEST_KEY = 'connection_test'
MULTI_TEST_KEY = '0123456789'
TEST_DATA = 'Hello test'
def self.get_mem_cache_if_available
begin
require 'memcache'
cache = MemCache.new('127.0.0.1')
# Test availability of the connection
cache.set(CONN_TEST_KEY, 1)
unless cache.get(CONN_TEST_KEY) == 1
puts 'Warning: memcache server available but corrupted.'
return nil
end
rescue LoadError, MemCache::MemCacheError
return nil
# You need to start a memcached server inorder to run these tests
class MemCacheStoreTest < ActionController::IntegrationTest
class TestController < ActionController::Base
def no_session_access
head :ok
end
return cache
def set_session_value
session[:foo] = "bar"
head :ok
end
def get_session_value
render :text => "foo: #{session[:foo].inspect}"
end
def get_session_id
session[:foo]
render :text => "#{request.session_options[:id]}"
end
def call_reset_session
session[:bar]
reset_session
session[:bar] = "baz"
head :ok
end
def rescue_action(e) raise end
end
CACHE = get_mem_cache_if_available
begin
DispatcherApp = ActionController::Dispatcher.new
MemCacheStoreApp = ActionController::Session::MemCacheStore.new(
DispatcherApp, :key => '_session_id')
def test_initialization
assert_raise(ArgumentError) { new_session('session_id' => '!invalid_id') }
new_session do |s|
assert_equal Hash.new, s.cache.get('session:' + s.session_id)
def setup
@integration_session = open_session(MemCacheStoreApp)
end
def test_setting_and_getting_session_value
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
get '/get_session_value'
assert_response :success
assert_equal 'foo: "bar"', response.body
end
end
def test_getting_nil_session_value
with_test_route_set do
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
end
end
def test_setting_session_value_after_session_reset
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
session_id = cookies['_session_id']
get '/call_reset_session'
assert_response :success
assert_not_equal [], headers['Set-Cookie']
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
get '/get_session_id'
assert_response :success
assert_not_equal session_id, response.body
end
end
def test_getting_session_id
with_test_route_set do
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
session_id = cookies['_session_id']
get '/get_session_id'
assert_response :success
assert_equal session_id, response.body
end
end
def test_prevents_session_fixation
with_test_route_set do
get '/get_session_value'
assert_response :success
assert_equal 'foo: nil', response.body
session_id = cookies['_session_id']
reset!
get '/set_session_value', :_session_id => session_id
assert_response :success
assert_equal nil, cookies['_session_id']
end
end
rescue LoadError, RuntimeError
$stderr.puts "Skipping MemCacheStoreTest tests. Start memcached and try again."
end
def test_storage
d = rand(0xffff)
new_session do |s|
session_key = 'session:' + s.session_id
unless CACHE
s.cache.expects(:get).with(session_key) \
.returns(:test => d)
s.cache.expects(:set).with(session_key,
has_entry(:test, d),
0)
end
s[:test] = d
s.close
assert_equal d, s.cache.get(session_key)[:test]
assert_equal d, s[:test]
end
end
def test_deletion
new_session do |s|
session_key = 'session:' + s.session_id
unless CACHE
s.cache.expects(:delete)
s.cache.expects(:get).with(session_key) \
.returns(nil)
end
s[:test] = rand(0xffff)
s.delete
assert_nil s.cache.get(session_key)
end
end
def test_other_session_retrieval
new_session do |sa|
unless CACHE
sa.cache.expects(:set).with('session:' + sa.session_id,
has_entry(:test, TEST_DATA),
0)
end
sa[:test] = TEST_DATA
sa.close
new_session('session_id' => sa.session_id) do |sb|
unless CACHE
sb.cache.expects(:[]).with('session:' + sb.session_id) \
.returns(:test => TEST_DATA)
end
assert_equal(TEST_DATA, sb[:test])
end
end
end
def test_multiple_sessions
s_slots = Array.new(10)
operation = :write
last_data = nil
reads = writes = 0
50.times do
current = rand(10)
s_slots[current] ||= new_session('session_id' => MULTI_TEST_KEY,
'new_session' => true)
s = s_slots[current]
case operation
when :write
last_data = rand(0xffff)
unless CACHE
s.cache.expects(:set).with('session:' + MULTI_TEST_KEY,
{ :test => last_data },
0)
end
s[:test] = last_data
s.close
writes += 1
when :read
# Make CGI::Session#[] think there was no data retrieval yet.
# Normally, the session caches the data during its lifetime.
s.instance_variable_set(:@data, nil)
unless CACHE
s.cache.expects(:[]).with('session:' + MULTI_TEST_KEY) \
.returns(:test => last_data)
end
d = s[:test]
assert_equal(last_data, d, "OK reads: #{reads}, OK writes: #{writes}")
reads += 1
end
operation = rand(5) == 0 ? :write : :read
end
end
private
def obtain_session_options
options = { 'database_manager' => CGI::Session::MemCacheStore,
'session_key' => '_test_app_session'
}
# if don't have running memcache server we use mock instead
unless CACHE
options['cache'] = c = mock
c.stubs(:[]).with(regexp_matches(SESSION_KEY_RE))
c.stubs(:get).with(regexp_matches(SESSION_KEY_RE)) \
.returns(Hash.new)
c.stubs(:add).with(regexp_matches(SESSION_KEY_RE),
instance_of(Hash),
0)
def with_test_route_set
with_routing do |set|
set.draw do |map|
map.with_options :controller => "mem_cache_store_test/test" do |c|
c.connect "/:action"
end
end
yield
end
end
options
end
def new_session(options = {})
with_cgi do |cgi|
@options = obtain_session_options.merge(options)
session = CGI::Session.new(cgi, @options)
yield session if block_given?
return session
end
end
def with_cgi
ENV['REQUEST_METHOD'] = 'GET'
ENV['HTTP_HOST'] = 'example.com'
ENV['QUERY_STRING'] = ''
cgi = CGI.new('query', StringIO.new(''))
yield cgi if block_given?
cgi
end
end
end # defined? MemCache
end # uses_mocha

View file

@ -0,0 +1,58 @@
require 'abstract_unit'
require 'stringio'
class ActionController::TestSessionTest < ActiveSupport::TestCase
def test_calling_delete_without_parameters_raises_deprecation_warning_and_calls_to_clear_test_session
assert_deprecated(/use clear instead/){ ActionController::TestSession.new.delete }
end
def test_calling_update_without_parameters_raises_deprecation_warning_and_calls_to_clear_test_session
assert_deprecated(/use replace instead/){ ActionController::TestSession.new.update }
end
def test_calling_close_raises_deprecation_warning
assert_deprecated(/sessions should no longer be closed/){ ActionController::TestSession.new.close }
end
def test_defaults
session = ActionController::TestSession.new
assert_equal({}, session.data)
assert_equal('', session.session_id)
end
def test_ctor_allows_setting
session = ActionController::TestSession.new({:one => 'one', :two => 'two'})
assert_equal('one', session[:one])
assert_equal('two', session[:two])
end
def test_setting_session_item_sets_item
session = ActionController::TestSession.new
session[:key] = 'value'
assert_equal('value', session[:key])
end
def test_calling_delete_removes_item_and_returns_its_value
session = ActionController::TestSession.new
session[:key] = 'value'
assert_equal('value', session[:key])
assert_equal('value', session.delete(:key))
assert_nil(session[:key])
end
def test_calling_update_with_params_passes_to_attributes
session = ActionController::TestSession.new()
session.update('key' => 'value')
assert_equal('value', session[:key])
end
def test_clear_emptys_session
params = {:one => 'one', :two => 'two'}
session = ActionController::TestSession.new({:one => 'one', :two => 'two'})
session.clear
assert_nil(session[:one])
assert_nil(session[:two])
end
end

View file

@ -1,89 +0,0 @@
require 'abstract_unit'
class SessionFixationTest < Test::Unit::TestCase
class MockCGI < CGI #:nodoc:
attr_accessor :stdoutput, :env_table
def initialize(env, data = '')
self.env_table = env
self.stdoutput = StringIO.new
super(nil, StringIO.new(data))
end
end
class TestController < ActionController::Base
session :session_key => '_myapp_session_id', :secret => CGI::Session.generate_unique_id, :except => :default_session_key
session :cookie_only => false, :only => :allow_session_fixation
def default_session_key
render :text => "default_session_key"
end
def custom_session_key
render :text => "custom_session_key: #{params[:id]}"
end
def allow_session_fixation
render :text => "allow_session_fixation"
end
def rescue_action(e) raise end
end
def setup
@controller = TestController.new
end
def test_should_be_able_to_make_a_successful_request
cgi = mock_cgi_for_request_to(:custom_session_key, :id => 1)
assert_nothing_raised do
@controller.send(:process, ActionController::CgiRequest.new(cgi, {}), ActionController::CgiResponse.new(cgi))
end
assert_equal 'custom_session_key: 1', @controller.response.body
assert_not_nil @controller.session
end
def test_should_catch_session_fixation_attempt
cgi = mock_cgi_for_request_to(:custom_session_key, :_myapp_session_id => 42)
assert_raises ActionController::CgiRequest::SessionFixationAttempt do
@controller.send(:process, ActionController::CgiRequest.new(cgi, {}), ActionController::CgiResponse.new(cgi))
end
assert_nil @controller.session
end
def test_should_not_catch_session_fixation_attempt_when_cookie_only_setting_is_disabled
cgi = mock_cgi_for_request_to(:allow_session_fixation, :_myapp_session_id => 42)
assert_nothing_raised do
@controller.send(:process, ActionController::CgiRequest.new(cgi, {}), ActionController::CgiResponse.new(cgi))
end
assert ! @controller.response.body.blank?
assert_not_nil @controller.session
end
def test_should_catch_session_fixation_attempt_with_default_session_key
ActionController::Base.session_store = :p_store # using the default session_key is not possible with cookie store
cgi = mock_cgi_for_request_to(:default_session_key, :_session_id => 42)
assert_raises ActionController::CgiRequest::SessionFixationAttempt do
@controller.send(:process, ActionController::CgiRequest.new(cgi, {}), ActionController::CgiResponse.new(cgi))
end
assert @controller.response.body.blank?
assert_nil @controller.session
end
private
def mock_cgi_for_request_to(action, params = {})
MockCGI.new({
"REQUEST_METHOD" => "GET",
"QUERY_STRING" => "action=#{action}&#{params.to_query}",
"REQUEST_URI" => "/",
"SERVER_PORT" => "80",
"HTTP_HOST" => "testdomain.com" }, '')
end
end

View file

@ -1,178 +0,0 @@
require 'abstract_unit'
class SessionManagementTest < Test::Unit::TestCase
class SessionOffController < ActionController::Base
session :off
def show
render :text => "done"
end
def tell
render :text => "done"
end
end
class SessionOffOnController < ActionController::Base
session :off
session :on, :only => :tell
def show
render :text => "done"
end
def tell
render :text => "done"
end
end
class TestController < ActionController::Base
session :off, :only => :show
session :session_secure => true, :except => :show
session :off, :only => :conditional,
:if => Proc.new { |r| r.parameters[:ws] }
def show
render :text => "done"
end
def tell
render :text => "done"
end
def conditional
render :text => ">>>#{params[:ws]}<<<"
end
end
class SpecializedController < SessionOffController
session :disabled => false, :only => :something
def something
render :text => "done"
end
def another
render :text => "done"
end
end
class AssociationCachingTestController < ActionController::Base
class ObjectWithAssociationCache
def initialize
@cached_associations = false
end
def fetch_associations
@cached_associations = true
end
def clear_association_cache
@cached_associations = false
end
def has_cached_associations?
@cached_associations
end
end
def show
session[:object] = ObjectWithAssociationCache.new
session[:object].fetch_associations
if session[:object].has_cached_associations?
render :text => "has cached associations"
else
render :text => "does not have cached associations"
end
end
def tell
if session[:object]
if session[:object].has_cached_associations?
render :text => "has cached associations"
else
render :text => "does not have cached associations"
end
else
render :text => "there is no object"
end
end
end
def setup
@request, @response = ActionController::TestRequest.new,
ActionController::TestResponse.new
end
def test_session_off_globally
@controller = SessionOffController.new
get :show
assert_equal false, @request.session_options
get :tell
assert_equal false, @request.session_options
end
def test_session_off_then_on_globally
@controller = SessionOffOnController.new
get :show
assert_equal false, @request.session_options
get :tell
assert_instance_of Hash, @request.session_options
assert_equal false, @request.session_options[:disabled]
end
def test_session_off_conditionally
@controller = TestController.new
get :show
assert_equal false, @request.session_options
get :tell
assert_instance_of Hash, @request.session_options
assert @request.session_options[:session_secure]
end
def test_controller_specialization_overrides_settings
@controller = SpecializedController.new
get :something
assert_instance_of Hash, @request.session_options
get :another
assert_equal false, @request.session_options
end
def test_session_off_with_if
@controller = TestController.new
get :conditional
assert_instance_of Hash, @request.session_options
get :conditional, :ws => "ws"
assert_equal false, @request.session_options
end
def test_session_store_setting
ActionController::Base.session_store = :drb_store
assert_equal CGI::Session::DRbStore, ActionController::Base.session_store
if Object.const_defined?(:ActiveRecord)
ActionController::Base.session_store = :active_record_store
assert_equal CGI::Session::ActiveRecordStore, ActionController::Base.session_store
end
end
def test_process_cleanup_with_session_management_support
@controller = AssociationCachingTestController.new
get :show
assert_equal "has cached associations", @response.body
get :tell
assert_equal "does not have cached associations", @response.body
end
def test_session_is_enabled
@controller = TestController.new
get :show
assert_nothing_raised do
assert_equal false, @controller.session_enabled?
end
get :tell
assert @controller.session_enabled?
end
end

View file

@ -1,7 +1,7 @@
require 'abstract_unit'
require 'controller/fake_controllers'
class TestTest < Test::Unit::TestCase
class TestTest < ActionController::TestCase
class TestController < ActionController::Base
def no_op
render :text => 'dummy'
@ -23,8 +23,13 @@ class TestTest < Test::Unit::TestCase
render :text => 'Success'
end
def reset_the_session
reset_session
render :text => 'ignore me'
end
def render_raw_post
raise Test::Unit::AssertionFailedError, "#raw_post is blank" if request.raw_post.blank?
raise ActiveSupport::TestCase::Assertion, "#raw_post is blank" if request.raw_post.blank?
render :text => request.raw_post
end
@ -171,6 +176,24 @@ XML
assert_equal 'value2', session[:symbol]
end
def test_session_is_cleared_from_controller_after_reset_session
process :set_session
process :reset_the_session
assert_equal Hash.new, @controller.session.to_hash
end
def test_session_is_cleared_from_response_after_reset_session
process :set_session
process :reset_the_session
assert_equal Hash.new, @response.session.to_hash
end
def test_session_is_cleared_from_request_after_reset_session
process :set_session
process :reset_the_session
assert_equal Hash.new, @request.session.to_hash
end
def test_process_with_request_uri_with_no_params
process :test_uri
assert_equal "/test_test/test/test_uri", @response.body
@ -492,6 +515,14 @@ XML
assert_nil @request.instance_variable_get("@request_method")
end
def test_params_reset_after_post_request
post :no_op, :foo => "bar"
assert_equal "bar", @request.params[:foo]
@request.recycle!
post :no_op
assert @request.params[:foo].blank?
end
%w(controller response request).each do |variable|
%w(get post put delete head process).each do |method|
define_method("test_#{variable}_missing_for_#{method}_raises_error") do
@ -580,7 +611,7 @@ XML
assert_equal @response.redirect_url, redirect_to_url
# Must be a :redirect response.
assert_raise(Test::Unit::AssertionFailedError) do
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to 'created resource'
end
end
@ -602,9 +633,9 @@ XML
end
end
class CleanBacktraceTest < Test::Unit::TestCase
class CleanBacktraceTest < ActionController::TestCase
def test_should_reraise_the_same_object
exception = Test::Unit::AssertionFailedError.new('message')
exception = ActiveSupport::TestCase::Assertion.new('message')
clean_backtrace { raise exception }
rescue Exception => caught
assert_equal exception.object_id, caught.object_id
@ -613,7 +644,7 @@ class CleanBacktraceTest < Test::Unit::TestCase
def test_should_clean_assertion_lines_from_backtrace
path = File.expand_path("#{File.dirname(__FILE__)}/../../lib/action_controller")
exception = Test::Unit::AssertionFailedError.new('message')
exception = ActiveSupport::TestCase::Assertion.new('message')
exception.set_backtrace ["#{path}/abc", "#{path}/assertions/def"]
clean_backtrace { raise exception }
rescue Exception => caught
@ -629,21 +660,17 @@ class CleanBacktraceTest < Test::Unit::TestCase
end
end
class InferringClassNameTest < Test::Unit::TestCase
class InferringClassNameTest < ActionController::TestCase
def test_determine_controller_class
assert_equal ContentController, determine_class("ContentControllerTest")
end
def test_determine_controller_class_with_nonsense_name
assert_raises ActionController::NonInferrableControllerError do
determine_class("HelloGoodBye")
end
assert_nil determine_class("HelloGoodBye")
end
def test_determine_controller_class_with_sensible_name_where_no_controller_exists
assert_raises ActionController::NonInferrableControllerError do
determine_class("NoControllerWithThisNameTest")
end
assert_nil determine_class("NoControllerWithThisNameTest")
end
private

View file

@ -2,7 +2,7 @@ require 'abstract_unit'
ActionController::UrlRewriter
class UrlRewriterTests < Test::Unit::TestCase
class UrlRewriterTests < ActionController::TestCase
def setup
@request = ActionController::TestRequest.new
@params = {}
@ -46,6 +46,20 @@ class UrlRewriterTests < Test::Unit::TestCase
)
end
def test_anchor_should_call_to_param
assert_equal(
'http://test.host/c/a/i#anchor',
@rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor'))
)
end
def test_anchor_should_be_cgi_escaped
assert_equal(
'http://test.host/c/a/i#anc%2Fhor',
@rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor'))
)
end
def test_overwrite_params
@params[:controller] = 'hi'
@params[:action] = 'bye'
@ -85,8 +99,7 @@ class UrlRewriterTests < Test::Unit::TestCase
end
end
class UrlWriterTests < Test::Unit::TestCase
class UrlWriterTests < ActionController::TestCase
class W
include ActionController::UrlWriter
end
@ -100,7 +113,7 @@ class UrlWriterTests < Test::Unit::TestCase
end
def test_exception_is_thrown_without_host
assert_raises RuntimeError do
assert_raise RuntimeError do
W.new.url_for :controller => 'c', :action => 'a', :id => 'i'
end
end
@ -111,6 +124,18 @@ class UrlWriterTests < Test::Unit::TestCase
)
end
def test_anchor_should_call_to_param
assert_equal('/c/a#anchor',
W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anchor'))
)
end
def test_anchor_should_be_cgi_escaped
assert_equal('/c/a#anc%2Fhor',
W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anc/hor'))
)
end
def test_default_host
add_host!
assert_equal('http://www.basecamphq.com/c/a/i',
@ -302,6 +327,57 @@ class UrlWriterTests < Test::Unit::TestCase
assert_generates("/image", :controller=> :image)
end
def test_named_routes_with_nil_keys
ActionController::Routing::Routes.clear!
ActionController::Routing::Routes.draw do |map|
map.main '', :controller => 'posts', :format => nil
map.resources :posts
map.connect ':controller/:action/:id'
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include ActionController::UrlWriter }
kls.default_url_options[:host] = 'www.basecamphq.com'
controller = kls.new
params = {:action => :index, :controller => :posts, :format => :xml}
assert_equal("http://www.basecamphq.com/posts.xml", controller.send(:url_for, params))
params[:format] = nil
assert_equal("http://www.basecamphq.com/", controller.send(:url_for, params))
ensure
ActionController::Routing::Routes.load!
end
def test_formatted_url_methods_are_deprecated
ActionController::Routing::Routes.draw do |map|
map.resources :posts
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include ActionController::UrlWriter }
controller = kls.new
params = {:id => 1, :format => :xml}
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
end
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
end
ensure
ActionController::Routing::Routes.load!
end
def test_multiple_includes_maintain_distinct_options
first_class = Class.new { include ActionController::UrlWriter }
second_class = Class.new { include ActionController::UrlWriter }
first_host, second_host = 'firsthost.com', 'secondhost.com'
first_class.default_url_options[:host] = first_host
second_class.default_url_options[:host] = second_host
assert_equal first_class.default_url_options[:host], first_host
assert_equal second_class.default_url_options[:host], second_host
end
private
def extract_params(url)
url.split('?', 2).last.split('&')

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
class VerificationTest < Test::Unit::TestCase
class VerificationTest < ActionController::TestCase
class TestController < ActionController::Base
verify :only => :guarded_one, :params => "one",
:add_flash => { :error => 'unguarded' },

View file

@ -1,6 +1,6 @@
require 'abstract_unit'
class ViewLoadPathsTest < Test::Unit::TestCase
class ViewLoadPathsTest < ActionController::TestCase
class TestController < ActionController::Base
def self.controller_path() "test" end
def rescue_action(e) raise end
@ -41,31 +41,31 @@ class ViewLoadPathsTest < Test::Unit::TestCase
def teardown
ActiveSupport::Deprecation.behavior = @old_behavior
end
def test_template_load_path_was_set_correctly
assert_equal [FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
end
def test_controller_appends_view_path_correctly
@controller.append_view_path 'foo'
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths.map(&:to_s)
@controller.append_view_path(%w(bar baz))
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
@controller.append_view_path(FIXTURE_LOAD_PATH)
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
end
def test_controller_prepends_view_path_correctly
@controller.prepend_view_path 'baz'
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
@controller.prepend_view_path(%w(foo bar))
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
@controller.prepend_view_path(FIXTURE_LOAD_PATH)
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
end
def test_template_appends_view_path_correctly
@ -73,10 +73,10 @@ class ViewLoadPathsTest < Test::Unit::TestCase
class_view_paths = TestController.view_paths
@controller.append_view_path 'foo'
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths.map(&:to_s)
@controller.append_view_path(%w(bar baz))
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
assert_equal class_view_paths, TestController.view_paths
end
@ -85,10 +85,10 @@ class ViewLoadPathsTest < Test::Unit::TestCase
class_view_paths = TestController.view_paths
@controller.prepend_view_path 'baz'
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
@controller.prepend_view_path(%w(foo bar))
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
assert_equal class_view_paths, TestController.view_paths
end
@ -130,12 +130,12 @@ class ViewLoadPathsTest < Test::Unit::TestCase
A.view_paths = ['a/path']
assert_equal ['a/path'], A.view_paths
assert_equal ['a/path'], A.view_paths.map(&:to_s)
assert_equal A.view_paths, B.view_paths
assert_equal original_load_paths, C.view_paths
C.view_paths = []
assert_nothing_raised { C.view_paths << 'c/path' }
assert_equal ['c/path'], C.view_paths
assert_equal ['c/path'], C.view_paths.map(&:to_s)
end
end

View file

@ -1,19 +1,7 @@
require 'abstract_unit'
class WebServiceTest < Test::Unit::TestCase
class MockCGI < CGI #:nodoc:
attr_accessor :stdoutput, :env_table
def initialize(env, data = '')
self.env_table = env
self.stdoutput = StringIO.new
super(nil, StringIO.new(data))
end
end
class WebServiceTest < ActionController::IntegrationTest
class TestController < ActionController::Base
session :off
def assign_parameters
if params[:full]
render :text => dump_params_keys
@ -22,7 +10,7 @@ class WebServiceTest < Test::Unit::TestCase
end
end
def dump_params_keys(hash=params)
def dump_params_keys(hash = params)
hash.keys.sort.inject("") do |s, k|
value = hash[k]
value = Hash === value ? "(#{dump_params_keys(value)})" : ""
@ -33,7 +21,7 @@ class WebServiceTest < Test::Unit::TestCase
def rescue_action(e) raise end
end
def setup
@controller = TestController.new
@default_param_parsers = ActionController::Base.param_parsers.dup
@ -44,186 +32,229 @@ class WebServiceTest < Test::Unit::TestCase
end
def test_check_parameters
process('GET')
assert_equal '', @controller.response.body
with_test_route_set do
get "/"
assert_equal '', @controller.response.body
end
end
def test_post_xml
process('POST', 'application/xml', '<entry attributed="true"><summary>content...</summary></entry>')
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
with_test_route_set do
post "/", '<entry attributed="true"><summary>content...</summary></entry>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
end
end
def test_put_xml
process('PUT', 'application/xml', '<entry attributed="true"><summary>content...</summary></entry>')
with_test_route_set do
put "/", '<entry attributed="true"><summary>content...</summary></entry>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
end
end
def test_put_xml_using_a_type_node
process('PUT', 'application/xml', '<type attributed="true"><summary>content...</summary></type>')
with_test_route_set do
put "/", '<type attributed="true"><summary>content...</summary></type>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'content...', @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'content...', @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
end
end
def test_put_xml_using_a_type_node_and_attribute
process('PUT', 'application/xml', '<type attributed="true"><summary type="boolean">false</summary></type>')
with_test_route_set do
put "/", '<type attributed="true"><summary type="boolean">false</summary></type>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal false, @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal false, @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
end
end
def test_post_xml_using_a_type_node
process('POST', 'application/xml', '<font attributed="true"><type>arial</type></font>')
with_test_route_set do
post "/", '<font attributed="true"><type>arial</type></font>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'font', @controller.response.body
assert @controller.params.has_key?(:font)
assert_equal 'arial', @controller.params['font']['type']
assert_equal 'true', @controller.params["font"]['attributed']
assert_equal 'font', @controller.response.body
assert @controller.params.has_key?(:font)
assert_equal 'arial', @controller.params['font']['type']
assert_equal 'true', @controller.params["font"]['attributed']
end
end
def test_post_xml_using_a_root_node_named_type
process('POST', 'application/xml', '<type type="integer">33</type>')
with_test_route_set do
post "/", '<type type="integer">33</type>',
{'CONTENT_TYPE' => 'application/xml'}
assert @controller.params.has_key?(:type)
assert_equal 33, @controller.params['type']
assert @controller.params.has_key?(:type)
assert_equal 33, @controller.params['type']
end
end
def test_post_xml_using_an_attributted_node_named_type
ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| XmlSimple.xml_in(data, 'ForceArray' => false) }
process('POST', 'application/xml', '<request><type type="string">Arial,12</type><z>3</z></request>')
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access }
post "/", '<request><type type="string">Arial,12</type><z>3</z></request>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type, z', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'string', @controller.params['type']['type']
assert_equal 'Arial,12', @controller.params['type']['content']
assert_equal '3', @controller.params['z']
assert_equal 'type, z', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'Arial,12', @controller.params['type'], @controller.params.inspect
assert_equal '3', @controller.params['z'], @controller.params.inspect
end
end
def test_register_and_use_yaml
ActionController::Base.param_parsers[Mime::YAML] = Proc.new { |d| YAML.load(d) }
process('POST', 'application/x-yaml', {"entry" => "loaded from yaml"}.to_yaml)
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'loaded from yaml', @controller.params["entry"]
with_test_route_set do
ActionController::Base.param_parsers[Mime::YAML] = Proc.new { |d| YAML.load(d) }
post "/", {"entry" => "loaded from yaml"}.to_yaml,
{'CONTENT_TYPE' => 'application/x-yaml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'loaded from yaml', @controller.params["entry"]
end
end
def test_register_and_use_yaml_as_symbol
ActionController::Base.param_parsers[Mime::YAML] = :yaml
process('POST', 'application/x-yaml', {"entry" => "loaded from yaml"}.to_yaml)
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'loaded from yaml', @controller.params["entry"]
with_test_route_set do
ActionController::Base.param_parsers[Mime::YAML] = :yaml
post "/", {"entry" => "loaded from yaml"}.to_yaml,
{'CONTENT_TYPE' => 'application/x-yaml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'loaded from yaml', @controller.params["entry"]
end
end
def test_register_and_use_xml_simple
ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| XmlSimple.xml_in(data, 'ForceArray' => false) }
process('POST', 'application/xml', '<request><summary>content...</summary><title>SimpleXml</title></request>' )
assert_equal 'summary, title', @controller.response.body
assert @controller.params.has_key?(:summary)
assert @controller.params.has_key?(:title)
assert_equal 'content...', @controller.params["summary"]
assert_equal 'SimpleXml', @controller.params["title"]
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access }
post "/", '<request><summary>content...</summary><title>SimpleXml</title></request>',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'summary, title', @controller.response.body
assert @controller.params.has_key?(:summary)
assert @controller.params.has_key?(:title)
assert_equal 'content...', @controller.params["summary"]
assert_equal 'SimpleXml', @controller.params["title"]
end
end
def test_use_xml_ximple_with_empty_request
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
assert_nothing_raised { process('POST', 'application/xml', "") }
assert_equal "", @controller.response.body
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
assert_nothing_raised { post "/", "", {'CONTENT_TYPE' => 'application/xml'} }
assert_equal "", @controller.response.body
end
end
def test_dasherized_keys_as_xml
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
process('POST', 'application/xml', "<first-key>\n<sub-key>...</sub-key>\n</first-key>", true)
assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body
assert_equal "...", @controller.params[:first_key][:sub_key]
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
post "/?full=1", "<first-key>\n<sub-key>...</sub-key>\n</first-key>",
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body
assert_equal "...", @controller.params[:first_key][:sub_key]
end
end
def test_typecast_as_xml
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
process('POST', 'application/xml', <<-XML)
<data>
<a type="integer">15</a>
<b type="boolean">false</b>
<c type="boolean">true</c>
<d type="date">2005-03-17</d>
<e type="datetime">2005-03-17T21:41:07Z</e>
<f>unparsed</f>
<g type="integer">1</g>
<g>hello</g>
<g type="date">1974-07-25</g>
</data>
XML
params = @controller.params
assert_equal 15, params[:data][:a]
assert_equal false, params[:data][:b]
assert_equal true, params[:data][:c]
assert_equal Date.new(2005,3,17), params[:data][:d]
assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
assert_equal "unparsed", params[:data][:f]
assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
xml = <<-XML
<data>
<a type="integer">15</a>
<b type="boolean">false</b>
<c type="boolean">true</c>
<d type="date">2005-03-17</d>
<e type="datetime">2005-03-17T21:41:07Z</e>
<f>unparsed</f>
<g type="integer">1</g>
<g>hello</g>
<g type="date">1974-07-25</g>
</data>
XML
post "/", xml, {'CONTENT_TYPE' => 'application/xml'}
params = @controller.params
assert_equal 15, params[:data][:a]
assert_equal false, params[:data][:b]
assert_equal true, params[:data][:c]
assert_equal Date.new(2005,3,17), params[:data][:d]
assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
assert_equal "unparsed", params[:data][:f]
assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
end
end
def test_entities_unescaped_as_xml_simple
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
process('POST', 'application/xml', <<-XML)
<data>&lt;foo &quot;bar&apos;s&quot; &amp; friends&gt;</data>
XML
assert_equal %(<foo "bar's" & friends>), @controller.params[:data]
with_test_route_set do
ActionController::Base.param_parsers[Mime::XML] = :xml_simple
xml = <<-XML
<data>&lt;foo &quot;bar&apos;s&quot; &amp; friends&gt;</data>
XML
post "/", xml, {'CONTENT_TYPE' => 'application/xml'}
assert_equal %(<foo "bar's" & friends>), @controller.params[:data]
end
end
def test_typecast_as_yaml
ActionController::Base.param_parsers[Mime::YAML] = :yaml
process('POST', 'application/x-yaml', <<-YAML)
---
data:
a: 15
b: false
c: true
d: 2005-03-17
e: 2005-03-17T21:41:07Z
f: unparsed
g:
- 1
- hello
- 1974-07-25
YAML
params = @controller.params
assert_equal 15, params[:data][:a]
assert_equal false, params[:data][:b]
assert_equal true, params[:data][:c]
assert_equal Date.new(2005,3,17), params[:data][:d]
assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
assert_equal "unparsed", params[:data][:f]
assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
with_test_route_set do
ActionController::Base.param_parsers[Mime::YAML] = :yaml
yaml = <<-YAML
---
data:
a: 15
b: false
c: true
d: 2005-03-17
e: 2005-03-17T21:41:07Z
f: unparsed
g:
- 1
- hello
- 1974-07-25
YAML
post "/", yaml, {'CONTENT_TYPE' => 'application/x-yaml'}
params = @controller.params
assert_equal 15, params[:data][:a]
assert_equal false, params[:data][:b]
assert_equal true, params[:data][:c]
assert_equal Date.new(2005,3,17), params[:data][:d]
assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
assert_equal "unparsed", params[:data][:f]
assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
end
end
private
def process(verb, content_type = 'application/x-www-form-urlencoded', data = '', full=false)
cgi = MockCGI.new({
'REQUEST_METHOD' => verb,
'CONTENT_TYPE' => content_type,
'QUERY_STRING' => "action=assign_parameters&controller=webservicetest/test#{"&full=1" if full}",
"REQUEST_URI" => "/",
"HTTP_HOST" => 'testdomain.com',
"CONTENT_LENGTH" => data.size,
"SERVER_PORT" => "80",
"HTTPS" => "off"}, data)
@controller.send(:process, ActionController::CgiRequest.new(cgi, {}), ActionController::CgiResponse.new(cgi))
end
private
def with_test_route_set
with_routing do |set|
set.draw do |map|
map.with_options :controller => "web_service_test/test" do |c|
c.connect "/", :action => "assign_parameters"
end
end
yield
end
end
end

View file

@ -0,0 +1,3 @@
module FooHelper
def baz() end
end

View file

@ -0,0 +1 @@
hello <%= "my" %> world

View file

@ -0,0 +1 @@
abs_path_layout.rhtml <%= yield %>

View file

@ -0,0 +1 @@
<html><%= @content_for_layout %></html>

View file

@ -0,0 +1,2 @@
XHR!
<%= yield %>

View file

@ -0,0 +1,10 @@
--AaB03x
Content-Disposition: form-data; name="submit-name"
Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain
--AaB03x--

View file

@ -0,0 +1 @@
Hello

View file

@ -0,0 +1,9 @@
--AaB03x
Content-Disposition: form-data; name="submit-name"
Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename=""
--AaB03x--

View file

@ -0,0 +1 @@
500 localized error fixture

View file

@ -0,0 +1,23 @@
/* bank.css */
/* robber.css */
/* version.1.0.css */
/* bank.css */
/* bank.css */
/* robber.css */
/* version.1.0.css */
/* bank.css */
/* robber.css */
/* version.1.0.css */
/* robber.css */
/* version.1.0.css */

View file

@ -0,0 +1,63 @@
// prototype js
// effects js
// dragdrop js
// controls js
// prototype js
// effects js
// dragdrop js
// controls js
// application js
// bank js
// robber js
// version.1.0 js
// application js
// bank js
// prototype js
// effects js
// dragdrop js
// controls js
// prototype js
// effects js
// dragdrop js
// controls js
// application js
// bank js
// robber js
// version.1.0 js
// application js
// bank js
// robber js
// version.1.0 js
// robber js
// version.1.0 js

View file

@ -0,0 +1 @@
<%= question.name %>

View file

@ -12,4 +12,4 @@ another:
developer_id: 1
content: Nuh uh!
created_at: <%= 1.hour.ago.to_s(:db) %>
updated_at: nil
updated_at: nil

View file

@ -0,0 +1 @@
<%= render_from_helper %>

View file

@ -0,0 +1 @@
<%= render :partial => "two" %> world

View file

@ -0,0 +1 @@
Hello

View file

@ -0,0 +1 @@
non-template file

View file

@ -1,4 +1,4 @@
xml.html do
xml.p "Hello #{@name}"
xml << render("test/greeting")
xml << render(:file => "test/greeting")
end

View file

@ -0,0 +1 @@
Hey verden

View file

@ -0,0 +1 @@
Ola mundo

View file

@ -0,0 +1 @@
page.call "document.write", render(:partial => "one.html.erb")

View file

@ -0,0 +1 @@
page.call "document.write", render(:partial => "one")

View file

@ -0,0 +1 @@
alert('hello');

View file

@ -0,0 +1,2 @@
Русский текст
日本語のテキスト

View file

@ -4,43 +4,41 @@ class ActiveRecordHelperI18nTest < Test::Unit::TestCase
include ActionView::Helpers::ActiveRecordHelper
attr_reader :request
uses_mocha 'active_record_helper_i18n_test' do
def setup
@object = stub :errors => stub(:count => 1, :full_messages => ['full_messages'])
@object_name = 'book'
stubs(:content_tag).returns 'content_tag'
def setup
@object = stub :errors => stub(:count => 1, :full_messages => ['full_messages'])
@object_name = 'book'
stubs(:content_tag).returns 'content_tag'
I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved"
I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
end
I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved"
I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
end
def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message
I18n.expects(:translate).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').never
error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en')
end
def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message
I18n.expects(:translate).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').never
error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en')
end
def test_error_messages_for_given_no_header_option_it_translates_header_message
I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns 'header message'
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :locale => 'en')
end
def test_error_messages_for_given_no_header_option_it_translates_header_message
I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns 'header message'
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :locale => 'en')
end
def test_error_messages_for_given_a_message_option_it_does_not_translate_message
I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).never
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :message => 'message', :locale => 'en')
end
def test_error_messages_for_given_a_message_option_it_does_not_translate_message
I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).never
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :message => 'message', :locale => 'en')
end
def test_error_messages_for_given_no_message_option_it_translates_message
I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :locale => 'en')
end
def test_error_messages_for_given_object_name_it_translates_object_name
I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name).returns "1 error prohibited this #{@object_name} from being saved"
I18n.expects(:t).with(@object_name, :default => @object_name, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name
error_messages_for(:object => @object, :locale => 'en', :object_name => @object_name)
end
def test_error_messages_for_given_no_message_option_it_translates_message
I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns ''
error_messages_for(:object => @object, :locale => 'en')
end
def test_error_messages_for_given_object_name_it_translates_object_name
I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name).returns "1 error prohibited this #{@object_name} from being saved"
I18n.expects(:t).with(@object_name, :default => @object_name, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name
error_messages_for(:object => @object, :locale => 'en', :object_name => @object_name)
end
end

View file

@ -19,6 +19,30 @@ class ActiveRecordHelperTest < ActionView::TestCase
Column = Struct.new("Column", :type, :name, :human_name)
end
class DirtyPost
class Errors
def empty?
false
end
def count
1
end
def full_messages
["Author name can't be <em>empty</em>"]
end
def on(field)
"can't be <em>empty</em>"
end
end
def errors
Errors.new
end
end
def setup_post
@post = Post.new
def @post.errors
@ -146,7 +170,7 @@ class ActiveRecordHelperTest < ActionView::TestCase
@request_forgery_protection_token = 'authenticity_token'
@form_authenticity_token = '123'
assert_dom_equal(
%(<form action="create" method="post"><div style='margin:0;padding:0'><input type='hidden' name='authenticity_token' value='123' /></div><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
%(<form action="create" method="post"><div style='margin:0;padding:0;display:inline'><input type='hidden' name='authenticity_token' value='123' /></div><p><label for="post_title">Title</label><br /><input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /></p>\n<p><label for="post_body">Body</label><br /><div class="fieldWithErrors"><textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea></div></p><input name="commit" type="submit" value="Create" /></form>),
form("post")
)
end
@ -159,7 +183,7 @@ class ActiveRecordHelperTest < ActionView::TestCase
end
def test_form_with_action_option
@response.body = form("post", :action => "sign")
output_buffer << form("post", :action => "sign")
assert_select "form[action=sign]" do |form|
assert_select "input[type=submit][value=Sign]"
end
@ -195,10 +219,20 @@ class ActiveRecordHelperTest < ActionView::TestCase
assert_equal %(<div class="errorDeathByClass"><h1>1 error prohibited this post from being saved</h1><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>), error_messages_for("post", :class => "errorDeathByClass", :id => nil, :header_tag => "h1")
end
def test_error_messages_for_escapes_html
@dirty_post = DirtyPost.new
assert_dom_equal %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this dirty post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be &lt;em&gt;empty&lt;/em&gt;</li></ul></div>), error_messages_for("dirty_post")
end
def test_error_messages_for_handles_nil
assert_equal "", error_messages_for("notthere")
end
def test_error_message_on_escapes_html
@dirty_post = DirtyPost.new
assert_dom_equal "<div class=\"formError\">can't be &lt;em&gt;empty&lt;/em&gt;</div>", error_message_on(:dirty_post, :author_name)
end
def test_error_message_on_handles_nil
assert_equal "", error_message_on("notthere", "notthere")
end

View file

@ -38,8 +38,6 @@ class AssetTagHelperTest < ActionView::TestCase
@controller.request = @request
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
AssetTag::Cache.clear
AssetCollection::Cache.clear
end
def teardown
@ -166,6 +164,11 @@ class AssetTagHelperTest < ActionView::TestCase
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
end
def test_javascript_include_tag_is_html_safe
assert javascript_include_tag(:defaults).html_safe?
assert javascript_include_tag("prototype").html_safe?
end
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
@ -208,6 +211,13 @@ class AssetTagHelperTest < ActionView::TestCase
StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
def test_stylesheet_link_tag_is_html_safe
ENV["RAILS_ASSET_ID"] = ""
assert stylesheet_link_tag('dir/file').html_safe?
assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
assert stylesheet_tag('dir/file', {}).html_safe?
end
def test_custom_stylesheet_expansions
ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => ["head", "body", "tail"]
assert_dom_equal %(<link href="/stylesheets/first.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/last.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('first', :monkey, 'last')
@ -230,20 +240,18 @@ class AssetTagHelperTest < ActionView::TestCase
ImageLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
uses_mocha 'test image tag with windows behaviour' do
def test_image_tag_windows_behaviour
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
# This simulates the behaviour of File#exist? on windows when testing a file ending in "."
# If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".")
# OS X, linux etc will return false in this case.
File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true)
assert_equal '<img alt="Rails" src="/images/rails.png?1" />', image_tag('rails.png')
ensure
if old_asset_id
ENV["RAILS_ASSET_ID"] = old_asset_id
else
ENV.delete("RAILS_ASSET_ID")
end
def test_image_tag_windows_behaviour
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
# This simulates the behaviour of File#exist? on windows when testing a file ending in "."
# If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".")
# OS X, linux etc will return false in this case.
File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true)
assert_equal '<img alt="Rails" src="/images/rails.png?1" />', image_tag('rails.png')
ensure
if old_asset_id
ENV["RAILS_ASSET_ID"] = old_asset_id
else
ENV.delete("RAILS_ASSET_ID")
end
end
@ -281,6 +289,26 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal copy, source
end
def test_caching_image_path_with_caching_and_proc_asset_host_using_request
ENV['RAILS_ASSET_ID'] = ''
ActionController::Base.asset_host = Proc.new do |source, request|
if request.ssl?
"#{request.protocol}#{request.host_with_port}"
else
"#{request.protocol}assets#{source.length}.example.com"
end
end
ActionController::Base.perform_caching = true
@controller.request.stubs(:ssl?).returns(false)
assert_equal "http://assets15.example.com/images/xml.png", image_path("xml.png")
@controller.request.stubs(:ssl?).returns(true)
assert_equal "http://localhost/images/xml.png", image_path("xml.png")
end
def test_caching_javascript_include_tag_when_caching_on
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = 'http://a0.example.com'
@ -300,9 +328,17 @@ class AssetTagHelperTest < ActionView::TestCase
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js'))
assert_dom_equal(
%(<script src="http://a0.example.com/absolute/test.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => "/absolute/test")
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.js'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host
@ -359,6 +395,46 @@ class AssetTagHelperTest < ActionView::TestCase
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js'))
end
def test_caching_javascript_include_tag_when_caching_on_with_2_argument_object_asset_host
ENV['RAILS_ASSET_ID'] = ''
ActionController::Base.asset_host = Class.new do
def call(source, request)
if request.ssl?
"#{request.protocol}#{request.host_with_port}"
else
"#{request.protocol}assets#{source.length}.example.com"
end
end
end.new
ActionController::Base.perform_caching = true
assert_equal '/javascripts/vanilla.js'.length, 23
assert_dom_equal(
%(<script src="http://assets23.example.com/javascripts/vanilla.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => 'vanilla')
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js'))
class << @controller.request
def protocol() 'https://' end
def ssl?() true end
end
assert_equal '/javascripts/secure.js'.length, 22
assert_dom_equal(
%(<script src="https://localhost/javascripts/secure.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => 'secure')
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js'))
end
def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = 'http://a%d.example.com'
@ -490,9 +566,47 @@ class AssetTagHelperTest < ActionView::TestCase
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
assert_dom_equal(
%(<link href="http://a0.example.com/absolute/test.css" media="screen" rel="stylesheet" type="text/css" />),
stylesheet_link_tag(:all, :cache => "/absolute/test")
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_concat_stylesheet_link_tag_when_caching_off
ENV["RAILS_ASSET_ID"] = ""
assert_dom_equal(
%(<link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />),
stylesheet_link_tag(:all, :concat => true)
)
expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_dom_equal(
%(<link href="/stylesheets/money.css" media="screen" rel="stylesheet" type="text/css" />),
stylesheet_link_tag(:all, :concat => "money")
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
assert_dom_equal(
%(<link href="/absolute/test.css" media="screen" rel="stylesheet" type="text/css" />),
stylesheet_link_tag(:all, :concat => "/absolute/test")
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host

View file

@ -150,6 +150,26 @@ class ScrollsController < ActionController::Base
end
end
EOT
FEEDS["provide_builder"] = <<-'EOT'
# we pass in the new_xml to the helper so it doesn't
# call anything on the original builder
new_xml = Builder::XmlMarkup.new(:target=>'')
atom_feed(:xml => new_xml) do |feed|
feed.title("My great blog!")
feed.updated((@scrolls.first.created_at))
for scroll in @scrolls
feed.entry(scroll) do |entry|
entry.title(scroll.title)
entry.content(scroll.body, :type => 'html')
entry.author do |author|
author.name("DHH")
end
end
end
end
EOT
def index
@scrolls = [
Scroll.new(1, "1", "Hello One", "Something <i>COOL!</i>", Time.utc(2007, 12, 12, 15), Time.utc(2007, 12, 12, 15)),
@ -166,12 +186,10 @@ class ScrollsController < ActionController::Base
end
end
class AtomFeedTest < Test::Unit::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = ScrollsController.new
class AtomFeedTest < ActionController::TestCase
tests ScrollsController
def setup
@request.host = "www.nextangle.com"
end
@ -196,6 +214,15 @@ class AtomFeedTest < Test::Unit::TestCase
end
end
def test_providing_builder_to_atom_feed
with_restful_routing(:scrolls) do
get :index, :id=>"provide_builder"
# because we pass in the non-default builder, the content generated by the
# helper should go 'nowhere'. Leaving the response body blank.
assert @response.body.blank?
end
end
def test_entry_with_prefilled_options_should_use_those_instead_of_querying_the_record
with_restful_routing(:scrolls) do
get :index, :id => "entry_options"

View file

@ -4,32 +4,25 @@ require 'action_view/helpers/benchmark_helper'
class BenchmarkHelperTest < ActionView::TestCase
tests ActionView::Helpers::BenchmarkHelper
class MockLogger
attr_reader :logged
def initialize
@logged = []
end
def method_missing(method, *args)
@logged << [method, args]
end
def setup
super
controller.logger = ActiveSupport::BufferedLogger.new(StringIO.new)
controller.logger.auto_flushing = false
end
def controller
@controller ||= Struct.new(:logger).new(MockLogger.new)
def teardown
controller.logger.send(:clear_buffer)
end
def test_without_block
assert_raise(LocalJumpError) { benchmark }
assert controller.logger.logged.empty?
assert buffer.empty?
end
def test_defaults
i_was_run = false
benchmark { i_was_run = true }
assert i_was_run
assert 1, controller.logger.logged.size
assert_last_logged
end
@ -37,24 +30,57 @@ class BenchmarkHelperTest < ActionView::TestCase
i_was_run = false
benchmark('test_run') { i_was_run = true }
assert i_was_run
assert 1, controller.logger.logged.size
assert_last_logged 'test_run'
end
def test_with_message_and_level
def test_with_message_and_deprecated_level
i_was_run = false
benchmark('debug_run', :debug) { i_was_run = true }
assert_deprecated do
benchmark('debug_run', :debug) { i_was_run = true }
end
assert i_was_run
assert 1, controller.logger.logged.size
assert_last_logged 'debug_run', :debug
assert_last_logged 'debug_run'
end
def test_within_level
controller.logger.level = ActiveSupport::BufferedLogger::DEBUG
benchmark('included_debug_run', :level => :debug) { }
assert_last_logged 'included_debug_run'
end
def test_outside_level
controller.logger.level = ActiveSupport::BufferedLogger::ERROR
benchmark('skipped_debug_run', :level => :debug) { }
assert_no_match(/skipped_debug_run/, buffer.last)
ensure
controller.logger.level = ActiveSupport::BufferedLogger::DEBUG
end
def test_without_silencing
benchmark('debug_run', :silence => false) do
controller.logger.info "not silenced!"
end
assert_equal 2, buffer.size
end
def test_with_silencing
benchmark('debug_run', :silence => true) do
controller.logger.info "silenced!"
end
assert_equal 1, buffer.size
end
private
def assert_last_logged(message = 'Benchmarking', level = :info)
last = controller.logger.logged.last
assert 2, last.size
assert_equal level, last.first
assert 1, last[1].size
assert last[1][0] =~ /^#{message} \(.*\)$/
def buffer
controller.logger.send(:buffer)
end
def assert_last_logged(message = 'Benchmarking')
assert_match(/^#{message} \(.*\)$/, buffer.last)
end
end

View file

@ -1,59 +1,204 @@
require 'abstract_unit'
require 'controller/fake_models'
uses_mocha 'TestTemplateRecompilation' do
class CompiledTemplatesTest < Test::Unit::TestCase
def setup
@compiled_templates = ActionView::Base::CompiledTemplates
@compiled_templates.instance_methods.each do |m|
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
end
end
class CompiledTemplatesTest < Test::Unit::TestCase
def test_template_gets_compiled
def setup
@explicit_view_paths = nil
@compiled_templates = ActionView::Base::CompiledTemplates
@compiled_templates.instance_methods.each do |m|
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
end
end
def test_template_gets_compiled
with_caching(true) do
assert_equal 0, @compiled_templates.instance_methods.size
assert_deprecated do
assert_equal "Hello world!", render("test/hello_world.erb")
end
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
assert_equal 1, @compiled_templates.instance_methods.size
end
end
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
with_caching(true) do
assert_equal 0, @compiled_templates.instance_methods.size
assert_deprecated do
assert_equal "Hello world!", render("test/hello_world.erb")
assert_equal "Hello world!", render("test/hello_world.erb", {:foo => "bar"})
end
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
assert_equal "Hello world!", render(:file => "test/hello_world.erb", :locals => {:foo => "bar"})
assert_equal 2, @compiled_templates.instance_methods.size
end
def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
assert_equal 0, @compiled_templates.instance_methods.size
assert_deprecated do
assert_equal "Hello world!", render("test/hello_world.erb")
ActionView::Template.any_instance.expects(:compile!).never
assert_equal "Hello world!", render("test/hello_world.erb")
end
end
def test_compiled_template_will_always_be_recompiled_when_eager_loaded_templates_is_off
ActionView::PathSet::Path.expects(:eager_load_templates?).times(4).returns(false)
assert_equal 0, @compiled_templates.instance_methods.size
assert_deprecated do
assert_equal "Hello world!", render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
end
ActionView::Template.any_instance.expects(:compile!).times(3)
assert_deprecated do
3.times { assert_equal "Hello world!", render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
end
assert_equal 1, @compiled_templates.instance_methods.size
end
private
def render(*args)
ActionView::Base.new(ActionController::Base.view_paths, {}).render(*args)
end
end
def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
with_caching(true) do
assert_equal 0, @compiled_templates.instance_methods.size
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
ActionView::Template.any_instance.expects(:compile!).never
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
end
end
def test_template_changes_are_not_reflected_with_cached_template_loading
with_caching(true) do
with_reloading(false) do
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
modify_template "test/hello_world.erb", "Goodbye world!" do
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
end
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
end
end
end
def test_template_changes_are_reflected_without_cached_template_loading
with_caching(true) do
with_reloading(true) do
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
modify_template "test/hello_world.erb", "Goodbye world!" do
assert_equal "Goodbye world!", render(:file => "test/hello_world.erb")
end
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
end
end
end
def test_template_becomes_missing_if_deleted_without_cached_template_loading
with_reloading(true) do
assert_equal 'Hello world!', render(:file => 'test/hello_world.erb')
delete_template 'test/hello_world.erb' do
assert_raise(ActionView::MissingTemplate) { render(:file => 'test/hello_world.erb') }
end
assert_equal 'Hello world!', render(:file => 'test/hello_world.erb')
end
end
def test_swapping_template_handler_is_working_without_cached_template_loading
with_reloading(true) do
assert_equal 'Hello world!', render(:file => 'test/hello_world')
delete_template 'test/hello_world.erb' do
rename_template 'test/hello_world_from_rxml.builder', 'test/hello_world.builder' do
assert_equal "<html>\n <p>Hello</p>\n</html>\n", render(:file => 'test/hello_world')
end
end
assert_equal 'Hello world!', render(:file => 'test/hello_world')
end
end
def test_adding_localized_template_will_take_precedence_without_cached_template_loading
with_reloading(true) do
assert_equal 'Hello world!', render(:file => 'test/hello_world')
rename_template 'test/hello_world.da.html.erb', 'test/hello_world.en.html.erb' do
assert_equal 'Hey verden', render(:file => 'test/hello_world')
end
end
end
def test_deleting_localized_template_will_fall_back_to_non_localized_template_without_cached_template_loading
with_reloading(true) do
rename_template 'test/hello_world.da.html.erb', 'test/hello_world.en.html.erb' do
assert_equal 'Hey verden', render(:file => 'test/hello_world')
delete_template 'test/hello_world.en.html.erb' do
assert_equal 'Hello world!', render(:file => 'test/hello_world')
end
assert_equal 'Hey verden', render(:file => 'test/hello_world')
end
end
end
def test_parallel_reloadable_view_paths_are_working
with_reloading(true) do
view_paths_copy = new_reloadable_view_paths
assert_equal 'Hello world!', render(:file => 'test/hello_world')
with_view_paths(view_paths_copy, new_reloadable_view_paths) do
assert_equal 'Hello world!', render(:file => 'test/hello_world')
end
modify_template 'test/hello_world.erb', 'Goodbye world!' do
assert_equal 'Goodbye world!', render(:file => 'test/hello_world')
modify_template 'test/hello_world.erb', 'So long, world!' do
with_view_paths(view_paths_copy, new_reloadable_view_paths) do
assert_equal 'So long, world!', render(:file => 'test/hello_world')
end
assert_equal 'So long, world!', render(:file => 'test/hello_world')
end
end
end
end
private
def render(*args)
view_paths = @explicit_view_paths || ActionController::Base.view_paths
ActionView::Base.new(view_paths, {}).render(*args)
end
def with_view_paths(*args)
args.each do |view_paths|
begin
@explicit_view_paths = view_paths
yield
ensure
@explicit_view_paths = nil
end
end
end
def reset_mtime_of(template_name, view_paths_to_use)
view_paths_to_use.find_template(template_name).previously_last_modified = 10.seconds.ago unless ActionView::Base.cache_template_loading?
end
def modify_template(template, content, view_paths_to_use = ActionController::Base.view_paths)
filename = filename_for(template)
old_content = File.read(filename)
begin
File.open(filename, "wb+") { |f| f.write(content) }
reset_mtime_of(template, view_paths_to_use)
yield
ensure
File.open(filename, "wb+") { |f| f.write(old_content) }
reset_mtime_of(template, view_paths_to_use)
end
end
def filename_for(template)
File.join(FIXTURE_LOAD_PATH, template)
end
def rename_template(old_name, new_name)
File.rename(filename_for(old_name), filename_for(new_name))
yield
ensure
File.rename(filename_for(new_name), filename_for(old_name))
end
def delete_template(template, &block)
rename_template(template, File.join(File.dirname(template), "__#{File.basename(template)}"), &block)
end
def with_caching(perform_caching)
old_perform_caching = ActionController::Base.perform_caching
begin
ActionController::Base.perform_caching = perform_caching
yield
ensure
ActionController::Base.perform_caching = old_perform_caching
end
end
def with_reloading(reload_templates, view_paths_owner = ActionController::Base)
old_view_paths, old_cache_templates = view_paths_owner.view_paths, ActionView::Base.cache_template_loading
begin
ActionView::Base.cache_template_loading = !reload_templates
view_paths_owner.view_paths = view_paths_for(reload_templates)
yield
ensure
view_paths_owner.view_paths, ActionView::Base.cache_template_loading = old_view_paths, old_cache_templates
end
end
def new_reloadable_view_paths
ActionView::PathSet.new(CACHED_VIEW_PATHS.map(&:to_s))
end
def view_paths_for(reload_templates)
# reloadable paths are cheap to create
reload_templates ? new_reloadable_view_paths : CACHED_VIEW_PATHS
end
end

View file

@ -8,66 +8,65 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase
@from = Time.mktime(2004, 6, 6, 21, 45, 0)
end
uses_mocha 'date_helper_distance_of_time_in_words_i18n_test' do
# distance_of_time_in_words
# distance_of_time_in_words
def test_distance_of_time_in_words_calls_i18n
{ # with include_seconds
[2.seconds, true] => [:'less_than_x_seconds', 5],
[9.seconds, true] => [:'less_than_x_seconds', 10],
[19.seconds, true] => [:'less_than_x_seconds', 20],
[30.seconds, true] => [:'half_a_minute', nil],
[59.seconds, true] => [:'less_than_x_minutes', 1],
[60.seconds, true] => [:'x_minutes', 1],
def test_distance_of_time_in_words_calls_i18n
{ # with include_seconds
[2.seconds, true] => [:'less_than_x_seconds', 5],
[9.seconds, true] => [:'less_than_x_seconds', 10],
[19.seconds, true] => [:'less_than_x_seconds', 20],
[30.seconds, true] => [:'half_a_minute', nil],
[59.seconds, true] => [:'less_than_x_minutes', 1],
[60.seconds, true] => [:'x_minutes', 1],
# without include_seconds
[29.seconds, false] => [:'less_than_x_minutes', 1],
[60.seconds, false] => [:'x_minutes', 1],
[44.minutes, false] => [:'x_minutes', 44],
[61.minutes, false] => [:'about_x_hours', 1],
[24.hours, false] => [:'x_days', 1],
[30.days, false] => [:'about_x_months', 1],
[60.days, false] => [:'x_months', 2],
[1.year, false] => [:'about_x_years', 1],
[3.years, false] => [:'over_x_years', 3]
# without include_seconds
[29.seconds, false] => [:'less_than_x_minutes', 1],
[60.seconds, false] => [:'x_minutes', 1],
[44.minutes, false] => [:'x_minutes', 44],
[61.minutes, false] => [:'about_x_hours', 1],
[24.hours, false] => [:'x_days', 1],
[30.days, false] => [:'about_x_months', 1],
[60.days, false] => [:'x_months', 2],
[1.year, false] => [:'about_x_years', 1],
[3.years + 6.months, false] => [:'over_x_years', 3],
[3.years + 10.months, false] => [:'almost_x_years', 4]
}.each do |passed, expected|
assert_distance_of_time_in_words_translates_key passed, expected
end
}.each do |passed, expected|
assert_distance_of_time_in_words_translates_key passed, expected
end
end
def assert_distance_of_time_in_words_translates_key(passed, expected)
diff, include_seconds = *passed
key, count = *expected
to = @from + diff
def assert_distance_of_time_in_words_translates_key(passed, expected)
diff, include_seconds = *passed
key, count = *expected
to = @from + diff
options = {:locale => 'en', :scope => :'datetime.distance_in_words'}
options[:count] = count if count
options = {:locale => 'en', :scope => :'datetime.distance_in_words'}
options[:count] = count if count
I18n.expects(:t).with(key, options)
distance_of_time_in_words(@from, to, include_seconds, :locale => 'en')
end
I18n.expects(:t).with(key, options)
distance_of_time_in_words(@from, to, include_seconds, :locale => 'en')
end
def test_distance_of_time_pluralizations
{ [:'less_than_x_seconds', 1] => 'less than 1 second',
[:'less_than_x_seconds', 2] => 'less than 2 seconds',
[:'less_than_x_minutes', 1] => 'less than a minute',
[:'less_than_x_minutes', 2] => 'less than 2 minutes',
[:'x_minutes', 1] => '1 minute',
[:'x_minutes', 2] => '2 minutes',
[:'about_x_hours', 1] => 'about 1 hour',
[:'about_x_hours', 2] => 'about 2 hours',
[:'x_days', 1] => '1 day',
[:'x_days', 2] => '2 days',
[:'about_x_years', 1] => 'about 1 year',
[:'about_x_years', 2] => 'about 2 years',
[:'over_x_years', 1] => 'over 1 year',
[:'over_x_years', 2] => 'over 2 years'
def test_distance_of_time_pluralizations
{ [:'less_than_x_seconds', 1] => 'less than 1 second',
[:'less_than_x_seconds', 2] => 'less than 2 seconds',
[:'less_than_x_minutes', 1] => 'less than a minute',
[:'less_than_x_minutes', 2] => 'less than 2 minutes',
[:'x_minutes', 1] => '1 minute',
[:'x_minutes', 2] => '2 minutes',
[:'about_x_hours', 1] => 'about 1 hour',
[:'about_x_hours', 2] => 'about 2 hours',
[:'x_days', 1] => '1 day',
[:'x_days', 2] => '2 days',
[:'about_x_years', 1] => 'about 1 year',
[:'about_x_years', 2] => 'about 2 years',
[:'over_x_years', 1] => 'over 1 year',
[:'over_x_years', 2] => 'over 2 years'
}.each do |args, expected|
key, count = *args
assert_equal expected, I18n.t(key, :count => count, :scope => 'datetime.distance_in_words')
end
}.each do |args, expected|
key, count = *args
assert_equal expected, I18n.t(key, :count => count, :scope => 'datetime.distance_in_words')
end
end
end
@ -76,38 +75,47 @@ class DateHelperSelectTagsI18nTests < Test::Unit::TestCase
include ActionView::Helpers::DateHelper
attr_reader :request
uses_mocha 'date_helper_select_tags_i18n_tests' do
def setup
I18n.stubs(:translate).with(:'date.month_names', :locale => 'en').returns Date::MONTHNAMES
end
def setup
@prompt_defaults = {:year => 'Year', :month => 'Month', :day => 'Day', :hour => 'Hour', :minute => 'Minute', :second => 'Seconds'}
# select_month
def test_select_month_given_use_month_names_option_does_not_translate_monthnames
I18n.expects(:translate).never
select_month(8, :locale => 'en', :use_month_names => Date::MONTHNAMES)
end
def test_select_month_translates_monthnames
I18n.expects(:translate).with(:'date.month_names', :locale => 'en').returns Date::MONTHNAMES
select_month(8, :locale => 'en')
end
def test_select_month_given_use_short_month_option_translates_abbr_monthnames
I18n.expects(:translate).with(:'date.abbr_month_names', :locale => 'en').returns Date::ABBR_MONTHNAMES
select_month(8, :locale => 'en', :use_short_month => true)
end
# date_or_time_select
def test_date_or_time_select_given_an_order_options_does_not_translate_order
I18n.expects(:translate).never
datetime_select('post', 'updated_at', :order => [:year, :month, :day], :locale => 'en')
end
def test_date_or_time_select_given_no_order_options_translates_order
I18n.expects(:translate).with(:'date.order', :locale => 'en').returns [:year, :month, :day]
datetime_select('post', 'updated_at', :locale => 'en')
end
I18n.stubs(:translate).with(:'date.month_names', :locale => 'en').returns Date::MONTHNAMES
end
end
# select_month
def test_select_month_given_use_month_names_option_does_not_translate_monthnames
I18n.expects(:translate).never
select_month(8, :locale => 'en', :use_month_names => Date::MONTHNAMES)
end
def test_select_month_translates_monthnames
I18n.expects(:translate).with(:'date.month_names', :locale => 'en').returns Date::MONTHNAMES
select_month(8, :locale => 'en')
end
def test_select_month_given_use_short_month_option_translates_abbr_monthnames
I18n.expects(:translate).with(:'date.abbr_month_names', :locale => 'en').returns Date::ABBR_MONTHNAMES
select_month(8, :locale => 'en', :use_short_month => true)
end
def test_date_or_time_select_translates_prompts
@prompt_defaults.each do |key, prompt|
I18n.expects(:translate).with(('datetime.prompts.' + key.to_s).to_sym, :locale => 'en').returns prompt
end
I18n.expects(:translate).with(:'date.order', :locale => 'en').returns [:year, :month, :day]
datetime_select('post', 'updated_at', :locale => 'en', :include_seconds => true, :prompt => true)
end
# date_or_time_select
def test_date_or_time_select_given_an_order_options_does_not_translate_order
I18n.expects(:translate).never
datetime_select('post', 'updated_at', :order => [:year, :month, :day], :locale => 'en')
end
def test_date_or_time_select_given_no_order_options_translates_order
I18n.expects(:translate).with(:'date.order', :locale => 'en').returns [:year, :month, :day]
datetime_select('post', 'updated_at', :locale => 'en')
end
end

View file

@ -53,13 +53,14 @@ class DateHelperTest < ActionView::TestCase
assert_equal "about 2 hours", distance_of_time_in_words(from, to + 89.minutes + 30.seconds)
assert_equal "about 24 hours", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 29.seconds)
# 1440..2879
# 1440..2529
assert_equal "1 day", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 30.seconds)
assert_equal "1 day", distance_of_time_in_words(from, to + 47.hours + 59.minutes + 29.seconds)
assert_equal "1 day", distance_of_time_in_words(from, to + 41.hours + 59.minutes + 29.seconds)
# 2880..43199
assert_equal "2 days", distance_of_time_in_words(from, to + 47.hours + 59.minutes + 30.seconds)
assert_equal "29 days", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 29.seconds)
# 2530..43199
assert_equal "2 days", distance_of_time_in_words(from, to + 42.hours + 59.minutes + 30.seconds)
assert_equal "3 days", distance_of_time_in_words(from, to + 2.days + 12.hours)
assert_equal "30 days", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 29.seconds)
# 43200..86399
assert_equal "about 1 month", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 30.seconds)
@ -69,13 +70,28 @@ class DateHelperTest < ActionView::TestCase
assert_equal "2 months", distance_of_time_in_words(from, to + 59.days + 23.hours + 59.minutes + 30.seconds)
assert_equal "12 months", distance_of_time_in_words(from, to + 1.years - 31.seconds)
# 525600..1051199
assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years - 30.seconds)
assert_equal "about 1 year", distance_of_time_in_words(from, to + 2.years - 31.seconds)
# > 525599
assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years - 30.seconds)
assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years + 3.months - 1.day)
assert_equal "over 1 year", distance_of_time_in_words(from, to + 1.years + 6.months)
# > 1051199
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 30.seconds)
assert_equal "over 10 years", distance_of_time_in_words(from, to + 10.years)
assert_equal "almost 2 years", distance_of_time_in_words(from, to + 2.years - 3.months + 1.day)
assert_equal "about 2 years", distance_of_time_in_words(from, to + 2.years + 3.months - 1.day)
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 3.months + 1.day)
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 9.months - 1.day)
assert_equal "almost 3 years", distance_of_time_in_words(from, to + 2.years + 9.months + 1.day)
assert_equal "almost 5 years", distance_of_time_in_words(from, to + 5.years - 3.months + 1.day)
assert_equal "about 5 years", distance_of_time_in_words(from, to + 5.years + 3.months - 1.day)
assert_equal "over 5 years", distance_of_time_in_words(from, to + 5.years + 3.months + 1.day)
assert_equal "over 5 years", distance_of_time_in_words(from, to + 5.years + 9.months - 1.day)
assert_equal "almost 6 years", distance_of_time_in_words(from, to + 5.years + 9.months + 1.day)
assert_equal "almost 10 years", distance_of_time_in_words(from, to + 10.years - 3.months + 1.day)
assert_equal "about 10 years", distance_of_time_in_words(from, to + 10.years + 3.months - 1.day)
assert_equal "over 10 years", distance_of_time_in_words(from, to + 10.years + 3.months + 1.day)
assert_equal "over 10 years", distance_of_time_in_words(from, to + 10.years + 9.months - 1.day)
assert_equal "almost 11 years", distance_of_time_in_words(from, to + 10.years + 9.months + 1.day)
# test to < from
assert_equal "about 4 hours", distance_of_time_in_words(from + 4.hours, to)
@ -104,7 +120,7 @@ class DateHelperTest < ActionView::TestCase
def test_distance_in_words_with_dates
start_date = Date.new 1975, 1, 31
end_date = Date.new 1977, 1, 31
assert_equal("over 2 years", distance_of_time_in_words(start_date, end_date))
assert_equal("about 2 years", distance_of_time_in_words(start_date, end_date))
end
def test_distance_in_words_with_integers
@ -153,6 +169,22 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_day(16, {}, :class => 'selector')
end
def test_select_day_with_default_prompt
expected = %(<select id="date_day" name="date[day]">\n)
expected << %(<option value="">Day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_day(16, :prompt => true)
end
def test_select_day_with_custom_prompt
expected = %(<select id="date_day" name="date[day]">\n)
expected << %(<option value="">Choose day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_day(16, :prompt => 'Choose day')
end
def test_select_month
expected = %(<select id="date_month" name="date[month]">\n)
expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
@ -276,6 +308,22 @@ class DateHelperTest < ActionView::TestCase
#assert result.include?('<option value="1">January')
end
def test_select_month_with_default_prompt
expected = %(<select id="date_month" name="date[month]">\n)
expected << %(<option value="">Month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_month(8, :prompt => true)
end
def test_select_month_with_custom_prompt
expected = %(<select id="date_month" name="date[month]">\n)
expected << %(<option value="">Choose month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_month(8, :prompt => 'Choose month')
end
def test_select_year
expected = %(<select id="date_year" name="date[year]">\n)
expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
@ -344,6 +392,22 @@ class DateHelperTest < ActionView::TestCase
#assert result.include?('<option value="2003"')
end
def test_select_year_with_default_prompt
expected = %(<select id="date_year" name="date[year]">\n)
expected << %(<option value="">Year</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_year(nil, :start_year => 2003, :end_year => 2005, :prompt => true)
end
def test_select_year_with_custom_prompt
expected = %(<select id="date_year" name="date[year]">\n)
expected << %(<option value="">Choose year</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_year(nil, :start_year => 2003, :end_year => 2005, :prompt => 'Choose year')
end
def test_select_hour
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
@ -392,6 +456,22 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), {}, :class => 'selector', :accesskey => 'M')
end
def test_select_hour_with_default_prompt
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="">Hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true)
end
def test_select_hour_with_custom_prompt
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="">Choose hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => 'Choose hour')
end
def test_select_minute
expected = %(<select id="date_minute" name="date[minute]">\n)
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
@ -470,6 +550,22 @@ class DateHelperTest < ActionView::TestCase
#assert result.include?('<option value="00">00')
end
def test_select_minute_with_default_prompt
expected = %(<select id="date_minute" name="date[minute]">\n)
expected << %(<option value="">Minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true)
end
def test_select_minute_with_custom_prompt
expected = %(<select id="date_minute" name="date[minute]">\n)
expected << %(<option value="">Choose minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => 'Choose minute')
end
def test_select_second
expected = %(<select id="date_second" name="date[second]">\n)
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
@ -524,6 +620,22 @@ class DateHelperTest < ActionView::TestCase
#assert result.include?('<option value="00">00')
end
def test_select_second_with_default_prompt
expected = %(<select id="date_second" name="date[second]">\n)
expected << %(<option value="">Seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true)
end
def test_select_second_with_custom_prompt
expected = %(<select id="date_second" name="date[second]">\n)
expected << %(<option value="">Choose seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => 'Choose seconds')
end
def test_select_date
expected = %(<select id="date_first_year" name="date[first][year]">\n)
expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
@ -914,6 +1026,57 @@ class DateHelperTest < ActionView::TestCase
assert_nothing_raised { select_datetime(Date.today) }
end
def test_select_datetime_with_default_prompt
expected = %(<select id="date_first_year" name="date[first][year]">\n)
expected << %(<option value="">Year</option>\n<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_month" name="date[first][month]">\n)
expected << %(<option value="">Month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_day" name="date[first][day]">\n)
expected << %(<option value="">Day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_hour" name="date[first][hour]">\n)
expected << %(<option value="">Hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_minute" name="date[first][minute]">\n)
expected << %(<option value="">Minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), :start_year => 2003, :end_year => 2005,
:prefix => "date[first]", :prompt => true)
end
def test_select_datetime_with_custom_prompt
expected = %(<select id="date_first_year" name="date[first][year]">\n)
expected << %(<option value="">Choose year</option>\n<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_month" name="date[first][month]">\n)
expected << %(<option value="">Choose month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_day" name="date[first][day]">\n)
expected << %(<option value="">Choose day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_hour" name="date[first][hour]">\n)
expected << %(<option value="">Choose hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
expected << %(<select id="date_first_minute" name="date[first][minute]">\n)
expected << %(<option value="">Choose minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), :start_year => 2003, :end_year => 2005, :prefix => "date[first]",
:prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year', :hour => 'Choose hour', :minute => 'Choose minute'})
end
def test_select_time
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
@ -995,6 +1158,40 @@ class DateHelperTest < ActionView::TestCase
assert_nothing_raised { select_time(Date.today) }
end
def test_select_time_with_default_prompt
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="">Hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
expected << %(<select id="date_minute" name="date[minute]">\n)
expected << %(<option value="">Minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
expected << %(<select id="date_second" name="date[second]">\n)
expected << %(<option value="">Seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :include_seconds => true, :prompt => true)
end
def test_select_time_with_custom_prompt
expected = %(<select id="date_hour" name="date[hour]">\n)
expected << %(<option value="">Choose hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
expected << %(<select id="date_minute" name="date[minute]">\n)
expected << %(<option value="">Choose minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
expected << %(<select id="date_second" name="date[second]">\n)
expected << %(<option value="">Choose seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true, :include_seconds => true,
:prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
end
def test_date_select
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
@ -1047,6 +1244,38 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal(expected, output_buffer)
end
def test_date_select_within_fields_for_with_index
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
id = 27
fields_for :post, @post, :index => id do |f|
concat f.date_select(:written_on)
end
expected = "<select id='post_#{id}_written_on_1i' name='post[#{id}][written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
expected << "<select id='post_#{id}_written_on_2i' name='post[#{id}][written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
expected << "<select id='post_#{id}_written_on_3i' name='post[#{id}][written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
assert_dom_equal(expected, output_buffer)
end
def test_date_select_within_fields_for_with_blank_index
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
id = nil
fields_for :post, @post, :index => id do |f|
concat f.date_select(:written_on)
end
expected = "<select id='post_#{id}_written_on_1i' name='post[#{id}][written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
expected << "<select id='post_#{id}_written_on_2i' name='post[#{id}][written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
expected << "<select id='post_#{id}_written_on_3i' name='post[#{id}][written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
assert_dom_equal(expected, output_buffer)
end
def test_date_select_with_index
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
@ -1062,7 +1291,6 @@ class DateHelperTest < ActionView::TestCase
expected << %{<select id="post_456_written_on_3i" name="post[#{id}][written_on(3i)]">\n}
expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
assert_dom_equal expected, date_select("post", "written_on", :index => id)
@ -1149,13 +1377,13 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, date_select("post", "written_on", :include_blank => true)
end
def test_date_select_with_nil_and_blank_and_order
@post = Post.new
start_year = Time.now.year-5
end_year = Time.now.year+5
expected = '<input name="post[written_on(3i)]" type="hidden" id="post_written_on_3i"/>' + "\n"
expected << %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}
expected << "<option value=\"\"></option>\n"
@ -1277,6 +1505,46 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, date_select("post", "written_on", { :date_separator => " / " })
end
def test_date_select_with_default_prompt
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}
expected << %{<option value="">Year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n}
expected << %{<option value="">Month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}
expected << %{<option value="">Day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
assert_dom_equal expected, date_select("post", "written_on", :prompt => true)
end
def test_date_select_with_custom_prompt
@post = Post.new
@post.written_on = Date.new(2004, 6, 15)
expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}
expected << %{<option value="">Choose year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n}
expected << %{<option value="">Choose month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}
expected << %{<option value="">Choose day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
assert_dom_equal expected, date_select("post", "written_on", :prompt => {:year => 'Choose year', :month => 'Choose month', :day => 'Choose day'})
end
def test_time_select
@post = Post.new
@post.written_on = Time.local(2004, 6, 15, 15, 16, 35)
@ -1403,6 +1671,48 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, time_select("post", "written_on", { :time_separator => " - ", :include_seconds => true })
end
def test_time_select_with_default_prompt
@post = Post.new
@post.written_on = Time.local(2004, 6, 15, 15, 16, 35)
expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}
expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n}
expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n}
expected << %(<select id="post_written_on_4i" name="post[written_on(4i)]">\n)
expected << %(<option value="">Hour</option>\n)
0.upto(23) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 15}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
expected << " : "
expected << %(<select id="post_written_on_5i" name="post[written_on(5i)]">\n)
expected << %(<option value="">Minute</option>\n)
0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
assert_dom_equal expected, time_select("post", "written_on", :prompt => true)
end
def test_time_select_with_custom_prompt
@post = Post.new
@post.written_on = Time.local(2004, 6, 15, 15, 16, 35)
expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}
expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n}
expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n}
expected << %(<select id="post_written_on_4i" name="post[written_on(4i)]">\n)
expected << %(<option value="">Choose hour</option>\n)
0.upto(23) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 15}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
expected << " : "
expected << %(<select id="post_written_on_5i" name="post[written_on(5i)]">\n)
expected << %(<option value="">Choose minute</option>\n)
0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
assert_dom_equal expected, time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute'})
end
def test_datetime_select
@post = Post.new
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
@ -1432,40 +1742,38 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, datetime_select("post", "updated_at")
end
uses_mocha 'TestDatetimeSelectDefaultsToTimeZoneNowWhenConfigTimeZoneIsSet' do
def test_datetime_select_defaults_to_time_zone_now_when_config_time_zone_is_set
time = stub(:year => 2004, :month => 6, :day => 15, :hour => 16, :min => 35, :sec => 0)
time_zone = mock()
time_zone.expects(:now).returns time
Time.zone_default = time_zone
@post = Post.new
def test_datetime_select_defaults_to_time_zone_now_when_config_time_zone_is_set
time = stub(:year => 2004, :month => 6, :day => 15, :hour => 16, :min => 35, :sec => 0)
time_zone = mock()
time_zone.expects(:now).returns time
Time.zone_default = time_zone
@post = Post.new
expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}
expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}
expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n}
expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n}
expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n}
expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n}
expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
expected << " &mdash; "
expected << " &mdash; "
expected << %{<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n}
expected << "</select>\n"
expected << " : "
expected << %{<select id="post_updated_at_5i" name="post[updated_at(5i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35" selected="selected">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n}
expected << "</select>\n"
expected << " : "
expected << %{<select id="post_updated_at_5i" name="post[updated_at(5i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35" selected="selected">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
assert_dom_equal expected, datetime_select("post", "updated_at")
ensure
Time.zone_default = nil
end
assert_dom_equal expected, datetime_select("post", "updated_at")
ensure
Time.zone_default = nil
end
def test_datetime_select_with_html_options_within_fields_for
@ -1526,6 +1834,64 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, datetime_select("post", "updated_at", { :date_separator => " / ", :datetime_separator => " , ", :time_separator => " - ", :include_seconds => true })
end
def test_datetime_select_with_default_prompt
@post = Post.new
@post.updated_at = nil
expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}
expected << %{<option value="">Year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n}
expected << %{<option value="">Month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n}
expected << %{<option value="">Day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
expected << " &mdash; "
expected << %{<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n}
expected << %{<option value="">Hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n}
expected << "</select>\n"
expected << " : "
expected << %{<select id="post_updated_at_5i" name="post[updated_at(5i)]">\n}
expected << %{<option value="">Minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
assert_dom_equal expected, datetime_select("post", "updated_at", :start_year=>1999, :end_year=>2009, :prompt => true)
end
def test_datetime_select_with_custom_prompt
@post = Post.new
@post.updated_at = nil
expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}
expected << %{<option value="">Choose year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n}
expected << %{<option value="">Choose month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n}
expected << %{<option value="">Choose day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
expected << " &mdash; "
expected << %{<select id="post_updated_at_4i" name="post[updated_at(4i)]">\n}
expected << %{<option value="">Choose hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n}
expected << "</select>\n"
expected << " : "
expected << %{<select id="post_updated_at_5i" name="post[updated_at(5i)]">\n}
expected << %{<option value="">Choose minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
assert_dom_equal expected, datetime_select("post", "updated_at", :start_year=>1999, :end_year=>2009, :prompt => {:year => 'Choose year', :month => 'Choose month', :day => 'Choose day', :hour => 'Choose hour', :minute => 'Choose minute'})
end
def test_date_select_with_zero_value_and_no_start_year
expected = %(<select id="date_first_year" name="date[first][year]">\n)
(Date.today.year-5).upto(Date.today.year+1) { |y| expected << %(<option value="#{y}">#{y}</option>\n) }
@ -1645,6 +2011,40 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, datetime_select("post", "updated_at", :index => id)
end
def test_datetime_select_within_fields_for_with_options_index
@post = Post.new
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
id = 456
fields_for :post, @post, :index => id do |f|
concat f.datetime_select(:updated_at)
end
expected = %{<select id="post_456_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n}
expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
expected << %{<select id="post_456_updated_at_2i" name="post[#{id}][updated_at(2i)]">\n}
expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n}
expected << "</select>\n"
expected << %{<select id="post_456_updated_at_3i" name="post[#{id}][updated_at(3i)]">\n}
expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n}
expected << "</select>\n"
expected << " &mdash; "
expected << %{<select id="post_456_updated_at_4i" name="post[#{id}][updated_at(4i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n}
expected << "</select>\n"
expected << " : "
expected << %{<select id="post_456_updated_at_5i" name="post[#{id}][updated_at(5i)]">\n}
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35" selected="selected">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
assert_dom_equal expected, output_buffer
end
def test_datetime_select_with_auto_index
@post = Post.new
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
@ -1932,7 +2332,7 @@ class DateHelperTest < ActionView::TestCase
@post = Post.new
@post.updated_at = Time.local(2008, 7, 16, 23, 30)
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -1944,7 +2344,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -1958,7 +2358,7 @@ class DateHelperTest < ActionView::TestCase
@post = Post.new
@post.updated_at = Time.local(2008, 7, 16, 23, 30)
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -1970,7 +2370,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -1984,7 +2384,7 @@ class DateHelperTest < ActionView::TestCase
@post = Post.new
@post.updated_at = Time.local(2008, 7, 16, 23, 30)
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -1996,7 +2396,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2007,7 +2407,7 @@ class DateHelperTest < ActionView::TestCase
end
def test_select_date_should_not_change_passed_options_hash
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2019,7 +2419,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2030,7 +2430,7 @@ class DateHelperTest < ActionView::TestCase
end
def test_select_datetime_should_not_change_passed_options_hash
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2042,7 +2442,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2053,7 +2453,7 @@ class DateHelperTest < ActionView::TestCase
end
def test_select_time_should_not_change_passed_options_hash
options = {
options = {
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,
@ -2065,7 +2465,7 @@ class DateHelperTest < ActionView::TestCase
# note: the literal hash is intentional to show that the actual options hash isn't modified
# don't change this!
assert_equal({
assert_equal({
:order => [ :year, :month, :day ],
:default => { :year => 2008, :month => 7, :day => 16, :hour => 23, :minute => 30, :second => 1 },
:discard_type => false,

View file

@ -15,21 +15,78 @@ silence_warnings do
def new_record?
@new_record
end
attr_accessor :author
def author_attributes=(attributes); end
attr_accessor :comments
def comments_attributes=(attributes); end
attr_accessor :tags
def tags_attributes=(attributes); end
end
class Comment
attr_reader :id
attr_reader :post_id
def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
def save; @id = 1; @post_id = 1 end
def new_record?; @id.nil? end
def to_param; @id; end
def name
@id.nil? ? 'new comment' : "comment ##{@id}"
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
attr_accessor :relevances
def relevances_attributes=(attributes); end
end
class Tag
attr_reader :id
attr_reader :post_id
def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
def save; @id = 1; @post_id = 1 end
def new_record?; @id.nil? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
attr_accessor :relevances
def relevances_attributes=(attributes); end
end
class CommentRelevance
attr_reader :id
attr_reader :comment_id
def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
def save; @id = 1; @comment_id = 1 end
def new_record?; @id.nil? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
end
end
class Comment::Nested < Comment; end
class TagRelevance
attr_reader :id
attr_reader :tag_id
def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
def save; @id = 1; @tag_id = 1 end
def new_record?; @id.nil? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
end
class Author < Comment
attr_accessor :post
def post_attributes=(attributes); end
end
end
class FormHelperTest < ActionView::TestCase
tests ActionView::Helpers::FormHelper
@ -88,6 +145,27 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, "for" => "my_for"))
end
def test_label_with_id_attribute_as_symbol
assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
end
def test_label_with_id_attribute_as_string
assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
end
def test_label_with_for_and_id_attributes_as_symbol
assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
end
def test_label_with_for_and_id_attributes_as_string
assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
end
def test_label_for_radio_buttons_with_value
assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
end
def test_text_field
assert_dom_equal(
'<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
@ -160,36 +238,36 @@ class FormHelperTest < ActionView::TestCase
def test_check_box
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret")
)
@post.secret = 0
assert_dom_equal(
'<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret")
)
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret" ,{"checked"=>"checked"})
)
@post.secret = true
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret")
)
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret?")
)
@post.secret = ['0']
assert_dom_equal(
'<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret")
)
@post.secret = ['1']
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret")
)
end
@ -197,14 +275,14 @@ class FormHelperTest < ActionView::TestCase
def test_check_box_with_explicit_checked_and_unchecked_values
@post.secret = "on"
assert_dom_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" /><input name="post[secret]" type="hidden" value="off" />',
'<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
check_box("post", "secret", {}, "on", "off")
)
end
def test_checkbox_disabled_still_submits_checked_value
assert_dom_equal(
'<input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="1" />',
'<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret", { :disabled => :true })
)
end
@ -233,6 +311,16 @@ class FormHelperTest < ActionView::TestCase
)
end
def test_radio_button_with_booleans
assert_dom_equal('<input id="post_secret_true" name="post[secret]" type="radio" value="true" />',
radio_button("post", "secret", true)
)
assert_dom_equal('<input id="post_secret_false" name="post[secret]" type="radio" value="false" />',
radio_button("post", "secret", false)
)
end
def test_text_area
assert_dom_equal(
'<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
@ -279,7 +367,7 @@ class FormHelperTest < ActionView::TestCase
text_area("post", "body", "name" => "really!")
)
assert_dom_equal(
'<input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" /><input name="i mean it" type="hidden" value="0" />',
'<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
check_box("post", "secret", "name" => "i mean it")
)
assert_dom_equal text_field("post", "title", "name" => "dont guess"),
@ -299,7 +387,7 @@ class FormHelperTest < ActionView::TestCase
text_area("post", "body", "id" => "really!")
)
assert_dom_equal(
'<input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret", "id" => "i mean it")
)
assert_dom_equal text_field("post", "title", "id" => "dont guess"),
@ -324,7 +412,7 @@ class FormHelperTest < ActionView::TestCase
text_area("post[]", "body")
)
assert_dom_equal(
"<input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" /><input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" />",
"<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
check_box("post[]", "secret")
)
assert_dom_equal(
@ -350,8 +438,8 @@ class FormHelperTest < ActionView::TestCase
"<label for='post_title'>Title</label>" +
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='commit' id='post_submit' type='submit' value='Create post' />" +
"</form>"
@ -367,11 +455,11 @@ class FormHelperTest < ActionView::TestCase
expected =
"<form action='http://www.example.com' id='create-post' method='post'>" +
"<div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>" +
"<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"</form>"
assert_dom_equal expected, output_buffer
@ -388,8 +476,8 @@ class FormHelperTest < ActionView::TestCase
"<form action='http://www.example.com' id='create-post' method='post'>" +
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"</form>"
assert_dom_equal expected, output_buffer
@ -408,8 +496,8 @@ class FormHelperTest < ActionView::TestCase
"<label for=\"post_123_title\">Title</label>" +
"<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
"<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
"<input name='post[123][secret]' type='hidden' value='0' />" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
"</form>"
assert_dom_equal expected, output_buffer
@ -426,8 +514,8 @@ class FormHelperTest < ActionView::TestCase
"<form action='http://www.example.com' method='post'>" +
"<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
"<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
"<input name='post[][secret]' type='hidden' value='0' />" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
"</form>"
assert_dom_equal expected, output_buffer
@ -463,7 +551,7 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_index
def test_nested_fields_for_with_index_and_parent_fields
form_for('post', @post, :index => 1) do |c|
concat c.text_field(:title)
c.fields_for('comment', @comment, :index => 1) do |r|
@ -479,7 +567,7 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_index
def test_form_for_with_index_and_nested_fields_for
form_for(:post, @post, :index => 1) do |f|
f.fields_for(:comment, @post) do |c|
concat c.text_field(:title)
@ -521,6 +609,20 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_index_radio_button
form_for(:post, @post) do |f|
f.fields_for(:comment, @post, :index => 5) do |c|
concat c.radio_button(:title, "hello")
end
end
expected = "<form action='http://www.example.com' method='post'>" +
"<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" +
"</form>"
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_auto_index_on_both
form_for("post[]", @post) do |f|
f.fields_for("comment[]", @post) do |c|
@ -558,6 +660,283 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
@post.author = Author.new
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:author) do |af|
concat af.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
form_for(:post, @post) do |f|
f.fields_for(:author, Author.new(123)) do |af|
assert_not_nil af.object
assert_equal 123, af.object.id
end
end
end
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
@post.author = Author.new(321)
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:author) do |af|
concat af.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
@post.author = Author.new(321)
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:author) do |af|
concat af.hidden_field(:id)
concat af.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
form_for(:post, @post) do |f|
concat f.text_field(:title)
@post.comments.each do |comment|
f.fields_for(:comments, comment) do |cf|
concat cf.text_field(:name)
end
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
form_for(:post, @post) do |f|
concat f.text_field(:title)
@post.comments.each do |comment|
f.fields_for(:comments, comment) do |cf|
concat cf.hidden_field(:id)
concat cf.text_field(:name)
end
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
@post.comments = [Comment.new, Comment.new]
form_for(:post, @post) do |f|
concat f.text_field(:title)
@post.comments.each do |comment|
f.fields_for(:comments, comment) do |cf|
concat cf.text_field(:name)
end
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
@post.comments = [Comment.new(321), Comment.new]
form_for(:post, @post) do |f|
concat f.text_field(:title)
@post.comments.each do |comment|
f.fields_for(:comments, comment) do |cf|
concat cf.text_field(:name)
end
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_an_empty_supplied_attributes_collection
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, []) do |cf|
concat cf.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, @post.comments) do |cf|
concat cf.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
@post.comments = [Comment.new(321), Comment.new]
yielded_comments = []
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments) do |cf|
concat cf.text_field(:name)
yielded_comments << cf.object
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'
assert_dom_equal expected, output_buffer
assert_equal yielded_comments, @post.comments
end
def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
@post.comments = []
form_for(:post, @post) do |f|
f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf|
concat cf.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_uses_unique_indices_for_different_collection_associations
@post.comments = [Comment.new(321)]
@post.tags = [Tag.new(123), Tag.new(456)]
@post.comments[0].relevances = []
@post.tags[0].relevances = []
@post.tags[1].relevances = []
form_for(:post, @post) do |f|
f.fields_for(:comments, @post.comments[0]) do |cf|
concat cf.text_field(:name)
cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
concat crf.text_field(:value)
end
end
f.fields_for(:tags, @post.tags[0]) do |tf|
concat tf.text_field(:value)
tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
concat trf.text_field(:value)
end
end
f.fields_for('tags', @post.tags[1]) do |tf|
concat tf.text_field(:value)
tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
concat trf.text_field(:value)
end
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
'<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
'<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
'<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
'<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
'<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
'<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
'<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_fields_for
fields_for(:post, @post) do |f|
concat f.text_field(:title)
@ -568,8 +947,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -584,8 +963,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
"<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
"<input name='post[123][secret]' type='hidden' value='0' />"
"<input name='post[123][secret]' type='hidden' value='0' />" +
"<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -600,8 +979,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
"<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
"<input name='post[][secret]' type='hidden' value='0' />"
"<input name='post[][secret]' type='hidden' value='0' />" +
"<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -616,8 +995,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
"<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />" +
"<input name='post[abc][secret]' type='hidden' value='0' />"
"<input name='post[abc][secret]' type='hidden' value='0' />" +
"<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -632,8 +1011,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -648,8 +1027,8 @@ class FormHelperTest < ActionView::TestCase
expected =
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' />"
"<input name='post[secret]' type='hidden' value='0' />" +
"<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
assert_dom_equal expected, output_buffer
end
@ -694,8 +1073,8 @@ class FormHelperTest < ActionView::TestCase
"<form action='http://www.example.com' id='create-post' method='post'>" +
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
"<input name='parent_post[secret]' type='hidden' value='0' />" +
"<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
"</form>"
assert_dom_equal expected, output_buffer
@ -725,7 +1104,7 @@ class FormHelperTest < ActionView::TestCase
(field_helpers - %w(hidden_field)).each do |selector|
src = <<-END_SRC
def #{selector}(field, *args, &proc)
"<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>"
("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
end
END_SRC
class_eval src, __FILE__, __LINE__
@ -743,8 +1122,7 @@ class FormHelperTest < ActionView::TestCase
"<form action='http://www.example.com' method='post'>" +
"<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
"</form>"
assert_dom_equal expected, output_buffer
@ -764,8 +1142,7 @@ class FormHelperTest < ActionView::TestCase
"<form action='http://www.example.com' method='post'>" +
"<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
"</form>"
assert_dom_equal expected, output_buffer
@ -820,8 +1197,7 @@ class FormHelperTest < ActionView::TestCase
%(<form action="http://www.example.com" onsubmit="new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" method="post">) +
"<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' /><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
"</form>"
assert_dom_equal expected, output_buffer
@ -837,12 +1213,52 @@ class FormHelperTest < ActionView::TestCase
expected =
"<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
"<input name='post[secret]' type='hidden' value='0' /><br/>"
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
assert_dom_equal expected, output_buffer
end
def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
klass = nil
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
f.fields_for(:comments, Comment.new) do |nested_fields|
klass = nested_fields.class
''
end
end
assert_equal LabelledFormBuilder, klass
end
def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
klass = nil
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
klass = nested_fields.class
''
end
end
assert_equal LabelledFormBuilder, klass
end
class LabelledFormBuilderSubclass < LabelledFormBuilder; end
def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
klass = nil
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
klass = nested_fields.class
''
end
end
assert_equal LabelledFormBuilderSubclass, klass
end
def test_form_for_with_html_options_adds_options_to_form_tag
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
@ -873,7 +1289,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_existing_object
form_for(@post) do |f| end
expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
assert_equal expected, output_buffer
end
@ -894,7 +1310,7 @@ class FormHelperTest < ActionView::TestCase
form_for([@post, @comment]) {}
expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
assert_dom_equal expected, output_buffer
end
@ -913,7 +1329,7 @@ class FormHelperTest < ActionView::TestCase
form_for([:admin, @post, @comment]) {}
expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
assert_dom_equal expected, output_buffer
end
@ -929,7 +1345,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_existing_object_and_custom_url
form_for(@post, :url => "/super_posts") do |f| end
expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
assert_equal expected, output_buffer
end

View file

@ -0,0 +1,27 @@
require 'abstract_unit'
class FormOptionsHelperI18nTests < ActionView::TestCase
tests ActionView::Helpers::FormOptionsHelper
def setup
@prompt_message = 'Select!'
I18n.backend.send(:init_translations)
I18n.backend.store_translations :en, :support => { :select => { :prompt => @prompt_message } }
end
def teardown
I18n.backend = I18n::Backend::Simple.new
end
def test_select_with_prompt_true_translates_prompt_message
I18n.expects(:translate).with('support.select.prompt', { :default => 'Please select' })
select('post', 'category', [], :prompt => true)
end
def test_select_with_translated_prompt
assert_dom_equal(
%Q(<select id="post_category" name="post[category]"><option value="">#{@prompt_message}</option>\n</select>),
select('post', 'category', [], :prompt => true)
)
end
end

Some files were not shown because too many files have changed in this diff Show more