aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/rails-2.0.2/actionpack/test/controller
diff options
context:
space:
mode:
authorfrancis <francis>2008-01-23 01:48:14 +0000
committerfrancis <francis>2008-01-23 01:48:14 +0000
commit60eaae4f7df1f1dae91defb87d3707451c359cf4 (patch)
treee74835c37779a2f094e810960cda07b99a75330e /vendor/rails-2.0.2/actionpack/test/controller
parent71d22c740302e1f83bbbd89b229734ea9c67493c (diff)
Freeze in rails 2.0.2 (Am I going to regret having this beast in CVS?)
Diffstat (limited to 'vendor/rails-2.0.2/actionpack/test/controller')
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/action_pack_assertions_test.rb492
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/addresses_render_test.rb43
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/assert_select_test.rb682
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/base_test.rb134
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/benchmark_test.rb33
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/caching_test.rb349
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/capture_test.rb89
-rwxr-xr-xvendor/rails-2.0.2/actionpack/test/controller/cgi_test.rb115
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/components_test.rb140
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/content_type_test.rb139
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb0
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/user_controller.rb0
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb0
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/cookie_test.rb135
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/custom_handler_test.rb41
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb37
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/dispatcher_test.rb123
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/fake_controllers.rb16
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/fake_models.rb5
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/filter_params_test.rb43
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/filters_test.rb856
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/flash_test.rb146
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/fragment_store_setting_test.rb47
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/helper_test.rb206
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/document_test.rb124
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/node_test.rb69
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/sanitizer_test.rb250
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tag_node_test.rb239
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/text_node_test.rb51
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tokenizer_test.rb125
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/http_authentication_test.rb54
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/integration_test.rb255
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/layout_test.rb239
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/mime_responds_test.rb506
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/mime_type_test.rb55
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/new_render_test.rb832
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/polymorphic_routes_test.rb98
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/record_identifier_test.rb103
-rwxr-xr-xvendor/rails-2.0.2/actionpack/test/controller/redirect_test.rb258
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/render_test.rb464
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/request_forgery_protection_test.rb217
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/request_test.rb836
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/rescue_test.rb501
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/resources_test.rb787
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/routing_test.rb2203
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/selector_test.rb628
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/send_file_test.rb127
-rwxr-xr-xvendor/rails-2.0.2/actionpack/test/controller/session/cookie_store_test.rb246
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/session/mem_cache_store_test.rb182
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/session_fixation_test.rb89
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/session_management_test.rb156
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/test_test.rb623
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/url_rewriter_test.rb246
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/verification_test.rb253
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/view_paths_test.rb137
-rw-r--r--vendor/rails-2.0.2/actionpack/test/controller/webservice_test.rb184
56 files changed, 15008 insertions, 0 deletions
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/action_pack_assertions_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/action_pack_assertions_test.rb
new file mode 100644
index 000000000..1eb9610d0
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/action_pack_assertions_test.rb
@@ -0,0 +1,492 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+# a controller class to facilitate the tests
+class ActionPackAssertionsController < ActionController::Base
+
+ # this does absolutely nothing
+ def nothing() head :ok end
+
+ # a standard template
+ def hello_world() render :template => "test/hello_world"; end
+
+ # a standard template
+ def hello_xml_world() render :template => "test/hello_xml_world"; end
+
+ # a redirect to an internal location
+ def redirect_internal() redirect_to "/nothing"; end
+
+ def redirect_to_action() redirect_to :action => "flash_me", :id => 1, :params => { "panda" => "fun" }; end
+
+ def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end
+
+ def redirect_to_controller_with_symbol() redirect_to :controller => :elsewhere, :action => :flash_me; end
+
+ def redirect_to_path() redirect_to '/some/path' end
+
+ def redirect_to_named_route() redirect_to route_one_url end
+
+ # a redirect to an external location
+ def redirect_external() redirect_to "http://www.rubyonrails.org"; end
+
+ # a 404
+ def response404() head '404 AWOL' end
+
+ # a 500
+ def response500() head '500 Sorry' end
+
+ # a fictional 599
+ def response599() head '599 Whoah!' end
+
+ # putting stuff in the flash
+ def flash_me
+ flash['hello'] = 'my name is inigo montoya...'
+ render :text => "Inconceivable!"
+ end
+
+ # we have a flash, but nothing is in it
+ def flash_me_naked
+ flash.clear
+ render :text => "wow!"
+ end
+
+ # assign some template instance variables
+ def assign_this
+ @howdy = "ho"
+ render :inline => "Mr. Henke"
+ end
+
+ def render_based_on_parameters
+ render :text => "Mr. #{params[:name]}"
+ end
+
+ def render_url
+ render :text => "<div>#{url_for(:action => 'flash_me', :only_path => true)}</div>"
+ end
+
+ def render_text_with_custom_content_type
+ render :text => "Hello!", :content_type => Mime::RSS
+ end
+
+ # puts something in the session
+ def session_stuffing
+ session['xmas'] = 'turkey'
+ render :text => "ho ho ho"
+ end
+
+ # raises exception on get requests
+ def raise_on_get
+ raise "get" if request.get?
+ render :text => "request method: #{request.env['REQUEST_METHOD']}"
+ end
+
+ # raises exception on post requests
+ def raise_on_post
+ raise "post" if request.post?
+ render :text => "request method: #{request.env['REQUEST_METHOD']}"
+ end
+
+ def get_valid_record
+ @record = Class.new do
+ def valid?
+ true
+ end
+
+ def errors
+ Class.new do
+ def full_messages; []; end
+ end.new
+ end
+
+ end.new
+
+ render :nothing => true
+ end
+
+
+ def get_invalid_record
+ @record = Class.new do
+
+ def valid?
+ false
+ end
+
+ def errors
+ Class.new do
+ def full_messages; ['...stuff...']; end
+ end.new
+ end
+ end.new
+
+ render :nothing => true
+ end
+
+ # 911
+ def rescue_action(e) raise; end
+end
+
+module Admin
+ class InnerModuleController < ActionController::Base
+ def index
+ render :nothing => true
+ end
+
+ def redirect_to_index
+ redirect_to admin_inner_module_path
+ end
+
+ def redirect_to_absolute_controller
+ redirect_to :controller => '/content'
+ end
+
+ def redirect_to_fellow_controller
+ redirect_to :controller => 'user'
+ end
+
+ def redirect_to_top_level_named_route
+ redirect_to top_level_url(:id => "foo")
+ end
+ end
+end
+
+# ---------------------------------------------------------------------------
+
+
+# tell the controller where to find its templates but start from parent
+# directory of test_request_response to simulate the behaviour of a
+# production environment
+ActionPackAssertionsController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+# a test case to exercise the new capabilities TestRequest & TestResponse
+class ActionPackAssertionsControllerTest < Test::Unit::TestCase
+ # let's get this party started
+ def setup
+ ActionController::Routing::Routes.reload
+ ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module content admin/user))
+ @controller = ActionPackAssertionsController.new
+ @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
+ end
+
+ def teardown
+ ActionController::Routing::Routes.reload
+ end
+
+ # -- assertion-based testing ------------------------------------------------
+
+ def test_assert_tag_and_url_for
+ get :render_url
+ assert_tag :content => "/action_pack_assertions/flash_me"
+ end
+
+ # test the get method, make sure the request really was a get
+ def test_get
+ assert_raise(RuntimeError) { get :raise_on_get }
+ get :raise_on_post
+ assert_equal @response.body, 'request method: GET'
+ end
+
+ # test the get method, make sure the request really was a get
+ def test_post
+ assert_raise(RuntimeError) { post :raise_on_post }
+ post :raise_on_get
+ assert_equal @response.body, 'request method: POST'
+ end
+
+# the following test fails because the request_method is now cached on the request instance
+# test the get/post switch within one test action
+# def test_get_post_switch
+# post :raise_on_get
+# assert_equal @response.body, 'request method: POST'
+# get :raise_on_post
+# assert_equal @response.body, 'request method: GET'
+# post :raise_on_get
+# assert_equal @response.body, 'request method: POST'
+# get :raise_on_post
+# assert_equal @response.body, 'request method: GET'
+# end
+
+ # test the redirection to a named route
+ def test_assert_redirect_to_named_route
+ with_routing do |set|
+ set.draw do |map|
+ map.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing'
+ map.connect ':controller/:action/:id'
+ end
+ set.install_helpers
+
+ process :redirect_to_named_route
+ assert_redirected_to 'http://test.host/route_one'
+ assert_redirected_to route_one_url
+ assert_redirected_to :route_one_url
+ end
+ end
+
+ def test_assert_redirect_to_named_route_failure
+ with_routing do |set|
+ set.draw do |map|
+ map.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'one'
+ map.route_two 'route_two', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
+ map.connect ':controller/:action/:id'
+ end
+ process :redirect_to_named_route
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to 'http://test.host/route_two'
+ end
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
+ end
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to route_two_url
+ end
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to :route_two_url
+ end
+ end
+ end
+
+ def test_assert_redirect_to_nested_named_route
+ with_routing do |set|
+ set.draw do |map|
+ map.admin_inner_module 'admin/inner_module', :controller => 'admin/inner_module', :action => 'index'
+ map.connect ':controller/:action/:id'
+ end
+ @controller = Admin::InnerModuleController.new
+ process :redirect_to_index
+ # redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}>
+ assert_redirected_to admin_inner_module_path
+ end
+ end
+
+ def test_assert_redirected_to_top_level_named_route_from_nested_controller
+ with_routing do |set|
+ set.draw do |map|
+ map.top_level '/action_pack_assertions/:id', :controller => 'action_pack_assertions', :action => 'index'
+ map.connect ':controller/:action/:id'
+ end
+ @controller = Admin::InnerModuleController.new
+ process :redirect_to_top_level_named_route
+ # passes -> assert_redirected_to "http://test.host/action_pack_assertions/foo"
+ assert_redirected_to "/action_pack_assertions/foo"
+ end
+ end
+
+ # -- standard request/response object testing --------------------------------
+
+ # make sure that the template objects exist
+ def test_template_objects_alive
+ process :assign_this
+ assert !@response.has_template_object?('hi')
+ assert @response.has_template_object?('howdy')
+ end
+
+ # make sure we don't have template objects when we shouldn't
+ def test_template_object_missing
+ process :nothing
+ assert_nil @response.template_objects['howdy']
+ end
+
+ # check the empty flashing
+ def test_flash_me_naked
+ process :flash_me_naked
+ assert !@response.has_flash?
+ assert !@response.has_flash_with_contents?
+ end
+
+ # check if we have flash objects
+ def test_flash_haves
+ process :flash_me
+ assert @response.has_flash?
+ assert @response.has_flash_with_contents?
+ assert @response.has_flash_object?('hello')
+ end
+
+ # ensure we don't have flash objects
+ def test_flash_have_nots
+ process :nothing
+ assert !@response.has_flash?
+ assert !@response.has_flash_with_contents?
+ assert_nil @response.flash['hello']
+ end
+
+ # check if we were rendered by a file-based template?
+ def test_rendered_action
+ process :nothing
+ assert !@response.rendered_with_file?
+
+ process :hello_world
+ assert @response.rendered_with_file?
+ assert 'hello_world', @response.rendered_file
+ end
+
+ # check the redirection location
+ def test_redirection_location
+ process :redirect_internal
+ assert_equal 'http://test.host/nothing', @response.redirect_url
+
+ process :redirect_external
+ assert_equal 'http://www.rubyonrails.org', @response.redirect_url
+ end
+
+ def test_no_redirect_url
+ process :nothing
+ assert_nil @response.redirect_url
+ end
+
+
+ # check server errors
+ def test_server_error_response_code
+ process :response500
+ assert @response.server_error?
+
+ process :response599
+ assert @response.server_error?
+
+ process :response404
+ assert !@response.server_error?
+ end
+
+ # check a 404 response code
+ def test_missing_response_code
+ process :response404
+ assert @response.missing?
+ end
+
+ # check to see if our redirection matches a pattern
+ def test_redirect_url_match
+ process :redirect_external
+ assert @response.redirect?
+ assert @response.redirect_url_match?("rubyonrails")
+ assert @response.redirect_url_match?(/rubyonrails/)
+ assert !@response.redirect_url_match?("phpoffrails")
+ assert !@response.redirect_url_match?(/perloffrails/)
+ end
+
+ # check for a redirection
+ def test_redirection
+ process :redirect_internal
+ assert @response.redirect?
+
+ process :redirect_external
+ assert @response.redirect?
+
+ process :nothing
+ assert !@response.redirect?
+ end
+
+ # check a successful response code
+ def test_successful_response_code
+ process :nothing
+ assert @response.success?
+ end
+
+ # a basic check to make sure we have a TestResponse object
+ def test_has_response
+ process :nothing
+ assert_kind_of ActionController::TestResponse, @response
+ end
+
+ def test_render_based_on_parameters
+ process :render_based_on_parameters, "name" => "David"
+ assert_equal "Mr. David", @response.body
+ end
+
+ def test_follow_redirect
+ process :redirect_to_action
+ assert_redirected_to :action => "flash_me"
+
+ follow_redirect
+ assert_equal 1, @request.parameters["id"].to_i
+
+ assert "Inconceivable!", @response.body
+ end
+
+ def test_follow_redirect_outside_current_action
+ process :redirect_to_controller
+ assert_redirected_to :controller => "elsewhere", :action => "flash_me"
+
+ assert_raises(RuntimeError, "Can't follow redirects outside of current controller (elsewhere)") { follow_redirect }
+ end
+
+ def test_assert_redirection_fails_with_incorrect_controller
+ process :redirect_to_controller
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to :controller => "action_pack_assertions", :action => "flash_me"
+ end
+ end
+
+ def test_assert_redirection_with_extra_controller_option
+ get :redirect_to_action
+ assert_redirected_to :controller => 'action_pack_assertions', :action => "flash_me", :id => 1, :params => { :panda => 'fun' }
+ end
+
+ def test_redirected_to_url_leadling_slash
+ process :redirect_to_path
+ assert_redirected_to '/some/path'
+ end
+ def test_redirected_to_url_no_leadling_slash
+ process :redirect_to_path
+ assert_redirected_to 'some/path'
+ end
+ def test_redirected_to_url_full_url
+ process :redirect_to_path
+ assert_redirected_to 'http://test.host/some/path'
+ end
+
+ def test_assert_redirection_with_symbol
+ process :redirect_to_controller_with_symbol
+ assert_nothing_raised {
+ assert_redirected_to :controller => "elsewhere", :action => "flash_me"
+ }
+ process :redirect_to_controller_with_symbol
+ assert_nothing_raised {
+ assert_redirected_to :controller => :elsewhere, :action => :flash_me
+ }
+ end
+
+ def test_redirected_to_with_nested_controller
+ @controller = Admin::InnerModuleController.new
+ get :redirect_to_absolute_controller
+ assert_redirected_to :controller => 'content'
+
+ get :redirect_to_fellow_controller
+ assert_redirected_to :controller => 'admin/user'
+ end
+
+ def test_assert_valid
+ get :get_valid_record
+ assert_valid assigns('record')
+ end
+
+ def test_assert_valid_failing
+ get :get_invalid_record
+
+ begin
+ assert_valid assigns('record')
+ assert false
+ rescue Test::Unit::AssertionFailedError => e
+ end
+ end
+end
+
+class ActionPackHeaderTest < Test::Unit::TestCase
+ def setup
+ @controller = ActionPackAssertionsController.new
+ @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
+ end
+
+ def test_rendering_xml_sets_content_type
+ process :hello_xml_world
+ assert_equal('application/xml; charset=utf-8', @response.headers['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'])
+ 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']
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/addresses_render_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/addresses_render_test.rb
new file mode 100644
index 000000000..d1e9122dc
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/addresses_render_test.rb
@@ -0,0 +1,43 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class Address
+
+ def Address.count(conditions = nil, join = nil)
+ nil
+ end
+
+ def Address.find_all(arg1, arg2, arg3, arg4)
+ []
+ end
+
+ def self.find(*args)
+ []
+ end
+end
+
+class AddressesTestController < ActionController::Base
+ def self.controller_name; "addresses"; end
+ def self.controller_path; "addresses"; end
+end
+
+AddressesTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class AddressesTest < Test::Unit::TestCase
+ def setup
+ @controller = AddressesTestController.new
+
+ # 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
+
+ def test_list
+ get :list
+ assert_equal "We only need to get this far!", @response.body.chomp
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/assert_select_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/assert_select_test.rb
new file mode 100644
index 000000000..b0f3d6ced
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/assert_select_test.rb
@@ -0,0 +1,682 @@
+#--
+# Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
+# Under MIT and/or CC By license.
+#++
+
+require "#{File.dirname(__FILE__)}/../abstract_unit"
+require "#{File.dirname(__FILE__)}/fake_controllers"
+
+
+unless defined?(ActionMailer)
+ begin
+ $:.unshift(File.dirname(__FILE__) + "/../../../actionmailer/lib")
+ require 'action_mailer'
+ rescue LoadError
+ require 'rubygems'
+ gem 'actionmailer'
+ end
+end
+
+class AssertSelectTest < Test::Unit::TestCase
+ class AssertSelectController < ActionController::Base
+ def response_with=(content)
+ @content = content
+ end
+
+ def response_with(&block)
+ @update = block
+ end
+
+ def html()
+ render :text=>@content, :layout=>false, :content_type=>Mime::HTML
+ @content = nil
+ end
+
+ def rjs()
+ render :update do |page|
+ @update.call page
+ end
+ @update = nil
+ end
+
+ def xml()
+ render :text=>@content, :layout=>false, :content_type=>Mime::XML
+ @content = nil
+ end
+
+ def rescue_action(e)
+ raise e
+ 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
+
+ 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 = []
+ end
+
+
+ def teardown
+ ActionMailer::Base.deliveries.clear
+ end
+
+ def assert_failure(message, &block)
+ e = assert_raises(AssertionFailedError, &block)
+ assert_match(message, e.message) if Regexp === message
+ assert_equal(message, e.message) if String === message
+ end
+
+ #
+ # Test assert select.
+ #
+
+ def test_assert_select
+ render_html %Q{<div id="1"></div><div id="2"></div>}
+ assert_select "div", 2
+ assert_failure(/Expected at least 3 elements matching \"div\", found 2/) { assert_select "div", 3 }
+ assert_failure(/Expected at least 1 element matching \"p\", found 0/) { assert_select "p" }
+ end
+
+
+ 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 }
+ 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/ }
+ 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 }
+ # 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 }
+ end
+
+
+ def test_counts
+ render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
+ assert_nothing_raised { assert_select "div", 2 }
+ assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
+ assert_select "div", 3
+ end
+ assert_nothing_raised { assert_select "div", 1..2 }
+ assert_failure(/Expected between 3 and 4 elements matching \"div\", found 2/) do
+ assert_select "div", 3..4
+ end
+ assert_nothing_raised { assert_select "div", :count=>2 }
+ assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
+ assert_select "div", :count=>3
+ end
+ assert_nothing_raised { assert_select "div", :minimum=>1 }
+ assert_nothing_raised { assert_select "div", :minimum=>2 }
+ assert_failure(/Expected at least 3 elements matching \"div\", found 2/) do
+ assert_select "div", :minimum=>3
+ end
+ assert_nothing_raised { assert_select "div", :maximum=>2 }
+ assert_nothing_raised { assert_select "div", :maximum=>3 }
+ assert_failure(/Expected at most 1 element matching \"div\", found 2/) do
+ assert_select "div", :maximum=>1
+ end
+ assert_nothing_raised { assert_select "div", :minimum=>1, :maximum=>2 }
+ assert_failure(/Expected between 3 and 4 elements matching \"div\", found 2/) do
+ assert_select "div", :minimum=>3, :maximum=>4
+ end
+ end
+
+
+ def test_substitution_values
+ render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
+ assert_select "div#?", /\d+/ do |elements|
+ assert_equal 2, elements.size
+ end
+ assert_select "div" do
+ assert_select "div#?", /\d+/ do |elements|
+ assert_equal 2, elements.size
+ assert_select "#1"
+ assert_select "#2"
+ end
+ end
+ end
+
+
+ def test_nested_assert_select
+ render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
+ assert_select "div" do |elements|
+ assert_equal 2, elements.size
+ assert_select elements[0], "#1"
+ assert_select elements[1], "#2"
+ end
+ assert_select "div" do
+ assert_select "div" do |elements|
+ assert_equal 2, elements.size
+ # Testing in a group is one thing
+ assert_select "#1,#2"
+ # Testing individually is another.
+ assert_select "#1"
+ assert_select "#2"
+ assert_select "#3", false
+ end
+ end
+
+ assert_failure(/Expected at least 1 element matching \"#4\", found 0\./) do
+ assert_select "div" do
+ assert_select "#4"
+ end
+ end
+ end
+
+
+ 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 }
+ end
+ end
+
+
+ # With single result.
+ def test_assert_select_from_rjs_with_single_result
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
+ end
+ assert_select "div" do |elements|
+ assert elements.size == 2
+ assert_select "#1"
+ assert_select "#2"
+ end
+ assert_select "div#?", /\d+/ do |elements|
+ assert_select "#1"
+ assert_select "#2"
+ end
+ end
+
+ # With multiple results.
+ def test_assert_select_from_rjs_with_multiple_results
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ end
+ assert_select "div" do |elements|
+ assert elements.size == 2
+ assert_select "#1"
+ assert_select "#2"
+ end
+ end
+
+
+ #
+ # Test css_select.
+ #
+
+
+ def test_css_select
+ render_html %Q{<div id="1"></div><div id="2"></div>}
+ assert 2, css_select("div").size
+ assert 0, css_select("p").size
+ end
+
+
+ def test_nested_css_select
+ render_html %Q{<div id="1">foo</div><div id="2">foo</div>}
+ assert_select "div#?", /\d+/ do |elements|
+ assert_equal 1, css_select(elements[0], "div").size
+ assert_equal 1, css_select(elements[1], "div").size
+ end
+ assert_select "div" do
+ assert_equal 2, css_select("div").size
+ css_select("div").each do |element|
+ # Testing as a group is one thing
+ assert !css_select("#1,#2").empty?
+ # Testing individually is another
+ assert !css_select("#1").empty?
+ assert !css_select("#2").empty?
+ end
+ end
+ end
+
+
+ # With one result.
+ def test_css_select_from_rjs_with_single_result
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
+ end
+ assert_equal 2, css_select("div").size
+ assert_equal 1, css_select("#1").size
+ assert_equal 1, css_select("#2").size
+ end
+
+ # With multiple results.
+ def test_css_select_from_rjs_with_multiple_results
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ end
+
+ assert_equal 2, css_select("div").size
+ assert_equal 1, css_select("#1").size
+ assert_equal 1, css_select("#2").size
+ end
+
+
+ #
+ # Test assert_select_rjs.
+ #
+
+
+ # Test that we can pick up all statements in the result.
+ def test_assert_select_rjs_picks_up_all_statements
+ render_rjs do |page|
+ page.replace "test", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
+ end
+
+ found = false
+ assert_select_rjs do
+ assert_select "#1"
+ assert_select "#2"
+ assert_select "#3"
+ found = true
+ end
+ assert found
+ end
+
+ # 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 }
+ end
+
+ def test_assert_select_rjs_with_unicode
+ # Test that non-ascii characters (which are converted into \uXXXX in RJS) are decoded correctly.
+ render_rjs do |page|
+ page.replace "test", "<div id=\"1\">\343\203\201\343\202\261\343\203\203\343\203\210</div>"
+ end
+ assert_select_rjs do
+ assert_select "#1", :text => "\343\203\201\343\202\261\343\203\203\343\203\210"
+ assert_select "#1", "\343\203\201\343\202\261\343\203\203\343\203\210"
+ assert_select "#1", Regexp.new("\343\203\201..\343\203\210",0,'U')
+ assert_raises(AssertionFailedError) { assert_select "#1", Regexp.new("\343\203\201.\343\203\210",0,'U') }
+ end
+ end
+
+ def test_assert_select_rjs_with_id
+ # Test that we can pick up all statements in the result.
+ render_rjs do |page|
+ page.replace "test1", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
+ end
+ assert_select_rjs "test1" do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_select_rjs "test2" do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_select_rjs "test3" do
+ assert_select "div", 1
+ assert_select "#3"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs "test4" }
+ end
+
+
+ def test_assert_select_rjs_for_replace
+ render_rjs do |page|
+ page.replace "test1", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
+ end
+ # Replace.
+ assert_select_rjs :replace do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_select_rjs :replace, "test1" do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs :replace, "test2" }
+ # Replace HTML.
+ assert_select_rjs :replace_html do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_select_rjs :replace_html, "test2" do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
+ end
+
+ def test_assert_select_rjs_for_chained_replace
+ render_rjs do |page|
+ page['test1'].replace "<div id=\"1\">foo</div>"
+ page['test2'].replace_html "<div id=\"2\">foo</div>"
+ page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
+ end
+ # Replace.
+ assert_select_rjs :chained_replace do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_select_rjs :chained_replace, "test1" do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs :chained_replace, "test2" }
+ # Replace HTML.
+ assert_select_rjs :chained_replace_html do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_select_rjs :chained_replace_html, "test2" do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs :replace_html, "test1" }
+ end
+
+ # Simple remove
+ def test_assert_select_rjs_for_remove
+ render_rjs do |page|
+ page.remove "test1"
+ end
+
+ assert_select_rjs :remove, "test1"
+ end
+
+ def test_assert_select_rjs_for_remove_ignores_block
+ render_rjs do |page|
+ page.remove "test1"
+ end
+
+ assert_nothing_raised do
+ assert_select_rjs :remove, "test1" do
+ assert_select "p"
+ end
+ end
+ end
+
+ # Simple show
+ def test_assert_select_rjs_for_show
+ render_rjs do |page|
+ page.show "test1"
+ end
+
+ assert_select_rjs :show, "test1"
+ end
+
+ def test_assert_select_rjs_for_show_ignores_block
+ render_rjs do |page|
+ page.show "test1"
+ end
+
+ assert_nothing_raised do
+ assert_select_rjs :show, "test1" do
+ assert_select "p"
+ end
+ end
+ end
+
+ # Simple hide
+ def test_assert_select_rjs_for_hide
+ render_rjs do |page|
+ page.hide "test1"
+ end
+
+ assert_select_rjs :hide, "test1"
+ end
+
+ def test_assert_select_rjs_for_hide_ignores_block
+ render_rjs do |page|
+ page.hide "test1"
+ end
+
+ assert_nothing_raised do
+ assert_select_rjs :hide, "test1" do
+ assert_select "p"
+ end
+ end
+ end
+
+ # Simple toggle
+ def test_assert_select_rjs_for_toggle
+ render_rjs do |page|
+ page.toggle "test1"
+ end
+
+ assert_select_rjs :toggle, "test1"
+ end
+
+ def test_assert_select_rjs_for_toggle_ignores_block
+ render_rjs do |page|
+ page.toggle "test1"
+ end
+
+ assert_nothing_raised do
+ assert_select_rjs :toggle, "test1" do
+ assert_select "p"
+ end
+ end
+ end
+
+ # Non-positioned insert.
+ def test_assert_select_rjs_for_nonpositioned_insert
+ render_rjs do |page|
+ page.replace "test1", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
+ end
+ assert_select_rjs :insert_html do
+ assert_select "div", 1
+ assert_select "#3"
+ end
+ assert_select_rjs :insert_html, "test3" do
+ assert_select "div", 1
+ assert_select "#3"
+ end
+ assert_raises(AssertionFailedError) { assert_select_rjs :insert_html, "test1" }
+ end
+
+ # Positioned insert.
+ def test_assert_select_rjs_for_positioned_insert
+ render_rjs do |page|
+ page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
+ page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>"
+ page.insert_html :before, "test3", "<div id=\"3\">foo</div>"
+ page.insert_html :after, "test4", "<div id=\"4\">foo</div>"
+ end
+ assert_select_rjs :insert, :top do
+ assert_select "div", 1
+ assert_select "#1"
+ end
+ assert_select_rjs :insert, :bottom do
+ assert_select "div", 1
+ assert_select "#2"
+ end
+ assert_select_rjs :insert, :before do
+ assert_select "div", 1
+ assert_select "#3"
+ end
+ assert_select_rjs :insert, :after do
+ assert_select "div", 1
+ assert_select "#4"
+ end
+ assert_select_rjs :insert_html do
+ assert_select "div", 4
+ end
+ end
+
+ # Simple selection from a single result.
+ def test_nested_assert_select_rjs_with_single_result
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
+ end
+
+ assert_select_rjs "test" do |elements|
+ assert_equal 2, elements.size
+ assert_select "#1"
+ assert_select "#2"
+ end
+ end
+
+ # Deal with two results.
+ def test_nested_assert_select_rjs_with_two_results
+ render_rjs do |page|
+ page.replace_html "test", "<div id=\"1\">foo</div>"
+ page.replace_html "test2", "<div id=\"2\">foo</div>"
+ end
+
+ assert_select_rjs "test" do |elements|
+ assert_equal 1, elements.size
+ assert_select "#1"
+ end
+
+ assert_select_rjs "test2" do |elements|
+ assert_equal 1, elements.size
+ assert_select "#2"
+ end
+ end
+
+
+ def test_feed_item_encoded
+ render_xml <<-EOF
+<rss version="2.0">
+ <channel>
+ <item>
+ <description>
+ <![CDATA[
+ <p>Test 1</p>
+ ]]>
+ </description>
+ </item>
+ <item>
+ <description>
+ <![CDATA[
+ <p>Test 2</p>
+ ]]>
+ </description>
+ </item>
+ </channel>
+</rss>
+EOF
+ assert_select "channel item description" do
+ # Test element regardless of wrapper.
+ assert_select_encoded do
+ assert_select "p", :count=>2, :text=>/Test/
+ end
+ # Test through encoded wrapper.
+ assert_select_encoded do
+ assert_select "encoded p", :count=>2, :text=>/Test/
+ end
+ # Use :root instead (recommended)
+ assert_select_encoded do
+ assert_select ":root p", :count=>2, :text=>/Test/
+ end
+ # Test individually.
+ assert_select "description" do |elements|
+ assert_select_encoded elements[0] do
+ assert_select "p", "Test 1"
+ end
+ assert_select_encoded elements[1] do
+ assert_select "p", "Test 2"
+ end
+ end
+ end
+
+ # Test that we only un-encode element itself.
+ assert_select "channel item" do
+ assert_select_encoded do
+ assert_select "p", 0
+ end
+ end
+ end
+
+
+ #
+ # Test assert_select_email
+ #
+
+ def test_assert_select_email
+ assert_raises(AssertionFailedError) { assert_select_email {} }
+ AssertSelectMailer.deliver_test "<div><p>foo</p><p>bar</p></div>"
+ assert_select_email do
+ assert_select "div:root" do
+ assert_select "p:first-child", "foo"
+ assert_select "p:last-child", "bar"
+ end
+ end
+ end
+
+
+ protected
+ def render_html(html)
+ @controller.response_with = html
+ get :html
+ end
+
+ def render_rjs(&block)
+ @controller.response_with &block
+ get :rjs
+ end
+
+ def render_xml(xml)
+ @controller.response_with = xml
+ get :xml
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/base_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/base_test.rb
new file mode 100644
index 000000000..60e61b628
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/base_test.rb
@@ -0,0 +1,134 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require 'test/unit'
+require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
+
+# Provide some controller to run the tests on.
+module Submodule
+ class ContainedEmptyController < ActionController::Base
+ end
+ class ContainedNonEmptyController < ActionController::Base
+ def public_action
+ end
+
+ hide_action :hidden_action
+ def hidden_action
+ raise "Noooo!"
+ end
+
+ def another_hidden_action
+ end
+ hide_action :another_hidden_action
+ end
+ class SubclassedController < ContainedNonEmptyController
+ hide_action :public_action # Hiding it here should not affect the superclass.
+ end
+end
+class EmptyController < ActionController::Base
+end
+class NonEmptyController < ActionController::Base
+ def public_action
+ end
+
+ hide_action :hidden_action
+ def hidden_action
+ end
+end
+
+class MethodMissingController < ActionController::Base
+
+ hide_action :shouldnt_be_called
+ def shouldnt_be_called
+ raise "NO WAY!"
+ end
+
+protected
+
+ def method_missing(selector)
+ render :text => selector.to_s
+ end
+
+end
+
+class ControllerClassTests < Test::Unit::TestCase
+ def test_controller_path
+ assert_equal 'empty', EmptyController.controller_path
+ assert_equal EmptyController.controller_path, EmptyController.new.controller_path
+ assert_equal 'submodule/contained_empty', Submodule::ContainedEmptyController.controller_path
+ assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path
+ end
+ def test_controller_name
+ assert_equal 'empty', EmptyController.controller_name
+ assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name
+ end
+end
+
+class ControllerInstanceTests < Test::Unit::TestCase
+ def setup
+ @empty = EmptyController.new
+ @contained = Submodule::ContainedEmptyController.new
+ @empty_controllers = [@empty, @contained, Submodule::SubclassedController.new]
+
+ @non_empty_controllers = [NonEmptyController.new,
+ Submodule::ContainedNonEmptyController.new]
+ end
+
+ def test_action_methods
+ @empty_controllers.each do |c|
+ hide_mocha_methods_from_controller(c)
+ assert_equal Set.new, c.send!(:action_methods), "#{c.controller_path} should be empty!"
+ end
+ @non_empty_controllers.each do |c|
+ hide_mocha_methods_from_controller(c)
+ assert_equal Set.new(%w(public_action)), c.send!(:action_methods), "#{c.controller_path} should not be empty!"
+ end
+ end
+
+ protected
+ # Mocha adds some public instance methods to Object that would be
+ # considered actions, so explicitly hide_action them.
+ def hide_mocha_methods_from_controller(controller)
+ mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__]
+ controller.class.send!(:hide_action, *mocha_methods)
+ end
+end
+
+
+class PerformActionTest < Test::Unit::TestCase
+ def use_controller(controller_class)
+ @controller = controller_class.new
+
+ # 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
+
+ def test_get_on_priv_should_show_selector
+ use_controller MethodMissingController
+ get :shouldnt_be_called
+ assert_response :success
+ assert_equal 'shouldnt_be_called', @response.body
+ end
+
+ def test_method_missing_is_not_an_action_name
+ use_controller MethodMissingController
+ assert ! @controller.send!(:action_methods).include?('method_missing')
+
+ get :method_missing
+ assert_response :success
+ assert_equal 'method_missing', @response.body
+ end
+
+ def test_get_on_hidden_should_fail
+ use_controller NonEmptyController
+ get :hidden_action
+ assert_response 404
+
+ get :another_hidden_action
+ assert_response 404
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/benchmark_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/benchmark_test.rb
new file mode 100644
index 000000000..f346e575e
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/benchmark_test.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require 'test/unit'
+
+# Provide some static controllers.
+class BenchmarkedController < ActionController::Base
+ def public_action
+ render :nothing => true
+ end
+
+ def rescue_action(e)
+ raise e
+ end
+end
+
+class BenchmarkTest < Test::Unit::TestCase
+ 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
+
+ def test_with_http_1_0_request
+ @request.host = nil
+ assert_nothing_raised { get :public_action }
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/caching_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/caching_test.rb
new file mode 100644
index 000000000..d6982fbc8
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/caching_test.rb
@@ -0,0 +1,349 @@
+require 'fileutils'
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+CACHE_DIR = 'test_cache'
+# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
+FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
+ActionController::Base.page_cache_directory = FILE_STORE_PATH
+ActionController::Base.fragment_cache_store = :file_store, FILE_STORE_PATH
+
+class PageCachingTestController < ActionController::Base
+ caches_page :ok, :no_content, :found, :not_found
+
+ def ok
+ head :ok
+ end
+
+ def no_content
+ head :no_content
+ end
+
+ def found
+ redirect_to :action => 'ok'
+ end
+
+ def not_found
+ head :not_found
+ end
+
+ def custom_path
+ render :text => "Super soaker"
+ cache_page("Super soaker", "/index.html")
+ end
+
+ def expire_custom_path
+ expire_page("/index.html")
+ head :ok
+ end
+
+ def trailing_slash
+ render :text => "Sneak attack"
+ end
+end
+
+class PageCachingTest < Test::Unit::TestCase
+ def setup
+ ActionController::Base.perform_caching = true
+
+ ActionController::Routing::Routes.draw do |map|
+ map.main '', :controller => 'posts'
+ map.resources :posts
+ map.connect ':controller/:action/:id'
+ end
+
+ @request = ActionController::TestRequest.new
+ @request.host = 'hostname.com'
+
+ @response = ActionController::TestResponse.new
+ @controller = PageCachingTestController.new
+
+ @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true}
+ @rewriter = ActionController::UrlRewriter.new(@request, @params)
+
+ FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
+ FileUtils.mkdir_p(FILE_STORE_PATH)
+ end
+
+ def teardown
+ FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
+
+ ActionController::Base.perform_caching = false
+ end
+
+ def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
+ @params[:format] = 'rss'
+ assert_equal '/posts.rss', @rewriter.rewrite(@params)
+ @params[:format] = nil
+ assert_equal '/', @rewriter.rewrite(@params)
+ end
+
+ def test_should_cache_get_with_ok_status
+ get :ok
+ assert_response :ok
+ assert_page_cached :ok, "get with ok status should have been cached"
+ end
+
+ def test_should_cache_with_custom_path
+ get :custom_path
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
+ end
+
+ def test_should_expire_cache_with_custom_path
+ get :custom_path
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
+
+ get :expire_custom_path
+ assert !File.exist?("#{FILE_STORE_PATH}/index.html")
+ end
+
+ def test_should_cache_without_trailing_slash_on_url
+ @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash'
+ assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
+ end
+
+ def test_should_cache_with_trailing_slash_on_url
+ @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash/'
+ 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.expects(:path).returns("/index.html")
+ get :ok
+ assert_response :ok
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
+ end
+ 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
+ assert_response status
+ assert_page_not_cached status, "#{method} with #{status} status shouldn't have been cached"
+ end
+ end
+ end
+ end
+
+ private
+ def assert_page_cached(action, message = "#{action} should have been cached")
+ assert page_cached?(action), message
+ end
+
+ def assert_page_not_cached(action, message = "#{action} shouldn't have been cached")
+ assert !page_cached?(action), message
+ end
+
+ def page_cached?(action)
+ File.exist? "#{FILE_STORE_PATH}/page_caching_test/#{action}.html"
+ end
+end
+
+
+class ActionCachingTestController < ActionController::Base
+ caches_action :index, :redirected, :forbidden
+ caches_action :show, :cache_path => 'http://test.host/custom/show'
+ caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
+
+ def index
+ @cache_this = Time.now.to_f.to_s
+ render :text => @cache_this
+ end
+
+ def redirected
+ redirect_to :action => 'index'
+ end
+
+ def forbidden
+ render :text => "Forbidden"
+ headers["Status"] = "403 Forbidden"
+ end
+
+ alias_method :show, :index
+ alias_method :edit, :index
+
+ def expire
+ expire_action :controller => 'action_caching_test', :action => 'index'
+ render :nothing => true
+ end
+
+end
+
+class ActionCachingMockController
+ attr_accessor :mock_url_for
+ attr_accessor :mock_path
+
+ def initialize
+ yield self if block_given?
+ end
+
+ def url_for(*args)
+ @mock_url_for
+ end
+
+ def request
+ mocked_path = @mock_path
+ Object.new.instance_eval(<<-EVAL)
+ def path; '#{@mock_path}' end
+ self
+ EVAL
+ end
+end
+
+class ActionCacheTest < Test::Unit::TestCase
+ def setup
+ reset!
+ FileUtils.mkdir_p(FILE_STORE_PATH)
+ @path_class = ActionController::Caching::Actions::ActionCachePath
+ @mock_controller = ActionCachingMockController.new
+ end
+
+ def teardown
+ FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
+ end
+
+ def test_simple_action_cache
+ get :index
+ cached_time = content_to_cache
+ assert_equal cached_time, @response.body
+ assert_cache_exists 'hostname.com/action_caching_test'
+ reset!
+
+ get :index
+ assert_equal cached_time, @response.body
+ end
+
+ def test_action_cache_with_custom_cache_path
+ get :show
+ cached_time = content_to_cache
+ assert_equal cached_time, @response.body
+ assert_cache_exists 'test.host/custom/show'
+ reset!
+
+ get :show
+ assert_equal cached_time, @response.body
+ end
+
+ def test_action_cache_with_custom_cache_path_in_block
+ get :edit
+ assert_cache_exists 'test.host/edit'
+ reset!
+
+ get :edit, :id => 1
+ assert_cache_exists 'test.host/1;edit'
+ end
+
+ def test_cache_expiration
+ get :index
+ cached_time = content_to_cache
+ reset!
+
+ get :index
+ assert_equal cached_time, @response.body
+ reset!
+
+ get :expire
+ reset!
+
+ get :index
+ new_cached_time = content_to_cache
+ assert_not_equal cached_time, @response.body
+ reset!
+
+ get :index
+ assert_response :success
+ assert_equal new_cached_time, @response.body
+ end
+
+ def test_cache_is_scoped_by_subdomain
+ @request.host = 'jamis.hostname.com'
+ get :index
+ jamis_cache = content_to_cache
+
+ reset!
+
+ @request.host = 'david.hostname.com'
+ get :index
+ david_cache = content_to_cache
+ assert_not_equal jamis_cache, @response.body
+
+ reset!
+
+ @request.host = 'jamis.hostname.com'
+ get :index
+ assert_equal jamis_cache, @response.body
+
+ reset!
+
+ @request.host = 'david.hostname.com'
+ get :index
+ assert_equal david_cache, @response.body
+ end
+
+ def test_redirect_is_not_cached
+ get :redirected
+ assert_response :redirect
+ reset!
+
+ get :redirected
+ assert_response :redirect
+ end
+
+ def test_forbidden_is_not_cached
+ get :forbidden
+ assert_response :forbidden
+ reset!
+
+ get :forbidden
+ assert_response :forbidden
+ end
+
+ def test_xml_version_of_resource_is_treated_as_different_cache
+ @mock_controller.mock_url_for = 'http://example.org/posts/'
+ @mock_controller.mock_path = '/posts/index.xml'
+ path_object = @path_class.new(@mock_controller, {})
+ assert_equal 'xml', path_object.extension
+ assert_equal 'example.org/posts/index.xml', path_object.path
+ end
+
+ def test_correct_content_type_is_returned_for_cache_hit
+ # run it twice to cache it the first time
+ get :index, :id => 'content-type.xml'
+ get :index, :id => 'content-type.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 = '/'
+
+ assert_equal 'example.org/index', @path_class.path_for(@mock_controller, {})
+ end
+
+ def test_file_extensions
+ get :index, :id => 'kitten.jpg'
+ get :index, :id => 'kitten.jpg'
+
+ assert_response :success
+ end
+
+ private
+ def content_to_cache
+ assigns(:cache_this)
+ end
+
+ def reset!
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @controller = ActionCachingTestController.new
+ @request.host = 'hostname.com'
+ end
+
+ def assert_cache_exists(path)
+ full_path = File.join(FILE_STORE_PATH, path + '.cache')
+ assert File.exist?(full_path), "#{full_path.inspect} does not exist."
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/capture_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/capture_test.rb
new file mode 100644
index 000000000..7ec5f32a3
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/capture_test.rb
@@ -0,0 +1,89 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class CaptureController < ActionController::Base
+ def self.controller_name; "test"; end
+ def self.controller_path; "test"; end
+
+ def content_for
+ render :layout => "talk_from_action"
+ end
+
+ def content_for_with_parameter
+ render :layout => "talk_from_action"
+ end
+
+ def content_for_concatenated
+ render :layout => "talk_from_action"
+ end
+
+ def erb_content_for
+ render :layout => "talk_from_action"
+ end
+
+ def block_content_for
+ render :layout => "talk_from_action"
+ end
+
+ def non_erb_block_content_for
+ render :layout => "talk_from_action"
+ end
+
+ def rescue_action(e) raise end
+end
+
+CaptureController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class CaptureTest < Test::Unit::TestCase
+ def setup
+ @controller = CaptureController.new
+
+ # 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
+
+ def test_simple_capture
+ get :capturing
+ assert_equal "Dreamy days", @response.body.strip
+ end
+
+ def test_content_for
+ get :content_for
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ def test_should_concatentate_content_for
+ get :content_for_concatenated
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ def test_erb_content_for
+ get :erb_content_for
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ def test_should_set_content_for_with_parameter
+ get :content_for_with_parameter
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ def test_block_content_for
+ get :block_content_for
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ def test_non_erb_block_content_for
+ get :non_erb_block_content_for
+ assert_equal expected_content_for_output, @response.body
+ end
+
+ private
+ def expected_content_for_output
+ "<title>Putting stuff in the title!</title>\n\nGreat stuff!"
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/cgi_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/cgi_test.rb
new file mode 100755
index 000000000..021781df9
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/cgi_test.rb
@@ -0,0 +1,115 @@
+require File.dirname(__FILE__) + '/../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", "HTTP_X_FORWARDED_HOST"=>"glu.ttono.us", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.5.1 (KHTML, like Gecko) Safari/312.3.1", "PATH_INFO"=>"", "HTTP_ACCEPT_LANGUAGE"=>"en", "HTTP_HOST"=>"glu.ttono.us:8007", "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", "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", "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"}
+ # cookie as returned by some Nokia phone browsers (no space after semicolon separator)
+ @alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace84796670c052c6ceb2451fb0f2;is_admin=yes"}
+ @fake_cgi = Struct.new(:env_table).new(@request_hash)
+ @request = ActionController::CgiRequest.new(@fake_cgi)
+ end
+
+ def default_test; 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
+ 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_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 ["c84ace84796670c052c6ceb2451fb0f2"], 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
+ data = 'flamenco=love'
+ @request.env['CONTENT_LENGTH'] = data.length
+ @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
+ @request.env['RAW_POST_DATA'] = data
+ 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 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
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/components_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/components_test.rb
new file mode 100644
index 000000000..debd8a274
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/components_test.rb
@@ -0,0 +1,140 @@
+require File.dirname(__FILE__) + '/../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
+ get :calling_from_controller
+ assert_equal "Lady of the House, speaking", @response.body
+ end
+
+ def test_calling_from_controller_with_params
+ get :calling_from_controller_with_params
+ assert_equal "David of the House, speaking", @response.body
+ end
+
+ def test_calling_from_controller_with_different_status_code
+ get :calling_from_controller_with_different_status_code
+ assert_equal 500, @response.response_code
+ end
+
+ def test_calling_from_template
+ get :calling_from_template
+ assert_equal "Ring, ring: Lady of the House, speaking", @response.body
+ end
+
+ def test_etag_is_set_for_parent_template_when_calling_from_template
+ get :calling_from_template
+ expected_etag = etag_for("Ring, ring: Lady of the House, speaking")
+ assert_equal expected_etag, @response.headers['ETag']
+ end
+
+ def test_internal_calling
+ get :internal_caller
+ assert_equal "Are you there? Yes, ma'am", @response.body
+ end
+
+ def test_flash
+ 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
+
+ def test_component_redirect_redirects
+ get :calling_redirected
+
+ assert_redirected_to :action => "being_called"
+ end
+
+ def test_component_multiple_redirect_redirects
+ test_component_redirect_redirects
+ test_internal_calling
+ end
+
+ def test_component_as_string_redirect_renders_redirected_action
+ get :calling_redirected_as_string
+
+ assert_equal "Lady of the House, speaking", @response.body
+ end
+
+ protected
+ def etag_for(text)
+ %("#{Digest::MD5.hexdigest(text)}")
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/content_type_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/content_type_test.rb
new file mode 100644
index 000000000..1841d37c0
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/content_type_test.rb
@@ -0,0 +1,139 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class ContentTypeController < ActionController::Base
+ def render_content_type_from_body
+ response.content_type = Mime::RSS
+ render :text => "hello world!"
+ end
+
+ def render_defaults
+ render :text => "hello world!"
+ end
+
+ def render_content_type_from_render
+ render :text => "hello world!", :content_type => Mime::RSS
+ end
+
+ def render_charset_from_body
+ response.charset = "utf-16"
+ render :text => "hello world!"
+ end
+
+ def render_default_for_rhtml
+ end
+
+ def render_default_for_rxml
+ end
+
+ def render_default_for_rjs
+ end
+
+ def render_change_for_rxml
+ response.content_type = Mime::HTML
+ render :action => "render_default_for_rxml"
+ end
+
+ def render_default_content_types_for_respond_to
+ respond_to do |format|
+ format.html { render :text => "hello world!" }
+ format.xml { render :action => "render_default_content_types_for_respond_to.rhtml" }
+ format.js { render :text => "hello world!" }
+ format.rss { render :text => "hello world!", :content_type => Mime::XML }
+ end
+ end
+
+ def rescue_action(e) raise end
+end
+
+ContentTypeController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class ContentTypeTest < Test::Unit::TestCase
+ def setup
+ @controller = ContentTypeController.new
+
+ # 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
+ get :render_defaults
+ assert_equal "utf-8", @response.charset
+ assert_equal Mime::HTML, @response.content_type
+ end
+
+ def test_render_changed_charset_default
+ ContentTypeController.default_charset = "utf-16"
+ get :render_defaults
+ assert_equal "utf-16", @response.charset
+ assert_equal Mime::HTML, @response.content_type
+ ContentTypeController.default_charset = "utf-8"
+ end
+
+ def test_content_type_from_body
+ get :render_content_type_from_body
+ assert_equal "application/rss+xml", @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_content_type_from_render
+ get :render_content_type_from_render
+ assert_equal "application/rss+xml", @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_charset_from_body
+ get :render_charset_from_body
+ assert_equal "utf-16", @response.charset
+ assert_equal Mime::HTML, @response.content_type
+ end
+
+ def test_default_for_rhtml
+ get :render_default_for_rhtml
+ assert_equal Mime::HTML, @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_default_for_rxml
+ get :render_default_for_rxml
+ assert_equal Mime::XML, @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_default_for_rjs
+ xhr :post, :render_default_for_rjs
+ assert_equal Mime::JS, @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_change_for_rxml
+ get :render_change_for_rxml
+ assert_equal Mime::HTML, @response.content_type
+ assert_equal "utf-8", @response.charset
+ end
+
+ def test_render_default_content_types_for_respond_to
+ @request.env["HTTP_ACCEPT"] = Mime::HTML.to_s
+ get :render_default_content_types_for_respond_to
+ assert_equal Mime::HTML, @response.content_type
+
+ @request.env["HTTP_ACCEPT"] = Mime::JS.to_s
+ get :render_default_content_types_for_respond_to
+ assert_equal Mime::JS, @response.content_type
+ end
+
+ def test_render_default_content_types_for_respond_to_with_template
+ @request.env["HTTP_ACCEPT"] = Mime::XML.to_s
+ get :render_default_content_types_for_respond_to
+ assert_equal Mime::XML, @response.content_type
+ end
+
+ def test_render_default_content_types_for_respond_to_with_overwrite
+ @request.env["HTTP_ACCEPT"] = Mime::RSS.to_s
+ get :render_default_content_types_for_respond_to
+ assert_equal Mime::XML, @response.content_type
+ end
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/user_controller.rb b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/user_controller.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/app/controllers/user_controller.rb
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/cookie_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/cookie_test.rb
new file mode 100644
index 000000000..6a833fee3
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/cookie_test.rb
@@ -0,0 +1,135 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class CookieTest < Test::Unit::TestCase
+ class TestController < ActionController::Base
+ def authenticate
+ cookies["user_name"] = "david"
+ end
+
+ def authenticate_for_fourteen_days
+ cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
+ end
+
+ def authenticate_for_fourteen_days_with_symbols
+ cookies[:user_name] = { :value => "david", :expires => Time.local(2005, 10, 10) }
+ end
+
+ def set_multiple_cookies
+ cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
+ cookies["login"] = "XJ-122"
+ end
+
+ def access_frozen_cookies
+ cookies["will"] = "work"
+ end
+
+ def logout
+ cookies.delete("user_name")
+ end
+
+ def delete_cookie_with_path
+ cookies.delete("user_name", :path => '/beaten')
+ render :text => "hello world"
+ end
+
+ def authenticate_with_http_only
+ cookies["user_name"] = { :value => "david", :http_only => true }
+ end
+
+ def rescue_action(e)
+ raise unless ActionController::MissingTemplate # No templates here, and we don't care about the output
+ end
+ end
+
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @controller = TestController.new
+ @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"]
+ 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"]
+ end
+
+ def test_setting_cookie_for_fourteen_days_with_symbols
+ get :authenticate_for_fourteen_days
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"]
+ 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
+ end
+
+ def test_multiple_cookies
+ get :set_multiple_cookies
+ assert_equal 2, @response.cookies.size
+ 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"]
+ end
+
+ def test_cookiejar_accessor
+ @request.cookies["user_name"] = CGI::Cookie.new("name" => "user_name", "value" => "david", "expires" => Time.local(2025, 10, 10))
+ @controller.request = @request
+ jar = ActionController::CookieJar.new(@controller)
+ assert_equal "david", jar["user_name"]
+ assert_equal nil, jar["something_else"]
+ 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))
+ @controller.request = @request
+ jar = ActionController::CookieJar.new(@controller)
+ assert_equal a, jar["pages"]
+ 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
+ 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
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/custom_handler_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/custom_handler_test.rb
new file mode 100644
index 000000000..2747a0f3c
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/custom_handler_test.rb
@@ -0,0 +1,41 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class CustomHandler
+ def initialize( view )
+ @view = view
+ end
+
+ def render( template, local_assigns )
+ [ template,
+ local_assigns,
+ @view ]
+ end
+end
+
+class CustomHandlerTest < Test::Unit::TestCase
+ def setup
+ ActionView::Base.register_template_handler "foo", CustomHandler
+ ActionView::Base.register_template_handler :foo2, CustomHandler
+ @view = ActionView::Base.new
+ end
+
+ def test_custom_render
+ result = @view.render_template( "foo", "hello <%= one %>", nil, :one => "two" )
+ assert_equal(
+ [ "hello <%= one %>", { :one => "two" }, @view ],
+ result )
+ end
+
+ def test_custom_render2
+ result = @view.render_template( "foo2", "hello <%= one %>", nil, :one => "two" )
+ assert_equal(
+ [ "hello <%= one %>", { :one => "two" }, @view ],
+ result )
+ end
+
+ def test_unhandled_extension
+ # uses the ERb handler by default if the extension isn't recognized
+ result = @view.render_template( "bar", "hello <%= one %>", nil, :one => "two" )
+ assert_equal "hello two", result
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb
new file mode 100644
index 000000000..6d7157e1a
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb
@@ -0,0 +1,37 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+
+class DeprecatedBaseMethodsTest < Test::Unit::TestCase
+ class Target < ActionController::Base
+
+ def home_url(greeting)
+ "http://example.com/#{greeting}"
+ end
+
+ def raises_name_error
+ this_method_doesnt_exist
+ end
+
+ def rescue_action(e) raise e end
+ end
+
+ Target.view_paths = [ File.dirname(__FILE__) + "/../../fixtures" ]
+
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @controller = Target.new
+ end
+
+ def test_log_error_silences_deprecation_warnings
+ get :raises_name_error
+ rescue => e
+ 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 }
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/dispatcher_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/dispatcher_test.rb
new file mode 100644
index 000000000..ec937ebfd
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/dispatcher_test.rb
@@ -0,0 +1,123 @@
+require "#{File.dirname(__FILE__)}/../abstract_unit"
+
+uses_mocha 'dispatcher tests' do
+
+require 'action_controller/dispatcher'
+
+class DispatcherTest < Test::Unit::TestCase
+ Dispatcher = ActionController::Dispatcher
+
+ def setup
+ @output = StringIO.new
+ ENV['REQUEST_METHOD'] = 'GET'
+
+ Dispatcher.callbacks[:prepare].clear
+ @dispatcher = Dispatcher.new(@output)
+ end
+
+ def teardown
+ ENV['REQUEST_METHOD'] = nil
+ end
+
+ def test_clears_dependencies_after_dispatch_if_in_loading_mode
+ Dependencies.stubs(:load?).returns(true)
+
+ ActionController::Routing::Routes.expects(:reload).once
+ Dependencies.expects(:clear).once
+
+ dispatch
+ end
+
+ def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
+ Dependencies.stubs(:load?).returns(false)
+
+ ActionController::Routing::Routes.expects(:reload).never
+ Dependencies.expects(:clear).never
+
+ dispatch
+ end
+
+ def test_failsafe_response
+ CGI.expects(:new).raises('some multipart parsing failure')
+
+ ActionController::Routing::Routes.stubs(:reload)
+ Dispatcher.stubs(: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
+ end
+
+ def test_reload_application_sets_unprepared_if_loading_dependencies
+ Dependencies.stubs(:load?).returns(false)
+ ActionController::Routing::Routes.expects(:reload).never
+ @dispatcher.unprepared = false
+ @dispatcher.send!(:reload_application)
+ assert !@dispatcher.unprepared
+
+ Dependencies.stubs(:load?).returns(true)
+ ActionController::Routing::Routes.expects(:reload).once
+ @dispatcher.send!(:reload_application)
+ assert @dispatcher.unprepared
+ end
+
+ def test_prepare_application_runs_callbacks_if_unprepared
+ a = b = c = nil
+ Dispatcher.to_prepare { a = b = c = 1 }
+ Dispatcher.to_prepare { b = c = 2 }
+ Dispatcher.to_prepare { c = 3 }
+
+ # Skip the callbacks when already prepared.
+ @dispatcher.unprepared = false
+ @dispatcher.send! :prepare_application
+ assert_nil a || b || c
+
+ # Perform the callbacks when unprepared.
+ @dispatcher.unprepared = true
+ @dispatcher.send! :prepare_application
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+
+ # But when not :load, make sure they are only run once
+ a = b = c = nil
+ @dispatcher.send! :prepare_application
+ assert_nil a || b || c
+ end
+
+ def test_to_prepare_with_identifier_replaces
+ a = b = nil
+ Dispatcher.to_prepare(:unique_id) { a = b = 1 }
+ Dispatcher.to_prepare(:unique_id) { a = 2 }
+
+ @dispatcher.unprepared = true
+ @dispatcher.send! :prepare_application
+ assert_equal 2, a
+ assert_equal nil, b
+ end
+
+ def test_to_prepare_only_runs_once_if_not_loading_dependencies
+ Dependencies.stubs(:load?).returns(false)
+ called = 0
+ Dispatcher.to_prepare(:unprepared_test) { called += 1 }
+ 2.times { dispatch }
+ assert_equal 1, called
+ end
+
+ private
+ def dispatch(output = @output)
+ controller = mock
+ controller.stubs(:process).returns(controller)
+ controller.stubs(:out).with(output).returns('response')
+
+ ActionController::Routing::Routes.stubs(:recognize).returns(controller)
+
+ Dispatcher.dispatch(nil, {}, output)
+ end
+
+ def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
+ assert_equal howmany, klass.subclasses.size, message
+ end
+end
+
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/fake_controllers.rb b/vendor/rails-2.0.2/actionpack/test/controller/fake_controllers.rb
new file mode 100644
index 000000000..5f958b284
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/fake_controllers.rb
@@ -0,0 +1,16 @@
+class << Object; alias_method :const_available?, :const_defined?; end
+
+class ContentController < Class.new(ActionController::Base)
+end
+class NotAController
+end
+module Admin
+ class << self; alias_method :const_available?, :const_defined?; end
+ class UserController < Class.new(ActionController::Base); end
+ class NewsFeedController < Class.new(ActionController::Base); end
+end
+
+ActionController::Routing::Routes.draw do |map|
+ map.route_one 'route_one', :controller => 'elsewhere', :action => 'flash_me'
+ map.connect ':controller/:action/:id'
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/fake_models.rb b/vendor/rails-2.0.2/actionpack/test/controller/fake_models.rb
new file mode 100644
index 000000000..2761b09f2
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/fake_models.rb
@@ -0,0 +1,5 @@
+class Customer < Struct.new(:name, :id)
+ def to_param
+ id.to_s
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/filter_params_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/filter_params_test.rb
new file mode 100644
index 000000000..7b810b162
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/filter_params_test.rb
@@ -0,0 +1,43 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class FilterParamController < ActionController::Base
+end
+
+class FilterParamTest < Test::Unit::TestCase
+ def setup
+ @controller = FilterParamController.new
+ end
+
+ def test_filter_parameters
+ assert FilterParamController.respond_to?(:filter_parameter_logging)
+ assert !@controller.respond_to?(:filter_parameters)
+
+ FilterParamController.filter_parameter_logging
+ assert @controller.respond_to?(:filter_parameters)
+
+ test_hashes = [[{},{},[]],
+ [{'foo'=>nil},{'foo'=>nil},[]],
+ [{'foo'=>'bar'},{'foo'=>'bar'},[]],
+ [{'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']]
+
+ test_hashes.each do |before_filter, after_filter, filter_words|
+ FilterParamController.filter_parameter_logging(*filter_words)
+ assert_equal after_filter, @controller.filter_parameters(before_filter)
+
+ filter_words.push('blah')
+ FilterParamController.filter_parameter_logging(*filter_words) do |key, value|
+ value.reverse! if key =~ /bargain/
+ end
+
+ before_filter['barg'] = {'bargain'=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}}
+ after_filter['barg'] = {'bargain'=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}}
+
+ assert_equal after_filter, @controller.filter_parameters(before_filter)
+ end
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/filters_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/filters_test.rb
new file mode 100644
index 000000000..188e75afd
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/filters_test.rb
@@ -0,0 +1,856 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+# FIXME: crashes Ruby 1.9
+class FilterTest < Test::Unit::TestCase
+ class TestController < ActionController::Base
+ before_filter :ensure_login
+ after_filter :clean_up
+
+ def show
+ render :inline => "ran action"
+ end
+
+ private
+ def ensure_login
+ @ran_filter ||= []
+ @ran_filter << "ensure_login"
+ end
+
+ def clean_up
+ @ran_after_filter ||= []
+ @ran_after_filter << "clean_up"
+ end
+ end
+
+ class ChangingTheRequirementsController < TestController
+ before_filter :ensure_login, :except => [:go_wild]
+
+ def go_wild
+ render :text => "gobble"
+ end
+ end
+
+ class TestMultipleFiltersController < ActionController::Base
+ before_filter :try_1
+ before_filter :try_2
+ before_filter :try_3
+
+ (1..3).each do |i|
+ define_method "fail_#{i}" do
+ render :text => i.to_s
+ end
+ end
+
+ protected
+ (1..3).each do |i|
+ define_method "try_#{i}" do
+ instance_variable_set :@try, i
+ if action_name == "fail_#{i}"
+ head(404)
+ end
+ end
+ end
+ end
+
+ class RenderingController < ActionController::Base
+ before_filter :render_something_else
+
+ def show
+ @ran_action = true
+ render :inline => "ran action"
+ end
+
+ private
+ def render_something_else
+ render :inline => "something else"
+ end
+ end
+
+ class ConditionalFilterController < ActionController::Base
+ def show
+ render :inline => "ran action"
+ end
+
+ def another_action
+ render :inline => "ran action"
+ end
+
+ def show_without_filter
+ render :inline => "ran action without filter"
+ end
+
+ private
+ def ensure_login
+ @ran_filter ||= []
+ @ran_filter << "ensure_login"
+ end
+
+ def clean_up_tmp
+ @ran_filter ||= []
+ @ran_filter << "clean_up_tmp"
+ end
+
+ def rescue_action(e) raise(e) end
+ end
+
+ class ConditionalCollectionFilterController < ConditionalFilterController
+ before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
+ end
+
+ class OnlyConditionSymController < ConditionalFilterController
+ before_filter :ensure_login, :only => :show
+ end
+
+ class ExceptConditionSymController < ConditionalFilterController
+ before_filter :ensure_login, :except => :show_without_filter
+ end
+
+ class BeforeAndAfterConditionController < ConditionalFilterController
+ before_filter :ensure_login, :only => :show
+ after_filter :clean_up_tmp, :only => :show
+ end
+
+ class OnlyConditionProcController < ConditionalFilterController
+ before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true }
+ end
+
+ class ExceptConditionProcController < ConditionalFilterController
+ before_filter(:except => :show_without_filter) {|c| c.assigns["ran_proc_filter"] = true }
+ end
+
+ class ConditionalClassFilter
+ def self.filter(controller) controller.assigns["ran_class_filter"] = true end
+ end
+
+ class OnlyConditionClassController < ConditionalFilterController
+ before_filter ConditionalClassFilter, :only => :show
+ end
+
+ class ExceptConditionClassController < ConditionalFilterController
+ before_filter ConditionalClassFilter, :except => :show_without_filter
+ end
+
+ class AnomolousYetValidConditionController < ConditionalFilterController
+ before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true}
+ end
+
+ class EmptyFilterChainController < TestController
+ self.filter_chain.clear
+ def show
+ @action_executed = true
+ render :text => "yawp!"
+ end
+ end
+
+ class PrependingController < TestController
+ prepend_before_filter :wonderful_life
+ # skip_before_filter :fire_flash
+
+ private
+ def wonderful_life
+ @ran_filter ||= []
+ @ran_filter << "wonderful_life"
+ end
+ end
+
+ class ConditionalSkippingController < TestController
+ skip_before_filter :ensure_login, :only => [ :login ]
+ skip_after_filter :clean_up, :only => [ :login ]
+
+ before_filter :find_user, :only => [ :change_password ]
+
+ def login
+ render :inline => "ran action"
+ end
+
+ def change_password
+ render :inline => "ran action"
+ end
+
+ protected
+ def find_user
+ @ran_filter ||= []
+ @ran_filter << "find_user"
+ end
+ end
+
+ class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
+ before_filter :conditional_in_parent, :only => [:show, :another_action]
+ after_filter :conditional_in_parent, :only => [:show, :another_action]
+
+ private
+
+ def conditional_in_parent
+ @ran_filter ||= []
+ @ran_filter << 'conditional_in_parent'
+ end
+ end
+
+ class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
+ skip_before_filter :conditional_in_parent, :only => :another_action
+ skip_after_filter :conditional_in_parent, :only => :another_action
+ end
+
+ class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
+ skip_before_filter :conditional_in_parent, :only => :show
+ end
+
+ class ProcController < PrependingController
+ before_filter(proc { |c| c.assigns["ran_proc_filter"] = true })
+ end
+
+ class ImplicitProcController < PrependingController
+ before_filter { |c| c.assigns["ran_proc_filter"] = true }
+ end
+
+ class AuditFilter
+ def self.filter(controller)
+ controller.assigns["was_audited"] = true
+ end
+ end
+
+ class AroundFilter
+ def before(controller)
+ @execution_log = "before"
+ controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
+ controller.assigns["before_ran"] = true
+ end
+
+ def after(controller)
+ controller.assigns["execution_log"] = @execution_log + " and after"
+ controller.assigns["after_ran"] = true
+ controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
+ end
+ end
+
+ class AppendedAroundFilter
+ def before(controller)
+ controller.class.execution_log << " before appended aroundfilter "
+ end
+
+ def after(controller)
+ controller.class.execution_log << " after appended aroundfilter "
+ end
+ end
+
+ class AuditController < ActionController::Base
+ before_filter(AuditFilter)
+
+ def show
+ render :text => "hello"
+ end
+ end
+
+ class AroundFilterController < PrependingController
+ around_filter AroundFilter.new
+ end
+
+ class BeforeAfterClassFilterController < PrependingController
+ begin
+ filter = AroundFilter.new
+ before_filter filter
+ after_filter filter
+ end
+ end
+
+ class MixedFilterController < PrependingController
+ cattr_accessor :execution_log
+
+ def initialize
+ @@execution_log = ""
+ end
+
+ before_filter { |c| c.class.execution_log << " before procfilter " }
+ prepend_around_filter AroundFilter.new
+
+ after_filter { |c| c.class.execution_log << " after procfilter " }
+ append_around_filter AppendedAroundFilter.new
+ end
+
+ class MixedSpecializationController < ActionController::Base
+ class OutOfOrder < StandardError; end
+
+ before_filter :first
+ before_filter :second, :only => :foo
+
+ def foo
+ render :text => 'foo'
+ end
+
+ def bar
+ render :text => 'bar'
+ end
+
+ protected
+ def first
+ @first = true
+ end
+
+ def second
+ raise OutOfOrder unless @first
+ end
+ end
+
+ class DynamicDispatchController < ActionController::Base
+ before_filter :choose
+
+ %w(foo bar baz).each do |action|
+ define_method(action) { render :text => action }
+ end
+
+ private
+ def choose
+ self.action_name = params[:choose]
+ end
+ end
+
+ class PrependingBeforeAndAfterController < ActionController::Base
+ prepend_before_filter :before_all
+ prepend_after_filter :after_all
+ before_filter :between_before_all_and_after_all
+
+ def before_all
+ @ran_filter ||= []
+ @ran_filter << 'before_all'
+ end
+
+ def after_all
+ @ran_filter ||= []
+ @ran_filter << 'after_all'
+ end
+
+ def between_before_all_and_after_all
+ @ran_filter ||= []
+ @ran_filter << 'between_before_all_and_after_all'
+ end
+ def show
+ render :text => 'hello'
+ end
+ end
+
+ class ErrorToRescue < Exception; end
+
+ class RescuingAroundFilterWithBlock
+ def filter(controller)
+ begin
+ yield
+ rescue ErrorToRescue => ex
+ controller.send! :render, :text => "I rescued this: #{ex.inspect}"
+ end
+ end
+ end
+
+ class RescuedController < ActionController::Base
+ around_filter RescuingAroundFilterWithBlock.new
+
+ def show
+ raise ErrorToRescue.new("Something made the bad noise.")
+ end
+
+ private
+ def rescue_action(exception)
+ raise exception
+ end
+ end
+
+ class NonYieldingAroundFilterController < ActionController::Base
+
+ before_filter :filter_one
+ around_filter :non_yielding_filter
+ before_filter :filter_two
+ after_filter :filter_three
+
+ def index
+ render :inline => "index"
+ end
+
+ #make sure the controller complains
+ def rescue_action(e); raise e; end
+
+ private
+
+ def filter_one
+ @filters ||= []
+ @filters << "filter_one"
+ end
+
+ def filter_two
+ @filters << "filter_two"
+ end
+
+ def non_yielding_filter
+ @filters << "zomg it didn't yield"
+ @filter_return_value
+ end
+
+ def filter_three
+ @filters << "filter_three"
+ end
+
+ end
+
+ def test_non_yielding_around_filters_not_returning_false_do_not_raise
+ controller = NonYieldingAroundFilterController.new
+ controller.instance_variable_set "@filter_return_value", true
+ assert_nothing_raised do
+ test_process(controller, "index")
+ end
+ end
+
+ def test_non_yielding_around_filters_returning_false_do_not_raise
+ controller = NonYieldingAroundFilterController.new
+ controller.instance_variable_set "@filter_return_value", false
+ assert_nothing_raised do
+ test_process(controller, "index")
+ end
+ end
+
+ def test_after_filters_are_not_run_if_around_filter_returns_false
+ controller = NonYieldingAroundFilterController.new
+ controller.instance_variable_set "@filter_return_value", false
+ test_process(controller, "index")
+ assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
+ end
+
+ def test_after_filters_are_not_run_if_around_filter_does_not_yield
+ controller = NonYieldingAroundFilterController.new
+ controller.instance_variable_set "@filter_return_value", true
+ test_process(controller, "index")
+ assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
+ end
+
+ def test_empty_filter_chain
+ assert_equal 0, EmptyFilterChainController.filter_chain.size
+ assert test_process(EmptyFilterChainController).template.assigns['action_executed']
+ end
+
+ def test_added_filter_to_inheritance_graph
+ assert_equal [ :ensure_login ], TestController.before_filters
+ end
+
+ def test_base_class_in_isolation
+ assert_equal [ ], ActionController::Base.before_filters
+ end
+
+ def test_prepending_filter
+ assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters
+ end
+
+ def test_running_filters
+ assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
+ end
+
+ def test_running_filters_with_proc
+ assert test_process(ProcController).template.assigns["ran_proc_filter"]
+ end
+
+ def test_running_filters_with_implicit_proc
+ assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
+ end
+
+ def test_running_filters_with_class
+ assert test_process(AuditController).template.assigns["was_audited"]
+ end
+
+ def test_running_anomolous_yet_valid_condition_filters
+ response = test_process(AnomolousYetValidConditionController)
+ assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
+ assert response.template.assigns["ran_class_filter"]
+ assert response.template.assigns["ran_proc_filter1"]
+ assert response.template.assigns["ran_proc_filter2"]
+
+ response = test_process(AnomolousYetValidConditionController, "show_without_filter")
+ assert_equal nil, response.template.assigns["ran_filter"]
+ assert !response.template.assigns["ran_class_filter"]
+ assert !response.template.assigns["ran_proc_filter1"]
+ assert !response.template.assigns["ran_proc_filter2"]
+ end
+
+ def test_running_collection_condition_filters
+ assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
+ end
+
+ def test_running_only_condition_filters
+ assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
+ assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]
+
+ assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
+ assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
+
+ assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
+ assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
+ end
+
+ def test_running_except_condition_filters
+ assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
+ assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]
+
+ assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
+ assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
+
+ assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
+ assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
+ end
+
+ def test_running_before_and_after_condition_filters
+ assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
+ assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
+ end
+
+ def test_bad_filter
+ bad_filter_controller = Class.new(ActionController::Base)
+ assert_raises(ActionController::ActionControllerError) do
+ bad_filter_controller.before_filter 2
+ end
+ end
+
+ def test_around_filter
+ controller = test_process(AroundFilterController)
+ assert controller.template.assigns["before_ran"]
+ assert controller.template.assigns["after_ran"]
+ end
+
+ def test_before_after_class_filter
+ controller = test_process(BeforeAfterClassFilterController)
+ assert controller.template.assigns["before_ran"]
+ assert controller.template.assigns["after_ran"]
+ end
+
+ def test_having_properties_in_around_filter
+ controller = test_process(AroundFilterController)
+ assert_equal "before and after", controller.template.assigns["execution_log"]
+ end
+
+ def test_prepending_and_appending_around_filter
+ controller = test_process(MixedFilterController)
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
+ " after appended aroundfilter after aroundfilter after procfilter ",
+ MixedFilterController.execution_log
+ end
+
+ def test_rendering_breaks_filtering_chain
+ response = test_process(RenderingController)
+ assert_equal "something else", response.body
+ assert !response.template.assigns["ran_action"]
+ end
+
+ def test_filters_with_mixed_specialization_run_in_order
+ assert_nothing_raised do
+ response = test_process(MixedSpecializationController, 'bar')
+ assert_equal 'bar', response.body
+ end
+
+ assert_nothing_raised do
+ response = test_process(MixedSpecializationController, 'foo')
+ assert_equal 'foo', response.body
+ end
+ end
+
+ def test_dynamic_dispatch
+ %w(foo bar baz).each do |action|
+ request = ActionController::TestRequest.new
+ request.query_parameters[:choose] = action
+ response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
+ assert_equal action, response.body
+ end
+ end
+
+ def test_running_prepended_before_and_after_filter
+ assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length
+ response = test_process(PrependingBeforeAndAfterController)
+ assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"]
+ end
+
+ def test_conditional_skipping_of_filters
+ assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
+ assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
+
+ assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
+ assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
+ end
+
+ def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
+ assert_nil test_process(ChildOfConditionalParentController, 'another_action').template.assigns['ran_filter']
+ end
+
+ def test_condition_skipping_of_filters_when_siblings_also_have_conditions
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter'], "1"
+ assert_equal nil, test_process(AnotherChildOfConditionalParentController).template.assigns['ran_filter']
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
+ end
+
+ def test_changing_the_requirements
+ assert_equal nil, test_process(ChangingTheRequirementsController, "go_wild").template.assigns['ran_filter']
+ end
+
+ def test_a_rescuing_around_filter
+ response = nil
+ assert_nothing_raised do
+ response = test_process(RescuedController)
+ end
+
+ assert response.success?
+ assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
+ end
+
+ private
+ def test_process(controller, action = "show")
+ request = ActionController::TestRequest.new
+ request.action = action
+ controller.process(request, ActionController::TestResponse.new)
+ end
+end
+
+
+
+class PostsController < ActionController::Base
+ def rescue_action(e); raise e; end
+
+ module AroundExceptions
+ class Error < StandardError ; end
+ class Before < Error ; end
+ class After < Error ; end
+ end
+ include AroundExceptions
+
+ class DefaultFilter
+ include AroundExceptions
+ end
+
+ module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n")
+
+ private
+ def default_action
+ render :inline => "#{action_name} called"
+ end
+end
+
+class ControllerWithSymbolAsFilter < PostsController
+ around_filter :raise_before, :only => :raises_before
+ around_filter :raise_after, :only => :raises_after
+ around_filter :without_exception, :only => :no_raise
+
+ private
+ def raise_before
+ raise Before
+ yield
+ end
+
+ def raise_after
+ yield
+ raise After
+ end
+
+ def without_exception
+ # Do stuff...
+ 1 + 1
+
+ yield
+
+ # Do stuff...
+ 1 + 1
+ end
+end
+
+class ControllerWithFilterClass < PostsController
+ class YieldingFilter < DefaultFilter
+ def self.filter(controller)
+ yield
+ raise After
+ end
+ end
+
+ around_filter YieldingFilter, :only => :raises_after
+end
+
+class ControllerWithFilterInstance < PostsController
+ class YieldingFilter < DefaultFilter
+ def filter(controller)
+ yield
+ raise After
+ end
+ end
+
+ around_filter YieldingFilter.new, :only => :raises_after
+end
+
+class ControllerWithFilterMethod < PostsController
+ class YieldingFilter < DefaultFilter
+ def filter(controller)
+ yield
+ raise After
+ end
+ end
+
+ around_filter YieldingFilter.new.method(:filter), :only => :raises_after
+end
+
+class ControllerWithProcFilter < PostsController
+ around_filter(:only => :no_raise) do |c,b|
+ c.assigns['before'] = true
+ b.call
+ c.assigns['after'] = true
+ end
+end
+
+class ControllerWithWrongFilterType < PostsController
+ around_filter lambda { yield }, :only => :no_raise
+end
+
+class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
+ around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
+end
+
+class ControllerWithAllTypesOfFilters < PostsController
+ before_filter :before
+ around_filter :around
+ after_filter :after
+ around_filter :around_again
+
+ private
+ def before
+ @ran_filter ||= []
+ @ran_filter << 'before'
+ end
+
+ def around
+ @ran_filter << 'around (before yield)'
+ yield
+ @ran_filter << 'around (after yield)'
+ end
+
+ def after
+ @ran_filter << 'after'
+ end
+
+ def around_again
+ @ran_filter << 'around_again (before yield)'
+ yield
+ @ran_filter << 'around_again (after yield)'
+ end
+end
+
+class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
+ skip_filter :around_again
+ skip_filter :after
+end
+
+class YieldingAroundFiltersTest < Test::Unit::TestCase
+ include PostsController::AroundExceptions
+
+ def test_filters_registering
+ assert_equal 1, ControllerWithFilterMethod.filter_chain.size
+ assert_equal 1, ControllerWithFilterClass.filter_chain.size
+ assert_equal 1, ControllerWithFilterInstance.filter_chain.size
+ assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
+ assert_equal 1, ControllerWithWrongFilterType.filter_chain.size
+ assert_equal 6, ControllerWithNestedFilters.filter_chain.size
+ assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
+ end
+
+ def test_wrong_filter_type
+ assert_raise(ActionController::ActionControllerError) do
+ test_process(ControllerWithWrongFilterType,'no_raise')
+ end
+ end
+
+ def test_base
+ controller = PostsController
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_nothing_raised { test_process(controller,'raises_before') }
+ assert_nothing_raised { test_process(controller,'raises_after') }
+ assert_nothing_raised { test_process(controller,'no_filter') }
+ end
+
+ def test_with_symbol
+ controller = ControllerWithSymbolAsFilter
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_raise(Before) { test_process(controller,'raises_before') }
+ assert_raise(After) { test_process(controller,'raises_after') }
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ end
+
+ def test_with_class
+ controller = ControllerWithFilterClass
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_raise(After) { test_process(controller,'raises_after') }
+ end
+
+ def test_with_instance
+ controller = ControllerWithFilterInstance
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_raise(After) { test_process(controller,'raises_after') }
+ end
+
+ def test_with_method
+ controller = ControllerWithFilterMethod
+ assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_raise(After) { test_process(controller,'raises_after') }
+ end
+
+ def test_with_proc
+ controller = test_process(ControllerWithProcFilter,'no_raise')
+ assert controller.template.assigns['before']
+ assert controller.template.assigns['after']
+ end
+
+ def test_nested_filters
+ controller = ControllerWithNestedFilters
+ assert_nothing_raised do
+ begin
+ test_process(controller,'raises_both')
+ rescue Before, After
+ end
+ end
+ assert_raise Before do
+ begin
+ test_process(controller,'raises_both')
+ rescue After
+ end
+ end
+ end
+
+ def test_filter_order_with_all_filter_types
+ controller = test_process(ControllerWithAllTypesOfFilters,'no_raise')
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after',controller.template.assigns['ran_filter'].join(' ')
+ end
+
+ def test_filter_order_with_skip_filter_method
+ controller = test_process(ControllerWithTwoLessFilters,'no_raise')
+ assert_equal 'before around (before yield) around (after yield)',controller.template.assigns['ran_filter'].join(' ')
+ end
+
+ def test_first_filter_in_multiple_before_filter_chain_halts
+ controller = ::FilterTest::TestMultipleFiltersController.new
+ response = test_process(controller, 'fail_1')
+ assert_equal ' ', response.body
+ assert_equal 1, controller.instance_variable_get(:@try)
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
+ end
+
+ def test_second_filter_in_multiple_before_filter_chain_halts
+ controller = ::FilterTest::TestMultipleFiltersController.new
+ response = test_process(controller, 'fail_2')
+ assert_equal ' ', response.body
+ assert_equal 2, controller.instance_variable_get(:@try)
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
+ end
+
+ def test_last_filter_in_multiple_before_filter_chain_halts
+ controller = ::FilterTest::TestMultipleFiltersController.new
+ response = test_process(controller, 'fail_3')
+ assert_equal ' ', response.body
+ assert_equal 3, controller.instance_variable_get(:@try)
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
+ end
+
+ protected
+ def test_process(controller, action = "show")
+ request = ActionController::TestRequest.new
+ request.action = action
+ controller.process(request, ActionController::TestResponse.new)
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/flash_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/flash_test.rb
new file mode 100644
index 000000000..4a6f3c9e0
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/flash_test.rb
@@ -0,0 +1,146 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class FlashTest < Test::Unit::TestCase
+ class TestController < ActionController::Base
+ def set_flash
+ flash["that"] = "hello"
+ render :inline => "hello"
+ end
+
+ def set_flash_now
+ flash.now["that"] = "hello"
+ flash.now["foo"] ||= "bar"
+ flash.now["foo"] ||= "err"
+ @flashy = flash.now["that"]
+ @flash_copy = {}.update flash
+ render :inline => "hello"
+ end
+
+ def attempt_to_use_flash_now
+ @flash_copy = {}.update flash
+ @flashy = flash["that"]
+ render :inline => "hello"
+ end
+
+ def use_flash
+ @flash_copy = {}.update flash
+ @flashy = flash["that"]
+ render :inline => "hello"
+ end
+
+ def use_flash_and_keep_it
+ @flash_copy = {}.update flash
+ @flashy = flash["that"]
+ flash.keep
+ render :inline => "hello"
+ end
+
+ def use_flash_and_update_it
+ flash.update("this" => "hello again")
+ @flash_copy = {}.update flash
+ render :inline => "hello"
+ end
+
+ def use_flash_after_reset_session
+ flash["that"] = "hello"
+ @flashy_that = flash["that"]
+ reset_session
+ @flashy_that_reset = flash["that"]
+ flash["this"] = "good-bye"
+ @flashy_this = flash["this"]
+ render :inline => "hello"
+ end
+
+ def rescue_action(e)
+ raise unless ActionController::MissingTemplate === e
+ end
+
+ # methods for test_sweep_after_halted_filter_chain
+ before_filter :halt_and_redir, :only => "filter_halting_action"
+
+ def std_action
+ @flash_copy = {}.update(flash)
+ end
+
+ def filter_halting_action
+ @flash_copy = {}.update(flash)
+ end
+
+ def halt_and_redir
+ flash["foo"] = "bar"
+ redirect_to :action => "std_action"
+ @flash_copy = {}.update(flash)
+ end
+ end
+
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @controller = TestController.new
+ end
+
+ def test_flash
+ get :set_flash
+
+ get :use_flash
+ assert_equal "hello", @response.template.assigns["flash_copy"]["that"]
+ assert_equal "hello", @response.template.assigns["flashy"]
+
+ get :use_flash
+ assert_nil @response.template.assigns["flash_copy"]["that"], "On second flash"
+ end
+
+ def test_keep_flash
+ get :set_flash
+
+ get :use_flash_and_keep_it
+ assert_equal "hello", @response.template.assigns["flash_copy"]["that"]
+ assert_equal "hello", @response.template.assigns["flashy"]
+
+ get :use_flash
+ assert_equal "hello", @response.template.assigns["flash_copy"]["that"], "On second flash"
+
+ get :use_flash
+ assert_nil @response.template.assigns["flash_copy"]["that"], "On third flash"
+ end
+
+ def test_flash_now
+ get :set_flash_now
+ assert_equal "hello", @response.template.assigns["flash_copy"]["that"]
+ assert_equal "bar" , @response.template.assigns["flash_copy"]["foo"]
+ assert_equal "hello", @response.template.assigns["flashy"]
+
+ get :attempt_to_use_flash_now
+ assert_nil @response.template.assigns["flash_copy"]["that"]
+ assert_nil @response.template.assigns["flash_copy"]["foo"]
+ assert_nil @response.template.assigns["flashy"]
+ end
+
+ def test_update_flash
+ get :set_flash
+ get :use_flash_and_update_it
+ assert_equal "hello", @response.template.assigns["flash_copy"]["that"]
+ assert_equal "hello again", @response.template.assigns["flash_copy"]["this"]
+ get :use_flash
+ 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"]
+ assert_equal "good-bye", @response.template.assigns["flashy_this"]
+ assert_nil @response.template.assigns["flashy_that_reset"]
+ end
+
+ def test_sweep_after_halted_filter_chain
+ get :std_action
+ assert_nil @response.template.assigns["flash_copy"]["foo"]
+ get :filter_halting_action
+ assert_equal "bar", @response.template.assigns["flash_copy"]["foo"]
+ get :std_action # follow redirection
+ assert_equal "bar", @response.template.assigns["flash_copy"]["foo"]
+ get :std_action
+ assert_nil @response.template.assigns["flash_copy"]["foo"]
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/fragment_store_setting_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/fragment_store_setting_test.rb
new file mode 100644
index 000000000..3df6fd0be
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/fragment_store_setting_test.rb
@@ -0,0 +1,47 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+MemCache = Struct.new(:MemCache, :address) unless Object.const_defined?(:MemCache)
+
+class FragmentCacheStoreSettingTest < Test::Unit::TestCase
+ def teardown
+ ActionController::Base.fragment_cache_store = ActionController::Caching::Fragments::MemoryStore.new
+ end
+
+ def test_file_fragment_cache_store
+ ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"
+ assert_kind_of(
+ ActionController::Caching::Fragments::FileStore,
+ ActionController::Base.fragment_cache_store
+ )
+ assert_equal "/path/to/cache/directory", ActionController::Base.fragment_cache_store.cache_path
+ end
+
+ def test_drb_fragment_cache_store
+ ActionController::Base.fragment_cache_store = :drb_store, "druby://localhost:9192"
+ assert_kind_of(
+ ActionController::Caching::Fragments::DRbStore,
+ ActionController::Base.fragment_cache_store
+ )
+ assert_equal "druby://localhost:9192", ActionController::Base.fragment_cache_store.address
+ end
+
+ if defined? CGI::Session::MemCacheStore
+ def test_mem_cache_fragment_cache_store
+ ActionController::Base.fragment_cache_store = :mem_cache_store, "localhost"
+ assert_kind_of(
+ ActionController::Caching::Fragments::MemCacheStore,
+ ActionController::Base.fragment_cache_store
+ )
+ assert_equal %w(localhost), ActionController::Base.fragment_cache_store.addresses
+ end
+ end
+
+ def test_object_assigned_fragment_cache_store
+ ActionController::Base.fragment_cache_store = ActionController::Caching::Fragments::FileStore.new("/path/to/cache/directory")
+ assert_kind_of(
+ ActionController::Caching::Fragments::FileStore,
+ ActionController::Base.fragment_cache_store
+ )
+ assert_equal "/path/to/cache/directory", ActionController::Base.fragment_cache_store.cache_path
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/helper_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/helper_test.rb
new file mode 100644
index 000000000..117f73b76
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/helper_test.rb
@@ -0,0 +1,206 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+ActionController::Helpers::HELPERS_DIR.replace File.dirname(__FILE__) + '/../fixtures/helpers'
+
+class TestController < ActionController::Base
+ attr_accessor :delegate_attr
+ def delegate_method() end
+ def rescue_action(e) raise end
+end
+
+module Fun
+ class GamesController < ActionController::Base
+ def render_hello_world
+ render :inline => "hello: <%= stratego %>"
+ end
+
+ def rescue_action(e) raise end
+ end
+
+ class PdfController < ActionController::Base
+ def test
+ render :inline => "test: <%= foobar %>"
+ end
+
+ def rescue_action(e) raise end
+ end
+end
+
+class ApplicationController < ActionController::Base
+ helper :all
+end
+
+module LocalAbcHelper
+ def a() end
+ def b() end
+ def c() end
+end
+
+class HelperTest < Test::Unit::TestCase
+ def setup
+ # Increment symbol counter.
+ @symbol = (@@counter ||= 'A0').succ!.dup
+
+ # Generate new controller class.
+ controller_class_name = "Helper#{@symbol}Controller"
+ eval("class #{controller_class_name} < TestController; end")
+ @controller_class = self.class.const_get(controller_class_name)
+
+ # Generate new template class and assign to controller.
+ template_class_name = "Test#{@symbol}View"
+ eval("class #{template_class_name} < ActionView::Base; end")
+ @template_class = self.class.const_get(template_class_name)
+ @controller_class.template_class = @template_class
+
+ # Set default test helper.
+ self.test_helper = LocalAbcHelper
+ end
+
+ def teardown
+ # Reset template class.
+ #ActionController::Base.template_class = ActionView::Base
+ end
+
+
+ def test_deprecated_helper
+ assert_equal expected_helper_methods, missing_methods
+ assert_nothing_raised { @controller_class.helper TestHelper }
+ assert_equal [], missing_methods
+ end
+
+ def test_declare_helper
+ require 'abc_helper'
+ self.test_helper = AbcHelper
+ assert_equal expected_helper_methods, missing_methods
+ assert_nothing_raised { @controller_class.helper :abc }
+ assert_equal [], missing_methods
+ end
+
+ def test_declare_missing_helper
+ assert_equal expected_helper_methods, missing_methods
+ assert_raise(MissingSourceFile) { @controller_class.helper :missing }
+ end
+
+ def test_declare_missing_file_from_helper
+ require 'broken_helper'
+ rescue LoadError => e
+ assert_nil(/\bbroken_helper\b/.match(e.to_s)[1])
+ end
+
+ def test_helper_block
+ assert_nothing_raised {
+ @controller_class.helper { def block_helper_method; end }
+ }
+ assert master_helper_methods.include?('block_helper_method')
+ end
+
+ def test_helper_block_include
+ assert_equal expected_helper_methods, missing_methods
+ assert_nothing_raised {
+ @controller_class.helper { include TestHelper }
+ }
+ assert [], missing_methods
+ end
+
+ def test_helper_method
+ assert_nothing_raised { @controller_class.helper_method :delegate_method }
+ assert master_helper_methods.include?('delegate_method')
+ end
+
+ def test_helper_attr
+ assert_nothing_raised { @controller_class.helper_attr :delegate_attr }
+ assert master_helper_methods.include?('delegate_attr')
+ assert master_helper_methods.include?('delegate_attr=')
+ end
+
+ def test_helper_for_nested_controller
+ request = ActionController::TestRequest.new
+ response = ActionController::TestResponse.new
+ request.action = 'render_hello_world'
+
+ assert_equal 'hello: Iz guuut!', Fun::GamesController.process(request, response).body
+ end
+
+ def test_helper_for_acronym_controller
+ request = ActionController::TestRequest.new
+ response = ActionController::TestResponse.new
+ request.action = 'test'
+
+ assert_equal 'test: baz', Fun::PdfController.process(request, response).body
+ end
+
+ def test_all_helpers
+ methods = ApplicationController.master_helper_module.instance_methods.map(&:to_s)
+
+ # abc_helper.rb
+ assert methods.include?('bare_a')
+
+ # fun/games_helper.rb
+ assert methods.include?('stratego')
+
+ # fun/pdf_helper.rb
+ assert methods.include?('foobar')
+ end
+
+ private
+ def expected_helper_methods
+ TestHelper.instance_methods.map(&:to_s)
+ end
+
+ def master_helper_methods
+ @controller_class.master_helper_module.instance_methods.map(&:to_s)
+ end
+
+ def missing_methods
+ expected_helper_methods - master_helper_methods
+ end
+
+ def test_helper=(helper_module)
+ silence_warnings { self.class.const_set('TestHelper', helper_module) }
+ end
+end
+
+
+class IsolatedHelpersTest < Test::Unit::TestCase
+ class A < ActionController::Base
+ def index
+ render :inline => '<%= shout %>'
+ end
+
+ def rescue_action(e) raise end
+ end
+
+ class B < A
+ helper { def shout; 'B' end }
+
+ def index
+ render :inline => '<%= shout %>'
+ end
+ end
+
+ class C < A
+ helper { def shout; 'C' end }
+
+ def index
+ render :inline => '<%= shout %>'
+ end
+ end
+
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @request.action = 'index'
+ end
+
+ def test_helper_in_a
+ assert_raise(NameError) { A.process(@request, @response) }
+ end
+
+ def test_helper_in_b
+ assert_equal 'B', B.process(@request, @response).body
+ end
+
+ def test_helper_in_c
+ assert_equal 'C', C.process(@request, @response).body
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/document_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/document_test.rb
new file mode 100644
index 000000000..0719883f3
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/document_test.rb
@@ -0,0 +1,124 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class DocumentTest < Test::Unit::TestCase
+ def test_handle_doctype
+ doc = nil
+ assert_nothing_raised do
+ doc = HTML::Document.new <<-HTML.strip
+ <!DOCTYPE "blah" "blah" "blah">
+ <html>
+ </html>
+ HTML
+ end
+ assert_equal 3, doc.root.children.length
+ assert_equal %{<!DOCTYPE "blah" "blah" "blah">}, doc.root.children[0].content
+ assert_match %r{\s+}m, doc.root.children[1].content
+ assert_equal "html", doc.root.children[2].name
+ end
+
+ def test_find_img
+ doc = HTML::Document.new <<-HTML.strip
+ <html>
+ <body>
+ <p><img src="hello.gif"></p>
+ </body>
+ </html>
+ HTML
+ assert doc.find(:tag=>"img", :attributes=>{"src"=>"hello.gif"})
+ end
+
+ def test_find_all
+ doc = HTML::Document.new <<-HTML.strip
+ <html>
+ <body>
+ <p class="test"><img src="hello.gif"></p>
+ <div class="foo">
+ <p class="test">something</p>
+ <p>here is <em class="test">more</em></p>
+ </div>
+ </body>
+ </html>
+ HTML
+ all = doc.find_all :attributes => { :class => "test" }
+ assert_equal 3, all.length
+ assert_equal [ "p", "p", "em" ], all.map { |n| n.name }
+ end
+
+ def test_find_with_text
+ doc = HTML::Document.new <<-HTML.strip
+ <html>
+ <body>
+ <p>Some text</p>
+ </body>
+ </html>
+ HTML
+ assert doc.find(:content => "Some text")
+ assert doc.find(:tag => "p", :child => { :content => "Some text" })
+ assert doc.find(:tag => "p", :child => "Some text")
+ assert doc.find(:tag => "p", :content => "Some text")
+ end
+
+ def test_parse_xml
+ assert_nothing_raised { HTML::Document.new("<tags><tag/></tags>", true, true) }
+ assert_nothing_raised { HTML::Document.new("<outer><link>something</link></outer>", true, true) }
+ end
+
+ def test_parse_document
+ doc = HTML::Document.new(<<-HTML)
+ <div>
+ <h2>blah</h2>
+ <table>
+ </table>
+ </div>
+ HTML
+ assert_not_nil doc.find(:tag => "div", :children => { :count => 1, :only => { :tag => "table" } })
+ end
+
+ def test_tag_nesting_nothing_to_s
+ doc = HTML::Document.new("<tag></tag>")
+ assert_equal "<tag></tag>", doc.root.to_s
+ end
+
+ def test_tag_nesting_space_to_s
+ doc = HTML::Document.new("<tag> </tag>")
+ assert_equal "<tag> </tag>", doc.root.to_s
+ end
+
+ def test_tag_nesting_text_to_s
+ doc = HTML::Document.new("<tag>text</tag>")
+ assert_equal "<tag>text</tag>", doc.root.to_s
+ end
+
+ def test_tag_nesting_tag_to_s
+ doc = HTML::Document.new("<tag><nested /></tag>")
+ assert_equal "<tag><nested /></tag>", doc.root.to_s
+ end
+
+ def test_parse_cdata
+ doc = HTML::Document.new(<<-HTML)
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title><![CDATA[<br>]]></title>
+ </head>
+ <body>
+ <p>this document has &lt;br&gt; for a title</p>
+ </body>
+</html>
+HTML
+
+ assert_nil doc.find(:tag => "title", :descendant => { :tag => "br" })
+ assert doc.find(:tag => "title", :child => "<br>")
+ end
+
+ def test_find_empty_tag
+ doc = HTML::Document.new("<div id='map'></div>")
+ assert_nil doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /./)
+ assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /\A\Z/)
+ assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /^$/)
+ assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => "")
+ assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => nil)
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/node_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/node_test.rb
new file mode 100644
index 000000000..1cf0a4bb6
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/node_test.rb
@@ -0,0 +1,69 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class NodeTest < Test::Unit::TestCase
+
+ class MockNode
+ def initialize(matched, value)
+ @matched = matched
+ @value = value
+ end
+
+ def find(conditions)
+ @matched && self
+ end
+
+ def to_s
+ @value.to_s
+ end
+ end
+
+ def setup
+ @node = HTML::Node.new("parent")
+ @node.children.concat [MockNode.new(false,1), MockNode.new(true,"two"), MockNode.new(false,:three)]
+ end
+
+ def test_match
+ assert !@node.match("foo")
+ end
+
+ def test_tag
+ assert !@node.tag?
+ end
+
+ def test_to_s
+ assert_equal "1twothree", @node.to_s
+ end
+
+ def test_find
+ assert_equal "two", @node.find('blah').to_s
+ end
+
+ def test_parse_strict
+ s = "<b foo='hello'' bar='baz'>"
+ assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
+ end
+
+ def test_parse_relaxed
+ s = "<b foo='hello'' bar='baz'>"
+ node = nil
+ assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
+ assert node.attributes.has_key?("foo")
+ assert !node.attributes.has_key?("bar")
+ end
+
+ def test_to_s_with_boolean_attrs
+ s = "<b foo bar>"
+ node = HTML::Node.parse(nil,0,0,s)
+ assert node.attributes.has_key?("foo")
+ assert node.attributes.has_key?("bar")
+ assert "<b foo bar>", node.to_s
+ end
+
+ def test_parse_with_unclosed_tag
+ s = "<span onmouseover='bang'"
+ node = nil
+ assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
+ assert node.attributes.has_key?("onmouseover")
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/sanitizer_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/sanitizer_test.rb
new file mode 100644
index 000000000..8fe9bbc5e
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/sanitizer_test.rb
@@ -0,0 +1,250 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class SanitizerTest < Test::Unit::TestCase
+ def setup
+ @sanitizer = nil # used by assert_sanitizer
+ end
+
+ def test_strip_tags
+ sanitizer = HTML::FullSanitizer.new
+ assert_equal("<<<bad html", sanitizer.sanitize("<<<bad html"))
+ assert_equal("<<", sanitizer.sanitize("<<<bad html>"))
+ assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me"))
+ assert_equal("This is a test.", sanitizer.sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
+ assert_equal("Weirdos", sanitizer.sanitize("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"))
+ assert_equal("This is a test.", sanitizer.sanitize("This is a test."))
+ assert_equal(
+ %{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize(
+ %{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
+ assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
+ [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
+ end
+
+ def test_strip_links
+ sanitizer = HTML::LinkSanitizer.new
+ assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me")
+ assert_equal "on my mind\nall day long", sanitizer.sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
+ assert_equal "0wn3d", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
+ assert_equal "Magic", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
+ assert_equal "FrrFox", sanitizer.sanitize("<href onlclick='steal()'>FrrFox</a></href>")
+ assert_equal "My mind\nall <b>day</b> long", sanitizer.sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
+ assert_equal "all <b>day</b> long", sanitizer.sanitize("<<a>a href='hello'>all <b>day</b> long<</A>/a>")
+
+ assert_equal "<a<a", sanitizer.sanitize("<a<a")
+ end
+
+ def test_sanitize_form
+ assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", ''
+ end
+
+ def test_sanitize_plaintext
+ raw = "<plaintext><span>foo</span></plaintext>"
+ assert_sanitized raw, "<span>foo</span>"
+ end
+
+ def test_sanitize_script
+ assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
+ end
+
+ # fucked
+ def test_sanitize_js_handlers
+ raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
+ assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
+ end
+
+ def test_sanitize_javascript_href
+ raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>}
+ assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>}
+ end
+
+ def test_sanitize_image_src
+ raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>}
+ assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>}
+ end
+
+ HTML::WhiteListSanitizer.allowed_tags.each do |tag_name|
+ define_method "test_should_allow_#{tag_name}_tag" do
+ assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end)
+ end
+ end
+
+ def test_should_allow_anchors
+ assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>)
+ end
+
+ # RFC 3986, sec 4.2
+ def test_allow_colons_in_path_component
+ assert_sanitized("<a href=\"./this:that\">foo</a>")
+ end
+
+ %w(src width height alt).each do |img_attr|
+ define_method "test_should_allow_image_#{img_attr}_attribute" do
+ assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />)
+ end
+ end
+
+ def test_should_handle_non_html
+ assert_sanitized 'abc'
+ end
+
+ def test_should_handle_blank_text
+ assert_sanitized nil
+ assert_sanitized ''
+ end
+
+ def test_should_allow_custom_tags
+ text = "<u>foo</u>"
+ sanitizer = HTML::WhiteListSanitizer.new
+ assert_equal(text, sanitizer.sanitize(text, :tags => %w(u)))
+ end
+
+ def test_should_allow_only_custom_tags
+ text = "<u>foo</u> with <i>bar</i>"
+ sanitizer = HTML::WhiteListSanitizer.new
+ assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u)))
+ end
+
+ def test_should_allow_custom_tags_with_attributes
+ text = %(<blockquote cite="http://example.com/">foo</blockquote>)
+ sanitizer = HTML::WhiteListSanitizer.new
+ assert_equal(text, sanitizer.sanitize(text))
+ end
+
+ def test_should_allow_custom_tags_with_custom_attributes
+ text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
+ sanitizer = HTML::WhiteListSanitizer.new
+ assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo']))
+ end
+
+ [%w(img src), %w(a href)].each do |(tag, attr)|
+ define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
+ assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>)
+ end
+ end
+
+ def test_should_flag_bad_protocols
+ sanitizer = HTML::WhiteListSanitizer.new
+ %w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto|
+ assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad")
+ end
+ end
+
+ def test_should_accept_good_protocols
+ sanitizer = HTML::WhiteListSanitizer.new
+ HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
+ assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good")
+ end
+ end
+
+ def test_should_reject_hex_codes_in_protocol
+ assert_sanitized %(<a href="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;29">1</a>), "<a>1</a>"
+ assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29")
+ end
+
+ def test_should_block_script_tag
+ assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), ""
+ end
+
+ [%(<IMG SRC="javascript:alert('XSS');">),
+ %(<IMG SRC=javascript:alert('XSS')>),
+ %(<IMG SRC=JaVaScRiPt:alert('XSS')>),
+ %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
+ %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>),
+ %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
+ %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>),
+ %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>),
+ %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>),
+ %(<IMG SRC="jav\tascript:alert('XSS');">),
+ %(<IMG SRC="jav&#x09;ascript:alert('XSS');">),
+ %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">),
+ %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">),
+ %(<IMG SRC=" &#14; javascript:alert('XSS');">),
+ %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
+ define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
+ assert_sanitized img_hack, "<img>"
+ end
+ end
+
+ def test_should_sanitize_tag_broken_up_by_null
+ assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")"
+ end
+
+ def test_should_sanitize_invalid_script_tag
+ assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), ""
+ end
+
+ def test_should_sanitize_script_tag_with_multiple_open_brackets
+ assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;"
+ assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(&lt;a)
+ end
+
+ def test_should_sanitize_unclosed_script
+ assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>"
+ end
+
+ def test_should_sanitize_half_open_scripts
+ assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>"
+ end
+
+ def test_should_not_fall_for_ridiculous_hack
+ img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
+ assert_sanitized img_hack, "<img>"
+ end
+
+ # fucked
+ def test_should_sanitize_attributes
+ assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>)
+ end
+
+ def test_should_sanitize_illegal_style_properties
+ raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
+ expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;)
+ assert_equal expected, sanitize_css(raw)
+ end
+
+ def test_should_sanitize_xul_style_attributes
+ raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
+ assert_equal '', sanitize_css(raw)
+ end
+
+ def test_should_sanitize_invalid_tag_names
+ assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f")
+ end
+
+ def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags
+ assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>")
+ end
+
+ def test_should_sanitize_invalid_tag_names_in_single_tags
+ assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />")
+ end
+
+ def test_should_sanitize_img_dynsrc_lowsrc
+ assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />")
+ end
+
+ def test_should_sanitize_div_background_image_unicode_encoded
+ raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029)
+ assert_equal '', sanitize_css(raw)
+ end
+
+ def test_should_sanitize_div_style_expression
+ raw = %(width: expression(alert('XSS'));)
+ assert_equal '', sanitize_css(raw)
+ end
+
+ def test_should_sanitize_img_vbscript
+ assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
+ end
+
+protected
+ def assert_sanitized(input, expected = nil)
+ @sanitizer ||= HTML::WhiteListSanitizer.new
+ assert_equal expected || input, @sanitizer.sanitize(input)
+ end
+
+ def sanitize_css(input)
+ (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input)
+ end
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tag_node_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tag_node_test.rb
new file mode 100644
index 000000000..daeada9b9
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tag_node_test.rb
@@ -0,0 +1,239 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class TagNodeTest < Test::Unit::TestCase
+ def test_open_without_attributes
+ node = tag("<tag>")
+ assert_equal "tag", node.name
+ assert_equal Hash.new, node.attributes
+ assert_nil node.closing
+ end
+
+ def test_open_with_attributes
+ node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >")
+ assert_equal "tag1", node.name
+ assert_equal "hey_ho", node["foo"]
+ assert_equal "blah blah", node["x:bar"]
+ assert_equal "blah blah blah", node["baz"]
+ end
+
+ def test_self_closing_without_attributes
+ node = tag("<tag/>")
+ assert_equal "tag", node.name
+ assert_equal Hash.new, node.attributes
+ assert_equal :self, node.closing
+ end
+
+ def test_self_closing_with_attributes
+ node = tag("<tag a=b/>")
+ assert_equal "tag", node.name
+ assert_equal( { "a" => "b" }, node.attributes )
+ assert_equal :self, node.closing
+ end
+
+ def test_closing_without_attributes
+ node = tag("</tag>")
+ assert_equal "tag", node.name
+ assert_nil node.attributes
+ assert_equal :close, node.closing
+ end
+
+ def test_bracket_op_when_no_attributes
+ node = tag("</tag>")
+ assert_nil node["foo"]
+ end
+
+ def test_bracket_op_when_attributes
+ node = tag("<tag a=b/>")
+ assert_equal "b", node["a"]
+ end
+
+ def test_attributes_with_escaped_quotes
+ node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">")
+ assert_equal "b\\'c", node["a"]
+ assert_equal "bob \\\"float\\\"", node["b"]
+ end
+
+ def test_to_s
+ node = tag("<a b=c d='f' g=\"h 'i'\" />")
+ assert_equal %(<a b='c' d='f' g='h \\'i\\'' />), node.to_s
+ end
+
+ def test_tag
+ assert tag("<tag>").tag?
+ end
+
+ def test_match_tag_as_string
+ assert tag("<tag>").match(:tag => "tag")
+ assert !tag("<tag>").match(:tag => "b")
+ end
+
+ def test_match_tag_as_regexp
+ assert tag("<tag>").match(:tag => /t.g/)
+ assert !tag("<tag>").match(:tag => /t[bqs]g/)
+ end
+
+ def test_match_attributes_as_string
+ t = tag("<tag a=something b=else />")
+ assert t.match(:attributes => {"a" => "something"})
+ assert t.match(:attributes => {"b" => "else"})
+ end
+
+ def test_match_attributes_as_regexp
+ t = tag("<tag a=something b=else />")
+ assert t.match(:attributes => {"a" => /^something$/})
+ assert t.match(:attributes => {"b" => /e.*e/})
+ assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/})
+ end
+
+ def test_match_attributes_as_number
+ t = tag("<tag a=15 b=3.1415 />")
+ assert t.match(:attributes => {"a" => 15})
+ assert t.match(:attributes => {"b" => 3.1415})
+ assert t.match(:attributes => {"a" => 15, "b" => 3.1415})
+ end
+
+ def test_match_attributes_exist
+ t = tag("<tag a=15 b=3.1415 />")
+ assert t.match(:attributes => {"a" => true})
+ assert t.match(:attributes => {"b" => true})
+ assert t.match(:attributes => {"a" => true, "b" => true})
+ end
+
+ def test_match_attributes_not_exist
+ t = tag("<tag a=15 b=3.1415 />")
+ assert t.match(:attributes => {"c" => false})
+ assert t.match(:attributes => {"c" => nil})
+ assert t.match(:attributes => {"a" => true, "c" => false})
+ end
+
+ def test_match_parent_success
+ t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
+ assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}})
+ end
+
+ def test_match_parent_fail
+ t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
+ assert !t.match(:parent => {:tag => /kafka/})
+ end
+
+ def test_match_child_success
+ t = tag("<tag x:k='something'>")
+ tag("<child v=john a=kelly>", t)
+ tag("<sib m=vaughn v=james>", t)
+ assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}})
+ assert t.match(:child => { :attributes => {"a" => "kelly"}})
+ end
+
+ def test_match_child_fail
+ t = tag("<tag x:k='something'>")
+ tag("<child v=john a=kelly>", t)
+ tag("<sib m=vaughn v=james>", t)
+ assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}})
+ assert !t.match(:child => { :attributes => {"v" => false}})
+ end
+
+ def test_match_ancestor_success
+ t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
+ assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}})
+ assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}})
+ end
+
+ def test_match_ancestor_fail
+ t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
+ assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}})
+ assert !t.match(:ancestor => {:attributes => {"v" => false}})
+ end
+
+ def test_match_descendant_success
+ tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
+ assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}})
+ assert t.match(:descendant => {:attributes => {"m" => "vaughn"}})
+ end
+
+ def test_match_descendant_fail
+ tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
+ assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}})
+ assert !t.match(:descendant => {:attributes => {"v" => false}})
+ end
+
+ def test_match_child_count
+ t = tag("<tag x:k='something'>")
+ tag("hello", t)
+ tag("<child v=john a=kelly>", t)
+ tag("<sib m=vaughn v=james>", t)
+ assert t.match(:children => { :count => 2 })
+ assert t.match(:children => { :count => 2..4 })
+ assert t.match(:children => { :less_than => 4 })
+ assert t.match(:children => { :greater_than => 1 })
+ assert !t.match(:children => { :count => 3 })
+ end
+
+ def test_conditions_as_strings
+ t = tag("<tag x:k='something'>")
+ assert t.match("tag" => "tag")
+ assert t.match("attributes" => { "x:k" => "something" })
+ assert !t.match("tag" => "gat")
+ assert !t.match("attributes" => { "x:j" => "something" })
+ end
+
+ def test_attributes_as_symbols
+ t = tag("<child v=john a=kelly>")
+ assert t.match(:attributes => { :v => /oh/ })
+ assert t.match(:attributes => { :a => /ll/ })
+ end
+
+ def test_match_sibling
+ t = tag("<tag x:k='something'>")
+ tag("hello", t)
+ tag("<span a=b>", t)
+ tag("world", t)
+ m = tag("<span k=r>", t)
+ tag("<span m=l>", t)
+
+ assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}})
+ assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}})
+ assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}})
+ end
+
+ def test_match_sibling_before
+ t = tag("<tag x:k='something'>")
+ tag("hello", t)
+ tag("<span a=b>", t)
+ tag("world", t)
+ m = tag("<span k=r>", t)
+ tag("<span m=l>", t)
+
+ assert m.match(:before => {:tag => "span", :attributes => {:m => true}})
+ assert !m.match(:before => {:tag => "span", :attributes => {:a => true}})
+ assert !m.match(:before => {:tag => "span", :attributes => {:k => true}})
+ end
+
+ def test_match_sibling_after
+ t = tag("<tag x:k='something'>")
+ tag("hello", t)
+ tag("<span a=b>", t)
+ tag("world", t)
+ m = tag("<span k=r>", t)
+ tag("<span m=l>", t)
+
+ assert m.match(:after => {:tag => "span", :attributes => {:a => true}})
+ assert !m.match(:after => {:tag => "span", :attributes => {:m => true}})
+ assert !m.match(:after => {:tag => "span", :attributes => {:k => true}})
+ end
+
+ def test_to_s
+ t = tag("<b x='foo'>")
+ tag("hello", t)
+ tag("<hr />", t)
+ assert_equal %(<b x="foo">hello<hr /></b>), t.to_s
+ end
+
+ private
+
+ def tag(content, parent=nil)
+ node = HTML::Node.parse(parent,0,0,content)
+ parent.children << node if parent
+ node
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/text_node_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/text_node_test.rb
new file mode 100644
index 000000000..9853701fd
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/text_node_test.rb
@@ -0,0 +1,51 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class TextNodeTest < Test::Unit::TestCase
+ def setup
+ @node = HTML::Text.new(nil, 0, 0, "hello, howdy, aloha, annyeong")
+ end
+
+ def test_to_s
+ assert_equal "hello, howdy, aloha, annyeong", @node.to_s
+ end
+
+ def test_find_string
+ assert_equal @node, @node.find("hello, howdy, aloha, annyeong")
+ assert_equal false, @node.find("bogus")
+ end
+
+ def test_find_regexp
+ assert_equal @node, @node.find(/an+y/)
+ assert_nil @node.find(/b/)
+ end
+
+ def test_find_hash
+ assert_equal @node, @node.find(:content => /howdy/)
+ assert_nil @node.find(:content => /^howdy$/)
+ assert_equal false, @node.find(:content => "howdy")
+ end
+
+ def test_find_other
+ assert_nil @node.find(:hello)
+ end
+
+ def test_match_string
+ assert @node.match("hello, howdy, aloha, annyeong")
+ assert_equal false, @node.match("bogus")
+ end
+
+ def test_match_regexp
+ assert_not_nil @node, @node.match(/an+y/)
+ assert_nil @node.match(/b/)
+ end
+
+ def test_match_hash
+ assert_not_nil @node, @node.match(:content => "howdy")
+ assert_nil @node.match(:content => /^howdy$/)
+ end
+
+ def test_match_other
+ assert_nil @node.match(:hello)
+ end
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tokenizer_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tokenizer_test.rb
new file mode 100644
index 000000000..437136b9a
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/html-scanner/tokenizer_test.rb
@@ -0,0 +1,125 @@
+require File.dirname(__FILE__) + '/../../abstract_unit'
+require 'test/unit'
+
+class TokenizerTest < Test::Unit::TestCase
+
+ def test_blank
+ tokenize ""
+ assert_end
+ end
+
+ def test_space
+ tokenize " "
+ assert_next " "
+ assert_end
+ end
+
+ def test_tag_simple_open
+ tokenize "<tag>"
+ assert_next "<tag>"
+ assert_end
+ end
+
+ def test_tag_simple_self_closing
+ tokenize "<tag />"
+ assert_next "<tag />"
+ assert_end
+ end
+
+ def test_tag_simple_closing
+ tokenize "</tag>"
+ assert_next "</tag>"
+ end
+
+ def test_tag_with_single_quoted_attribute
+ tokenize %{<tag a='hello'>x}
+ assert_next %{<tag a='hello'>}
+ end
+
+ def test_tag_with_single_quoted_attribute_with_escape
+ tokenize %{<tag a='hello\\''>x}
+ assert_next %{<tag a='hello\\''>}
+ end
+
+ def test_tag_with_double_quoted_attribute
+ tokenize %{<tag a="hello">x}
+ assert_next %{<tag a="hello">}
+ end
+
+ def test_tag_with_double_quoted_attribute_with_escape
+ tokenize %{<tag a="hello\\"">x}
+ assert_next %{<tag a="hello\\"">}
+ end
+
+ def test_tag_with_unquoted_attribute
+ tokenize %{<tag a=hello>x}
+ assert_next %{<tag a=hello>}
+ end
+
+ def test_tag_with_lt_char_in_attribute
+ tokenize %{<tag a="x < y">x}
+ assert_next %{<tag a="x < y">}
+ end
+
+ def test_tag_with_gt_char_in_attribute
+ tokenize %{<tag a="x > y">x}
+ assert_next %{<tag a="x > y">}
+ end
+
+ def test_doctype_tag
+ tokenize %{<!DOCTYPE "blah" "blah" "blah">\n <html>}
+ assert_next %{<!DOCTYPE "blah" "blah" "blah">}
+ assert_next %{\n }
+ assert_next %{<html>}
+ end
+
+ def test_cdata_tag
+ tokenize %{<![CDATA[<br>]]>}
+ assert_next %{<![CDATA[<br>]]>}
+ assert_end
+ end
+
+ def test_less_than_with_space
+ tokenize %{original < hello > world}
+ assert_next %{original }
+ assert_next %{< hello > world}
+ end
+
+ def test_less_than_without_matching_greater_than
+ tokenize %{hello <span onmouseover="gotcha"\n<b>foo</b>\nbar</span>}
+ assert_next %{hello }
+ assert_next %{<span onmouseover="gotcha"\n}
+ assert_next %{<b>}
+ assert_next %{foo}
+ assert_next %{</b>}
+ assert_next %{\nbar}
+ assert_next %{</span>}
+ assert_end
+ end
+
+ def test_unterminated_comment
+ tokenize %{hello <!-- neverending...}
+ assert_next %{hello }
+ assert_next %{<!-- neverending...}
+ assert_end
+ end
+
+ private
+
+ def tokenize(text)
+ @tokenizer = HTML::Tokenizer.new(text)
+ end
+
+ def assert_next(expected, message=nil)
+ token = @tokenizer.next
+ assert_equal expected, token, message
+ end
+
+ def assert_sequence(*expected)
+ assert_next expected.shift until expected.empty?
+ end
+
+ def assert_end(message=nil)
+ assert_nil @tokenizer.next, message
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/http_authentication_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/http_authentication_test.rb
new file mode 100644
index 000000000..6f7b31a41
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/http_authentication_test.rb
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../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
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/integration_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/integration_test.rb
new file mode 100644
index 000000000..4213bb4af
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/integration_test.rb
@@ -0,0 +1,255 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+$:.unshift File.dirname(__FILE__) + '/../../../railties/lib'
+require 'action_controller/integration'
+
+uses_mocha 'integration' do
+
+# Stub process for testing.
+module ActionController
+ module Integration
+ class Session
+ def process(*args)
+ end
+
+ def generic_url_rewriter
+ end
+ end
+ end
+end
+
+class SessionTest < Test::Unit::TestCase
+ def setup
+ @session = ActionController::Integration::Session.new
+ end
+ def test_https_bang_works_and_sets_truth_by_default
+ assert !@session.https?
+ @session.https!
+ assert @session.https?
+ @session.https! false
+ assert !@session.https?
+ end
+
+ def test_host!
+ assert_not_equal "glu.ttono.us", @session.host
+ @session.host! "rubyonrails.com"
+ assert_equal "rubyonrails.com", @session.host
+ end
+
+ def test_follow_redirect_raises_when_no_redirect
+ @session.stubs(:redirect?).returns(false)
+ 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)
+ @session.stubs(:redirect?).returns(false)
+ @session.request_via_redirect(:put, path, args, headers)
+ end
+
+ def test_request_via_redirect_follows_redirects
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
+ @session.stubs(:redirect?).returns(true, true, false)
+ @session.expects(:follow_redirect!).times(2)
+ @session.request_via_redirect(:get, path, args, headers)
+ end
+
+ def test_request_via_redirect_returns_status
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
+ @session.stubs(:redirect?).returns(false)
+ @session.stubs(:status).returns(200)
+ assert_equal 200, @session.request_via_redirect(:get, path, args, headers)
+ end
+
+ def test_get_via_redirect
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
+ @session.expects(:request_via_redirect).with(:get, path, args, headers)
+ @session.get_via_redirect(path, args, headers)
+ end
+
+ def test_post_via_redirect
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
+ @session.expects(:request_via_redirect).with(:post, path, args, headers)
+ @session.post_via_redirect(path, args, headers)
+ end
+
+ def test_put_via_redirect
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
+ @session.expects(:request_via_redirect).with(:put, path, args, headers)
+ @session.put_via_redirect(path, args, headers)
+ end
+
+ def test_delete_via_redirect
+ path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue" }
+ @session.expects(:request_via_redirect).with(:delete, path, args, headers)
+ @session.delete_via_redirect(path, args, headers)
+ end
+
+ def test_url_for_with_controller
+ options = {:action => 'show'}
+ mock_controller = mock()
+ mock_controller.expects(:url_for).with(options).returns('/show')
+ @session.stubs(:controller).returns(mock_controller)
+ assert_equal '/show', @session.url_for(options)
+ end
+
+ def test_url_for_without_controller
+ options = {:action => 'show'}
+ mock_rewriter = mock()
+ mock_rewriter.expects(:rewrite).with(options).returns('/show')
+ @session.stubs(:generic_url_rewriter).returns(mock_rewriter)
+ @session.stubs(:controller).returns(nil)
+ assert_equal '/show', @session.url_for(options)
+ end
+
+ def test_redirect_bool_with_status_in_300s
+ @session.stubs(:status).returns 301
+ assert @session.redirect?
+ end
+
+ def test_redirect_bool_with_status_in_200s
+ @session.stubs(:status).returns 200
+ assert !@session.redirect?
+ end
+
+ def test_get
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ @session.expects(:process).with(:get,path,params,headers)
+ @session.get(path,params,headers)
+ end
+
+ def test_post
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ @session.expects(:process).with(:post,path,params,headers)
+ @session.post(path,params,headers)
+ end
+
+ def test_put
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ @session.expects(:process).with(:put,path,params,headers)
+ @session.put(path,params,headers)
+ end
+
+ def test_delete
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ @session.expects(:process).with(:delete,path,params,headers)
+ @session.delete(path,params,headers)
+ end
+
+ def test_head
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ @session.expects(:process).with(:head,path,params,headers)
+ @session.head(path,params,headers)
+ end
+
+ def test_xml_http_request_get
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest",
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
+ )
+ @session.expects(:process).with(:get,path,params,headers_after_xhr)
+ @session.xml_http_request(:get,path,params,headers)
+ end
+
+ def test_xml_http_request_post
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest",
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
+ )
+ @session.expects(:process).with(:post,path,params,headers_after_xhr)
+ @session.xml_http_request(:post,path,params,headers)
+ end
+
+ def test_xml_http_request_put
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest",
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
+ )
+ @session.expects(:process).with(:put,path,params,headers_after_xhr)
+ @session.xml_http_request(:put,path,params,headers)
+ end
+
+ def test_xml_http_request_delete
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest",
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
+ )
+ @session.expects(:process).with(:delete,path,params,headers_after_xhr)
+ @session.xml_http_request(:delete,path,params,headers)
+ end
+
+ def test_xml_http_request_head
+ path = "/index"; params = "blah"; headers = {:location => 'blah'}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest",
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
+ )
+ @session.expects(:process).with(:head,path,params,headers_after_xhr)
+ @session.xml_http_request(:head,path,params,headers)
+ end
+
+ def test_xml_http_request_override_accept
+ path = "/index"; params = "blah"; headers = {:location => 'blah', "Accept" => "application/xml"}
+ headers_after_xhr = headers.merge(
+ "X-Requested-With" => "XMLHttpRequest"
+ )
+ @session.expects(:process).with(:post,path,params,headers_after_xhr)
+ @session.xml_http_request(:post,path,params,headers)
+ end
+end
+
+class IntegrationTestTest < Test::Unit::TestCase
+
+ def setup
+ @test = ::ActionController::IntegrationTest.new(:default_test)
+ @test.class.stubs(:fixture_table_names).returns([])
+ @session = @test.open_session
+ end
+
+ def test_opens_new_session
+ @test.class.expects(:fixture_table_names).times(2).returns(['foo'])
+
+ session1 = @test.open_session { |sess| }
+ session2 = @test.open_session # implicit session
+
+ assert_equal ::ActionController::Integration::Session, session1.class
+ assert_equal ::ActionController::Integration::Session, session2.class
+ assert_not_equal session1, session2
+ 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
+
+ def self.fixture_table_names
+ []
+ end
+
+ def test_integration_methods_called
+ %w( get post head put delete ).each do |verb|
+ assert_nothing_raised("'#{verb}' should use integration test methods") { send!(verb, '/') }
+ end
+ end
+
+end
+
+# TODO
+# class MockCGITest < Test::Unit::TestCase
+# end
+
+end # uses_mocha
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/layout_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/layout_test.rb
new file mode 100644
index 000000000..85cc3a084
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/layout_test.rb
@@ -0,0 +1,239 @@
+require File.dirname(__FILE__) + '/../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
+ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ]
+
+class LayoutTest < ActionController::Base
+ def self.controller_path; 'views' end
+ self.view_paths = ActionController::Base.view_paths.dup
+end
+
+# Restore view_paths to previous value
+ActionController::Base.view_paths = old_load_paths
+
+class ProductController < LayoutTest
+end
+
+class ItemController < LayoutTest
+end
+
+class ThirdPartyTemplateLibraryController < LayoutTest
+end
+
+module ControllerNameSpace
+end
+
+class ControllerNameSpace::NestedController < LayoutTest
+end
+
+class MultipleExtensions < LayoutTest
+end
+
+class MabView
+ def initialize(view)
+ end
+
+ def render(text, locals = {})
+ text
+ end
+end
+
+ActionView::Base::register_template_handler :mab, MabView
+
+class LayoutAutoDiscoveryTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_application_layout_is_default_when_no_controller_match
+ @controller = ProductController.new
+ get :hello
+ assert_equal 'layout_test.rhtml hello.rhtml', @response.body
+ end
+
+ def test_controller_name_layout_name_match
+ @controller = ItemController.new
+ get :hello
+ assert_equal 'item.rhtml hello.rhtml', @response.body
+ end
+
+ def test_third_party_template_library_auto_discovers_layout
+ @controller = ThirdPartyTemplateLibraryController.new
+ get :hello
+ assert_equal 'layouts/third_party_template_library', @controller.active_layout
+ assert_equal 'layouts/third_party_template_library', @response.layout
+ assert_equal 'Mab', @response.body
+ end
+
+ 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 '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 'multiple_extensions.html.erb hello.rhtml', @response.body.strip
+ end
+end
+
+class ExemptFromLayoutTest < Test::Unit::TestCase
+ def setup
+ @controller = LayoutTest.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_rjs_exempt_from_layout
+ assert @controller.send!(:template_exempt_from_layout?, 'test.rjs')
+ end
+
+ def test_rhtml_and_rxml_not_exempt_from_layout
+ assert !@controller.send!(:template_exempt_from_layout?, 'test.rhtml')
+ assert !@controller.send!(:template_exempt_from_layout?, 'test.rxml')
+ end
+
+ def test_other_extension_not_exempt_from_layout
+ assert !@controller.send!(:template_exempt_from_layout?, 'test.random')
+ end
+
+ def test_add_extension_to_exempt_from_layout
+ ['rpdf', :rpdf].each do |ext|
+ assert_nothing_raised do
+ ActionController::Base.exempt_from_layout ext
+ end
+ assert @controller.send!(:template_exempt_from_layout?, "test.#{ext}")
+ end
+ end
+
+ def test_add_regexp_to_exempt_from_layout
+ ActionController::Base.exempt_from_layout /\.rdoc/
+ assert @controller.send!(:template_exempt_from_layout?, 'test.rdoc')
+ end
+
+ def test_rhtml_exempt_from_layout_status_should_prevent_layout_render
+ ActionController::Base.exempt_from_layout :rhtml
+
+ assert @controller.send!(:template_exempt_from_layout?, 'test.rhtml')
+ assert @controller.send!(:template_exempt_from_layout?, 'hello.rhtml')
+
+ get :hello
+ assert_equal 'hello.rhtml', @response.body
+ ActionController::Base.exempt_from_layout.delete(/\.rhtml$/)
+ end
+end
+
+
+class DefaultLayoutController < LayoutTest
+end
+
+class HasOwnLayoutController < LayoutTest
+ layout 'item'
+end
+
+class SetsLayoutInRenderController < LayoutTest
+ def hello
+ render :layout => 'third_party_template_library'
+ end
+end
+
+class RendersNoLayoutController < LayoutTest
+ def hello
+ render :layout => false
+ end
+end
+
+class LayoutSetInResponseTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_layout_set_when_using_default_layout
+ @controller = DefaultLayoutController.new
+ get :hello
+ assert_equal 'layouts/layout_test', @response.layout
+ end
+
+ def test_layout_set_when_set_in_controller
+ @controller = HasOwnLayoutController.new
+ get :hello
+ assert_equal 'layouts/item', @response.layout
+ end
+
+ def test_layout_set_when_using_render
+ @controller = SetsLayoutInRenderController.new
+ get :hello
+ assert_equal 'layouts/third_party_template_library', @response.layout
+ end
+
+ def test_layout_is_not_set_when_none_rendered
+ @controller = RendersNoLayoutController.new
+ get :hello
+ assert_nil @response.layout
+ end
+
+ def test_exempt_from_layout_honored_by_render_template
+ ActionController::Base.exempt_from_layout :rhtml
+ @controller = RenderWithTemplateOptionController.new
+
+ assert @controller.send(:template_exempt_from_layout?, 'alt/hello.rhtml')
+
+ get :hello
+ assert_equal "alt/hello.rhtml", @response.body.strip
+
+ ensure
+ ActionController::Base.exempt_from_layout.delete(/\.rhtml$/)
+ end
+end
+
+class RenderWithTemplateOptionController < LayoutTest
+ def hello
+ render :template => 'alt/hello'
+ end
+end
+
+class SetsNonExistentLayoutFile < LayoutTest
+ layout "nofile.rhtml"
+end
+
+class LayoutExceptionRaised < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_exception_raised_when_layout_file_not_found
+ @controller = SetsNonExistentLayoutFile.new
+ get :hello
+ @response.template.class.module_eval { attr_accessor :exception }
+ assert_equal ActionController::MissingTemplate, @response.template.exception.class
+ end
+end
+
+class LayoutStatusIsRendered < LayoutTest
+ def hello
+ render :status => 401
+ end
+end
+
+class LayoutStatusIsRenderedTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_layout_status_is_rendered
+ @controller = LayoutStatusIsRendered.new
+ get :hello
+ assert_response 401
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/mime_responds_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/mime_responds_test.rb
new file mode 100644
index 000000000..f121dd9f8
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/mime_responds_test.rb
@@ -0,0 +1,506 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class RespondToController < ActionController::Base
+ layout :set_layout
+
+ def html_xml_or_rss
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.xml { render :text => "XML" }
+ type.rss { render :text => "RSS" }
+ type.all { render :text => "Nothing" }
+ end
+ end
+
+ def js_or_html
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.js { render :text => "JS" }
+ type.all { render :text => "Nothing" }
+ end
+ end
+
+ def json_or_yaml
+ respond_to do |type|
+ type.json { render :text => "JSON" }
+ type.yaml { render :text => "YAML" }
+ end
+ end
+
+ def html_or_xml
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.xml { render :text => "XML" }
+ type.all { render :text => "Nothing" }
+ end
+ end
+
+ def forced_xml
+ request.format = :xml
+
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.xml { render :text => "XML" }
+ end
+ end
+
+ def just_xml
+ respond_to do |type|
+ type.xml { render :text => "XML" }
+ end
+ end
+
+ def using_defaults
+ respond_to do |type|
+ type.html
+ type.js
+ type.xml
+ end
+ end
+
+ def using_defaults_with_type_list
+ respond_to(:html, :js, :xml)
+ end
+
+ def made_for_content_type
+ respond_to do |type|
+ type.rss { render :text => "RSS" }
+ type.atom { render :text => "ATOM" }
+ type.all { render :text => "Nothing" }
+ end
+ end
+
+ def custom_type_handling
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.custom("application/crazy-xml") { render :text => "Crazy XML" }
+ type.all { render :text => "Nothing" }
+ end
+ end
+
+ def custom_constant_handling
+ Mime::Type.register("text/x-mobile", :mobile)
+
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.mobile { render :text => "Mobile" }
+ end
+ ensure
+ Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
+ end
+
+ def custom_constant_handling_without_block
+ Mime::Type.register("text/x-mobile", :mobile)
+
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.mobile
+ end
+
+ ensure
+ Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
+ end
+
+ def handle_any
+ respond_to do |type|
+ type.html { render :text => "HTML" }
+ type.any(:js, :xml) { render :text => "Either JS or XML" }
+ end
+ end
+
+ def all_types_with_layout
+ respond_to do |type|
+ type.html
+ type.js
+ end
+ end
+
+ def iphone_with_html_response_type
+ Mime::Type.register_alias("text/html", :iphone)
+ request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
+
+ respond_to do |type|
+ type.html { @type = "Firefox" }
+ type.iphone { @type = "iPhone" }
+ end
+
+ ensure
+ Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
+ end
+
+ def iphone_with_html_response_type_without_layout
+ Mime::Type.register_alias("text/html", :iphone)
+ request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
+
+ respond_to do |type|
+ type.html { @type = "Firefox"; render :action => "iphone_with_html_response_type" }
+ type.iphone { @type = "iPhone" ; render :action => "iphone_with_html_response_type" }
+ end
+
+ ensure
+ Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
+ end
+
+ def rescue_action(e)
+ raise
+ end
+
+ protected
+ def set_layout
+ if ["all_types_with_layout", "iphone_with_html_response_type"].include?(action_name)
+ "respond_to/layouts/standard"
+ elsif action_name == "iphone_with_html_response_type_without_layout"
+ "respond_to/layouts/missing"
+ end
+ end
+end
+
+RespondToController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class MimeControllerTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @controller = RespondToController.new
+ @request.host = "www.example.com"
+ end
+
+ def test_html
+ @request.env["HTTP_ACCEPT"] = "text/html"
+ get :js_or_html
+ assert_equal 'HTML', @response.body
+
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+
+ get :just_xml
+ assert_response 406
+ end
+
+ def test_all
+ @request.env["HTTP_ACCEPT"] = "*/*"
+ get :js_or_html
+ assert_equal 'HTML', @response.body # js is not part of all
+
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+
+ get :just_xml
+ assert_equal 'XML', @response.body
+ end
+
+ def test_xml
+ @request.env["HTTP_ACCEPT"] = "application/xml"
+ get :html_xml_or_rss
+ assert_equal 'XML', @response.body
+ end
+
+ def test_js_or_html
+ @request.env["HTTP_ACCEPT"] = "text/javascript, text/html"
+ get :js_or_html
+ assert_equal 'JS', @response.body
+
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+
+ get :just_xml
+ assert_response 406
+ end
+
+ def test_json_or_yaml
+ get :json_or_yaml
+ assert_equal 'JSON', @response.body
+
+ get :json_or_yaml, :format => 'json'
+ assert_equal 'JSON', @response.body
+
+ get :json_or_yaml, :format => 'yaml'
+ assert_equal 'YAML', @response.body
+
+ { 'YAML' => %w(text/yaml),
+ 'JSON' => %w(application/json text/x-json)
+ }.each do |body, content_types|
+ content_types.each do |content_type|
+ @request.env['HTTP_ACCEPT'] = content_type
+ get :json_or_yaml
+ assert_equal body, @response.body
+ end
+ end
+ end
+
+ def test_js_or_anything
+ @request.env["HTTP_ACCEPT"] = "text/javascript, */*"
+ get :js_or_html
+ assert_equal 'JS', @response.body
+
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+
+ get :just_xml
+ assert_equal 'XML', @response.body
+ end
+
+ def test_using_defaults
+ @request.env["HTTP_ACCEPT"] = "*/*"
+ get :using_defaults
+ assert_equal "text/html", @response.content_type
+ assert_equal 'Hello world!', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
+ get :using_defaults
+ assert_equal "text/javascript", @response.content_type
+ assert_equal '$("body").visualEffect("highlight");', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "application/xml"
+ get :using_defaults
+ assert_equal "application/xml", @response.content_type
+ assert_equal "<p>Hello world!</p>\n", @response.body
+ end
+
+ def test_using_defaults_with_type_list
+ @request.env["HTTP_ACCEPT"] = "*/*"
+ get :using_defaults_with_type_list
+ assert_equal "text/html", @response.content_type
+ assert_equal 'Hello world!', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
+ get :using_defaults_with_type_list
+ assert_equal "text/javascript", @response.content_type
+ assert_equal '$("body").visualEffect("highlight");', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "application/xml"
+ get :using_defaults_with_type_list
+ assert_equal "application/xml", @response.content_type
+ assert_equal "<p>Hello world!</p>\n", @response.body
+ end
+
+ def test_with_atom_content_type
+ @request.env["CONTENT_TYPE"] = "application/atom+xml"
+ get :made_for_content_type
+ assert_equal "ATOM", @response.body
+ end
+
+ def test_with_rss_content_type
+ @request.env["CONTENT_TYPE"] = "application/rss+xml"
+ get :made_for_content_type
+ assert_equal "RSS", @response.body
+ end
+
+ def test_synonyms
+ @request.env["HTTP_ACCEPT"] = "application/javascript"
+ get :js_or_html
+ assert_equal 'JS', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "application/x-xml"
+ get :html_xml_or_rss
+ assert_equal "XML", @response.body
+ end
+
+ def test_custom_types
+ @request.env["HTTP_ACCEPT"] = "application/crazy-xml"
+ get :custom_type_handling
+ assert_equal "application/crazy-xml", @response.content_type
+ assert_equal 'Crazy XML', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/html"
+ get :custom_type_handling
+ assert_equal "text/html", @response.content_type
+ assert_equal 'HTML', @response.body
+ end
+
+ def test_xhtml_alias
+ @request.env["HTTP_ACCEPT"] = "application/xhtml+xml,application/xml"
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+ end
+
+ def test_firefox_simulation
+ @request.env["HTTP_ACCEPT"] = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
+ get :html_or_xml
+ assert_equal 'HTML', @response.body
+ end
+
+ def test_handle_any
+ @request.env["HTTP_ACCEPT"] = "*/*"
+ get :handle_any
+ assert_equal 'HTML', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
+ get :handle_any
+ assert_equal 'Either JS or XML', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/xml"
+ get :handle_any
+ assert_equal 'Either JS or XML', @response.body
+ end
+
+ def test_rjs_type_skips_layout
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
+ get :all_types_with_layout
+ assert_equal 'RJS for all_types_with_layout', @response.body
+ end
+
+ def test_html_type_with_layout
+ @request.env["HTTP_ACCEPT"] = "text/html"
+ get :all_types_with_layout
+ assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
+ end
+
+ def test_xhr
+ xhr :get, :js_or_html
+ assert_equal 'JS', @response.body
+
+ xhr :get, :using_defaults
+ assert_equal '$("body").visualEffect("highlight");', @response.body
+ end
+
+ def test_custom_constant
+ get :custom_constant_handling, :format => "mobile"
+ assert_equal "text/x-mobile", @response.content_type
+ assert_equal "Mobile", @response.body
+ end
+
+ def test_custom_constant_handling_without_block
+ get :custom_constant_handling_without_block, :format => "mobile"
+ assert_equal "text/x-mobile", @response.content_type
+ assert_equal "Mobile", @response.body
+ end
+
+ def test_forced_format
+ get :html_xml_or_rss
+ assert_equal "HTML", @response.body
+
+ get :html_xml_or_rss, :format => "html"
+ assert_equal "HTML", @response.body
+
+ get :html_xml_or_rss, :format => "xml"
+ assert_equal "XML", @response.body
+
+ get :html_xml_or_rss, :format => "rss"
+ assert_equal "RSS", @response.body
+ end
+
+ def test_internally_forced_format
+ get :forced_xml
+ assert_equal "XML", @response.body
+
+ get :forced_xml, :format => "html"
+ assert_equal "XML", @response.body
+ end
+
+ def test_extension_synonyms
+ get :html_xml_or_rss, :format => "xhtml"
+ assert_equal "HTML", @response.body
+ end
+
+ def test_render_action_for_html
+ @controller.instance_eval do
+ def render(*args)
+ unless args.empty?
+ @action = args.first[:action]
+ end
+ response.body = "#{@action} - #{@template.template_format}"
+ end
+ end
+
+ get :using_defaults
+ assert_equal "using_defaults - html", @response.body
+
+ get :using_defaults, :format => "xml"
+ assert_equal "using_defaults - xml", @response.body
+ end
+
+ def test_format_with_custom_response_type
+ get :iphone_with_html_response_type
+ assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body
+
+ get :iphone_with_html_response_type, :format => "iphone"
+ assert_equal "text/html", @response.content_type
+ assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
+ end
+
+ def test_format_with_custom_response_type_and_request_headers
+ @request.env["HTTP_ACCEPT"] = "text/iphone"
+ get :iphone_with_html_response_type
+ assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_format_with_custom_response_type_and_request_headers_with_only_one_layout_present
+ get :iphone_with_html_response_type_without_layout
+ assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/iphone"
+ assert_raises(ActionController::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
+ end
+end
+
+class AbstractPostController < ActionController::Base
+ class << self
+ def view_paths
+ [ File.dirname(__FILE__) + "/../fixtures/post_test/" ]
+ end
+ end
+end
+
+# For testing layouts which are set automatically
+class PostController < AbstractPostController
+ around_filter :with_iphone
+
+ def index
+ respond_to do |type|
+ type.html
+ type.iphone
+ end
+ end
+
+ protected
+ def with_iphone
+ Mime::Type.register_alias("text/html", :iphone)
+ request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
+ yield
+ ensure
+ Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
+ end
+end
+
+class SuperPostController < PostController
+ def index
+ respond_to do |type|
+ type.html
+ type.iphone
+ end
+ end
+end
+
+class MimeControllerLayoutsTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @controller = PostController.new
+ @request.host = "www.example.com"
+ end
+
+ def test_missing_layout_renders_properly
+ get :index
+ assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/iphone"
+ get :index
+ assert_equal 'Hello iPhone', @response.body
+ end
+
+ def test_format_with_inherited_layouts
+ @controller = SuperPostController.new
+
+ get :index
+ assert_equal 'Super Firefox', @response.body
+
+ @request.env["HTTP_ACCEPT"] = "text/iphone"
+ get :index
+ assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
+ end
+end
+
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/mime_type_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/mime_type_test.rb
new file mode 100644
index 000000000..d4aea3c01
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/mime_type_test.rb
@@ -0,0 +1,55 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class MimeTypeTest < Test::Unit::TestCase
+ Mime::Type.register "image/png", :png
+ Mime::Type.register "application/pdf", :pdf
+
+ def test_parse_single
+ Mime::LOOKUP.keys.each do |mime_type|
+ assert_equal [Mime::Type.lookup(mime_type)], Mime::Type.parse(mime_type)
+ end
+ end
+
+ def test_parse_without_q
+ accept = "text/xml,application/xhtml+xml,text/yaml,application/xml,text/html,image/png,text/plain,application/pdf,*/*"
+ expect = [Mime::HTML, Mime::XML, Mime::YAML, Mime::PNG, Mime::TEXT, Mime::PDF, Mime::ALL]
+ assert_equal expect, Mime::Type.parse(accept)
+ end
+
+ def test_parse_with_q
+ accept = "text/xml,application/xhtml+xml,text/yaml; q=0.3,application/xml,text/html; q=0.8,image/png,text/plain; q=0.5,application/pdf,*/*; q=0.2"
+ expect = [Mime::HTML, Mime::XML, Mime::PNG, Mime::PDF, Mime::TEXT, Mime::YAML, Mime::ALL]
+ assert_equal expect, Mime::Type.parse(accept)
+ end
+
+ # Accept header send with user HTTP_USER_AGENT: Sunrise/0.42j (Windows XP)
+ def test_parse_crappy_broken_acceptlines
+ accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/*,,*/*;q=0.5"
+ expect = [Mime::HTML, Mime::XML, "image/*", Mime::TEXT, Mime::ALL]
+ assert_equal expect, Mime::Type.parse(accept).collect { |c| c.to_s }
+ end
+
+ def test_custom_type
+ Mime::Type.register("image/gif", :gif)
+ assert_nothing_raised do
+ Mime::GIF
+ assert_equal Mime::GIF, Mime::SET.last
+ end
+ ensure
+ Mime.module_eval { remove_const :GIF if const_defined?(:GIF) }
+ end
+
+ def test_type_convenience_methods
+ types = [:html, :xml, :png, :pdf, :yaml, :url_encoded_form]
+ types.each do |type|
+ mime = Mime.const_get(type.to_s.upcase)
+ assert mime.send("#{type}?"), "Mime::#{type.to_s.upcase} is not #{type}?"
+ (types - [type]).each { |t| assert !mime.send("#{t}?"), "Mime::#{t.to_s.upcase} is #{t}?" }
+ end
+ end
+
+ def test_mime_all_is_html
+ assert Mime::ALL.all?, "Mime::ALL is not all?"
+ assert Mime::ALL.html?, "Mime::ALL is not html?"
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/new_render_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/new_render_test.rb
new file mode 100644
index 000000000..3168daeae
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/new_render_test.rb
@@ -0,0 +1,832 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require File.dirname(__FILE__) + '/fake_models'
+
+class CustomersController < ActionController::Base
+end
+
+module Fun
+ class GamesController < ActionController::Base
+ def hello_world
+ end
+ end
+end
+
+module NewRenderTestHelper
+ def rjs_helper_method_from_module
+ page.visual_effect :highlight
+ end
+end
+
+class NewRenderTestController < ActionController::Base
+ layout :determine_layout
+
+ def self.controller_name; "test"; end
+ def self.controller_path; "test"; end
+
+ def hello_world
+ end
+
+ def render_hello_world
+ render :template => "test/hello_world"
+ end
+
+ def render_hello_world_from_variable
+ @person = "david"
+ render :text => "hello #{@person}"
+ end
+
+ def render_action_hello_world
+ render :action => "hello_world"
+ end
+
+ def render_action_hello_world_as_symbol
+ render :action => :hello_world
+ end
+
+ def render_text_hello_world
+ render :text => "hello world"
+ end
+
+ def render_text_hello_world_with_layout
+ @variable_for_layout = ", I'm here!"
+ render :text => "hello world", :layout => true
+ end
+
+ def hello_world_with_layout_false
+ render :layout => false
+ end
+
+ def render_custom_code
+ render :text => "hello world", :status => "404 Moved"
+ end
+
+ def render_file_with_instance_variables
+ @secret = 'in the sauce'
+ path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
+ render :file => path
+ end
+
+ def render_file_with_locals
+ path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
+ render :file => path, :locals => {:secret => 'in the sauce'}
+ end
+
+ def render_file_not_using_full_path
+ @secret = 'in the sauce'
+ render :file => 'test/render_file_with_ivar', :use_full_path => true
+ end
+
+ def render_file_not_using_full_path_with_relative_path
+ @secret = 'in the sauce'
+ render :file => 'test/../test/render_file_with_ivar', :use_full_path => true
+ end
+
+ def render_file_not_using_full_path_with_dot_in_path
+ @secret = 'in the sauce'
+ render :file => 'test/dot.directory/render_file_with_ivar', :use_full_path => true
+ end
+
+ def render_xml_hello
+ @name = "David"
+ render :template => "test/hello"
+ end
+
+ def greeting
+ # let's just rely on the template
+ end
+
+ def layout_test
+ render :action => "hello_world"
+ end
+
+ def layout_test_with_different_layout
+ render :action => "hello_world", :layout => "standard"
+ end
+
+ def rendering_without_layout
+ render :action => "hello_world", :layout => false
+ end
+
+ def layout_overriding_layout
+ render :action => "hello_world", :layout => "standard"
+ end
+
+ def rendering_nothing_on_layout
+ render :nothing => true
+ end
+
+ def builder_layout_test
+ render :action => "hello"
+ end
+
+ def partials_list
+ @test_unchanged = 'hello'
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :action => "list"
+ end
+
+ def partial_only
+ render :partial => true
+ end
+
+ def partial_only_with_layout
+ render :partial => "partial_only", :layout => true
+ end
+
+ def partial_with_locals
+ render :partial => "customer", :locals => { :customer => Customer.new("david") }
+ end
+
+ def partial_collection
+ render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
+ end
+
+ def partial_collection_with_locals
+ render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
+ end
+
+ def empty_partial_collection
+ render :partial => "customer", :collection => []
+ end
+
+ def partial_with_hash_object
+ render :partial => "hash_object", :object => {:first_name => "Sam"}
+ end
+
+ def partial_hash_collection
+ render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
+ end
+
+ def partial_hash_collection_with_locals
+ render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" }
+ end
+
+ def partial_with_implicit_local_assignment
+ @customer = Customer.new("Marcel")
+ render :partial => "customer"
+ end
+
+ def missing_partial
+ render :partial => 'thisFileIsntHere'
+ end
+
+ def hello_in_a_string
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :text => "How's there? " << render_to_string(:template => "test/list")
+ end
+
+ def render_to_string_with_assigns
+ @before = "i'm before the render"
+ render_to_string :text => "foo"
+ @after = "i'm after the render"
+ render :action => "test/hello_world"
+ end
+
+ def render_to_string_with_partial
+ @partial_only = render_to_string :partial => "partial_only"
+ @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
+ render :action => "test/hello_world"
+ end
+
+ def render_to_string_with_exception
+ render_to_string :file => "exception that will not be caught - this will certainly not work", :use_full_path => true
+ end
+
+ def render_to_string_with_caught_exception
+ @before = "i'm before the render"
+ begin
+ render_to_string :file => "exception that will be caught- hope my future instance vars still work!", :use_full_path => true
+ rescue
+ end
+ @after = "i'm after the render"
+ render :action => "test/hello_world"
+ end
+
+ def accessing_params_in_template
+ render :inline => "Hello: <%= params[:name] %>"
+ end
+
+ def accessing_params_in_template_with_layout
+ render :layout => nil, :inline => "Hello: <%= params[:name] %>"
+ end
+
+ def render_with_explicit_template
+ render :template => "test/hello_world"
+ end
+
+ def double_render
+ render :text => "hello"
+ render :text => "world"
+ end
+
+ def double_redirect
+ redirect_to :action => "double_render"
+ redirect_to :action => "double_render"
+ end
+
+ def render_and_redirect
+ render :text => "hello"
+ redirect_to :action => "double_render"
+ end
+
+ def render_to_string_and_render
+ @stuff = render_to_string :text => "here is some cached stuff"
+ render :text => "Hi web users! #{@stuff}"
+ end
+
+ def rendering_with_conflicting_local_vars
+ @name = "David"
+ def @template.name() nil end
+ render :action => "potential_conflicts"
+ end
+
+ def hello_world_from_rxml_using_action
+ render :action => "hello_world_from_rxml.builder"
+ end
+
+ def hello_world_from_rxml_using_template
+ render :template => "test/hello_world_from_rxml.builder"
+ end
+
+ def head_with_location_header
+ head :location => "/foo"
+ end
+
+ def head_with_symbolic_status
+ head :status => params[:status].intern
+ end
+
+ def head_with_integer_status
+ head :status => params[:status].to_i
+ end
+
+ def head_with_string_status
+ head :status => params[:status]
+ end
+
+ def head_with_custom_header
+ head :x_custom_header => "something"
+ end
+
+ def head_with_status_code_first
+ head :forbidden, :x_custom_header => "something"
+ end
+
+ def render_with_location
+ render :xml => "<hello/>", :location => "http://example.com", :status => 201
+ end
+
+ def render_with_object_location
+ customer = Customer.new("Some guy", 1)
+ render :xml => "<customer/>", :location => customer_url(customer), :status => :created
+ end
+
+ def render_with_to_xml
+ to_xmlable = Class.new do
+ def to_xml
+ "<i-am-xml/>"
+ end
+ end.new
+
+ render :xml => to_xmlable
+ end
+
+ helper NewRenderTestHelper
+ helper do
+ def rjs_helper_method(value)
+ page.visual_effect :highlight, value
+ end
+ end
+
+ def enum_rjs_test
+ render :update do |page|
+ page.select('.product').each do |value|
+ page.rjs_helper_method_from_module
+ page.rjs_helper_method(value)
+ page.sortable(value, :url => { :action => "order" })
+ page.draggable(value)
+ end
+ end
+ end
+
+ def delete_with_js
+ @project_id = 4
+ end
+
+ def render_js_with_explicit_template
+ @project_id = 4
+ render :template => 'test/delete_with_js'
+ end
+
+ def render_js_with_explicit_action_template
+ @project_id = 4
+ render :action => 'delete_with_js'
+ end
+
+ def update_page
+ render :update do |page|
+ page.replace_html 'balance', '$37,000,000.00'
+ page.visual_effect :highlight, 'balance'
+ end
+ end
+
+ def update_page_with_instance_variables
+ @money = '$37,000,000.00'
+ @div_id = 'balance'
+ render :update do |page|
+ page.replace_html @div_id, @money
+ page.visual_effect :highlight, @div_id
+ end
+ end
+
+ def action_talk_to_layout
+ # Action template sets variable that's picked up by layout
+ end
+
+ def render_text_with_assigns
+ @hello = "world"
+ render :text => "foo"
+ end
+
+ def yield_content_for
+ render :action => "content_for", :layout => "yield"
+ end
+
+ def render_content_type_from_body
+ response.content_type = Mime::RSS
+ render :text => "hello world!"
+ end
+
+ def render_call_to_partial_with_layout
+ render :action => "calling_partial_with_layout"
+ end
+
+ def render_using_layout_around_block
+ render :action => "using_layout_around_block"
+ end
+
+ def rescue_action(e) raise end
+
+ private
+ def determine_layout
+ case action_name
+ when "hello_world", "layout_test", "rendering_without_layout",
+ "rendering_nothing_on_layout", "render_text_hello_world",
+ "render_text_hello_world_with_layout",
+ "hello_world_with_layout_false",
+ "partial_only", "partial_only_with_layout",
+ "accessing_params_in_template",
+ "accessing_params_in_template_with_layout",
+ "render_with_explicit_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 "builder_layout_test"
+ "layouts/builder"
+ when "action_talk_to_layout", "layout_overriding_layout"
+ "layouts/talk_from_action"
+ end
+ end
+end
+
+NewRenderTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class NewRenderTest < Test::Unit::TestCase
+ def setup
+ @controller = NewRenderTestController.new
+
+ # 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
+
+ def test_simple_show
+ get :hello_world
+ assert_response :success
+ assert_template "test/hello_world"
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_do_with_render
+ get :render_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_do_with_render_from_variable
+ get :render_hello_world_from_variable
+ assert_equal "hello david", @response.body
+ end
+
+ def test_do_with_render_action
+ get :render_action_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_do_with_render_action_as_symbol
+ get :render_action_hello_world_as_symbol
+ assert_template "test/hello_world"
+ end
+
+ def test_do_with_render_text
+ get :render_text_hello_world
+ assert_equal "hello world", @response.body
+ end
+
+ def test_do_with_render_text_and_layout
+ 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
+ end
+
+ def test_do_with_render_custom_code
+ get :render_custom_code
+ assert_response :missing
+ end
+
+ def test_render_file_with_instance_variables
+ get :render_file_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
+ end
+
+ def test_render_file_not_using_full_path_with_relative_path
+ get :render_file_not_using_full_path_with_relative_path
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ def test_render_file_not_using_full_path_with_dot_in_path
+ get :render_file_not_using_full_path_with_dot_in_path
+ 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_attempt_to_access_object_method
+ assert_raises(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 }
+ end
+
+ def test_access_to_request_in_view
+ view_internals_old_value = ActionController::Base.view_controller_internals
+
+ ActionController::Base.view_controller_internals = false
+ ActionController::Base.protected_variables_cache = nil
+
+ get :hello_world
+ assert !assigns.include?('request'), 'request should not be in assigns'
+
+ ActionController::Base.view_controller_internals = true
+ ActionController::Base.protected_variables_cache = nil
+
+ get :hello_world
+ assert !assigns.include?('request'), 'request should not be in assigns'
+ assert_kind_of ActionController::AbstractRequest, assigns['_request']
+ assert_kind_of ActionController::AbstractRequest, @response.template.request
+
+ ensure
+ ActionController::Base.view_controller_internals = view_internals_old_value
+ ActionController::Base.protected_variables_cache = nil
+ end
+
+ def test_render_xml
+ get :render_xml_hello
+ assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
+ end
+
+ def test_enum_rjs_test
+ get :enum_rjs_test
+ assert_equal <<-EOS.strip, @response.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)})}});
+new Draggable(value, {});
+});
+EOS
+ end
+
+ def test_render_xml_with_default
+ get :greeting
+ assert_equal "<p>This is grand!</p>\n", @response.body
+ end
+
+ def test_render_rjs_with_default
+ get :delete_with_js
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_render_rjs_template_explicitly
+ get :render_js_with_explicit_template
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_rendering_rjs_action_explicitly
+ get :render_js_with_explicit_action_template
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_layout_rendering
+ get :layout_test
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_layout_test_with_different_layout
+ get :layout_test_with_different_layout
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_rendering_without_layout
+ get :rendering_without_layout
+ assert_equal "Hello world!", @response.body
+ end
+
+ def test_layout_overriding_layout
+ get :layout_overriding_layout
+ assert_no_match %r{<title>}, @response.body
+ end
+
+ def test_rendering_nothing_on_layout
+ get :rendering_nothing_on_layout
+ assert_equal " ", @response.body
+ end
+
+ def test_render_xml_with_layouts
+ 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
+
+ def test_partial_only
+ get :partial_only
+ assert_equal "only partial", @response.body
+ end
+
+ def test_partial_only_with_layout
+ get :partial_only_with_layout
+ assert_equal "<html>only partial</html>", @response.body
+ end
+
+ def test_render_to_string
+ assert_not_deprecated { get :hello_in_a_string }
+ assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
+ end
+
+ def test_render_to_string_doesnt_break_assigns
+ get :render_to_string_with_assigns
+ assert_equal "i'm before the render", assigns(:before)
+ assert_equal "i'm after the render", assigns(:after)
+ end
+
+ def test_render_to_string_partial
+ get :render_to_string_with_partial
+ assert_equal "only partial", assigns(:partial_only)
+ assert_equal "Hello: david", assigns(:partial_with_locals)
+ end
+
+ def test_bad_render_to_string_still_throws_exception
+ assert_raises(ActionController::MissingTemplate) { get :render_to_string_with_exception }
+ end
+
+ def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
+ assert_nothing_raised { get :render_to_string_with_caught_exception }
+ assert_equal "i'm before the render", assigns(:before)
+ assert_equal "i'm after the render", assigns(:after)
+ end
+
+ def test_nested_rendering
+ get :hello_world
+ assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body
+ end
+
+ def test_accessing_params_in_template
+ get :accessing_params_in_template, :name => "David"
+ assert_equal "Hello: David", @response.body
+ end
+
+ def test_accessing_params_in_template_with_layout
+ get :accessing_params_in_template_with_layout, :name => "David"
+ assert_equal "<html>Hello: David</html>", @response.body
+ end
+
+ def test_render_with_explicit_template
+ get :render_with_explicit_template
+ assert_response :success
+ end
+
+ def test_double_render
+ assert_raises(ActionController::DoubleRenderError) { get :double_render }
+ end
+
+ def test_double_redirect
+ assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
+ end
+
+ def test_render_and_redirect
+ assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
+ end
+
+ # specify the one exception to double render rule - render_to_string followed by render
+ def test_render_to_string_and_render
+ get :render_to_string_and_render
+ assert_equal("Hi web users! here is some cached stuff", @response.body)
+ end
+
+ def test_rendering_with_conflicting_local_vars
+ get :rendering_with_conflicting_local_vars
+ assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
+ end
+
+ def test_action_talk_to_layout
+ get :action_talk_to_layout
+ assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
+ end
+
+ def test_partials_list
+ get :partials_list
+ assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
+ end
+
+ def test_partial_with_locals
+ get :partial_with_locals
+ assert_equal "Hello: david", @response.body
+ end
+
+ def test_partial_collection
+ get :partial_collection
+ assert_equal "Hello: davidHello: mary", @response.body
+ end
+
+ def test_partial_collection_with_locals
+ get :partial_collection_with_locals
+ assert_equal "Bonjour: davidBonjour: mary", @response.body
+ end
+
+ def test_empty_partial_collection
+ get :empty_partial_collection
+ assert_equal " ", @response.body
+ end
+
+ def test_partial_with_hash_object
+ get :partial_with_hash_object
+ assert_equal "Sam\nmaS\n", @response.body
+ end
+
+ def test_hash_partial_collection
+ get :partial_hash_collection
+ assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
+ end
+
+ def test_partial_hash_collection_with_locals
+ get :partial_hash_collection_with_locals
+ assert_equal "Hola: PratikHola: Amy", @response.body
+ end
+
+ def test_partial_with_implicit_local_assignment
+ get :partial_with_implicit_local_assignment
+ assert_equal "Hello: Marcel", @response.body
+ end
+
+ def test_render_missing_partial_template
+ assert_raises(ActionView::ActionViewError) do
+ get :missing_partial
+ end
+ end
+
+ def test_render_text_with_assigns
+ get :render_text_with_assigns
+ assert_equal "world", assigns["hello"]
+ end
+
+ def test_update_page
+ get :update_page
+ assert_template nil
+ assert_equal 'text/javascript; charset=utf-8', @response.headers['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_match /balance/, @response.body
+ assert_match /\$37/, @response.body
+ end
+
+ def test_yield_content_for
+ assert_not_deprecated { get :yield_content_for }
+ assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
+ end
+
+
+ def test_overwritting_rendering_relative_file_with_extension
+ get :hello_world_from_rxml_using_template
+ assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
+
+ get :hello_world_from_rxml_using_action
+ assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
+ end
+
+
+ def test_head_with_location_header
+ get :head_with_location_header
+ assert @response.body.blank?
+ assert_equal "/foo", @response.headers["Location"]
+ assert_response :ok
+ end
+
+ def test_head_with_custom_header
+ get :head_with_custom_header
+ assert @response.body.blank?
+ assert_equal "something", @response.headers["X-Custom-Header"]
+ assert_response :ok
+ end
+
+ def test_head_with_symbolic_status
+ get :head_with_symbolic_status, :status => "ok"
+ assert_equal "200 OK", @response.headers["Status"]
+ assert_response :ok
+
+ get :head_with_symbolic_status, :status => "not_found"
+ assert_equal "404 Not Found", @response.headers["Status"]
+ assert_response :not_found
+
+ 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
+ assert_response status
+ end
+ end
+
+ def test_head_with_integer_status
+ ActionController::StatusCodes::STATUS_CODES.each do |code, message|
+ get :head_with_integer_status, :status => code.to_s
+ assert_equal message, @response.message
+ end
+ end
+
+ def test_head_with_string_status
+ get :head_with_string_status, :status => "404 Eat Dirt"
+ assert_equal 404, @response.response_code
+ assert_equal "Eat Dirt", @response.message
+ assert_response :not_found
+ end
+
+ def test_head_with_status_code_first
+ get :head_with_status_code_first
+ assert_equal 403, @response.response_code
+ assert_equal "Forbidden", @response.message
+ assert_equal "something", @response.headers["X-Custom-Header"]
+ assert_response :forbidden
+ end
+
+ def test_rendering_with_location_should_set_header
+ get :render_with_location
+ assert_equal "http://example.com", @response.headers["Location"]
+ end
+
+ def test_rendering_xml_should_call_to_xml_if_possible
+ get :render_with_to_xml
+ assert_equal "<i-am-xml/>", @response.body
+ end
+
+ def test_rendering_with_object_location_should_set_header_with_url_for
+ ActionController::Routing::Routes.draw do |map|
+ map.resources :customers
+ map.connect ':controller/:action/:id'
+ end
+
+ get :render_with_object_location
+ assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
+ end
+
+ def test_render_call_to_partial_with_layout
+ get :render_call_to_partial_with_layout
+ assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
+ end
+
+ def test_using_layout_around_block
+ get :using_layout_around_block
+ assert_equal "Before (David)\nInside from block\nAfter", @response.body
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/polymorphic_routes_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/polymorphic_routes_test.rb
new file mode 100644
index 000000000..3e72063e9
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/polymorphic_routes_test.rb
@@ -0,0 +1,98 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class Article
+ attr_reader :id
+ def save; @id = 1 end
+ def new_record?; @id.nil? end
+ def name
+ @id.nil? ? 'new post' : "post ##{@id}"
+ end
+end
+
+class Comment
+ attr_reader :id
+ def post_id; 1 end
+ def save; @id = 1 end
+ def new_record?; @id.nil? end
+ def name
+ @id.nil? ? 'new comment' : "comment ##{@id}"
+ end
+end
+
+class Comment::Nested < Comment; end
+
+class Test::Unit::TestCase
+ protected
+ def articles_url
+ 'http://www.example.com/articles'
+ end
+ alias_method :new_article_url, :articles_url
+
+ def article_url(article)
+ "http://www.example.com/articles/#{article.id}"
+ end
+
+ def article_comments_url(article)
+ "http://www.example.com/articles/#{article.id}/comments"
+ end
+
+ def article_comment_url(article, comment)
+ "http://www.example.com/articles/#{article.id}/comments/#{comment.id}"
+ end
+
+ def admin_articles_url
+ "http://www.example.com/admin/articles"
+ end
+ alias_method :new_admin_article_url, :admin_articles_url
+
+ def admin_article_url(article)
+ "http://www.example.com/admin/articles/#{article.id}"
+ end
+
+ def admin_article_comments_url(article)
+ "http://www.example.com/admin/articles/#{article.id}/comments"
+ end
+
+ def admin_article_comment_url(article, comment)
+ "http://www.example.com/admin/test/articles/#{article.id}/comments/#{comment.id}"
+ end
+end
+
+
+class PolymorphicRoutesTest < Test::Unit::TestCase
+ include ActionController::PolymorphicRoutes
+
+ def setup
+ @article = Article.new
+ @comment = Comment.new
+ end
+
+ def test_with_record
+ assert_equal(articles_url, polymorphic_url(@article, :action => 'new'))
+ assert_equal(articles_url, polymorphic_url(@article))
+ @article.save
+ assert_equal(article_url(@article), polymorphic_url(@article))
+ end
+
+ # TODO: Needs to be updated to correctly know about whether the object is in a hash or not
+ def xtest_with_hash
+ @article.save
+ assert_equal(article_url(@article), polymorphic_url(:id => @article))
+ end
+
+ def test_with_array
+ assert_equal(article_comments_url(@article), polymorphic_url([@article, @comment]))
+ @comment.save
+ assert_equal(article_comment_url(@article, @comment), polymorphic_url([@article, @comment]))
+ end
+
+ def test_with_array_and_namespace
+ assert_equal(admin_articles_url, polymorphic_url([:admin, @article], :action => 'new'))
+ assert_equal(admin_articles_url, polymorphic_url([:admin, @article]))
+ @article.save
+ assert_equal(admin_article_url(@article), polymorphic_url([:admin, @article]))
+ assert_equal(admin_article_comments_url(@article), polymorphic_url([:admin, @article, @comment]))
+ @comment.save
+ assert_equal(admin_article_comment_url(@article, @comment), polymorphic_url([:admin, @article, @comment]))
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/record_identifier_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/record_identifier_test.rb
new file mode 100644
index 000000000..86d196cfd
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/record_identifier_test.rb
@@ -0,0 +1,103 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class Comment
+ attr_reader :id
+ def save; @id = 1 end
+ def new_record?; @id.nil? end
+ def name
+ @id.nil? ? 'new comment' : "comment ##{@id}"
+ end
+end
+
+class Comment::Nested < Comment; end
+
+class Test::Unit::TestCase
+ protected
+ def comments_url
+ 'http://www.example.com/comments'
+ end
+
+ def comment_url(comment)
+ "http://www.example.com/comments/#{comment.id}"
+ end
+end
+
+
+class RecordIdentifierTest < Test::Unit::TestCase
+ include ActionController::RecordIdentifier
+
+ def setup
+ @klass = Comment
+ @record = @klass.new
+ @singular = 'comment'
+ @plural = 'comments'
+ end
+
+ def test_dom_id_with_new_record
+ assert_equal "new_#{@singular}", dom_id(@record)
+ end
+
+ def test_dom_id_with_new_record_and_prefix
+ assert_equal "custom_prefix_#{@singular}", dom_id(@record, :custom_prefix)
+ end
+
+ def test_dom_id_with_saved_record
+ @record.save
+ assert_equal "#{@singular}_1", dom_id(@record)
+ end
+
+ def test_dom_id_with_prefix
+ @record.save
+ assert_equal "edit_#{@singular}_1", dom_id(@record, :edit)
+ end
+
+ def test_partial_path
+ expected = "#{@plural}/#{@singular}"
+ assert_equal expected, partial_path(@record)
+ assert_equal expected, partial_path(Comment)
+ end
+
+ def test_dom_class
+ assert_equal @singular, dom_class(@record)
+ end
+
+ def test_dom_class_with_prefix
+ assert_equal "custom_prefix_#{@singular}", dom_class(@record, :custom_prefix)
+ end
+
+ def test_singular_class_name
+ assert_equal @singular, singular_class_name(@record)
+ end
+
+ def test_singular_class_name_for_class
+ assert_equal @singular, singular_class_name(@klass)
+ end
+
+ def test_plural_class_name
+ assert_equal @plural, plural_class_name(@record)
+ end
+
+ def test_plural_class_name_for_class
+ assert_equal @plural, plural_class_name(@klass)
+ end
+
+ private
+ def method_missing(method, *args)
+ RecordIdentifier.send(method, *args)
+ end
+end
+
+class NestedRecordIdentifierTest < RecordIdentifierTest
+ def setup
+ @klass = Comment::Nested
+ @record = @klass.new
+ @singular = 'comment_nested'
+ @plural = 'comment_nesteds'
+ end
+
+ def test_partial_path
+ expected = "comment/nesteds/nested"
+ assert_equal expected, partial_path(@record)
+ assert_equal expected, partial_path(Comment::Nested)
+ end
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/redirect_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/redirect_test.rb
new file mode 100755
index 000000000..4a3b8254a
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/redirect_test.rb
@@ -0,0 +1,258 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class WorkshopsController < ActionController::Base
+end
+
+class Workshop
+ attr_accessor :id, :new_record
+
+ def initialize(id, new_record)
+ @id, @new_record = id, new_record
+ end
+
+ def new_record?
+ @new_record
+ end
+
+ def to_s
+ id.to_s
+ end
+end
+
+class RedirectController < ActionController::Base
+ def simple_redirect
+ redirect_to :action => "hello_world"
+ end
+
+ def redirect_with_status
+ redirect_to({:action => "hello_world", :status => 301})
+ end
+
+ def redirect_with_status_hash
+ redirect_to({:action => "hello_world"}, {:status => 301})
+ end
+
+ def url_redirect_with_status
+ redirect_to("http://www.example.com", :status => :moved_permanently)
+ end
+
+ def url_redirect_with_status_hash
+ redirect_to("http://www.example.com", {:status => 301})
+ end
+
+ def relative_url_redirect_with_status
+ redirect_to("/things/stuff", :status => :found)
+ end
+
+ def relative_url_redirect_with_status_hash
+ redirect_to("/things/stuff", {:status => 301})
+ end
+
+ def redirect_to_back_with_status
+ redirect_to :back, :status => 307
+ end
+
+ def host_redirect
+ redirect_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ end
+
+ def module_redirect
+ redirect_to :controller => 'module_test/module_redirect', :action => "hello_world"
+ end
+
+ def redirect_with_assigns
+ @hello = "world"
+ redirect_to :action => "hello_world"
+ end
+
+ def redirect_to_back
+ redirect_to :back
+ end
+
+ def redirect_to_existing_record
+ redirect_to Workshop.new(5, false)
+ end
+
+ def redirect_to_new_record
+ redirect_to Workshop.new(5, true)
+ end
+
+ def rescue_errors(e) raise e end
+
+ def rescue_action(e) raise end
+
+ protected
+ def dashbord_url(id, message)
+ url_for :action => "dashboard", :params => { "id" => id, "message" => message }
+ end
+end
+
+class RedirectTest < Test::Unit::TestCase
+ def setup
+ @controller = RedirectController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_simple_redirect
+ get :simple_redirect
+ assert_response :redirect
+ assert_equal "http://test.host/redirect/hello_world", redirect_to_url
+ end
+
+ def test_redirect_with_no_status
+ get :simple_redirect
+ assert_response 302
+ assert_equal "http://test.host/redirect/hello_world", redirect_to_url
+ end
+
+ def test_redirect_with_status
+ get :redirect_with_status
+ assert_response 301
+ assert_equal "http://test.host/redirect/hello_world", redirect_to_url
+ end
+
+ def test_redirect_with_status_hash
+ get :redirect_with_status_hash
+ assert_response 301
+ assert_equal "http://test.host/redirect/hello_world", redirect_to_url
+ end
+
+ def test_url_redirect_with_status
+ get :url_redirect_with_status
+ assert_response 301
+ assert_equal "http://www.example.com", redirect_to_url
+ end
+
+ def test_url_redirect_with_status_hash
+ get :url_redirect_with_status_hash
+ assert_response 301
+ assert_equal "http://www.example.com", redirect_to_url
+ end
+
+
+ def test_relative_url_redirect_with_status
+ get :relative_url_redirect_with_status
+ assert_response 302
+ assert_equal "http://test.host/things/stuff", redirect_to_url
+ end
+
+ def test_relative_url_redirect_with_status_hash
+ get :relative_url_redirect_with_status_hash
+ assert_response 301
+ assert_equal "http://test.host/things/stuff", redirect_to_url
+ end
+
+ def test_redirect_to_back_with_status
+ @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from"
+ get :redirect_to_back_with_status
+ assert_response 307
+ assert_equal "http://www.example.com/coming/from", redirect_to_url
+ end
+
+ def test_simple_redirect_using_options
+ get :host_redirect
+ assert_response :redirect
+ assert_redirected_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ end
+
+ def test_redirect_error_with_pretty_diff
+ get :host_redirect
+ assert_response :redirect
+ begin
+ assert_redirected_to :action => "other_host", :only_path => true
+ rescue Test::Unit::AssertionFailedError => err
+ expected_msg, redirection_msg, diff_msg = err.message.scan(/<\{[^\}]+\}>/).collect { |s| s[2..-3] }
+ assert_match %r("only_path"=>false), redirection_msg
+ assert_match %r("host"=>"other.test.host"), redirection_msg
+ assert_match %r("action"=>"other_host"), redirection_msg
+ assert_match %r("only_path"=>false), diff_msg
+ assert_match %r("host"=>"other.test.host"), diff_msg
+ end
+ end
+
+ def test_module_redirect
+ get :module_redirect
+ assert_response :redirect
+ assert_redirected_to "http://test.host/module_test/module_redirect/hello_world"
+ end
+
+ def test_module_redirect_using_options
+ get :module_redirect
+ assert_response :redirect
+ assert_redirected_to :controller => 'module_test/module_redirect', :action => 'hello_world'
+ end
+
+ def test_redirect_with_assigns
+ get :redirect_with_assigns
+ assert_response :redirect
+ assert_equal "world", assigns["hello"]
+ end
+
+ def test_redirect_to_back
+ @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from"
+ get :redirect_to_back
+ assert_response :redirect
+ assert_equal "http://www.example.com/coming/from", redirect_to_url
+ end
+
+ def test_redirect_to_back_with_no_referer
+ assert_raises(ActionController::RedirectBackError) {
+ @request.env["HTTP_REFERER"] = nil
+ get :redirect_to_back
+ }
+ end
+
+ def test_redirect_to_record
+ ActionController::Routing::Routes.draw do |map|
+ map.resources :workshops
+ map.connect ':controller/:action/:id'
+ end
+
+ get :redirect_to_existing_record
+ assert_equal "http://test.host/workshops/5", redirect_to_url
+
+ get :redirect_to_new_record
+ assert_equal "http://test.host/workshops", redirect_to_url
+ end
+end
+
+module ModuleTest
+ class ModuleRedirectController < ::RedirectController
+ def module_redirect
+ redirect_to :controller => '/redirect', :action => "hello_world"
+ end
+ end
+
+ class ModuleRedirectTest < Test::Unit::TestCase
+ def setup
+ @controller = ModuleRedirectController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_simple_redirect
+ get :simple_redirect
+ assert_response :redirect
+ assert_equal "http://test.host/module_test/module_redirect/hello_world", redirect_to_url
+ end
+
+ def test_simple_redirect_using_options
+ get :host_redirect
+ assert_response :redirect
+ assert_redirected_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ end
+
+ def test_module_redirect
+ get :module_redirect
+ assert_response :redirect
+ assert_equal "http://test.host/redirect/hello_world", redirect_to_url
+ end
+
+ def test_module_redirect_using_options
+ get :module_redirect
+ assert_response :redirect
+ assert_redirected_to :controller => 'redirect', :action => "hello_world"
+ end
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/render_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/render_test.rb
new file mode 100644
index 000000000..2827d7b71
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/render_test.rb
@@ -0,0 +1,464 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require File.dirname(__FILE__) + '/fake_models'
+
+module Fun
+ class GamesController < ActionController::Base
+ def hello_world
+ end
+ end
+end
+
+
+# FIXME: crashes Ruby 1.9
+class TestController < ActionController::Base
+ layout :determine_layout
+
+ def hello_world
+ end
+
+ def render_hello_world
+ render :template => "test/hello_world"
+ end
+
+ def render_hello_world_from_variable
+ @person = "david"
+ render :text => "hello #{@person}"
+ end
+
+ def render_action_hello_world
+ render :action => "hello_world"
+ end
+
+ def render_action_hello_world_with_symbol
+ render :action => :hello_world
+ end
+
+ def render_text_hello_world
+ render :text => "hello world"
+ end
+
+ def render_json_hello_world
+ render :json => {:hello => 'world'}.to_json
+ end
+
+ def render_json_hello_world_with_callback
+ render :json => {:hello => 'world'}.to_json, :callback => 'alert'
+ end
+
+ def render_json_with_custom_content_type
+ render :json => {:hello => 'world'}.to_json, :content_type => 'text/javascript'
+ end
+
+ def render_symbol_json
+ render :json => {:hello => 'world'}.to_json
+ end
+
+ def render_custom_code
+ render :text => "hello world", :status => 404
+ end
+
+ def render_nothing_with_appendix
+ render :text => "appended"
+ end
+
+ def render_invalid_args
+ render("test/hello")
+ end
+
+ def render_xml_hello
+ @name = "David"
+ render :template => "test/hello"
+ end
+
+ def render_xml_with_custom_content_type
+ render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
+ end
+
+ def heading
+ head :ok
+ end
+
+ def greeting
+ # let's just rely on the template
+ end
+
+ def layout_test
+ render :action => "hello_world"
+ end
+
+ def builder_layout_test
+ render :action => "hello"
+ end
+
+ def builder_partial_test
+ render :action => "hello_world_container"
+ end
+
+ def partials_list
+ @test_unchanged = 'hello'
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :action => "list"
+ end
+
+ def partial_only
+ render :partial => true
+ end
+
+ def hello_in_a_string
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :text => "How's there? " + render_to_string(:template => "test/list")
+ end
+
+ def accessing_params_in_template
+ render :inline => "Hello: <%= params[:name] %>"
+ end
+
+ def accessing_local_assigns_in_inline_template
+ name = params[:local_name]
+ render :inline => "<%= 'Goodbye, ' + local_name %>",
+ :locals => { :local_name => name }
+ end
+
+ def accessing_local_assigns_in_inline_template_with_string_keys
+ name = params[:local_name]
+ ActionView::Base.local_assigns_support_string_keys = true
+ render :inline => "<%= 'Goodbye, ' + local_name %>",
+ :locals => { "local_name" => name }
+ ActionView::Base.local_assigns_support_string_keys = false
+ end
+
+ def formatted_html_erb
+ end
+
+ def formatted_xml_erb
+ end
+
+ def render_to_string_test
+ @foo = render_to_string :inline => "this is a test"
+ end
+
+ def partial
+ render :partial => 'partial'
+ end
+
+ def partial_dot_html
+ render :partial => 'partial.html.erb'
+ end
+
+ def partial_as_rjs
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+
+ def respond_to_partial_as_rjs
+ respond_to do |format|
+ format.js do
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+ end
+ end
+
+ def default_render
+ if @alternate_default_render
+ @alternate_default_render.call
+ else
+ render
+ end
+ end
+
+ def render_alternate_default
+ # For this test, the method "default_render" is overridden:
+ @alternate_default_render = lambda {
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ }
+ end
+
+ def rescue_action(e) raise end
+
+ private
+ def determine_layout
+ case action_name
+ when "layout_test"; "layouts/standard"
+ when "builder_layout_test"; "layouts/builder"
+ when "render_symbol_json"; "layouts/standard" # to make sure layouts don't interfere
+ end
+ end
+end
+
+TestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class RenderTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @controller = TestController.new
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_simple_show
+ get :hello_world
+ assert_response 200
+ assert_template "test/hello_world"
+ end
+
+ def test_render
+ get :render_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_render_from_variable
+ get :render_hello_world_from_variable
+ assert_equal "hello david", @response.body
+ end
+
+ def test_render_action
+ get :render_action_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_render_action_with_symbol
+ get :render_action_hello_world_with_symbol
+ assert_template "test/hello_world"
+ end
+
+ def test_render_text
+ get :render_text_hello_world
+ assert_equal "hello world", @response.body
+ end
+
+ def test_render_json
+ get :render_json_hello_world
+ 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 '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 'text/javascript', @response.content_type
+ end
+
+ def test_render_symbol_json
+ get :render_symbol_json
+ assert_equal '{"hello": "world"}', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
+ def test_render_custom_code
+ get :render_custom_code
+ assert_response 404
+ assert_equal 'hello world', @response.body
+ end
+
+ def test_render_nothing_with_appendix
+ get :render_nothing_with_appendix
+ assert_response 200
+ 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 }
+ end
+
+ def test_private_methods
+ assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
+ end
+
+ def test_render_xml
+ 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_with_default
+ get :greeting
+ assert_equal "<p>This is grand!</p>\n", @response.body
+ end
+
+ def test_render_xml_with_partial
+ get :builder_partial_test
+ assert_equal "<test>\n <hello/>\n</test>\n", @response.body
+ end
+
+ def test_layout_rendering
+ get :layout_test
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_render_xml_with_layouts
+ 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
+
+ # def test_partials_list
+ # get :partials_list
+ # assert_equal "goodbyeHello: davidHello: marygoodbye\n", process_request.body
+ # end
+
+ def test_partial_only
+ get :partial_only
+ assert_equal "only partial", @response.body
+ end
+
+ def test_render_to_string
+ get :hello_in_a_string
+ assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
+ end
+
+ def test_render_to_string_resets_assigns
+ get :render_to_string_test
+ assert_equal "The value of foo is: ::this is a test::\n", @response.body
+ end
+
+ def test_nested_rendering
+ @controller = Fun::GamesController.new
+ get :hello_world
+ assert_equal "Living in a nested world", @response.body
+ end
+
+ def test_accessing_params_in_template
+ get :accessing_params_in_template, :name => "David"
+ assert_equal "Hello: David", @response.body
+ end
+
+ def test_accessing_local_assigns_in_inline_template
+ get :accessing_local_assigns_in_inline_template, :local_name => "Local David"
+ assert_equal "Goodbye, Local David", @response.body
+ end
+
+ def test_accessing_local_assigns_in_inline_template_with_string_keys
+ get :accessing_local_assigns_in_inline_template_with_string_keys, :local_name => "Local David"
+ assert_equal "Goodbye, Local David", @response.body
+ end
+
+ def test_render_200_should_set_etag
+ get :render_hello_world_from_variable
+ assert_equal etag_for("hello david"), @response.headers['ETag']
+ assert_equal "private, max-age=0, must-revalidate", @response.headers['Cache-Control']
+ end
+
+ def test_render_against_etag_request_should_304_when_match
+ @request.headers["HTTP_IF_NONE_MATCH"] = etag_for("hello david")
+ get :render_hello_world_from_variable
+ assert_equal "304 Not Modified", @response.headers['Status']
+ assert @response.body.empty?
+ end
+
+ def test_render_against_etag_request_should_200_when_no_match
+ @request.headers["HTTP_IF_NONE_MATCH"] = etag_for("hello somewhere else")
+ get :render_hello_world_from_variable
+ assert_equal "200 OK", @response.headers['Status']
+ assert !@response.body.empty?
+ end
+
+ def test_render_with_etag
+ get :render_hello_world_from_variable
+ expected_etag = etag_for('hello david')
+ assert_equal expected_etag, @response.headers['ETag']
+
+ @request.headers["HTTP_IF_NONE_MATCH"] = expected_etag
+ get :render_hello_world_from_variable
+ assert_equal "304 Not Modified", @response.headers['Status']
+
+ @request.headers["HTTP_IF_NONE_MATCH"] = "\"diftag\""
+ get :render_hello_world_from_variable
+ assert_equal "200 OK", @response.headers['Status']
+ end
+
+ def render_with_404_shouldnt_have_etag
+ get :render_custom_code
+ assert_nil @response.headers['ETag']
+ end
+
+ def test_etag_should_not_be_changed_when_already_set
+ expected_etag = etag_for("hello somewhere else")
+ @response.headers["ETag"] = expected_etag
+ get :render_hello_world_from_variable
+ assert_equal expected_etag, @response.headers['ETag']
+ end
+
+ def test_etag_should_govern_renders_with_layouts_too
+ 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
+
+ def test_should_render_formatted_template
+ get :formatted_html_erb
+ assert_equal 'formatted html erb', @response.body
+ end
+
+ def test_should_render_formatted_xml_erb_template
+ get :formatted_xml_erb, :format => :xml
+ assert_equal '<test>passed formatted xml erb</test>', @response.body
+ end
+
+ def test_should_render_formatted_html_erb_template
+ get :formatted_xml_erb
+ assert_equal '<test>passed formatted html erb</test>', @response.body
+ end
+
+ def test_should_render_formatted_html_erb_template_with_faulty_accepts_header
+ @request.env["HTTP_ACCEPT"] = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, appliction/x-shockwave-flash, */*"
+ get :formatted_xml_erb
+ assert_equal '<test>passed formatted html erb</test>', @response.body
+ end
+
+ def test_should_render_html_formatted_partial
+ get :partial
+ assert_equal 'partial html', @response.body
+ end
+
+ def test_should_render_html_partial_with_dot
+ get :partial_dot_html
+ assert_equal 'partial html', @response.body
+ end
+
+ def test_should_render_html_formatted_partial_with_rjs
+ xhr :get, :partial_as_rjs
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_should_render_html_formatted_partial_with_rjs_and_js_format
+ xhr :get, :respond_to_partial_as_rjs
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_should_render_js_partial
+ xhr :get, :partial, :format => 'js'
+ assert_equal 'partial js', @response.body
+ end
+
+ def test_should_render_with_alternate_default_render
+ xhr :get, :render_alternate_default
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_should_render_xml_but_keep_custom_content_type
+ get :render_xml_with_custom_content_type
+ assert_equal "application/atomsvc+xml", @response.content_type
+ end
+
+ protected
+
+ def etag_for(text)
+ %("#{Digest::MD5.hexdigest(text)}")
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/request_forgery_protection_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/request_forgery_protection_test.rb
new file mode 100644
index 000000000..616ff4f21
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/request_forgery_protection_test.rb
@@ -0,0 +1,217 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require 'digest/sha1'
+
+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
+ render :inline => "<%= form_tag('/') {} %>"
+ end
+
+ def show_button
+ render :inline => "<%= button_to('New', '/') {} %>"
+ end
+
+ 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
+
+class FreeCookieController < CsrfCookieMonsterController
+ self.allow_forgery_protection = false
+
+ def index
+ render :inline => "<%= form_tag('/') {} %>"
+ end
+
+ def show_button
+ render :inline => "<%= button_to('New', '/') {} %>"
+ end
+end
+
+# common test methods
+
+module RequestForgeryProtectionTests
+ def teardown
+ ActionController::Base.request_forgery_protection_token = nil
+ end
+
+ def test_should_render_form_with_token_tag
+ get :index
+ assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
+ end
+
+ def test_should_render_button_to_with_token_tag
+ get :show_button
+ assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
+ end
+
+ def test_should_allow_get
+ get :index
+ assert_response :success
+ end
+
+ def test_should_allow_post_without_token_on_unsafe_action
+ post :unsafe
+ assert_response :success
+ end
+
+ def test_should_not_allow_post_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { post :index }
+ end
+
+ def test_should_not_allow_put_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { put :index }
+ end
+
+ def test_should_not_allow_delete_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { delete :index }
+ end
+
+ def test_should_not_allow_xhr_post_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { xhr :post, :index }
+ end
+
+ def test_should_not_allow_xhr_put_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { xhr :put, :index }
+ end
+
+ def test_should_not_allow_xhr_delete_without_token
+ assert_raises(ActionController::InvalidAuthenticityToken) { xhr :delete, :index }
+ end
+
+ def test_should_allow_post_with_token
+ post :index, :authenticity_token => @token
+ assert_response :success
+ end
+
+ def test_should_allow_put_with_token
+ put :index, :authenticity_token => @token
+ assert_response :success
+ end
+
+ def test_should_allow_delete_with_token
+ delete :index, :authenticity_token => @token
+ assert_response :success
+ end
+
+ def test_should_allow_post_with_xml
+ post :index, :format => 'xml'
+ assert_response :success
+ end
+
+ def test_should_allow_put_with_xml
+ put :index, :format => 'xml'
+ assert_response :success
+ end
+
+ def test_should_allow_delete_with_xml
+ delete :index, :format => 'xml'
+ assert_response :success
+ end
+end
+
+# OK let's get our test on
+
+class RequestForgeryProtectionControllerTest < Test::Unit::TestCase
+ include RequestForgeryProtectionTests
+ def setup
+ @controller = RequestForgeryProtectionController.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
+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
+ def setup
+ @controller = FreeCookieController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
+ end
+
+ def test_should_not_render_form_with_token_tag
+ get :index
+ assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
+ end
+
+ def test_should_not_render_button_to_with_token_tag
+ get :show_button
+ assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
+ end
+
+ def test_should_allow_all_methods_without_token
+ [:post, :put, :delete].each do |method|
+ assert_nothing_raised { send(method, :index)}
+ end
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/request_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/request_test.rb
new file mode 100644
index 000000000..698d3cbd2
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/request_test.rb
@@ -0,0 +1,836 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require 'action_controller/integration'
+
+class RequestTest < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ end
+
+ def test_remote_ip
+ assert_equal '0.0.0.0', @request.remote_ip
+
+ @request.remote_addr = '1.2.3.4'
+ assert_equal '1.2.3.4', @request.remote_ip
+
+ @request.env['HTTP_CLIENT_IP'] = '2.3.4.5'
+ assert_equal '2.3.4.5', @request.remote_ip
+ @request.env.delete 'HTTP_CLIENT_IP'
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '172.16.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '192.168.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1, 10.0.0.1, 3.4.5.6'
+ assert_equal '3.4.5.6', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,3.4.5.6'
+ assert_equal '127.0.0.1', @request.remote_ip
+
+ @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,192.168.0.1'
+ assert_equal '1.2.3.4', @request.remote_ip
+ @request.env.delete 'HTTP_X_FORWARDED_FOR'
+ end
+
+ def test_domains
+ @request.host = "www.rubyonrails.org"
+ assert_equal "rubyonrails.org", @request.domain
+
+ @request.host = "www.rubyonrails.co.uk"
+ assert_equal "rubyonrails.co.uk", @request.domain(2)
+
+ @request.host = "192.168.1.200"
+ assert_nil @request.domain
+
+ @request.host = "foo.192.168.1.200"
+ assert_nil @request.domain
+
+ @request.host = "192.168.1.200.com"
+ assert_equal "200.com", @request.domain
+
+ @request.host = nil
+ assert_nil @request.domain
+ end
+
+ def test_subdomains
+ @request.host = "www.rubyonrails.org"
+ assert_equal %w( www ), @request.subdomains
+
+ @request.host = "www.rubyonrails.co.uk"
+ assert_equal %w( www ), @request.subdomains(2)
+
+ @request.host = "dev.www.rubyonrails.co.uk"
+ assert_equal %w( dev www ), @request.subdomains(2)
+
+ @request.host = "foobar.foobar.com"
+ assert_equal %w( foobar ), @request.subdomains
+
+ @request.host = "192.168.1.200"
+ assert_equal [], @request.subdomains
+
+ @request.host = "foo.192.168.1.200"
+ assert_equal [], @request.subdomains
+
+ @request.host = "192.168.1.200.com"
+ assert_equal %w( 192 168 1 ), @request.subdomains
+
+ @request.host = nil
+ assert_equal [], @request.subdomains
+ end
+
+ def test_port_string
+ @request.port = 80
+ assert_equal "", @request.port_string
+
+ @request.port = 8080
+ assert_equal ":8080", @request.port_string
+ end
+
+ def test_relative_url_root
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ @request.env['SERVER_SOFTWARE'] = 'lighttpd/1.2.3'
+ assert_equal '', @request.relative_url_root, "relative_url_root should be disabled on lighttpd"
+
+ @request.env['SERVER_SOFTWARE'] = 'apache/1.2.3 some random text'
+
+ @request.env['SCRIPT_NAME'] = nil
+ assert_equal "", @request.relative_url_root
+
+ @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
+ assert_equal "", @request.relative_url_root
+
+ @request.env['SCRIPT_NAME'] = "/myapp.rb"
+ assert_equal "", @request.relative_url_root
+
+ @request.relative_url_root = nil
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ assert_equal "/hieraki", @request.relative_url_root
+
+ @request.relative_url_root = nil
+ @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi"
+ assert_equal "/collaboration/hieraki", @request.relative_url_root
+
+ # apache/scgi case
+ @request.relative_url_root = nil
+ @request.env['SCRIPT_NAME'] = "/collaboration/hieraki"
+ assert_equal "/collaboration/hieraki", @request.relative_url_root
+
+ @request.relative_url_root = nil
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ @request.env['SERVER_SOFTWARE'] = 'lighttpd/1.2.3'
+ @request.env['RAILS_RELATIVE_URL_ROOT'] = "/hieraki"
+ assert_equal "/hieraki", @request.relative_url_root
+
+ # @env overrides path guess
+ @request.relative_url_root = nil
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ @request.env['SERVER_SOFTWARE'] = 'apache/1.2.3 some random text'
+ @request.env['RAILS_RELATIVE_URL_ROOT'] = "/real_url"
+ assert_equal "/real_url", @request.relative_url_root
+ end
+
+ def test_request_uri
+ @request.env['SERVER_SOFTWARE'] = 'Apache 42.342.3432'
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri?mapped=1"
+ assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
+ assert_equal "/path/of/some/uri", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri"
+ assert_equal "/path/of/some/uri", @request.request_uri
+ assert_equal "/path/of/some/uri", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/path/of/some/uri"
+ assert_equal "/path/of/some/uri", @request.request_uri
+ assert_equal "/path/of/some/uri", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/"
+ assert_equal "/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/?m=b"
+ assert_equal "/?m=b", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/"
+ @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
+ assert_equal "/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/hieraki/"
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ assert_equal "/hieraki/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI "/collaboration/hieraki/books/edit/2"
+ @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi"
+ assert_equal "/collaboration/hieraki/books/edit/2", @request.request_uri
+ assert_equal "/books/edit/2", @request.path
+
+ # The following tests are for when REQUEST_URI is not supplied (as in IIS)
+ @request.relative_url_root = nil
+ @request.set_REQUEST_URI nil
+ @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
+ @request.env['SCRIPT_NAME'] = nil #"/path/dispatch.rb"
+ assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
+ assert_equal "/path/of/some/uri", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
+ @request.env['SCRIPT_NAME'] = "/path/dispatch.rb"
+ assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
+ assert_equal "/of/some/uri", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/path/of/some/uri"
+ @request.env['SCRIPT_NAME'] = nil
+ assert_equal "/path/of/some/uri", @request.request_uri
+ assert_equal "/path/of/some/uri", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/"
+ assert_equal "/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/?m=b"
+ assert_equal "/?m=b", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/"
+ @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
+ assert_equal "/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.set_REQUEST_URI nil
+ @request.relative_url_root = nil
+ @request.env['PATH_INFO'] = "/hieraki/"
+ @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
+ assert_equal "/hieraki/", @request.request_uri
+ assert_equal "/", @request.path
+
+ @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
+ @request.relative_url_root = '/hieraki'
+ assert_equal "/dispatch.cgi", @request.path
+ @request.relative_url_root = nil
+
+ @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
+ @request.relative_url_root = '/foo'
+ assert_equal "/hieraki/dispatch.cgi", @request.path
+ @request.relative_url_root = nil
+
+ # This test ensures that Rails uses REQUEST_URI over PATH_INFO
+ @request.relative_url_root = nil
+ @request.env['REQUEST_URI'] = "/some/path"
+ @request.env['PATH_INFO'] = "/another/path"
+ @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
+ assert_equal "/some/path", @request.request_uri
+ assert_equal "/some/path", @request.path
+ end
+
+
+ def test_host_with_default_port
+ @request.host = "rubyonrails.org"
+ @request.port = 80
+ assert_equal "rubyonrails.org", @request.host_with_port
+ end
+
+ def test_host_with_non_default_port
+ @request.host = "rubyonrails.org"
+ @request.port = 81
+ assert_equal "rubyonrails.org:81", @request.host_with_port
+ end
+
+ def test_server_software
+ assert_equal nil, @request.server_software
+
+ @request.env['SERVER_SOFTWARE'] = 'Apache3.422'
+ assert_equal 'apache', @request.server_software
+
+ @request.env['SERVER_SOFTWARE'] = 'lighttpd(1.1.4)'
+ assert_equal 'lighttpd', @request.server_software
+ end
+
+ def test_xml_http_request
+ assert !@request.xml_http_request?
+ assert !@request.xhr?
+
+ @request.env['HTTP_X_REQUESTED_WITH'] = "DefinitelyNotAjax1.0"
+ assert !@request.xml_http_request?
+ assert !@request.xhr?
+
+ @request.env['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest"
+ assert @request.xml_http_request?
+ assert @request.xhr?
+ end
+
+ def test_reports_ssl
+ assert !@request.ssl?
+ @request.env['HTTPS'] = 'on'
+ assert @request.ssl?
+ end
+
+ def test_reports_ssl_when_proxied_via_lighttpd
+ assert !@request.ssl?
+ @request.env['HTTP_X_FORWARDED_PROTO'] = 'https'
+ assert @request.ssl?
+ end
+
+ def test_symbolized_request_methods
+ [:get, :post, :put, :delete].each do |method|
+ set_request_method_to method
+ assert_equal method, @request.method
+ end
+ end
+
+ def test_invalid_http_method_raises_exception
+ set_request_method_to :random_method
+ assert_raises(ActionController::UnknownHttpMethod) do
+ @request.method
+ end
+ end
+
+ def test_allow_method_hacking_on_post
+ set_request_method_to :post
+ [:get, :head, :options, :put, :post, :delete].each do |method|
+ @request.instance_eval { @parameters = { :_method => method } ; @request_method = nil }
+ assert_equal(method == :head ? :get : method, @request.method)
+ end
+ end
+
+ def test_invalid_method_hacking_on_post_raises_exception
+ set_request_method_to :post
+ @request.instance_eval { @parameters = { :_method => :random_method } ; @request_method = nil }
+ assert_raises(ActionController::UnknownHttpMethod) do
+ @request.method
+ end
+ end
+
+ def test_restrict_method_hacking
+ @request.instance_eval { @parameters = { :_method => 'put' } }
+ [:get, :put, :delete].each do |method|
+ set_request_method_to method
+ assert_equal method, @request.method
+ end
+ end
+
+ def test_head_masquarading_as_get
+ set_request_method_to :head
+ assert_equal :get, @request.method
+ assert @request.get?
+ assert @request.head?
+ end
+
+ def test_xml_format
+ @request.instance_eval { @parameters = { :format => 'xml' } }
+ assert_equal Mime::XML, @request.format
+ end
+
+ def test_xhtml_format
+ @request.instance_eval { @parameters = { :format => 'xhtml' } }
+ assert_equal Mime::HTML, @request.format
+ end
+
+ def test_txt_format
+ @request.instance_eval { @parameters = { :format => 'txt' } }
+ assert_equal Mime::TEXT, @request.format
+ end
+
+ def test_nil_format
+ @request.instance_eval { @parameters = { :format => nil } }
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
+ assert_equal Mime::JS, @request.format
+ end
+
+ def test_content_type
+ @request.env["CONTENT_TYPE"] = "text/html"
+ assert_equal Mime::HTML, @request.content_type
+ end
+
+ def test_content_no_type
+ assert_equal nil, @request.content_type
+ end
+
+ def test_content_type_xml
+ @request.env["CONTENT_TYPE"] = "application/xml"
+ assert_equal Mime::XML, @request.content_type
+ end
+
+ def test_content_type_with_charset
+ @request.env["CONTENT_TYPE"] = "application/xml; charset=UTF-8"
+ assert_equal Mime::XML, @request.content_type
+ end
+
+ def test_user_agent
+ assert_not_nil @request.user_agent
+ end
+
+ def test_parameters
+ @request.instance_eval { @request_parameters = { "foo" => 1 } }
+ @request.instance_eval { @query_parameters = { "bar" => 2 } }
+
+ assert_equal({"foo" => 1, "bar" => 2}, @request.parameters)
+ assert_equal({"foo" => 1}, @request.request_parameters)
+ assert_equal({"bar" => 2}, @request.query_parameters)
+ end
+
+ protected
+ def set_request_method_to(method)
+ @request.env['REQUEST_METHOD'] = method.to_s.upcase
+ @request.instance_eval { @request_method = nil }
+ end
+end
+
+
+class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase
+ def setup
+ @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
+ @query_string_with_empty = "action=create_customer&full_name="
+ @query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
+ @query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
+ @query_string_with_multiple_of_same_name =
+ "action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
+ @query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
+ @query_string_without_equal = "action"
+ @query_string_with_many_ampersands =
+ "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
+ @query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
+ end
+
+ def test_query_string
+ assert_equal(
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string)
+ )
+ end
+
+ def test_deep_query_string
+ expected = {'x' => {'y' => {'z' => '10'}}}
+ assert_equal(expected, ActionController::AbstractRequest.parse_query_parameters('x[y][z]=10'))
+ end
+
+ def test_deep_query_string_with_array
+ assert_equal({'x' => {'y' => {'z' => ['10']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10'))
+ assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
+ end
+
+ def test_deep_query_string_with_array_of_hash
+ assert_equal({'x' => {'y' => [{'z' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10'))
+ assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
+ end
+
+ def test_deep_query_string_with_array_of_hashes_with_one_pair
+ assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
+ assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
+ assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
+ end
+
+ def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
+ assert_equal(
+ {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
+ ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
+ )
+ end
+
+ def test_query_string_with_nil
+ assert_equal(
+ { "action" => "create_customer", "full_name" => ''},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty)
+ )
+ end
+
+ def test_query_string_with_array
+ assert_equal(
+ { "action" => "create_customer", "selected" => ["1", "2", "3"]},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_array)
+ )
+ end
+
+ def test_query_string_with_amps
+ assert_equal(
+ { "action" => "create_customer", "name" => "Don't & Does"},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_amps)
+ )
+ end
+
+ def test_query_string_with_many_equal
+ assert_equal(
+ { "action" => "create_customer", "full_name" => "abc=def=ghi"},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_equal)
+ )
+ end
+
+ def test_query_string_without_equal
+ assert_equal(
+ { "action" => nil },
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_without_equal)
+ )
+ end
+
+ def test_query_string_with_empty_key
+ assert_equal(
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty_key)
+ )
+ end
+
+ def test_query_string_with_many_ampersands
+ assert_equal(
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_ampersands)
+ )
+ end
+
+ def test_unbalanced_query_string_with_array
+ assert_equal(
+ {'location' => ["1", "2"], 'age_group' => ["2"]},
+ ActionController::AbstractRequest.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
+ )
+ assert_equal(
+ {'location' => ["1", "2"], 'age_group' => ["2"]},
+ ActionController::AbstractRequest.parse_request_parameters({'location[]' => ["1", "2"],
+ 'age_group[]' => ["2"]})
+ )
+ end
+
+
+ def test_request_hash_parsing
+ query = {
+ "note[viewers][viewer][][type]" => ["User", "Group"],
+ "note[viewers][viewer][][id]" => ["1", "2"]
+ }
+
+ expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
+
+ assert_equal(expected, ActionController::AbstractRequest.parse_request_parameters(query))
+ end
+
+
+ def test_parse_params
+ input = {
+ "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" => [ nil ],
+ "something_empty" => [ "" ],
+ "products[first]" => [ "Apple Computer" ],
+ "products[second]" => [ "Pc" ],
+ "" => [ 'Save' ]
+ }
+
+ expected_output = {
+ "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_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ UploadedStringIO = ActionController::UploadedStringIO
+ class MockUpload < UploadedStringIO
+ def initialize(content_type, original_path, *args)
+ self.content_type = content_type
+ self.original_path = original_path
+ super *args
+ end
+ end
+
+ def test_parse_params_from_multipart_upload
+ file = MockUpload.new('img/jpeg', 'foo.jpg')
+ ie_file = MockUpload.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
+ non_file_text_part = MockUpload.new('text/plain', '', 'abc')
+
+ input = {
+ "something" => [ UploadedStringIO.new("") ],
+ "array_of_stringios" => [[ UploadedStringIO.new("One"), UploadedStringIO.new("Two") ]],
+ "mixed_types_array" => [[ UploadedStringIO.new("Three"), "NotStringIO" ]],
+ "mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", UploadedStringIO.new("StringIO")]],
+ "ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", UploadedStringIO.new("StringIO")]],
+ "products[string]" => [ UploadedStringIO.new("Apple Computer") ],
+ "products[file]" => [ file ],
+ "ie_products[string]" => [ UploadedStringIO.new("Microsoft") ],
+ "ie_products[file]" => [ ie_file ],
+ "text_part" => [non_file_text_part]
+ }
+
+ expected_output = {
+ "something" => "",
+ "array_of_stringios" => ["One", "Two"],
+ "mixed_types_array" => [ "Three", "NotStringIO" ],
+ "mixed_types_as_checkboxes" => {
+ "strings" => {
+ "nested" => [ file, "String", "StringIO" ]
+ },
+ },
+ "ie_mixed_types_as_checkboxes" => {
+ "strings" => {
+ "nested" => [ ie_file, "String", "StringIO" ]
+ },
+ },
+ "products" => {
+ "string" => "Apple Computer",
+ "file" => file
+ },
+ "ie_products" => {
+ "string" => "Microsoft",
+ "file" => ie_file
+ },
+ "text_part" => "abc"
+ }
+
+ params = ActionController::AbstractRequest.parse_request_parameters(input)
+ assert_equal expected_output, params
+
+ # Lone filenames are preserved.
+ assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
+ assert_equal 'foo.jpg', params['products']['file'].original_filename
+
+ # But full Windows paths are reduced to their basename.
+ assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
+ assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
+ end
+
+ def test_parse_params_with_file
+ input = {
+ "customers[boston][first][name]" => [ "David" ],
+ "something_else" => [ "blah" ],
+ "logo" => [ File.new(File.dirname(__FILE__) + "/cgi_test.rb").path ]
+ }
+
+ expected_output = {
+ "customers" => {
+ "boston" => {
+ "first" => {
+ "name" => "David"
+ }
+ }
+ },
+ "something_else" => "blah",
+ "logo" => File.new(File.dirname(__FILE__) + "/cgi_test.rb").path,
+ }
+
+ assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_array
+ input = { "selected[]" => [ "1", "2", "3" ] }
+
+ expected_output = { "selected" => [ "1", "2", "3" ] }
+
+ assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_non_alphanumeric_name
+ input = { "a/b[c]" => %w(d) }
+ expected = { "a/b" => { "c" => "d" }}
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_single_brackets_in_middle
+ input = { "a/b[c]d" => %w(e) }
+ expected = { "a/b" => {} }
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_separated_brackets
+ input = { "a/b@[c]d[e]" => %w(f) }
+ expected = { "a/b@" => { }}
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_separated_brackets_and_array
+ input = { "a/b@[c]d[e][]" => %w(f) }
+ expected = { "a/b@" => { }}
+ assert_equal expected , ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_unmatched_brackets_and_array
+ input = { "a/b@[c][d[e][]" => %w(f) }
+ expected = { "a/b@" => { "c" => { }}}
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+
+ def test_parse_params_with_nil_key
+ input = { nil => nil, "test2" => %w(value1) }
+ expected = { "test2" => "value1" }
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
+ end
+end
+
+
+class MultipartRequestParameterParsingTest < Test::Unit::TestCase
+ FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
+
+ def test_single_parameter
+ params = process('single_parameter')
+ assert_equal({ 'foo' => 'bar' }, params)
+ end
+
+ def test_bracketed_param
+ assert_equal({ 'foo' => { 'baz' => 'bar'}}, process('bracketed_param'))
+ end
+
+ def test_text_file
+ params = process('text_file')
+ assert_equal %w(file foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ file = params['file']
+ assert_kind_of StringIO, file
+ assert_equal 'file.txt', file.original_filename
+ assert_equal "text/plain", file.content_type
+ assert_equal 'contents', file.read
+ end
+
+ def test_large_text_file
+ params = process('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
+
+ uses_mocha "test_no_rewind_stream" do
+ def test_no_rewind_stream
+ # Ensures that parse_multipart_form_parameters works with streams that cannot be rewound
+ file = File.open(File.join(FIXTURE_PATH, 'large_text_file'), 'rb')
+ file.expects(:rewind).raises(Errno::ESPIPE)
+ params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
+ assert_not_equal 0, file.pos # file was not rewound after reading
+ end
+ end
+
+ def test_binary_file
+ params = process('binary_file')
+ assert_equal %w(file flowers foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ file = params['file']
+ assert_kind_of StringIO, file
+ assert_equal 'file.csv', file.original_filename
+ assert_nil file.content_type
+ assert_equal 'contents', file.read
+
+ file = params['flowers']
+ assert_kind_of StringIO, file
+ assert_equal 'flowers.jpg', file.original_filename
+ assert_equal "image/jpeg", file.content_type
+ assert_equal 19512, file.size
+ #assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
+ end
+
+ def test_mixed_files
+ params = process('mixed_files')
+ assert_equal %w(files foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ # Ruby CGI doesn't handle multipart/mixed for us.
+ assert_kind_of String, params['files']
+ assert_equal 19756, params['files'].size
+ end
+
+ private
+ def process(name)
+ File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
+ params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
+ assert_equal 0, file.pos # file was rewound after reading
+ params
+ end
+ end
+end
+
+
+class XmlParamsParsingTest < Test::Unit::TestCase
+ def test_single_file
+ person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>")
+
+ 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
+
+ def test_multiple_files
+ person = parse_body(<<-end_body)
+ <person>
+ <name>David</name>
+ <avatars>
+ <avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar>
+ <avatar type='file' name='you.gif' content_type='image/gif'>#{Base64.encode64('DEF')}</avatar>
+ </avatars>
+ </person>
+ end_body
+
+ 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 parse_body(body)
+ env = { 'CONTENT_TYPE' => 'application/xml',
+ 'CONTENT_LENGTH' => body.size.to_s }
+ cgi = ActionController::Integration::Session::StubCGI.new(env, body)
+ ActionController::CgiRequest.new(cgi).request_parameters
+ end
+end
+
+class LegacyXmlParamsParsingTest < XmlParamsParsingTest
+ private
+ def parse_body(body)
+ env = { 'HTTP_X_POST_DATA_FORMAT' => 'xml',
+ 'CONTENT_LENGTH' => body.size.to_s }
+ cgi = ActionController::Integration::Session::StubCGI.new(env, body)
+ ActionController::CgiRequest.new(cgi).request_parameters
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/rescue_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/rescue_test.rb
new file mode 100644
index 000000000..a63fd0600
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/rescue_test.rb
@@ -0,0 +1,501 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+uses_mocha 'rescue' do
+
+class RescueController < ActionController::Base
+ class NotAuthorized < StandardError
+ end
+ class NotAuthorizedToRescueAsString < StandardError
+ end
+
+ class RecordInvalid < StandardError
+ end
+ class RecordInvalidToRescueAsString < StandardError
+ end
+
+ class NotAllowed < StandardError
+ end
+ class NotAllowedToRescueAsString < StandardError
+ end
+
+ class InvalidRequest < StandardError
+ end
+ class InvalidRequestToRescueAsString < StandardError
+ end
+
+ class BadGateway < StandardError
+ end
+ class BadGatewayToRescueAsString < StandardError
+ end
+
+ class ResourceUnavailable < StandardError
+ end
+ class ResourceUnavailableToRescueAsString < StandardError
+ end
+
+ # We use a fully-qualified name in some strings, and a relative constant
+ # name in some other to test correct handling of both cases.
+
+ rescue_from NotAuthorized, :with => :deny_access
+ rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access
+
+ rescue_from RecordInvalid, :with => :show_errors
+ rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors
+
+ rescue_from NotAllowed, :with => proc { head :forbidden }
+ rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden }
+
+ rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message }
+ rescue_from 'InvalidRequestToRescueAsString', :with => proc { |exception| render :text => exception.message }
+
+ rescue_from BadGateway do
+ head :status => 502
+ end
+ rescue_from 'BadGatewayToRescueAsString' do
+ head :status => 502
+ end
+
+ rescue_from ResourceUnavailable do |exception|
+ render :text => exception.message
+ end
+ rescue_from 'ResourceUnavailableToRescueAsString' do |exception|
+ render :text => exception.message
+ end
+
+ def raises
+ render :text => 'already rendered'
+ raise "don't panic!"
+ end
+
+ def method_not_allowed
+ raise ActionController::MethodNotAllowed.new(:get, :head, :put)
+ end
+
+ def not_implemented
+ raise ActionController::NotImplemented.new(:get, :put)
+ end
+
+ def not_authorized
+ raise NotAuthorized
+ end
+ def not_authorized_raise_as_string
+ raise NotAuthorizedToRescueAsString
+ end
+
+ def not_allowed
+ raise NotAllowed
+ end
+ def not_allowed_raise_as_string
+ raise NotAllowedToRescueAsString
+ end
+
+ def invalid_request
+ raise InvalidRequest
+ end
+ def invalid_request_raise_as_string
+ raise InvalidRequestToRescueAsString
+ end
+
+ def record_invalid
+ raise RecordInvalid
+ end
+ def record_invalid_raise_as_string
+ raise RecordInvalidToRescueAsString
+ end
+
+ def bad_gateway
+ raise BadGateway
+ end
+ def bad_gateway_raise_as_string
+ raise BadGatewayToRescueAsString
+ end
+
+ def resource_unavailable
+ raise ResourceUnavailable
+ end
+ def resource_unavailable_raise_as_string
+ raise ResourceUnavailableToRescueAsString
+ end
+
+ def missing_template
+ end
+
+ protected
+ def deny_access
+ head :forbidden
+ end
+
+ def show_errors(exception)
+ head :unprocessable_entity
+ end
+end
+
+class RescueTest < Test::Unit::TestCase
+ FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze
+
+ def setup
+ @controller = RescueController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ RescueController.consider_all_requests_local = true
+ @request.remote_addr = '1.2.3.4'
+ @request.host = 'example.com'
+
+ begin
+ raise 'foo'
+ rescue => @exception
+ end
+ end
+
+ def test_rescue_action_locally_if_all_requests_local
+ @controller.expects(:local_request?).never
+ @controller.expects(:rescue_action_locally).with(@exception)
+ @controller.expects(:rescue_action_in_public).never
+
+ with_all_requests_local do
+ @controller.send :rescue_action, @exception
+ end
+ end
+
+ def test_rescue_action_locally_if_remote_addr_is_localhost
+ @controller.expects(:local_request?).returns(true)
+ @controller.expects(:rescue_action_locally).with(@exception)
+ @controller.expects(:rescue_action_in_public).never
+
+ with_all_requests_local false do
+ @controller.send :rescue_action, @exception
+ end
+ end
+
+ def test_rescue_action_in_public_otherwise
+ @controller.expects(:local_request?).returns(false)
+ @controller.expects(:rescue_action_locally).never
+ @controller.expects(:rescue_action_in_public).with(@exception)
+
+ with_all_requests_local false do
+ @controller.send :rescue_action, @exception
+ end
+ end
+
+ def test_rescue_action_in_public_with_error_file
+ 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.html")
+ assert_equal body, @response.body
+ end
+
+ def test_rescue_action_in_public_without_error_file
+ with_rails_root '/tmp' do
+ with_all_requests_local false do
+ get :raises
+ end
+ end
+
+ assert_response :internal_server_error
+ assert_equal ' ', @response.body
+ end
+
+ def test_rescue_unknown_action_in_public_with_error_file
+ with_rails_root FIXTURE_PUBLIC do
+ with_all_requests_local false do
+ get :foobar_doesnt_exist
+ end
+ end
+
+ assert_response :not_found
+ body = File.read("#{FIXTURE_PUBLIC}/public/404.html")
+ assert_equal body, @response.body
+ end
+
+ def test_rescue_unknown_action_in_public_without_error_file
+ with_rails_root '/tmp' do
+ with_all_requests_local false do
+ get :foobar_doesnt_exist
+ end
+ end
+
+ assert_response :not_found
+ assert_equal ' ', @response.body
+ end
+
+ def test_rescue_missing_template_in_public
+ with_rails_root FIXTURE_PUBLIC do
+ with_all_requests_local true do
+ get :missing_template
+ end
+ end
+
+ assert_response :internal_server_error
+ assert @response.body.include?('missing_template'), "Response should include the template name."
+ end
+
+ def test_rescue_action_locally
+ get :raises
+ assert_response :internal_server_error
+ assert_template 'diagnostics.erb'
+ assert @response.body.include?('RescueController#raises'), "Response should include controller and action."
+ assert @response.body.include?("don't panic"), "Response should include exception message."
+ end
+
+ def test_local_request_when_remote_addr_is_localhost
+ @controller.expects(:request).returns(@request).at_least_once
+ with_remote_addr '127.0.0.1' do
+ assert @controller.send(:local_request?)
+ end
+ end
+
+ def test_local_request_when_remote_addr_isnt_locahost
+ @controller.expects(:request).returns(@request)
+ with_remote_addr '1.2.3.4' do
+ assert !@controller.send(:local_request?)
+ end
+ end
+
+ def test_rescue_responses
+ responses = ActionController::Base.rescue_responses
+
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses.default
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses[Exception.new]
+
+ assert_equal :not_found, responses[ActionController::RoutingError.name]
+ assert_equal :not_found, responses[ActionController::UnknownAction.name]
+ assert_equal :not_found, responses['ActiveRecord::RecordNotFound']
+ assert_equal :conflict, responses['ActiveRecord::StaleObjectError']
+ assert_equal :unprocessable_entity, responses['ActiveRecord::RecordInvalid']
+ assert_equal :unprocessable_entity, responses['ActiveRecord::RecordNotSaved']
+ assert_equal :method_not_allowed, responses['ActionController::MethodNotAllowed']
+ assert_equal :not_implemented, responses['ActionController::NotImplemented']
+ end
+
+ def test_rescue_templates
+ templates = ActionController::Base.rescue_templates
+
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates.default
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates[Exception.new]
+
+ assert_equal 'missing_template', templates[ActionController::MissingTemplate.name]
+ assert_equal 'routing_error', templates[ActionController::RoutingError.name]
+ assert_equal 'unknown_action', templates[ActionController::UnknownAction.name]
+ 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
+ head :not_implemented
+ end
+ assert_response :not_implemented
+ assert_equal "GET, PUT", @response.headers['Allow']
+ end
+
+ def test_method_not_allowed
+ with_all_requests_local false do
+ get :method_not_allowed
+ end
+ assert_response :method_not_allowed
+ assert_equal "GET, HEAD, PUT", @response.headers['Allow']
+ end
+
+ def test_rescue_handler
+ get :not_authorized
+ assert_response :forbidden
+ end
+ def test_rescue_handler_string
+ get :not_authorized_raise_as_string
+ assert_response :forbidden
+ end
+
+ def test_rescue_handler_with_argument
+ @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
+ get :record_invalid
+ end
+ def test_rescue_handler_with_argument_as_string
+ @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
+ get :record_invalid_raise_as_string
+ end
+
+ def test_proc_rescue_handler
+ get :not_allowed
+ assert_response :forbidden
+ end
+ def test_proc_rescue_handler_as_string
+ get :not_allowed_raise_as_string
+ assert_response :forbidden
+ end
+
+ def test_proc_rescue_handle_with_argument
+ get :invalid_request
+ assert_equal "RescueController::InvalidRequest", @response.body
+ end
+ def test_proc_rescue_handle_with_argument_as_string
+ get :invalid_request_raise_as_string
+ assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
+ end
+
+ def test_block_rescue_handler
+ get :bad_gateway
+ assert_response 502
+ end
+ def test_block_rescue_handler_as_string
+ get :bad_gateway_raise_as_string
+ assert_response 502
+ end
+
+ def test_block_rescue_handler_with_argument
+ get :resource_unavailable
+ assert_equal "RescueController::ResourceUnavailable", @response.body
+ end
+
+ def test_block_rescue_handler_with_argument_as_string
+ get :resource_unavailable_raise_as_string
+ assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
+ end
+
+
+ protected
+ def with_all_requests_local(local = true)
+ old_local, ActionController::Base.consider_all_requests_local =
+ ActionController::Base.consider_all_requests_local, local
+ yield
+ ensure
+ ActionController::Base.consider_all_requests_local = old_local
+ end
+
+ def with_remote_addr(addr)
+ old_remote_addr, @request.remote_addr = @request.remote_addr, addr
+ yield
+ ensure
+ @request.remote_addr = old_remote_addr
+ end
+
+ def with_rails_root(path = nil)
+ old_rails_root = RAILS_ROOT if defined?(RAILS_ROOT)
+ if path
+ silence_warnings { Object.const_set(:RAILS_ROOT, path) }
+ else
+ Object.remove_const(:RAILS_ROOT) rescue nil
+ end
+
+ yield
+
+ ensure
+ if old_rails_root
+ silence_warnings { Object.const_set(:RAILS_ROOT, old_rails_root) }
+ else
+ Object.remove_const(:RAILS_ROOT) rescue nil
+ end
+ end
+end
+
+class ExceptionInheritanceRescueController < ActionController::Base
+
+ class ParentException < StandardError
+ end
+
+ class ChildException < ParentException
+ end
+
+ class GrandchildException < ChildException
+ end
+
+ rescue_from ChildException, :with => lambda { head :ok }
+ rescue_from ParentException, :with => lambda { head :created }
+ rescue_from GrandchildException, :with => lambda { head :no_content }
+
+ def raise_parent_exception
+ raise ParentException
+ end
+
+ def raise_child_exception
+ raise ChildException
+ end
+
+ def raise_grandchild_exception
+ raise GrandchildException
+ end
+end
+
+class ExceptionInheritanceRescueTest < Test::Unit::TestCase
+
+ def setup
+ @controller = ExceptionInheritanceRescueController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_bottom_first
+ get :raise_grandchild_exception
+ assert_response :no_content
+ end
+
+ def test_inheritance_works
+ get :raise_child_exception
+ assert_response :created
+ end
+end
+
+class ControllerInheritanceRescueController < ExceptionInheritanceRescueController
+ class FirstExceptionInChildController < StandardError
+ end
+
+ class SecondExceptionInChildController < StandardError
+ end
+
+ rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone }
+
+ def raise_first_exception_in_child_controller
+ raise FirstExceptionInChildController
+ end
+
+ def raise_second_exception_in_child_controller
+ raise SecondExceptionInChildController
+ end
+end
+
+class ControllerInheritanceRescueControllerTest < Test::Unit::TestCase
+
+ def setup
+ @controller = ControllerInheritanceRescueController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_first_exception_in_child_controller
+ get :raise_first_exception_in_child_controller
+ assert_response :gone
+ end
+
+ def test_second_exception_in_child_controller
+ get :raise_second_exception_in_child_controller
+ assert_response :gone
+ end
+
+ def test_exception_in_parent_controller
+ get :raise_parent_exception
+ assert_response :created
+ end
+end
+end # uses_mocha
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/resources_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/resources_test.rb
new file mode 100644
index 000000000..8772e6628
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/resources_test.rb
@@ -0,0 +1,787 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class ResourcesController < ActionController::Base
+ def index() render :nothing => true end
+ alias_method :show, :index
+ def rescue_action(e) raise e end
+end
+
+class ThreadsController < ResourcesController; end
+class MessagesController < ResourcesController; end
+class CommentsController < ResourcesController; end
+class AuthorsController < ResourcesController; end
+class LogosController < ResourcesController; end
+
+class AccountsController < ResourcesController; end
+class AdminController < ResourcesController; end
+
+module Backoffice
+ class ProductsController < ResourcesController; end
+ class TagsController < ResourcesController; end
+ class ManufacturersController < ResourcesController; end
+ class ImagesController < ResourcesController; end
+
+ module Admin
+ class ProductsController < ResourcesController; end
+ class ImagesController < ResourcesController; end
+ end
+end
+
+class ResourcesTest < Test::Unit::TestCase
+
+
+ # The assertions in these tests are incompatible with the hash method
+ # optimisation. This could indicate user level problems
+ def setup
+ ActionController::Base.optimise_named_routes = false
+ end
+
+ def tear_down
+ ActionController::Base.optimise_named_routes = true
+ end
+
+ def test_should_arrange_actions
+ resource = ActionController::Resources::Resource.new(:messages,
+ :collection => { :rss => :get, :reorder => :post, :csv => :post },
+ :member => { :rss => :get, :atom => :get, :upload => :post, :fix => :post },
+ :new => { :preview => :get, :draft => :get })
+
+ assert_resource_methods [:rss], resource, :collection, :get
+ assert_resource_methods [:csv, :reorder], resource, :collection, :post
+ assert_resource_methods [:edit, :rss, :atom], resource, :member, :get
+ assert_resource_methods [:upload, :fix], resource, :member, :post
+ assert_resource_methods [:new, :preview, :draft], resource, :new, :get
+ end
+
+ def test_should_resource_controller_name_equal_resource_name_by_default
+ resource = ActionController::Resources::Resource.new(:messages, {})
+ assert_equal 'messages', resource.controller
+ end
+
+ def test_should_resource_controller_name_equal_controller_option
+ resource = ActionController::Resources::Resource.new(:messages, :controller => 'posts')
+ assert_equal 'posts', resource.controller
+ end
+
+ def test_should_all_singleton_paths_be_the_same
+ [ :path, :nesting_path_prefix, :member_path ].each do |method|
+ resource = ActionController::Resources::SingletonResource.new(:messages, :path_prefix => 'admin')
+ assert_equal 'admin/messages', resource.send(method)
+ end
+ end
+
+ def test_default_restful_routes
+ with_restful_routing :messages do
+ assert_simply_restful_for :messages
+ end
+ end
+
+ def test_multiple_default_restful_routes
+ with_restful_routing :messages, :comments do
+ assert_simply_restful_for :messages
+ assert_simply_restful_for :comments
+ end
+ end
+
+ def test_with_custom_conditions
+ with_restful_routing :messages, :conditions => { :subdomain => 'app' } do
+ assert_equal 'app', ActionController::Routing::Routes.named_routes.routes[:messages].conditions[:subdomain]
+ end
+ end
+
+ def test_irregular_id_with_no_requirements_should_raise_error
+ expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'}
+
+ with_restful_routing :messages do
+ assert_raises(ActionController::RoutingError) do
+ assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get)
+ end
+ end
+ end
+
+ def test_irregular_id_with_requirements_should_pass
+ expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'}
+
+ with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}) do
+ assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get)
+ end
+ end
+
+ def test_with_path_prefix_requirements
+ expected_options = {:controller => 'messages', :action => 'show', :thread_id => '1.1.1', :id => '1'}
+ with_restful_routing :messages, :path_prefix => '/thread/:thread_id', :requirements => {:thread_id => /[0-9]\.[0-9]\.[0-9]/} do
+ assert_recognizes(expected_options, :path => 'thread/1.1.1/messages/1', :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' }
+ end
+ end
+
+ def test_multiple_with_path_prefix
+ with_restful_routing :messages, :comments, :path_prefix => '/thread/:thread_id' do
+ assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
+ assert_simply_restful_for :comments, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
+ end
+ end
+
+ def test_with_name_prefix
+ with_restful_routing :messages, :name_prefix => 'post_' do
+ assert_simply_restful_for :messages, :name_prefix => 'post_'
+ end
+ end
+
+ def test_with_collection_actions
+ actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete }
+
+ with_restful_routing :messages, :collection => actions do
+ assert_restful_routes_for :messages do |options|
+ actions.each do |action, method|
+ assert_recognizes(options.merge(:action => action), :path => "/messages/#{action}", :method => method)
+ end
+ end
+
+ assert_restful_named_routes_for :messages do |options|
+ actions.keys.each do |action|
+ assert_named_route "/messages/#{action}", "#{action}_messages_path", :action => action
+ end
+ end
+ end
+ end
+
+ def test_with_collection_actions_and_name_prefix
+ actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete }
+
+ with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => 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 }
+
+ with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => 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, :format => 'xml'), :path => "/threads/1/messages/#{action}.xml", :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}.xml", "formatted_#{action}_thread_messages_path", :action => action, :format => 'xml'
+ end
+ end
+ end
+ end
+
+ def test_with_member_action
+ [:put, :post].each do |method|
+ with_restful_routing :messages, :member => { :mark => method } do
+ mark_options = {:action => 'mark', :id => '1'}
+ mark_path = "/messages/1/mark"
+ assert_restful_routes_for :messages do |options|
+ assert_recognizes(options.merge(mark_options), :path => mark_path, :method => method)
+ end
+
+ assert_restful_named_routes_for :messages do |options|
+ assert_named_route mark_path, :mark_message_path, mark_options
+ end
+ end
+ end
+ end
+
+ def test_with_two_member_actions_with_same_method
+ [:put, :post].each do |method|
+ with_restful_routing :messages, :member => { :mark => method, :unmark => method } do
+ %w(mark unmark).each do |action|
+ action_options = {:action => action, :id => '1'}
+ action_path = "/messages/1/#{action}"
+ assert_restful_routes_for :messages do |options|
+ assert_recognizes(options.merge(action_options), :path => action_path, :method => method)
+ end
+
+ assert_restful_named_routes_for :messages do |options|
+ assert_named_route action_path, "#{action}_message_path".to_sym, action_options
+ end
+ end
+ end
+ end
+ end
+
+ def test_with_new_action
+ with_restful_routing :messages, :new => { :preview => :post } do
+ preview_options = {:action => 'preview'}
+ preview_path = "/messages/new/preview"
+ assert_restful_routes_for :messages do |options|
+ assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ end
+
+ assert_restful_named_routes_for :messages do |options|
+ assert_named_route preview_path, :preview_new_message_path, preview_options
+ end
+ end
+ end
+
+ def test_with_new_action_with_name_prefix
+ with_restful_routing :messages, :new => { :preview => :post }, :path_prefix => '/threads/:thread_id', :name_prefix => 'thread_' do
+ preview_options = {:action => 'preview', :thread_id => '1'}
+ preview_path = "/threads/1/messages/new/preview"
+ assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
+ assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ 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, :preview_new_thread_message_path, preview_options
+ end
+ end
+ end
+
+ def test_with_formatted_new_action_with_name_prefix
+ with_restful_routing :messages, :new => { :preview => :post }, :path_prefix => '/threads/:thread_id', :name_prefix => 'thread_' do
+ preview_options = {:action => 'preview', :thread_id => '1', :format => 'xml'}
+ preview_path = "/threads/1/messages/new/preview.xml"
+ assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
+ assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ 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
+ end
+ end
+ end
+
+ def test_override_new_method
+ 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
+ ActionController::Routing::Routes.recognize_path("/messages/new", :method => :post)
+ end
+ end
+ end
+
+ with_restful_routing :messages, :new => { :new => :any } do
+ assert_restful_routes_for :messages do |options|
+ assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :post)
+ assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get)
+ end
+ end
+ end
+
+ def test_nested_restful_routes
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :threads do |map|
+ map.resources :messages do |map|
+ map.resources :comments
+ end
+ end
+ end
+
+ assert_simply_restful_for :threads
+ assert_simply_restful_for :messages,
+ :name_prefix => 'thread_',
+ :path_prefix => 'threads/1/',
+ :options => { :thread_id => '1' }
+ assert_simply_restful_for :comments,
+ :name_prefix => 'thread_message_',
+ :path_prefix => 'threads/1/messages/2/',
+ :options => { :thread_id => '1', :message_id => '2' }
+ end
+ end
+
+ def test_nested_restful_routes_with_overwritten_defaults
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :threads do |map|
+ map.resources :messages, :name_prefix => nil do |map|
+ map.resources :comments, :name_prefix => nil
+ end
+ end
+ end
+
+ assert_simply_restful_for :threads
+ assert_simply_restful_for :messages,
+ :path_prefix => 'threads/1/',
+ :options => { :thread_id => '1' }
+ assert_simply_restful_for :comments,
+ :path_prefix => 'threads/1/messages/2/',
+ :options => { :thread_id => '1', :message_id => '2' }
+ end
+ end
+
+ def test_restful_routes_dont_generate_duplicates
+ with_restful_routing :messages do
+ routes = ActionController::Routing::Routes.routes
+ routes.each do |route|
+ routes.each do |r|
+ next if route === r # skip the comparison instance
+ assert distinct_routes?(route, r), "Duplicate Route: #{route}"
+ end
+ end
+ end
+ end
+
+ def test_should_create_singleton_resource_routes
+ with_singleton_resources :account do
+ assert_singleton_restful_for :account
+ end
+ end
+
+ def test_should_create_multiple_singleton_resource_routes
+ with_singleton_resources :account, :logo do
+ assert_singleton_restful_for :account
+ assert_singleton_restful_for :logo
+ end
+ end
+
+ def test_should_create_nested_singleton_resource_routes
+ with_routing do |set|
+ set.draw do |map|
+ map.resource :admin, :controller => 'admin' do |admin|
+ admin.resource :account
+ end
+ end
+
+ assert_singleton_restful_for :admin, :controller => 'admin'
+ assert_singleton_restful_for :account, :name_prefix => "admin_", :path_prefix => 'admin/'
+ end
+ end
+
+ def test_resource_has_many_should_become_nested_resources
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :messages, :has_many => [ :comments, :authors ]
+ end
+
+ assert_simply_restful_for :messages
+ assert_simply_restful_for :comments, :name_prefix => "message_", :path_prefix => 'messages/1/', :options => { :message_id => '1' }
+ assert_simply_restful_for :authors, :name_prefix => "message_", :path_prefix => 'messages/1/', :options => { :message_id => '1' }
+ end
+ end
+
+ def test_resource_has_one_should_become_nested_resources
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :messages, :has_one => :logo
+ end
+
+ assert_simply_restful_for :messages
+ assert_singleton_restful_for :logo, :name_prefix => 'message_', :path_prefix => 'messages/1/', :options => { :message_id => '1' }
+ end
+ end
+
+ def test_singleton_resource_with_member_action
+ [:put, :post].each do |method|
+ with_singleton_resources :account, :member => { :reset => method } do
+ reset_options = {:action => 'reset'}
+ reset_path = "/account/reset"
+ assert_singleton_routes_for :account do |options|
+ assert_recognizes(options.merge(reset_options), :path => reset_path, :method => method)
+ end
+
+ assert_singleton_named_routes_for :account do |options|
+ assert_named_route reset_path, :reset_account_path, reset_options
+ end
+ end
+ end
+ end
+
+ def test_singleton_resource_with_two_member_actions_with_same_method
+ [:put, :post].each do |method|
+ with_singleton_resources :account, :member => { :reset => method, :disable => method } do
+ %w(reset disable).each do |action|
+ action_options = {:action => action}
+ action_path = "/account/#{action}"
+ assert_singleton_routes_for :account do |options|
+ assert_recognizes(options.merge(action_options), :path => action_path, :method => method)
+ end
+
+ assert_singleton_named_routes_for :account do |options|
+ assert_named_route action_path, "#{action}_account_path".to_sym, action_options
+ end
+ end
+ end
+ end
+ end
+
+ def test_should_nest_resources_in_singleton_resource
+ with_routing do |set|
+ set.draw do |map|
+ map.resource :account do |account|
+ account.resources :messages
+ end
+ end
+
+ assert_singleton_restful_for :account
+ assert_simply_restful_for :messages, :name_prefix => "account_", :path_prefix => 'account/'
+ end
+ end
+
+ def test_should_nest_resources_in_singleton_resource_with_path_prefix
+ with_routing do |set|
+ set.draw do |map|
+ map.resource(:account, :path_prefix => ':site_id') do |account|
+ account.resources :messages
+ end
+ end
+
+ assert_singleton_restful_for :account, :path_prefix => '7/', :options => { :site_id => '7' }
+ assert_simply_restful_for :messages, :name_prefix => "account_", :path_prefix => '7/account/', :options => { :site_id => '7' }
+ end
+ end
+
+ def test_should_nest_singleton_resource_in_resources
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :threads do |thread|
+ thread.resource :admin, :controller => 'admin'
+ end
+ end
+
+ assert_simply_restful_for :threads
+ assert_singleton_restful_for :admin, :controller => 'admin', :name_prefix => 'thread_', :path_prefix => 'threads/5/', :options => { :thread_id => '5' }
+ end
+ end
+
+ def test_should_not_allow_delete_or_put_on_collection_path
+ controller_name = :messages
+ with_restful_routing controller_name do
+ options = { :controller => controller_name.to_s }
+ collection_path = "/#{controller_name}"
+
+ assert_raises(ActionController::MethodNotAllowed) do
+ assert_recognizes(options.merge(:action => 'update'), :path => collection_path, :method => :put)
+ end
+
+ assert_raises(ActionController::MethodNotAllowed) do
+ assert_recognizes(options.merge(:action => 'destroy'), :path => collection_path, :method => :delete)
+ end
+ end
+ end
+
+ def test_resource_action_separator
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :messages, :collection => {:search => :get}, :new => {:preview => :any}, :name_prefix => 'thread_', :path_prefix => '/threads/:thread_id'
+ map.resource :account, :member => {:login => :get}, :new => {:preview => :any}, :name_prefix => 'admin_', :path_prefix => '/admin'
+ end
+
+ action_separator = ActionController::Base.resource_action_separator
+
+ assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' }
+ assert_named_route "/threads/1/messages#{action_separator}search", "search_thread_messages_path", {}
+ assert_named_route "/threads/1/messages/new", "new_thread_message_path", {}
+ assert_named_route "/threads/1/messages/new#{action_separator}preview", "preview_new_thread_message_path", {}
+ assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/'
+ assert_named_route "/admin/account#{action_separator}login", "login_admin_account_path", {}
+ assert_named_route "/admin/account/new", "new_admin_account_path", {}
+ assert_named_route "/admin/account/new#{action_separator}preview", "preview_new_admin_account_path", {}
+ end
+ end
+
+ def test_new_style_named_routes_for_resource
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :messages, :collection => {:search => :get}, :new => {:preview => :any}, :name_prefix => 'thread_', :path_prefix => '/threads/:thread_id'
+ end
+ assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' }
+ assert_named_route "/threads/1/messages/search", "search_thread_messages_path", {}
+ assert_named_route "/threads/1/messages/new", "new_thread_message_path", {}
+ assert_named_route "/threads/1/messages/new/preview", "preview_new_thread_message_path", {}
+ end
+ end
+
+ def test_new_style_named_routes_for_singleton_resource
+ with_routing do |set|
+ set.draw do |map|
+ map.resource :account, :member => {:login => :get}, :new => {:preview => :any}, :name_prefix => 'admin_', :path_prefix => '/admin'
+ end
+ assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/'
+ assert_named_route "/admin/account/login", "login_admin_account_path", {}
+ assert_named_route "/admin/account/new", "new_admin_account_path", {}
+ assert_named_route "/admin/account/new/preview", "preview_new_admin_account_path", {}
+ end
+ end
+
+ def test_resources_in_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.resources :products
+ end
+ end
+
+ assert_simply_restful_for :products, :controller => "backoffice/products", :name_prefix => 'backoffice_', :path_prefix => 'backoffice/'
+ end
+ end
+
+ def test_resource_has_many_in_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.resources :products, :has_many => :tags
+ end
+ end
+
+ assert_simply_restful_for :products, :controller => "backoffice/products", :name_prefix => 'backoffice_', :path_prefix => 'backoffice/'
+ assert_simply_restful_for :tags, :controller => "backoffice/tags", :name_prefix => "backoffice_product_", :path_prefix => 'backoffice/products/1/', :options => { :product_id => '1' }
+ end
+ end
+
+ def test_resource_has_one_in_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.resources :products, :has_one => :manufacturer
+ end
+ end
+
+ assert_simply_restful_for :products, :controller => "backoffice/products", :name_prefix => 'backoffice_', :path_prefix => 'backoffice/'
+ assert_singleton_restful_for :manufacturer, :controller => "backoffice/manufacturers", :name_prefix => 'backoffice_product_', :path_prefix => 'backoffice/products/1/', :options => { :product_id => '1' }
+ end
+ end
+
+ def test_resources_in_nested_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.namespace :admin do |admin|
+ admin.resources :products
+ end
+ end
+ end
+
+ assert_simply_restful_for :products, :controller => "backoffice/admin/products", :name_prefix => 'backoffice_admin_', :path_prefix => 'backoffice/admin/'
+ end
+ end
+
+ def test_resources_using_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :products, :namespace => "backoffice/"
+ end
+
+ assert_simply_restful_for :products, :controller => "backoffice/products"
+ end
+ end
+
+ def test_nested_resources_using_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.resources :products do |products|
+ products.resources :images
+ end
+ end
+ end
+
+ assert_simply_restful_for :images, :controller => "backoffice/images", :name_prefix => 'backoffice_product_', :path_prefix => 'backoffice/products/1/', :options => {:product_id => '1'}
+ end
+ end
+
+ def test_nested_resources_in_nested_namespace
+ with_routing do |set|
+ set.draw do |map|
+ map.namespace :backoffice do |backoffice|
+ backoffice.namespace :admin do |admin|
+ admin.resources :products do |products|
+ products.resources :images
+ end
+ end
+ end
+ end
+
+ assert_simply_restful_for :images, :controller => "backoffice/admin/images", :name_prefix => 'backoffice_admin_product_', :path_prefix => 'backoffice/admin/products/1/', :options => {:product_id => '1'}
+ end
+ end
+
+ protected
+ def with_restful_routing(*args)
+ with_routing do |set|
+ set.draw { |map| map.resources(*args) }
+ yield
+ end
+ end
+
+ def with_singleton_resources(*args)
+ with_routing do |set|
+ set.draw { |map| map.resource(*args) }
+ yield
+ end
+ end
+
+ # runs assert_restful_routes_for and assert_restful_named_routes for on the controller_name and options, without passing a block.
+ def assert_simply_restful_for(controller_name, options = {})
+ assert_restful_routes_for controller_name, options
+ assert_restful_named_routes_for controller_name, nil, options
+ end
+
+ def assert_singleton_restful_for(singleton_name, options = {})
+ assert_singleton_routes_for singleton_name, options
+ assert_singleton_named_routes_for singleton_name, options
+ end
+
+ def assert_restful_routes_for(controller_name, options = {})
+ options[:options] ||= {}
+ options[:options][:controller] = options[:controller] || controller_name.to_s
+
+ collection_path = "/#{options[:path_prefix]}#{controller_name}"
+ member_path = "#{collection_path}/1"
+ new_path = "#{collection_path}/new"
+ edit_member_path = "#{member_path}/edit"
+ formatted_edit_member_path = "#{member_path}/edit.xml"
+
+ with_options(options[:options]) do |controller|
+ controller.assert_routing collection_path, :action => 'index'
+ controller.assert_routing new_path, :action => 'new'
+ controller.assert_routing member_path, :action => 'show', :id => '1'
+ controller.assert_routing edit_member_path, :action => 'edit', :id => '1'
+ controller.assert_routing "#{collection_path}.xml", :action => 'index', :format => 'xml'
+ controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
+ controller.assert_routing "#{member_path}.xml", :action => 'show', :id => '1', :format => 'xml'
+ controller.assert_routing formatted_edit_member_path, :action => 'edit', :id => '1', :format => 'xml'
+ end
+
+ assert_recognizes(options[:options].merge(:action => 'index'), :path => collection_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'new'), :path => new_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'create'), :path => collection_path, :method => :post)
+ assert_recognizes(options[:options].merge(:action => 'show', :id => '1'), :path => member_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'edit', :id => '1'), :path => edit_member_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'update', :id => '1'), :path => member_path, :method => :put)
+ assert_recognizes(options[:options].merge(:action => 'destroy', :id => '1'), :path => member_path, :method => :delete)
+
+ assert_recognizes(options[:options].merge(:action => 'index', :format => 'xml'), :path => "#{collection_path}.xml", :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'create', :format => 'xml'), :path => "#{collection_path}.xml", :method => :post)
+ assert_recognizes(options[:options].merge(:action => 'show', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'edit', :id => '1', :format => 'xml'), :path => formatted_edit_member_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'update', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :put)
+ assert_recognizes(options[:options].merge(:action => 'destroy', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :delete)
+
+ yield options[:options] if block_given?
+ end
+
+ # test named routes like foo_path and foos_path map to the correct options.
+ def assert_restful_named_routes_for(controller_name, singular_name = nil, options = {})
+ if singular_name.is_a?(Hash)
+ options = singular_name
+ singular_name = nil
+ end
+ singular_name ||= controller_name.to_s.singularize
+
+ options[:options] ||= {}
+ options[:options][:controller] = options[:controller] || controller_name.to_s
+
+ @controller = "#{options[:options][:controller].camelize}Controller".constantize.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ get :index, options[:options]
+ options[:options].delete :action
+
+ full_prefix = "/#{options[:path_prefix]}#{controller_name}"
+ name_prefix = options[:name_prefix]
+
+ assert_named_route "#{full_prefix}", "#{name_prefix}#{controller_name}_path", options[:options]
+ assert_named_route "#{full_prefix}.xml", "formatted_#{name_prefix}#{controller_name}_path", options[:options].merge( :format => 'xml')
+ assert_named_route "#{full_prefix}/1", "#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1')
+ assert_named_route "#{full_prefix}/1.xml", "formatted_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml')
+
+ assert_named_route "#{full_prefix}/new", "new_#{name_prefix}#{singular_name}_path", options[:options]
+ assert_named_route "#{full_prefix}/new.xml", "formatted_new_#{name_prefix}#{singular_name}_path", options[:options].merge( :format => 'xml')
+ assert_named_route "#{full_prefix}/1/edit", "edit_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1')
+ assert_named_route "#{full_prefix}/1/edit.xml", "formatted_edit_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml')
+
+ yield options[:options] if block_given?
+ end
+
+ def assert_singleton_routes_for(singleton_name, options = {})
+ options[:options] ||= {}
+ options[:options][:controller] = options[:controller] || singleton_name.to_s.pluralize
+
+ full_path = "/#{options[:path_prefix]}#{singleton_name}"
+ new_path = "#{full_path}/new"
+ edit_path = "#{full_path}/edit"
+ formatted_edit_path = "#{full_path}/edit.xml"
+
+ with_options options[:options] do |controller|
+ controller.assert_routing full_path, :action => 'show'
+ controller.assert_routing new_path, :action => 'new'
+ controller.assert_routing edit_path, :action => 'edit'
+ controller.assert_routing "#{full_path}.xml", :action => 'show', :format => 'xml'
+ controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
+ controller.assert_routing formatted_edit_path, :action => 'edit', :format => 'xml'
+ end
+
+ assert_recognizes(options[:options].merge(:action => 'show'), :path => full_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'new'), :path => new_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'edit'), :path => edit_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'create'), :path => full_path, :method => :post)
+ assert_recognizes(options[:options].merge(:action => 'update'), :path => full_path, :method => :put)
+ assert_recognizes(options[:options].merge(:action => 'destroy'), :path => full_path, :method => :delete)
+
+ assert_recognizes(options[:options].merge(:action => 'show', :format => 'xml'), :path => "#{full_path}.xml", :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'edit', :format => 'xml'), :path => formatted_edit_path, :method => :get)
+ assert_recognizes(options[:options].merge(:action => 'create', :format => 'xml'), :path => "#{full_path}.xml", :method => :post)
+ assert_recognizes(options[:options].merge(:action => 'update', :format => 'xml'), :path => "#{full_path}.xml", :method => :put)
+ assert_recognizes(options[:options].merge(:action => 'destroy', :format => 'xml'), :path => "#{full_path}.xml", :method => :delete)
+
+ yield options[:options] if block_given?
+ end
+
+ def assert_singleton_named_routes_for(singleton_name, options = {})
+ (options[:options] ||= {})[:controller] ||= singleton_name.to_s.pluralize
+ @controller = "#{options[:options][:controller].camelize}Controller".constantize.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ get :show, options[:options]
+ options[:options].delete :action
+
+ full_path = "/#{options[:path_prefix]}#{singleton_name}"
+ 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}/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}/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')
+ end
+
+ def assert_named_route(expected, route, options)
+ actual = @controller.send(route, options) rescue $!.class.name
+ assert_equal expected, actual, "Error on route: #{route}(#{options.inspect})"
+ end
+
+ def assert_resource_methods(expected, resource, action_method, method)
+ assert_equal expected.length, resource.send("#{action_method}_methods")[method].size, "#{resource.send("#{action_method}_methods")[method].inspect}"
+ expected.each do |action|
+ assert resource.send("#{action_method}_methods")[method].include?(action),
+ "#{method} not in #{action_method} methods: #{resource.send("#{action_method}_methods")[method].inspect}"
+ end
+ end
+
+ def distinct_routes? (r1, r2)
+ if r1.conditions == r2.conditions and r1.requirements == r2.requirements then
+ if r1.segments.collect(&:to_s) == r2.segments.collect(&:to_s) then
+ return false
+ end
+ end
+ true
+ end
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/routing_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/routing_test.rb
new file mode 100644
index 000000000..281ef13b3
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/routing_test.rb
@@ -0,0 +1,2203 @@
+require "#{File.dirname(__FILE__)}/../abstract_unit"
+require "#{File.dirname(__FILE__)}/fake_controllers"
+require 'action_controller/routing'
+
+class MilestonesController < ActionController::Base
+ def index() head :ok end
+ alias_method :show, :index
+ def rescue_action(e) raise e end
+end
+
+RunTimeTests = ARGV.include? 'time'
+ROUTING = ActionController::Routing
+
+class ROUTING::RouteBuilder
+ attr_reader :warn_output
+
+ def warn(msg)
+ (@warn_output ||= []) << msg
+ end
+end
+
+# See RFC 3986, section 3.3 for allowed path characters.
+class UriReservedCharactersRoutingTest < Test::Unit::TestCase
+ def setup
+ ActionController::Routing.use_controllers! ['controller']
+ @set = ActionController::Routing::RouteSet.new
+ @set.draw do |map|
+ map.connect ':controller/:action/:variable'
+ end
+
+ safe, unsafe = %w(: @ & = + $ , ;), %w(^ / ? # [ ])
+ hex = unsafe.map { |char| '%' + char.unpack('H2').first.upcase }
+
+ @segment = "#{safe}#{unsafe}".freeze
+ @escaped = "#{safe}#{hex}".freeze
+ end
+
+ def test_route_generation_escapes_unsafe_path_characters
+ assert_equal "/contr#{@segment}oller/act#{@escaped}ion/var#{@escaped}iable",
+ @set.generate(:controller => "contr#{@segment}oller",
+ :action => "act#{@segment}ion",
+ :variable => "var#{@segment}iable")
+ end
+
+ def test_route_recognition_unescapes_path_components
+ options = { :controller => "controller",
+ :action => "act#{@segment}ion",
+ :variable => "var#{@segment}iable" }
+ assert_equal options, @set.recognize_path("/controller/act#{@escaped}ion/var#{@escaped}iable")
+ end
+end
+
+class LegacyRouteSetTests < Test::Unit::TestCase
+ attr_reader :rs
+ def setup
+ # These tests assume optimisation is on, so re-enable it.
+ ActionController::Base.optimise_named_routes = true
+
+ @rs = ::ActionController::Routing::RouteSet.new
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
+
+ ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
+ end
+
+ def test_default_setup
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
+
+ assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
+
+ assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10)
+
+ assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
+ assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'})
+
+ assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
+ assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
+ end
+
+ def test_ignores_leading_slash
+ @rs.draw {|m| m.connect '/:controller/:action/:id'}
+ test_default_setup
+ end
+
+ def test_time_recognition
+ n = 10000
+ if RunTimeTests
+ GC.start
+ rectime = Benchmark.realtime do
+ n.times do
+ rs.recognize_path("content")
+ rs.recognize_path("content/list")
+ rs.recognize_path("content/show/10")
+ rs.recognize_path("admin/user")
+ rs.recognize_path("admin/user/list")
+ rs.recognize_path("admin/user/show/10")
+ end
+ end
+ puts "\n\nRecognition (RouteSet):"
+ per_url = rectime / (n * 6)
+ puts "#{per_url * 1000} ms/url"
+ puts "#{1 / per_url} url/s\n\n"
+ end
+ end
+ def test_time_generation
+ n = 5000
+ if RunTimeTests
+ GC.start
+ pairs = [
+ [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}],
+ [{:controller => 'content'}, {:controller => 'content', :action => 'index'}],
+ [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}],
+ [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}],
+ [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}],
+ [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}],
+ [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}],
+ [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}],
+ ]
+ p = nil
+ gentime = Benchmark.realtime do
+ n.times do
+ pairs.each {|(a, b)| rs.generate(a, b)}
+ end
+ end
+
+ puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)"
+ per_url = gentime / (n * 8)
+ puts "#{per_url * 1000} ms/url"
+ puts "#{1 / per_url} url/s\n\n"
+ end
+ end
+
+ def test_route_with_colon_first
+ rs.draw do |map|
+ map.connect '/:controller/:action/:id', :action => 'index', :id => nil
+ map.connect ':url', :controller => 'tiny_url', :action => 'translate'
+ end
+ end
+
+ def test_route_with_regexp_for_controller
+ rs.draw do |map|
+ map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
+ map.connect ':controller/:action/:id'
+ end
+ assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
+ rs.recognize_path("/admin/user/foo"))
+ assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo"))
+ assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index")
+ assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo")
+ end
+
+ def test_route_with_regexp_and_dot
+ rs.draw do |map|
+ map.connect ':controller/:action/:file',
+ :controller => /admin|user/,
+ :action => /upload|download/,
+ :defaults => {:file => nil},
+ :requirements => {:file => %r{[^/]+(\.[^/]+)?}}
+ end
+ # Without a file extension
+ assert_equal '/user/download/file',
+ rs.generate(:controller => "user", :action => "download", :file => "file")
+ assert_equal(
+ {:controller => "user", :action => "download", :file => "file"},
+ rs.recognize_path("/user/download/file"))
+
+ # Now, let's try a file with an extension, really a dot (.)
+ assert_equal '/user/download/file.jpg',
+ rs.generate(
+ :controller => "user", :action => "download", :file => "file.jpg")
+ assert_equal(
+ {:controller => "user", :action => "download", :file => "file.jpg"},
+ rs.recognize_path("/user/download/file.jpg"))
+ end
+
+ def test_basic_named_route
+ rs.add_named_route :home, '', :controller => 'content', :action => 'list'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/",
+ x.send(:home_url))
+ end
+
+ def test_basic_named_route_with_relative_url_root
+ rs.add_named_route :home, '', :controller => 'content', :action => 'list'
+ x = setup_for_named_route
+ x.relative_url_root="/foo"
+ assert_equal("http://named.route.test/foo/",
+ x.send(:home_url))
+ assert_equal "/foo/", x.send(:home_path)
+ end
+
+ def test_named_route_with_option
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/page/new%20stuff",
+ x.send(:page_url, :title => 'new stuff'))
+ end
+
+ def test_named_route_with_default
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/page/AboutRails",
+ x.send(:page_url, :title => "AboutRails"))
+
+ end
+
+ def test_named_route_with_nested_controller
+ rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/admin/user",
+ x.send(:users_url))
+ end
+
+ uses_mocha "named route optimisation" do
+ def test_optimised_named_route_call_never_uses_url_for
+ rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index'
+ rs.add_named_route :user, 'admin/user/:id', :controller=>'/admin/user', :action=>'show'
+ x = setup_for_named_route
+ x.expects(:url_for).never
+ x.send(:users_url)
+ x.send(:users_path)
+ x.send(:user_url, 2, :foo=>"bar")
+ x.send(:user_path, 3, :bar=>"foo")
+ end
+
+ def test_optimised_named_route_with_host
+ rs.add_named_route :pages, 'pages', :controller => 'content', :action => 'show_page', :host => 'foo.com'
+ x = setup_for_named_route
+ x.expects(:url_for).with(:host => 'foo.com', :only_path => false, :controller => 'content', :action => 'show_page', :use_route => :pages).once
+ x.send(:pages_url)
+ end
+ end
+
+ def setup_for_named_route
+ klass = Class.new(MockController)
+ rs.install_helpers(klass)
+ klass.new(rs)
+ end
+
+ def test_named_route_without_hash
+ rs.draw do |map|
+ map.normal ':controller/:action/:id'
+ end
+ end
+
+ def test_named_route_root
+ rs.draw do |map|
+ map.root :controller => "hello"
+ end
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/", x.send(:root_url))
+ assert_equal("/", x.send(:root_path))
+ end
+
+ def test_named_route_with_regexps
+ rs.draw do |map|
+ map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show',
+ :year => /\d+/, :month => /\d+/, :day => /\d+/
+ map.connect ':controller/:action/:id'
+ end
+ x = setup_for_named_route
+ # assert_equal(
+ # {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false},
+ # x.send(:article_url, :title => 'hi')
+ # )
+ assert_equal(
+ "http://named.route.test/page/2005/6/10/hi",
+ x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
+ )
+ end
+
+ def test_changing_controller
+ assert_equal '/admin/stuff/show/10', rs.generate(
+ {:controller => 'stuff', :action => 'show', :id => 10},
+ {:controller => 'admin/user', :action => 'index'}
+ )
+ end
+
+ def test_paths_escaped
+ rs.draw do |map|
+ map.path 'file/*path', :controller => 'content', :action => 'show_file'
+ map.connect ':controller/:action/:id'
+ end
+
+ # No + to space in URI escaping, only for query params.
+ results = rs.recognize_path "/file/hello+world/how+are+you%3F"
+ assert results, "Recognition should have succeeded"
+ assert_equal ['hello+world', 'how+are+you?'], results[:path]
+
+ # Use %20 for space instead.
+ results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
+ assert results, "Recognition should have succeeded"
+ assert_equal ['hello world', 'how are you?'], results[:path]
+
+ results = rs.recognize_path "/file"
+ assert results, "Recognition should have succeeded"
+ assert_equal [], results[:path]
+ end
+
+ def test_paths_slashes_unescaped_with_ordered_parameters
+ rs.add_named_route :path, '/file/*path', :controller => 'content'
+
+ # No / to %2F in URI, only for query params.
+ x = setup_for_named_route
+ assert_equal("/file/hello/world", x.send(:path_path, 'hello/world'))
+ end
+
+ def test_non_controllers_cannot_be_matched
+ rs.draw do |map|
+ map.connect ':controller/:action/:id'
+ end
+ assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
+ end
+
+ def test_paths_do_not_accept_defaults
+ assert_raises(ActionController::RoutingError) do
+ rs.draw do |map|
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default)
+ map.connect ':controller/:action/:id'
+ end
+ end
+
+ rs.draw do |map|
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => []
+ map.connect ':controller/:action/:id'
+ end
+ end
+
+ def test_should_list_options_diff_when_routing_requirements_dont_match
+ rs.draw do |map|
+ map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
+ end
+ exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
+ assert_match /^post_url failed to generate/, exception.message
+ from_match = exception.message.match(/from \{[^\}]+\}/).to_s
+ assert_match /:bad_param=>"foo"/, from_match
+ assert_match /:action=>"show"/, from_match
+ assert_match /:controller=>"post"/, from_match
+
+ expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s
+ assert_no_match /:bad_param=>"foo"/, expected_match
+ assert_match /:action=>"show"/, expected_match
+ assert_match /:controller=>"post"/, expected_match
+
+ diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s
+ assert_match /:bad_param=>"foo"/, diff_match
+ assert_no_match /:action=>"show"/, diff_match
+ assert_no_match /:controller=>"post"/, diff_match
+ end
+
+ # this specifies the case where your formerly would get a very confusing error message with an empty diff
+ def test_should_have_better_error_message_when_options_diff_is_empty
+ rs.draw do |map|
+ map.content '/content/:query', :controller => 'content', :action => 'show'
+ end
+
+ exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") }
+ assert_match %r[:action=>"show"], exception.message
+ assert_match %r[:controller=>"content"], exception.message
+ assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message
+ assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message
+ end
+
+ def test_dynamic_path_allowed
+ rs.draw do |map|
+ map.connect '*path', :controller => 'content', :action => 'show_file'
+ end
+
+ assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo))
+ end
+
+ def test_dynamic_recall_paths_allowed
+ rs.draw do |map|
+ map.connect '*path', :controller => 'content', :action => 'show_file'
+ end
+
+ recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo))
+ assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path)
+ end
+
+ def test_backwards
+ rs.draw do |map|
+ map.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'})
+ assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show')
+ assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo')
+ end
+
+ def test_route_with_fixnum_default
+ rs.draw do |map|
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page')
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1)
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1')
+ assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10)
+
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page"))
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
+ assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
+ end
+
+ # For newer revision
+ def test_route_with_text_default
+ rs.draw do |map|
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo')
+ assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo"))
+
+ token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian
+ escaped_token = CGI::escape(token)
+
+ assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token)
+ assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}"))
+ end
+
+ def test_action_expiry
+ assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
+ end
+
+ def test_recognition_with_uppercase_controller_name
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
+
+ # these used to work, before the routes rewrite, but support for this was pulled in the new version...
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed"))
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed"))
+ end
+
+ def test_requirement_should_prevent_optional_id
+ rs.draw do |map|
+ map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
+ end
+
+ assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10)
+
+ assert_raises ActionController::RoutingError do
+ rs.generate(:controller => 'post', :action => 'show')
+ end
+ end
+
+ def test_both_requirement_and_optional
+ rs.draw do |map|
+ map.blog('test/:year', :controller => 'post', :action => 'show',
+ :defaults => { :year => nil },
+ :requirements => { :year => /\d{4}/ }
+ )
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show')
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil)
+
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/test",
+ x.send(:blog_url))
+ end
+
+ def test_set_to_nil_forgets
+ rs.draw do |map|
+ map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/pages/2005',
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005)
+ assert_equal '/pages/2005/6',
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6)
+ assert_equal '/pages/2005/6/12',
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12)
+
+ assert_equal '/pages/2005/6/4',
+ rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
+
+ assert_equal '/pages/2005/6',
+ rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
+
+ assert_equal '/pages/2005',
+ rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
+ end
+
+ def test_url_with_no_action_specified
+ rs.draw do |map|
+ map.connect '', :controller => 'content'
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
+ assert_equal '/', rs.generate(:controller => 'content')
+ end
+
+ def test_named_url_with_no_action_specified
+ rs.draw do |map|
+ map.home '', :controller => 'content'
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
+ assert_equal '/', rs.generate(:controller => 'content')
+
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/",
+ x.send(:home_url))
+ end
+
+ def test_url_generated_when_forgetting_action
+ [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash|
+ rs.draw do |map|
+ map.home '', hash
+ map.connect ':controller/:action/:id'
+ end
+ assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'})
+ assert_equal '/', rs.generate({:controller => 'content'})
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
+ end
+ end
+
+ def test_named_route_method
+ rs.draw do |map|
+ map.categories 'categories', :controller => 'content', :action => 'categories'
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories')
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
+ end
+
+ def test_named_routes_array
+ test_named_route_method
+ assert_equal [:categories], rs.named_routes.names
+ end
+
+ def test_nil_defaults
+ rs.draw do |map|
+ map.connect 'journal',
+ :controller => 'content',
+ :action => 'list_journal',
+ :date => nil, :user_id => nil
+ map.connect ':controller/:action/:id'
+ end
+
+ assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
+ end
+
+ def setup_request_method_routes_for(method)
+ @request = ActionController::TestRequest.new
+ @request.env["REQUEST_METHOD"] = method
+ @request.request_uri = "/match"
+
+ rs.draw do |r|
+ r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get }
+ r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post }
+ r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put }
+ r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete }
+ end
+ end
+
+ %w(GET POST PUT DELETE).each do |request_method|
+ define_method("test_request_method_recognized_with_#{request_method}") do
+ begin
+ Object.const_set(:BooksController, Class.new(ActionController::Base))
+
+ setup_request_method_routes_for(request_method)
+
+ assert_nothing_raised { rs.recognize(@request) }
+ assert_equal request_method.downcase, @request.path_parameters[:action]
+ ensure
+ Object.send(:remove_const, :BooksController) rescue nil
+ end
+ end
+ end
+
+ def test_subpath_recognized
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
+
+ rs.draw do |r|
+ r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
+ r.connect '/items/:id/:action', :controller => 'subpath_books'
+ r.connect '/posts/new/:action', :controller => 'subpath_books'
+ r.connect '/posts/:id', :controller => 'subpath_books', :action => "show"
+ end
+
+ hash = rs.recognize_path "/books/17/edit"
+ assert_not_nil hash
+ assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
+
+ hash = rs.recognize_path "/items/3/complete"
+ assert_not_nil hash
+ assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
+
+ hash = rs.recognize_path "/posts/new/preview"
+ assert_not_nil hash
+ assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
+
+ hash = rs.recognize_path "/posts/7"
+ assert_not_nil hash
+ assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
+ ensure
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
+ end
+
+ def test_subpath_generated
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
+
+ rs.draw do |r|
+ r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
+ r.connect '/items/:id/:action', :controller => 'subpath_books'
+ r.connect '/posts/new/:action', :controller => 'subpath_books'
+ end
+
+ assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit")
+ assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete")
+ assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview")
+ ensure
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
+ end
+
+ def test_failed_requirements_raises_exception_with_violated_requirements
+ rs.draw do |r|
+ r.foo_with_requirement 'foos/:id', :controller=>'foos', :requirements=>{:id=>/\d+/}
+ end
+
+ x = setup_for_named_route
+ assert_raises(ActionController::RoutingError) do
+ x.send(:foo_with_requirement_url, "I am Against the requirements")
+ end
+ end
+end
+
+class SegmentTest < Test::Unit::TestCase
+
+ def test_first_segment_should_interpolate_for_structure
+ s = ROUTING::Segment.new
+ def s.interpolation_statement(array) 'hello' end
+ assert_equal 'hello', s.continue_string_structure([])
+ end
+
+ def test_interpolation_statement
+ s = ROUTING::StaticSegment.new
+ s.value = "Hello"
+ assert_equal "Hello", eval(s.interpolation_statement([]))
+ assert_equal "HelloHello", eval(s.interpolation_statement([s]))
+
+ s2 = ROUTING::StaticSegment.new
+ s2.value = "-"
+ assert_equal "Hello-Hello", eval(s.interpolation_statement([s, s2]))
+
+ s3 = ROUTING::StaticSegment.new
+ s3.value = "World"
+ assert_equal "Hello-World", eval(s3.interpolation_statement([s, s2]))
+ end
+
+end
+
+class StaticSegmentTest < Test::Unit::TestCase
+
+ def test_interpolation_chunk_should_respect_raw
+ s = ROUTING::StaticSegment.new
+ s.value = 'Hello World'
+ assert ! s.raw?
+ assert_equal 'Hello%20World', s.interpolation_chunk
+
+ s.raw = true
+ assert s.raw?
+ assert_equal 'Hello World', s.interpolation_chunk
+ end
+
+ def test_regexp_chunk_should_escape_specials
+ s = ROUTING::StaticSegment.new
+
+ s.value = 'Hello*World'
+ assert_equal 'Hello\*World', s.regexp_chunk
+
+ s.value = 'HelloWorld'
+ assert_equal 'HelloWorld', s.regexp_chunk
+ end
+
+ def test_regexp_chunk_should_add_question_mark_for_optionals
+ s = ROUTING::StaticSegment.new
+ s.value = "/"
+ s.is_optional = true
+ assert_equal "/?", s.regexp_chunk
+
+ s.value = "hello"
+ assert_equal "(?:hello)?", s.regexp_chunk
+ end
+
+end
+
+class DynamicSegmentTest < Test::Unit::TestCase
+
+ def segment
+ unless @segment
+ @segment = ROUTING::DynamicSegment.new
+ @segment.key = :a
+ end
+ @segment
+ end
+
+ def test_extract_value
+ s = ROUTING::DynamicSegment.new
+ s.key = :a
+
+ hash = {:a => '10', :b => '20'}
+ assert_equal '10', eval(s.extract_value)
+
+ hash = {:b => '20'}
+ assert_equal nil, eval(s.extract_value)
+
+ s.default = '20'
+ assert_equal '20', eval(s.extract_value)
+ end
+
+ def test_default_local_name
+ assert_equal 'a_value', segment.local_name,
+ "Unexpected name -- all value_check tests will fail!"
+ end
+
+ def test_presence_value_check
+ a_value = 10
+ assert eval(segment.value_check)
+ end
+
+ def test_regexp_value_check_rejects_nil
+ segment.regexp = /\d+/
+ a_value = nil
+ assert ! eval(segment.value_check)
+ end
+
+ def test_optional_regexp_value_check_should_accept_nil
+ segment.regexp = /\d+/
+ segment.is_optional = true
+ a_value = nil
+ assert eval(segment.value_check)
+ end
+
+ def test_regexp_value_check_rejects_no_match
+ segment.regexp = /\d+/
+
+ a_value = "Hello20World"
+ assert ! eval(segment.value_check)
+
+ a_value = "20Hi"
+ assert ! eval(segment.value_check)
+ end
+
+ def test_regexp_value_check_accepts_match
+ segment.regexp = /\d+/
+
+ a_value = "30"
+ assert eval(segment.value_check)
+ end
+
+ def test_value_check_fails_on_nil
+ a_value = nil
+ assert ! eval(segment.value_check)
+ end
+
+ def test_optional_value_needs_no_check
+ segment.is_optional = true
+ a_value = nil
+ assert_equal nil, segment.value_check
+ end
+
+ def test_regexp_value_check_should_accept_match_with_default
+ segment.regexp = /\d+/
+ segment.default = '200'
+
+ a_value = '100'
+ assert eval(segment.value_check)
+ end
+
+ def test_expiry_should_not_trigger_once_expired
+ expired = true
+ hash = merged = {:a => 2, :b => 3}
+ options = {:b => 3}
+ expire_on = Hash.new { raise 'No!!!' }
+
+ eval(segment.expiry_statement)
+ rescue RuntimeError
+ flunk "Expiry check should not have occurred!"
+ end
+
+ def test_expiry_should_occur_according_to_expire_on
+ expired = false
+ hash = merged = {:a => 2, :b => 3}
+ options = {:b => 3}
+
+ expire_on = {:b => true, :a => false}
+ eval(segment.expiry_statement)
+ assert !expired
+ assert_equal({:a => 2, :b => 3}, hash)
+
+ expire_on = {:b => true, :a => true}
+ eval(segment.expiry_statement)
+ assert expired
+ assert_equal({:b => 3}, hash)
+ end
+
+ def test_extraction_code_should_return_on_nil
+ hash = merged = {:b => 3}
+ options = {:b => 3}
+ a_value = nil
+
+ # Local jump because of return inside eval.
+ assert_raises(LocalJumpError) { eval(segment.extraction_code) }
+ end
+
+ def test_extraction_code_should_return_on_mismatch
+ segment.regexp = /\d+/
+ hash = merged = {:a => 'Hi', :b => '3'}
+ options = {:b => '3'}
+ a_value = nil
+
+ # Local jump because of return inside eval.
+ assert_raises(LocalJumpError) { eval(segment.extraction_code) }
+ end
+
+ def test_extraction_code_should_accept_value_and_set_local
+ hash = merged = {:a => 'Hi', :b => '3'}
+ options = {:b => '3'}
+ a_value = nil
+ expired = true
+
+ eval(segment.extraction_code)
+ assert_equal 'Hi', a_value
+ end
+
+ def test_extraction_should_work_without_value_check
+ segment.default = 'hi'
+ hash = merged = {:b => '3'}
+ options = {:b => '3'}
+ a_value = nil
+ expired = true
+
+ eval(segment.extraction_code)
+ assert_equal 'hi', a_value
+ end
+
+ def test_extraction_code_should_perform_expiry
+ expired = false
+ hash = merged = {:a => 'Hi', :b => '3'}
+ options = {:b => '3'}
+ expire_on = {:a => true}
+ a_value = nil
+
+ eval(segment.extraction_code)
+ assert_equal 'Hi', a_value
+ assert expired
+ assert_equal options, hash
+ end
+
+ def test_interpolation_chunk_should_replace_value
+ a_value = 'Hi'
+ assert_equal a_value, eval(%("#{segment.interpolation_chunk}"))
+ end
+
+ def test_interpolation_chunk_should_accept_nil
+ a_value = nil
+ assert_equal '', eval(%("#{segment.interpolation_chunk('a_value')}"))
+ end
+
+ def test_value_regexp_should_be_nil_without_regexp
+ assert_equal nil, segment.value_regexp
+ end
+
+ def test_value_regexp_should_match_exacly
+ segment.regexp = /\d+/
+ assert_no_match segment.value_regexp, "Hello 10 World"
+ assert_no_match segment.value_regexp, "Hello 10"
+ assert_no_match segment.value_regexp, "10 World"
+ assert_match segment.value_regexp, "10"
+ end
+
+ def test_regexp_chunk_should_return_string
+ segment.regexp = /\d+/
+ assert_kind_of String, segment.regexp_chunk
+ end
+
+ def test_build_pattern_non_optional_with_no_captures
+ # Non optional
+ a_segment = ROUTING::DynamicSegment.new
+ a_segment.regexp = /\d+/ #number_of_captures is 0
+ assert_equal "(\\d+)stuff", a_segment.build_pattern('stuff')
+ end
+
+ def test_build_pattern_non_optional_with_captures
+ # Non optional
+ a_segment = ROUTING::DynamicSegment.new
+ a_segment.regexp = /(\d+)(.*?)/ #number_of_captures is 2
+ assert_equal "((\\d+)(.*?))stuff", a_segment.build_pattern('stuff')
+ end
+
+ def test_optionality_implied
+ a_segment = ROUTING::DynamicSegment.new
+ a_segment.key = :id
+ assert a_segment.optionality_implied?
+
+ a_segment.key = :action
+ assert a_segment.optionality_implied?
+ end
+end
+
+class ControllerSegmentTest < Test::Unit::TestCase
+
+ def test_regexp_should_only_match_possible_controllers
+ ActionController::Routing.with_controllers %w(admin/accounts admin/users account pages) do
+ cs = ROUTING::ControllerSegment.new :controller
+ regexp = %r{\A#{cs.regexp_chunk}\Z}
+
+ ActionController::Routing.possible_controllers.each do |name|
+ assert_match regexp, name
+ assert_no_match regexp, "#{name}_fake"
+
+ match = regexp.match name
+ assert_equal name, match[1]
+ end
+ end
+ end
+
+end
+
+uses_mocha 'RouteTest' do
+
+ class MockController
+ attr_accessor :routes
+
+ def initialize(routes)
+ self.routes = routes
+ end
+
+ def url_for(options)
+ only_path = options.delete(:only_path)
+
+ port = options.delete(:port) || 80
+ port_string = port == 80 ? '' : ":#{port}"
+
+ host = options.delete(:host) || "named.route.test"
+ anchor = "##{options.delete(:anchor)}" if options.key?(:anchor)
+
+ path = routes.generate(options)
+
+ only_path ? "#{path}#{anchor}" : "http://#{host}#{port_string}#{path}#{anchor}"
+ end
+
+ def request
+ @request ||= MockRequest.new(:host => "named.route.test", :method => :get)
+ end
+
+ def relative_url_root=(value)
+ request.relative_url_root=value
+ end
+ end
+
+ class MockRequest
+ attr_accessor :path, :path_parameters, :host, :subdomains, :domain,
+ :method, :relative_url_root
+
+ def initialize(values={})
+ values.each { |key, value| send("#{key}=", value) }
+ if values[:host]
+ subdomain, self.domain = values[:host].split(/\./, 2)
+ self.subdomains = [subdomain]
+ end
+ end
+
+ def protocol
+ "http://"
+ end
+
+ def host_with_port
+ (subdomains * '.') + '.' + domain
+ end
+ end
+
+class RouteTest < Test::Unit::TestCase
+
+ def setup
+ @route = ROUTING::Route.new
+ end
+
+ def slash_segment(is_optional = false)
+ returning ROUTING::DividerSegment.new('/') do |s|
+ s.is_optional = is_optional
+ end
+ end
+
+ def default_route
+ unless defined?(@default_route)
+ @default_route = ROUTING::Route.new
+
+ @default_route.segments << (s = ROUTING::StaticSegment.new)
+ s.value = '/'
+ s.raw = true
+
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
+ s.key = :controller
+
+ @default_route.segments << slash_segment(:optional)
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
+ s.key = :action
+ s.default = 'index'
+ s.is_optional = true
+
+ @default_route.segments << slash_segment(:optional)
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
+ s.key = :id
+ s.is_optional = true
+
+ @default_route.segments << slash_segment(:optional)
+ end
+ @default_route
+ end
+
+ def test_default_route_recognition
+ expected = {:controller => 'accounts', :action => 'show', :id => '10'}
+ assert_equal expected, default_route.recognize('/accounts/show/10')
+ assert_equal expected, default_route.recognize('/accounts/show/10/')
+
+ expected[:id] = 'jamis'
+ assert_equal expected, default_route.recognize('/accounts/show/jamis/')
+
+ expected.delete :id
+ assert_equal expected, default_route.recognize('/accounts/show')
+ assert_equal expected, default_route.recognize('/accounts/show/')
+
+ expected[:action] = 'index'
+ assert_equal expected, default_route.recognize('/accounts/')
+ assert_equal expected, default_route.recognize('/accounts')
+
+ assert_equal nil, default_route.recognize('/')
+ assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free')
+ end
+
+ def test_default_route_should_omit_default_action
+ o = {:controller => 'accounts', :action => 'index'}
+ assert_equal '/accounts', default_route.generate(o, o, {})
+ end
+
+ def test_default_route_should_include_default_action_when_id_present
+ o = {:controller => 'accounts', :action => 'index', :id => '20'}
+ assert_equal '/accounts/index/20', default_route.generate(o, o, {})
+ end
+
+ def test_default_route_should_work_with_action_but_no_id
+ o = {:controller => 'accounts', :action => 'list_all'}
+ assert_equal '/accounts/list_all', default_route.generate(o, o, {})
+ end
+
+ def test_default_route_should_uri_escape_pluses
+ expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' }
+ assert_equal expected, default_route.recognize('/accounts/show/hello world')
+ assert_equal expected, default_route.recognize('/accounts/show/hello%20world')
+ assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {})
+
+ expected[:id] = 'hello+world'
+ assert_equal expected, default_route.recognize('/accounts/show/hello+world')
+ assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld')
+ assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {})
+ end
+
+ def test_matches_controller_and_action
+ # requirement_for should only be called for the action and controller _once_
+ @route.expects(:requirement_for).with(:controller).times(1).returns('pages')
+ @route.expects(:requirement_for).with(:action).times(1).returns('show')
+
+ @route.requirements = {:controller => 'pages', :action => 'show'}
+ assert @route.matches_controller_and_action?('pages', 'show')
+ assert !@route.matches_controller_and_action?('not_pages', 'show')
+ assert !@route.matches_controller_and_action?('pages', 'not_show')
+ end
+
+ def test_parameter_shell
+ page_url = ROUTING::Route.new
+ page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/}
+ assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell)
+ end
+
+ def test_defaults
+ route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html"
+ assert_equal(
+ { :controller => "users", :action => "show", :format => "html" },
+ route.defaults)
+ end
+
+ def test_builder_complains_without_controller
+ assert_raises(ArgumentError) do
+ ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index"
+ end
+ end
+
+ def test_significant_keys_for_default_route
+ keys = default_route.significant_keys.sort_by {|k| k.to_s }
+ assert_equal [:action, :controller, :id], keys
+ end
+
+ def test_significant_keys
+ user_url = ROUTING::Route.new
+ user_url.segments << (s = ROUTING::StaticSegment.new)
+ s.value = '/'
+ s.raw = true
+
+ user_url.segments << (s = ROUTING::StaticSegment.new)
+ s.value = 'user'
+
+ user_url.segments << (s = ROUTING::StaticSegment.new)
+ s.value = '/'
+ s.raw = true
+ s.is_optional = true
+
+ user_url.segments << (s = ROUTING::DynamicSegment.new)
+ s.key = :user
+
+ user_url.segments << (s = ROUTING::StaticSegment.new)
+ s.value = '/'
+ s.raw = true
+ s.is_optional = true
+
+ user_url.requirements = {:controller => 'users', :action => 'show'}
+
+ keys = user_url.significant_keys.sort_by { |k| k.to_s }
+ assert_equal [:action, :controller, :user], keys
+ end
+
+ def test_build_empty_query_string
+ assert_equal '', @route.build_query_string({})
+ end
+
+ def test_build_query_string_with_nil_value
+ assert_equal '', @route.build_query_string({:x => nil})
+ end
+
+ def test_simple_build_query_string
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2'))
+ end
+
+ def test_convert_ints_build_query_string
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2))
+ end
+
+ def test_escape_spaces_build_query_string
+ assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world'))
+ end
+
+ def test_expand_array_build_query_string
+ assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2]))
+ end
+
+ def test_escape_spaces_build_query_string_selected_keys
+ assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x]))
+ end
+
+ private
+ def order_query_string(qs)
+ '?' + qs[1..-1].split('&').sort.join('&')
+ end
+end
+
+end # uses_mocha
+
+class RouteBuilderTest < Test::Unit::TestCase
+
+ def builder
+ @builder ||= ROUTING::RouteBuilder.new
+ end
+
+ def build(path, options)
+ builder.build(path, options)
+ end
+
+ def test_options_should_not_be_modified
+ requirements1 = { :id => /\w+/, :controller => /(?:[a-z](?:-?[a-z]+)*)/ }
+ requirements2 = requirements1.dup
+
+ assert_equal requirements1, requirements2
+
+ with_options(:controller => 'folder',
+ :requirements => requirements2) do |m|
+ m.build 'folders/new', :action => 'new'
+ end
+
+ assert_equal requirements1, requirements2
+ end
+
+ def test_segment_for_static
+ segment, rest = builder.segment_for 'ulysses'
+ assert_equal '', rest
+ assert_kind_of ROUTING::StaticSegment, segment
+ assert_equal 'ulysses', segment.value
+ end
+
+ def test_segment_for_action
+ segment, rest = builder.segment_for ':action'
+ assert_equal '', rest
+ assert_kind_of ROUTING::DynamicSegment, segment
+ assert_equal :action, segment.key
+ assert_equal 'index', segment.default
+ end
+
+ def test_segment_for_dynamic
+ segment, rest = builder.segment_for ':login'
+ assert_equal '', rest
+ assert_kind_of ROUTING::DynamicSegment, segment
+ assert_equal :login, segment.key
+ assert_equal nil, segment.default
+ assert ! segment.optional?
+ end
+
+ def test_segment_for_with_rest
+ segment, rest = builder.segment_for ':login/:action'
+ assert_equal :login, segment.key
+ assert_equal '/:action', rest
+ segment, rest = builder.segment_for rest
+ assert_equal '/', segment.value
+ assert_equal ':action', rest
+ segment, rest = builder.segment_for rest
+ assert_equal :action, segment.key
+ assert_equal '', rest
+ end
+
+ def test_segments_for
+ segments = builder.segments_for_route_path '/:controller/:action/:id'
+
+ assert_kind_of ROUTING::DividerSegment, segments[0]
+ assert_equal '/', segments[2].value
+
+ assert_kind_of ROUTING::DynamicSegment, segments[1]
+ assert_equal :controller, segments[1].key
+
+ assert_kind_of ROUTING::DividerSegment, segments[2]
+ assert_equal '/', segments[2].value
+
+ assert_kind_of ROUTING::DynamicSegment, segments[3]
+ assert_equal :action, segments[3].key
+
+ assert_kind_of ROUTING::DividerSegment, segments[4]
+ assert_equal '/', segments[4].value
+
+ assert_kind_of ROUTING::DynamicSegment, segments[5]
+ assert_equal :id, segments[5].key
+ end
+
+ def test_segment_for_action
+ s, r = builder.segment_for(':action/something/else')
+ assert_equal '/something/else', r
+ assert_equal :action, s.key
+ end
+
+ def test_action_default_should_not_trigger_on_prefix
+ s, r = builder.segment_for ':action_name/something/else'
+ assert_equal '/something/else', r
+ assert_equal :action_name, s.key
+ assert_equal nil, s.default
+ end
+
+ def test_divide_route_options
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
+ defaults, requirements = builder.divide_route_options(segments,
+ :action => 'buy', :person => /\w+/, :car => /\w+/,
+ :defaults => {:person => nil, :car => nil}
+ )
+
+ assert_equal({:action => 'buy', :person => nil, :car => nil}, defaults)
+ assert_equal({:person => /\w+/, :car => /\w+/}, requirements)
+ end
+
+ def test_assign_route_options
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
+ defaults = {:action => 'buy', :person => nil, :car => nil}
+ requirements = {:person => /\w+/, :car => /\w+/}
+
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
+ assert_equal({}, route_requirements)
+
+ assert_equal :action, segments[3].key
+ assert_equal 'buy', segments[3].default
+
+ assert_equal :person, segments[5].key
+ assert_equal %r/\w+/, segments[5].regexp
+ assert segments[5].optional?
+
+ assert_equal :car, segments[7].key
+ assert_equal %r/\w+/, segments[7].regexp
+ assert segments[7].optional?
+ end
+
+ def test_assign_route_options_with_anchor_chars
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
+ defaults = {:action => 'buy', :person => nil, :car => nil}
+ requirements = {:person => /\w+/, :car => /^\w+$/}
+
+ assert_raises ArgumentError do
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
+ end
+
+ requirements[:car] = /[^\/]+/
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
+ end
+
+
+ def test_optional_segments_preceding_required_segments
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
+ defaults = {:action => 'buy', :person => nil, :car => "model-t"}
+ assert builder.assign_route_options(segments, defaults, {}).empty?
+
+ 0.upto(1) { |i| assert !segments[i].optional?, "segment #{i} is optional and it shouldn't be" }
+ assert segments[2].optional?
+
+ assert_equal nil, builder.warn_output # should only warn on the :person segment
+ end
+
+ def test_segmentation_of_dot_path
+ segments = builder.segments_for_route_path '/books/:action.rss'
+ assert builder.assign_route_options(segments, {}, {}).empty?
+ assert_equal 6, segments.length # "/", "books", "/", ":action", ".", "rss"
+ assert !segments.any? { |seg| seg.optional? }
+ end
+
+ def test_segmentation_of_dynamic_dot_path
+ segments = builder.segments_for_route_path '/books/:action.:format'
+ assert builder.assign_route_options(segments, {}, {}).empty?
+ assert_equal 6, segments.length # "/", "books", "/", ":action", ".", ":format"
+ assert !segments.any? { |seg| seg.optional? }
+ assert_kind_of ROUTING::DynamicSegment, segments.last
+ end
+
+ def test_assignment_of_default_options
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
+ action, id = segments[-4], segments[-2]
+
+ assert_equal :action, action.key
+ assert_equal :id, id.key
+ assert ! action.optional?
+ assert ! id.optional?
+
+ builder.assign_default_route_options(segments)
+
+ assert_equal 'index', action.default
+ assert action.optional?
+ assert id.optional?
+ end
+
+ def test_assignment_of_default_options_respects_existing_defaults
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
+ action, id = segments[-4], segments[-2]
+
+ assert_equal :action, action.key
+ assert_equal :id, id.key
+ action.default = 'show'
+ action.is_optional = true
+
+ id.default = 'Welcome'
+ id.is_optional = true
+
+ builder.assign_default_route_options(segments)
+
+ assert_equal 'show', action.default
+ assert action.optional?
+ assert_equal 'Welcome', id.default
+ assert id.optional?
+ end
+
+ def test_assignment_of_default_options_respects_regexps
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
+ action = segments[-4]
+
+ assert_equal :action, action.key
+ action.regexp = /show|in/ # Use 'in' to check partial matches
+
+ builder.assign_default_route_options(segments)
+
+ assert_equal nil, action.default
+ assert ! action.optional?
+ end
+
+ def test_assignment_of_is_optional_when_default
+ segments = builder.segments_for_route_path '/books/:action.rss'
+ assert_equal segments[3].key, :action
+ segments[3].default = 'changes'
+ builder.ensure_required_segments(segments)
+ assert ! segments[3].optional?
+ end
+
+ def test_is_optional_is_assigned_to_default_segments
+ segments = builder.segments_for_route_path '/books/:action'
+ builder.assign_route_options(segments, {:action => 'index'}, {})
+
+ assert_equal segments[3].key, :action
+ assert segments[3].optional?
+ assert_kind_of ROUTING::DividerSegment, segments[2]
+ assert segments[2].optional?
+ end
+
+ # XXX is optional not being set right?
+ # /blah/:defaulted_segment <-- is the second slash optional? it should be.
+
+ def test_route_build
+ ActionController::Routing.with_controllers %w(users pages) do
+ r = builder.build '/:controller/:action/:id/', :action => nil
+
+ [0, 2, 4].each do |i|
+ assert_kind_of ROUTING::DividerSegment, r.segments[i]
+ assert_equal '/', r.segments[i].value
+ assert r.segments[i].optional? if i > 1
+ end
+
+ assert_kind_of ROUTING::DynamicSegment, r.segments[1]
+ assert_equal :controller, r.segments[1].key
+ assert_equal nil, r.segments[1].default
+
+ assert_kind_of ROUTING::DynamicSegment, r.segments[3]
+ assert_equal :action, r.segments[3].key
+ assert_equal 'index', r.segments[3].default
+
+ assert_kind_of ROUTING::DynamicSegment, r.segments[5]
+ assert_equal :id, r.segments[5].key
+ assert r.segments[5].optional?
+ end
+ end
+
+ def test_slashes_are_implied
+ routes = [
+ builder.build('/:controller/:action/:id/', :action => nil),
+ builder.build('/:controller/:action/:id', :action => nil),
+ builder.build(':controller/:action/:id', :action => nil),
+ builder.build('/:controller/:action/:id/', :action => nil)
+ ]
+ expected = routes.first.segments.length
+ routes.each_with_index do |route, i|
+ found = route.segments.length
+ assert_equal expected, found, "Route #{i + 1} has #{found} segments, expected #{expected}"
+ end
+ end
+
+end
+
+
+
+
+class RouteSetTest < Test::Unit::TestCase
+
+ def set
+ @set ||= ROUTING::RouteSet.new
+ end
+
+ def request
+ @request ||= MockRequest.new(:host => "named.routes.test", :method => :get)
+ end
+
+ def test_generate_extras
+ set.draw { |m| m.connect ':controller/:action/:id' }
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ assert_equal "/foo/bar/15", path
+ assert_equal %w(that this), extras.map(&:to_s).sort
+ end
+
+ def test_extra_keys
+ set.draw { |m| m.connect ':controller/:action/:id' }
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ assert_equal %w(that this), extras.map(&:to_s).sort
+ end
+
+ def test_generate_extras_not_first
+ set.draw do |map|
+ map.connect ':controller/:action/:id.:format'
+ map.connect ':controller/:action/:id'
+ end
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ assert_equal "/foo/bar/15", path
+ assert_equal %w(that this), extras.map(&:to_s).sort
+ end
+
+ def test_generate_not_first
+ set.draw do |map|
+ map.connect ':controller/:action/:id.:format'
+ map.connect ':controller/:action/:id'
+ end
+ assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello")
+ end
+
+ def test_extra_keys_not_first
+ set.draw do |map|
+ map.connect ':controller/:action/:id.:format'
+ map.connect ':controller/:action/:id'
+ end
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ assert_equal %w(that this), extras.map(&:to_s).sort
+ end
+
+ def test_draw
+ assert_equal 0, set.routes.size
+ set.draw do |map|
+ map.connect '/hello/world', :controller => 'a', :action => 'b'
+ end
+ assert_equal 1, set.routes.size
+ end
+
+ def test_named_draw
+ assert_equal 0, set.routes.size
+ set.draw do |map|
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
+ end
+ assert_equal 1, set.routes.size
+ assert_equal set.routes.first, set.named_routes[:hello]
+ end
+
+ def test_later_named_routes_take_precedence
+ set.draw do |map|
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
+ map.hello '/hello', :controller => 'a', :action => 'b'
+ end
+ assert_equal set.routes.last, set.named_routes[:hello]
+ end
+
+ def setup_named_route_test
+ set.draw do |map|
+ map.show '/people/:id', :controller => 'people', :action => 'show'
+ map.index '/people', :controller => 'people', :action => 'index'
+ map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi'
+ map.users '/admin/users', :controller => 'admin/users', :action => 'index'
+ end
+
+ klass = Class.new(MockController)
+ set.install_helpers(klass)
+ klass.new(set)
+ end
+
+ def test_named_route_hash_access_method
+ controller = setup_named_route_test
+
+ assert_equal(
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false },
+ controller.send(:hash_for_show_url, :id => 5))
+
+ assert_equal(
+ { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false },
+ controller.send(:hash_for_index_url))
+
+ assert_equal(
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true },
+ controller.send(:hash_for_show_path, :id => 5)
+ )
+ end
+
+ def test_named_route_url_method
+ controller = setup_named_route_test
+
+ assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5)
+ assert_equal "/people/5", controller.send(:show_path, :id => 5)
+
+ assert_equal "http://named.route.test/people", controller.send(:index_url)
+ assert_equal "/people", controller.send(:index_path)
+
+ assert_equal "http://named.route.test/admin/users", controller.send(:users_url)
+ assert_equal '/admin/users', controller.send(:users_path)
+ assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'})
+ end
+
+ def test_named_route_url_method_with_anchor
+ controller = setup_named_route_test
+
+ assert_equal "http://named.route.test/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
+ assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
+
+ assert_equal "http://named.route.test/people#location", controller.send(:index_url, :anchor => 'location')
+ assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
+
+ assert_equal "http://named.route.test/admin/users#location", controller.send(:users_url, :anchor => 'location')
+ assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
+
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5#location",
+ controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
+
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar#location",
+ controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
+
+ assert_equal "http://named.route.test/people?baz=bar#location",
+ controller.send(:index_url, :baz => "bar", :anchor => 'location')
+ end
+
+ def test_named_route_url_method_with_port
+ controller = setup_named_route_test
+ assert_equal "http://named.route.test:8080/people/5", controller.send(:show_url, 5, :port=>8080)
+ end
+
+ def test_named_route_url_method_with_host
+ controller = setup_named_route_test
+ assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
+ end
+
+
+ def test_named_route_url_method_with_ordered_parameters
+ controller = setup_named_route_test
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5",
+ controller.send(:multi_url, 7, "hello", 5)
+ end
+
+ def test_named_route_url_method_with_ordered_parameters_and_hash
+ controller = setup_named_route_test
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar",
+ controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
+ end
+
+ def test_named_route_url_method_with_no_positional_arguments
+ controller = setup_named_route_test
+ assert_equal "http://named.route.test/people?baz=bar",
+ controller.send(:index_url, :baz => "bar")
+ end
+
+ def test_draw_default_route
+ ActionController::Routing.with_controllers(['users']) do
+ set.draw do |map|
+ map.connect '/:controller/:action/:id'
+ end
+
+ assert_equal 1, set.routes.size
+ route = set.routes.first
+
+ assert route.segments.last.optional?
+
+ assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
+ assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
+
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
+ end
+ end
+
+ def test_draw_default_route_with_default_controller
+ ActionController::Routing.with_controllers(['users']) do
+ set.draw do |map|
+ map.connect '/:controller/:action/:id', :controller => 'users'
+ end
+ assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
+ end
+ end
+
+ def test_route_with_parameter_shell
+ ActionController::Routing.with_controllers(['users', 'pages']) do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
+ map.connect '/:controller/:action/:id'
+ end
+
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
+ assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
+
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
+ end
+ end
+
+ def test_route_requirements_with_anchor_chars_are_invalid
+ assert_raises ArgumentError do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/
+ end
+ end
+ assert_raises ArgumentError do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/
+ end
+ end
+ assert_raises ArgumentError do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/
+ end
+ end
+ assert_raises ArgumentError do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/
+ end
+ end
+ assert_raises ArgumentError do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/
+ end
+ end
+ assert_nothing_raised do
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/
+ end
+ assert_raises ActionController::RoutingError do
+ set.generate :controller => 'pages', :action => 'show', :id => 10
+ end
+ end
+ end
+
+ def test_non_path_route_requirements_match_all
+ set.draw do |map|
+ map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/
+ end
+ assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis')
+ assert_raises ActionController::RoutingError do
+ set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis')
+ end
+ assert_raises ActionController::RoutingError do
+ set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david')
+ end
+ end
+
+ def test_recognize_with_encoded_id_and_regex
+ set.draw do |map|
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/
+ end
+
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
+ end
+
+ def test_recognize_with_conditions
+ Object.const_set(:PeopleController, Class.new)
+
+ set.draw do |map|
+ map.with_options(:controller => "people") do |people|
+ people.people "/people", :action => "index", :conditions => { :method => :get }
+ people.connect "/people", :action => "create", :conditions => { :method => :post }
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
+ people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete }
+ end
+ end
+
+ request.path = "/people"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("index", request.path_parameters[:action])
+
+ request.method = :post
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("create", request.path_parameters[:action])
+
+ request.method = :put
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("update", request.path_parameters[:action])
+
+ begin
+ request.method = :bacon
+ set.recognize(request)
+ flunk 'Should have raised NotImplemented'
+ rescue ActionController::NotImplemented => e
+ assert_equal [:get, :post, :put, :delete], e.allowed_methods
+ end
+
+ request.path = "/people/5"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("show", request.path_parameters[:action])
+ assert_equal("5", request.path_parameters[:id])
+
+ request.method = :put
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("update", request.path_parameters[:action])
+ assert_equal("5", request.path_parameters[:id])
+
+ request.method = :delete
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("destroy", request.path_parameters[:action])
+ assert_equal("5", request.path_parameters[:id])
+
+ begin
+ request.method = :post
+ set.recognize(request)
+ flunk 'Should have raised MethodNotAllowed'
+ rescue ActionController::MethodNotAllowed => e
+ assert_equal [:get, :put, :delete], e.allowed_methods
+ end
+
+ ensure
+ Object.send(:remove_const, :PeopleController)
+ end
+
+ def test_typo_recognition
+ Object.const_set(:ArticlesController, Class.new)
+
+ set.draw do |map|
+ map.connect 'articles/:year/:month/:day/:title',
+ :controller => 'articles', :action => 'permalink',
+ :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
+ end
+
+ request.path = "/articles/2005/11/05/a-very-interesting-article"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("permalink", request.path_parameters[:action])
+ assert_equal("2005", request.path_parameters[:year])
+ assert_equal("11", request.path_parameters[:month])
+ assert_equal("05", request.path_parameters[:day])
+ assert_equal("a-very-interesting-article", request.path_parameters[:title])
+
+ ensure
+ Object.send(:remove_const, :ArticlesController)
+ end
+
+ def test_routing_traversal_does_not_load_extra_classes
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
+ set.draw do |map|
+ map.connect '/profile', :controller => 'profile'
+ end
+
+ request.path = '/profile'
+
+ set.recognize(request) rescue nil
+
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
+ end
+
+ def test_recognize_with_conditions_and_format
+ Object.const_set(:PeopleController, Class.new)
+
+ set.draw do |map|
+ map.with_options(:controller => "people") do |people|
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
+ people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get }
+ end
+ end
+
+ request.path = "/people/5"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("show", request.path_parameters[:action])
+ assert_equal("5", request.path_parameters[:id])
+
+ request.method = :put
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("update", request.path_parameters[:action])
+
+ request.path = "/people/5.png"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("show", request.path_parameters[:action])
+ assert_equal("5", request.path_parameters[:id])
+ assert_equal("png", request.path_parameters[:_format])
+ ensure
+ Object.send(:remove_const, :PeopleController)
+ end
+
+ def test_generate_with_default_action
+ set.draw do |map|
+ map.connect "/people", :controller => "people"
+ map.connect "/people/list", :controller => "people", :action => "list"
+ end
+
+ url = set.generate(:controller => "people", :action => "list")
+ assert_equal "/people/list", url
+ end
+
+ def test_root_map
+ Object.const_set(:PeopleController, Class.new)
+
+ set.draw { |map| map.root :controller => "people" }
+
+ request.path = ""
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("people", request.path_parameters[:controller])
+ assert_equal("index", request.path_parameters[:action])
+ ensure
+ Object.send(:remove_const, :PeopleController)
+ end
+
+
+ def test_namespace
+ Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
+
+ set.draw do |map|
+
+ map.namespace 'api' do |api|
+ api.route 'inventory', :controller => "products", :action => 'inventory'
+ end
+
+ end
+
+ request.path = "/api/inventory"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("api/products", request.path_parameters[:controller])
+ assert_equal("inventory", request.path_parameters[:action])
+ ensure
+ Object.send(:remove_const, :Api)
+ end
+
+
+ def test_namespaced_root_map
+ Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
+
+ set.draw do |map|
+
+ map.namespace 'api' do |api|
+ api.root :controller => "products"
+ end
+
+ end
+
+ request.path = "/api"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("api/products", request.path_parameters[:controller])
+ assert_equal("index", request.path_parameters[:action])
+ ensure
+ Object.send(:remove_const, :Api)
+ end
+
+ def test_generate_finds_best_fit
+ set.draw do |map|
+ map.connect "/people", :controller => "people", :action => "index"
+ map.connect "/ws/people", :controller => "people", :action => "index", :ws => true
+ end
+
+ url = set.generate(:controller => "people", :action => "index", :ws => true)
+ assert_equal "/ws/people", url
+ end
+
+ def test_generate_changes_controller_module
+ set.draw { |map| map.connect ':controller/:action/:id' }
+ current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
+ url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current)
+ assert_equal "/foo/bar/baz/7", url
+ end
+
+ def test_id_is_not_impossibly_sticky
+ set.draw do |map|
+ map.connect 'foo/:number', :controller => "people", :action => "index"
+ map.connect ':controller/:action/:id'
+ end
+
+ url = set.generate({:controller => "people", :action => "index", :number => 3},
+ {:controller => "people", :action => "index", :id => "21"})
+ assert_equal "/foo/3", url
+ end
+
+ def test_id_is_sticky_when_it_ought_to_be
+ set.draw do |map|
+ map.connect ':controller/:id/:action'
+ end
+
+ url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"})
+ assert_equal "/people/7/destroy", url
+ end
+
+ def test_use_static_path_when_possible
+ set.draw do |map|
+ map.connect 'about', :controller => "welcome", :action => "about"
+ map.connect ':controller/:action/:id'
+ end
+
+ url = set.generate({:controller => "welcome", :action => "about"},
+ {:controller => "welcome", :action => "get", :id => "7"})
+ assert_equal "/about", url
+ end
+
+ def test_generate
+ set.draw { |map| map.connect ':controller/:action/:id' }
+
+ args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
+ assert_equal "/foo/bar/7?x=y", set.generate(args)
+ assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
+ assert_equal [:x], set.extra_keys(args)
+ end
+
+ def test_named_routes_are_never_relative_to_modules
+ set.draw do |map|
+ map.connect "/connection/manage/:action", :controller => 'connection/manage'
+ map.connect "/connection/connection", :controller => "connection/connection"
+ map.family_connection "/connection", :controller => "connection"
+ end
+
+ url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'})
+ assert_equal "/connection/connection", url
+
+ url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'})
+ assert_equal "/connection", url
+ end
+
+ def test_action_left_off_when_id_is_recalled
+ set.draw do |map|
+ map.connect ':controller/:action/:id'
+ end
+ assert_equal '/post', set.generate(
+ {:controller => 'post', :action => 'index'},
+ {:controller => 'post', :action => 'show', :id => '10'}
+ )
+ end
+
+ def test_query_params_will_be_shown_when_recalled
+ set.draw do |map|
+ map.connect 'show_post/:parameter', :controller => 'post', :action => 'show'
+ map.connect ':controller/:action/:id'
+ end
+ assert_equal '/post/edit?parameter=1', set.generate(
+ {:action => 'edit', :parameter => 1},
+ {:controller => 'post', :action => 'show', :parameter => 1}
+ )
+ end
+
+ def test_expiry_determination_should_consider_values_with_to_param
+ set.draw { |map| map.connect 'projects/:project_id/:controller/:action' }
+ assert_equal '/projects/1/post/show', set.generate(
+ {:action => 'show', :project_id => 1},
+ {:controller => 'post', :action => 'show', :project_id => '1'})
+ end
+
+ def test_generate_all
+ set.draw do |map|
+ map.connect 'show_post/:id', :controller => 'post', :action => 'show'
+ map.connect ':controller/:action/:id'
+ end
+ all = set.generate(
+ {:action => 'show', :id => 10, :generate_all => true},
+ {:controller => 'post', :action => 'show'}
+ )
+ assert_equal 2, all.length
+ assert_equal '/show_post/10', all.first
+ assert_equal '/post/show/10', all.last
+ end
+
+ def test_named_route_in_nested_resource
+ set.draw do |map|
+ map.resources :projects do |project|
+ project.milestones 'milestones', :controller => 'milestones', :action => 'index'
+ end
+ end
+
+ request.path = "/projects/1/milestones"
+ request.method = :get
+ assert_nothing_raised { set.recognize(request) }
+ assert_equal("milestones", request.path_parameters[:controller])
+ assert_equal("index", request.path_parameters[:action])
+ end
+
+ def test_setting_root_in_namespace_using_symbol
+ assert_nothing_raised do
+ set.draw do |map|
+ map.namespace :admin do |admin|
+ admin.root :controller => 'home'
+ end
+ end
+ end
+ end
+
+ def test_setting_root_in_namespace_using_string
+ assert_nothing_raised do
+ set.draw do |map|
+ map.namespace 'admin' do |admin|
+ admin.root :controller => 'home'
+ end
+ end
+ end
+ end
+
+end
+
+class RoutingTest < Test::Unit::TestCase
+
+ def test_possible_controllers
+ true_controller_paths = ActionController::Routing.controller_paths
+
+ ActionController::Routing.use_controllers! nil
+
+ silence_warnings do
+ Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
+ end
+
+ ActionController::Routing.controller_paths = [
+ RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
+ ]
+
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
+ ensure
+ if true_controller_paths
+ ActionController::Routing.controller_paths = true_controller_paths
+ end
+ ActionController::Routing.use_controllers! nil
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
+ end
+
+ def test_possible_controllers_are_reset_on_each_load
+ true_possible_controllers = ActionController::Routing.possible_controllers
+ true_controller_paths = ActionController::Routing.controller_paths
+
+ ActionController::Routing.use_controllers! nil
+ root = File.dirname(__FILE__) + '/controller_fixtures'
+
+ ActionController::Routing.controller_paths = []
+ assert_equal [], ActionController::Routing.possible_controllers
+
+ ActionController::Routing::Routes.load!
+ ActionController::Routing.controller_paths = [
+ root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib'
+ ]
+
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
+ ensure
+ ActionController::Routing.controller_paths = true_controller_paths
+ ActionController::Routing.use_controllers! true_possible_controllers
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
+
+ ActionController::Routing::Routes.clear!
+ ActionController::Routing::Routes.load_routes!
+ end
+
+ def test_with_controllers
+ c = %w(admin/accounts admin/users account pages)
+ ActionController::Routing.with_controllers c do
+ assert_equal c, ActionController::Routing.possible_controllers
+ end
+ end
+
+ def test_normalize_unix_paths
+ load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models)
+ paths = ActionController::Routing.normalize_paths(load_paths)
+ assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models lib .), paths
+ end
+
+ def test_normalize_windows_paths
+ load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models)
+ paths = ActionController::Routing.normalize_paths(load_paths)
+ assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models lib .), paths
+ end
+
+ def test_routing_helper_module
+ assert_kind_of Module, ActionController::Routing::Helpers
+
+ h = ActionController::Routing::Helpers
+ c = Class.new
+ assert ! c.ancestors.include?(h)
+ ActionController::Routing::Routes.install_helpers c
+ assert c.ancestors.include?(h)
+ end
+
+end
+
+uses_mocha 'route loading' do
+ class RouteLoadingTest < Test::Unit::TestCase
+
+ def setup
+ routes.instance_variable_set '@routes_last_modified', nil
+ silence_warnings { Object.const_set :RAILS_ROOT, '.' }
+
+ @stat = stub_everything
+ end
+
+ def teardown
+ Object.send :remove_const, :RAILS_ROOT
+ end
+
+ def test_load
+ File.expects(:stat).returns(@stat)
+ routes.expects(:load).with(regexp_matches(/routes\.rb$/))
+
+ routes.reload
+ end
+
+ def test_no_reload_when_not_modified
+ @stat.expects(:mtime).times(2).returns(1)
+ File.expects(:stat).times(2).returns(@stat)
+ routes.expects(:load).with(regexp_matches(/routes\.rb$/)).at_most_once
+
+ 2.times { routes.reload }
+ end
+
+ def test_reload_when_modified
+ @stat.expects(:mtime).at_least(2).returns(1, 2)
+ File.expects(:stat).at_least(2).returns(@stat)
+ routes.expects(:load).with(regexp_matches(/routes\.rb$/)).times(2)
+
+ 2.times { routes.reload }
+ end
+
+ def test_bang_forces_reload
+ @stat.expects(:mtime).at_least(2).returns(1)
+ File.expects(:stat).at_least(2).returns(@stat)
+ routes.expects(:load).with(regexp_matches(/routes\.rb$/)).times(2)
+
+ 2.times { routes.reload! }
+ end
+
+ def test_adding_inflections_forces_reload
+ Inflector::Inflections.instance.expects(:uncountable).with('equipment')
+ routes.expects(:reload!)
+
+ Inflector.inflections { |inflect| inflect.uncountable('equipment') }
+ end
+
+ private
+ def routes
+ ActionController::Routing::Routes
+ end
+
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/selector_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/selector_test.rb
new file mode 100644
index 000000000..ca106ba23
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/selector_test.rb
@@ -0,0 +1,628 @@
+#--
+# Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
+# Under MIT and/or CC By license.
+#++
+
+require "#{File.dirname(__FILE__)}/../abstract_unit"
+require "#{File.dirname(__FILE__)}/fake_controllers"
+
+class SelectorTest < Test::Unit::TestCase
+ #
+ # Basic selector: element, id, class, attributes.
+ #
+
+ def test_element
+ parse(%Q{<div id="1"></div><p></p><div id="2"></div>})
+ # Match element by name.
+ select("div")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ # Not case sensitive.
+ select("DIV")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ # Universal match (all elements).
+ select("*")
+ assert_equal 3, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal nil, @matches[1].attributes["id"]
+ assert_equal "2", @matches[2].attributes["id"]
+ end
+
+
+ def test_identifier
+ parse(%Q{<div id="1"></div><p></p><div id="2"></div>})
+ # Match element by ID.
+ select("div#1")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ # Match element by ID, substitute value.
+ select("div#?", 2)
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Element name does not match ID.
+ select("p#?", 2)
+ assert_equal 0, @matches.size
+ # Use regular expression.
+ select("#?", /\d/)
+ assert_equal 2, @matches.size
+ end
+
+
+ def test_class_name
+ parse(%Q{<div id="1" class=" foo "></div><p id="2" class=" foo bar "></p><div id="3" class="bar"></div>})
+ # Match element with specified class.
+ select("div.foo")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ # Match any element with specified class.
+ select("*.foo")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ # Match elements with other class.
+ select("*.bar")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # Match only element with both class names.
+ select("*.bar.foo")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ end
+
+
+ def test_attribute
+ parse(%Q{<div id="1"></div><p id="2" title="" bar="foo"></p><div id="3" title="foo"></div>})
+ # Match element with attribute.
+ select("div[title]")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ # Match any element with attribute.
+ select("*[title]")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # Match element with attribute value.
+ select("*[title=foo]")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ # Match element with attribute and attribute value.
+ select("[bar=foo][title]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Not case sensitive.
+ select("[BAR=foo][TiTle]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ end
+
+
+ def test_attribute_quoted
+ parse(%Q{<div id="1" title="foo"></div><div id="2" title="bar"></div><div id="3" title=" bar "></div>})
+ # Match without quotes.
+ select("[title = bar]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Match with single quotes.
+ select("[title = 'bar' ]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Match with double quotes.
+ select("[title = \"bar\" ]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Match with spaces.
+ select("[title = \" bar \" ]")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ end
+
+
+ def test_attribute_equality
+ parse(%Q{<div id="1" title="foo bar"></div><div id="2" title="barbaz"></div>})
+ # Match (fail) complete value.
+ select("[title=bar]")
+ assert_equal 0, @matches.size
+ # Match space-separate word.
+ select("[title~=foo]")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ select("[title~=bar]")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ # Match beginning of value.
+ select("[title^=ba]")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Match end of value.
+ select("[title$=ar]")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ # Match text in value.
+ select("[title*=bar]")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ # Match first space separated word.
+ select("[title|=foo]")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ select("[title|=bar]")
+ assert_equal 0, @matches.size
+ end
+
+
+ #
+ # Selector composition: groups, sibling, children
+ #
+
+
+ def test_selector_group
+ parse(%Q{<h1 id="1"></h1><h2 id="2"></h2><h3 id="3"></h3>})
+ # Simple group selector.
+ select("h1,h3")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ select("h1 , h3")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # Complex group selector.
+ parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
+ select("h1 a, h3 a")
+ assert_equal 2, @matches.size
+ assert_equal "foo", @matches[0].attributes["href"]
+ assert_equal "baz", @matches[1].attributes["href"]
+ # And now for the three selector challenge.
+ parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
+ select("h1 a, h2 a, h3 a")
+ assert_equal 3, @matches.size
+ assert_equal "foo", @matches[0].attributes["href"]
+ assert_equal "bar", @matches[1].attributes["href"]
+ assert_equal "baz", @matches[2].attributes["href"]
+ end
+
+
+ def test_sibling_selector
+ parse(%Q{<h1 id="1"></h1><h2 id="2"></h2><h3 id="3"></h3>})
+ # Test next sibling.
+ select("h1+*")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ select("h1+h2")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ select("h1+h3")
+ assert_equal 0, @matches.size
+ select("*+h3")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ # Test any sibling.
+ select("h1~*")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ select("h2~*")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ end
+
+
+ def test_children_selector
+ parse(%Q{<div><p id="1"><span id="2"></span></p></div><div><p id="3"><span id="4" class="foo"></span></p></div>})
+ # Test child selector.
+ select("div>p")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ select("div>span")
+ assert_equal 0, @matches.size
+ select("div>p#3")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ select("div>p>span")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ # Test descendant selector.
+ select("div p")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ select("div span")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ select("div *#3")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ select("div *#4")
+ assert_equal 1, @matches.size
+ assert_equal "4", @matches[0].attributes["id"]
+ # This is here because it failed before when whitespaces
+ # were not properly stripped.
+ select("div .foo")
+ assert_equal 1, @matches.size
+ assert_equal "4", @matches[0].attributes["id"]
+ end
+
+
+ #
+ # Pseudo selectors: root, nth-child, empty, content, etc
+ #
+
+
+ def test_root_selector
+ parse(%Q{<div id="1"><div id="2"></div></div>})
+ # Can only find element if it's root.
+ select(":root")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ select("#1:root")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ select("#2:root")
+ assert_equal 0, @matches.size
+ # Opposite for nth-child.
+ select("#1:nth-child(1)")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_nth_child_odd_even
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Test odd nth children.
+ select("tr:nth-child(odd)")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # Test even nth children.
+ select("tr:nth-child(even)")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ end
+
+
+ def test_nth_child_a_is_zero
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Test the third child.
+ select("tr:nth-child(0n+3)")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ # Same but an can be omitted when zero.
+ select("tr:nth-child(3)")
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ # Second element (but not every second element).
+ select("tr:nth-child(0n+2)")
+ 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)") }
+ select("tr:nth-child(0)")
+ assert_equal 0, @matches.size
+ select("tr:nth-child(5)")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_nth_child_a_is_one
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # a is group of one, pick every element in group.
+ select("tr:nth-child(1n+0)")
+ assert_equal 4, @matches.size
+ # Same but a can be omitted when one.
+ select("tr:nth-child(n+0)")
+ assert_equal 4, @matches.size
+ # Same but b can be omitted when zero.
+ select("tr:nth-child(n)")
+ assert_equal 4, @matches.size
+ end
+
+
+ def test_nth_child_b_is_zero
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # If b is zero, pick the n-th element (here each one).
+ select("tr:nth-child(n+0)")
+ assert_equal 4, @matches.size
+ # If b is zero, pick the n-th element (here every second).
+ select("tr:nth-child(2n+0)")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # If a and b are both zero, no element selected.
+ select("tr:nth-child(0n+0)")
+ assert_equal 0, @matches.size
+ select("tr:nth-child(0)")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_nth_child_a_is_negative
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Since a is -1, picks the first three elements.
+ select("tr:nth-child(-n+3)")
+ assert_equal 3, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ assert_equal "3", @matches[2].attributes["id"]
+ # Since a is -2, picks the first in every second of first four elements.
+ select("tr:nth-child(-2n+3)")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ # Since a is -2, picks the first in every second of first three elements.
+ select("tr:nth-child(-2n+2)")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ end
+
+
+ def test_nth_child_b_is_negative
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Select last of four.
+ select("tr:nth-child(4n-1)")
+ assert_equal 1, @matches.size
+ assert_equal "4", @matches[0].attributes["id"]
+ # Select first of four.
+ select("tr:nth-child(4n-4)")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ # Select last of every second.
+ select("tr:nth-child(2n-1)")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ # Select nothing since an+b always < 0
+ select("tr:nth-child(-1n-1)")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_nth_child_substitution_values
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Test with ?n?.
+ select("tr:nth-child(?n?)", 2, 1)
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "3", @matches[1].attributes["id"]
+ select("tr:nth-child(?n?)", 2, 2)
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ select("tr:nth-child(?n?)", 4, 2)
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ # Test with ? (b only).
+ select("tr:nth-child(?)", 3)
+ assert_equal 1, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ select("tr:nth-child(?)", 5)
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_nth_last_child
+ parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # Last two elements.
+ select("tr:nth-last-child(-n+2)")
+ assert_equal 2, @matches.size
+ assert_equal "3", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ # All old elements counting from last one.
+ select("tr:nth-last-child(odd)")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ end
+
+
+ def test_nth_of_type
+ parse(%Q{<table><thead></thead><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # First two elements.
+ select("tr:nth-of-type(-n+2)")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ # All old elements counting from last one.
+ select("tr:nth-last-of-type(odd)")
+ assert_equal 2, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ assert_equal "4", @matches[1].attributes["id"]
+ end
+
+
+ def test_first_and_last
+ parse(%Q{<table><thead></thead><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
+ # First child.
+ select("tr:first-child")
+ assert_equal 0, @matches.size
+ select(":first-child")
+ assert_equal 1, @matches.size
+ assert_equal "thead", @matches[0].name
+ # First of type.
+ select("tr:first-of-type")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ select("thead:first-of-type")
+ assert_equal 1, @matches.size
+ assert_equal "thead", @matches[0].name
+ select("div:first-of-type")
+ assert_equal 0, @matches.size
+ # Last child.
+ select("tr:last-child")
+ assert_equal 1, @matches.size
+ assert_equal "4", @matches[0].attributes["id"]
+ # Last of type.
+ select("tr:last-of-type")
+ assert_equal 1, @matches.size
+ assert_equal "4", @matches[0].attributes["id"]
+ select("thead:last-of-type")
+ assert_equal 1, @matches.size
+ assert_equal "thead", @matches[0].name
+ select("div:last-of-type")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_first_and_last
+ # Only child.
+ parse(%Q{<table><tr></tr></table>})
+ select("table:only-child")
+ assert_equal 0, @matches.size
+ select("tr:only-child")
+ assert_equal 1, @matches.size
+ assert_equal "tr", @matches[0].name
+ parse(%Q{<table><tr></tr><tr></tr></table>})
+ select("tr:only-child")
+ assert_equal 0, @matches.size
+ # Only of type.
+ parse(%Q{<table><thead></thead><tr></tr><tr></tr></table>})
+ select("thead:only-of-type")
+ assert_equal 1, @matches.size
+ assert_equal "thead", @matches[0].name
+ select("td:only-of-type")
+ assert_equal 0, @matches.size
+ end
+
+
+ def test_empty
+ parse(%Q{<table><tr></tr></table>})
+ select("table:empty")
+ assert_equal 0, @matches.size
+ select("tr:empty")
+ assert_equal 1, @matches.size
+ parse(%Q{<div> </div>})
+ select("div:empty")
+ assert_equal 1, @matches.size
+ end
+
+
+ def test_content
+ parse(%Q{<div> </div>})
+ select("div:content()")
+ assert_equal 1, @matches.size
+ parse(%Q{<div>something </div>})
+ select("div:content()")
+ assert_equal 0, @matches.size
+ select("div:content(something)")
+ assert_equal 1, @matches.size
+ select("div:content( 'something' )")
+ assert_equal 1, @matches.size
+ select("div:content( \"something\" )")
+ assert_equal 1, @matches.size
+ select("div:content(?)", "something")
+ assert_equal 1, @matches.size
+ select("div:content(?)", /something/)
+ assert_equal 1, @matches.size
+ end
+
+
+ #
+ # Test negation.
+ #
+
+
+ def test_element_negation
+ parse(%Q{<p></p><div></div>})
+ select("*")
+ assert_equal 2, @matches.size
+ select("*:not(p)")
+ assert_equal 1, @matches.size
+ assert_equal "div", @matches[0].name
+ select("*:not(div)")
+ assert_equal 1, @matches.size
+ assert_equal "p", @matches[0].name
+ select("*:not(span)")
+ assert_equal 2, @matches.size
+ end
+
+
+ def test_id_negation
+ parse(%Q{<p id="1"></p><p id="2"></p>})
+ select("p")
+ assert_equal 2, @matches.size
+ select(":not(#1)")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ select(":not(#2)")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ end
+
+
+ def test_class_name_negation
+ parse(%Q{<p class="foo"></p><p class="bar"></p>})
+ select("p")
+ assert_equal 2, @matches.size
+ select(":not(.foo)")
+ assert_equal 1, @matches.size
+ assert_equal "bar", @matches[0].attributes["class"]
+ select(":not(.bar)")
+ assert_equal 1, @matches.size
+ assert_equal "foo", @matches[0].attributes["class"]
+ end
+
+
+ def test_attribute_negation
+ parse(%Q{<p title="foo"></p><p title="bar"></p>})
+ select("p")
+ assert_equal 2, @matches.size
+ select(":not([title=foo])")
+ assert_equal 1, @matches.size
+ assert_equal "bar", @matches[0].attributes["title"]
+ select(":not([title=bar])")
+ assert_equal 1, @matches.size
+ assert_equal "foo", @matches[0].attributes["title"]
+ end
+
+
+ def test_pseudo_class_negation
+ parse(%Q{<div><p id="1"></p><p id="2"></p></div>})
+ select("p")
+ assert_equal 2, @matches.size
+ select("p:not(:first-child)")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ select("p:not(:nth-child(2))")
+ assert_equal 1, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ end
+
+
+ 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())") }
+ select("p:not(#1):not(#3)")
+ assert_equal 1, @matches.size
+ assert_equal "2", @matches[0].attributes["id"]
+ end
+
+
+ def test_select_from_element
+ parse(%Q{<div><p id="1"></p><p id="2"></p></div>})
+ select("div")
+ @matches = @matches[0].select("p")
+ assert_equal 2, @matches.size
+ assert_equal "1", @matches[0].attributes["id"]
+ assert_equal "2", @matches[1].attributes["id"]
+ end
+
+
+protected
+
+ def parse(html)
+ @html = HTML::Document.new(html).root
+ end
+
+ def select(*selector)
+ @matches = HTML.selector(*selector).select(@html)
+ end
+
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/send_file_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/send_file_test.rb
new file mode 100644
index 000000000..2d876c1bb
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/send_file_test.rb
@@ -0,0 +1,127 @@
+require File.join(File.dirname(__FILE__), '..', '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
+end
+
+
+class SendFileController < ActionController::Base
+ include TestFileUtils
+ layout "layouts/standard" # to make sure layouts don't interfere
+
+ attr_writer :options
+ def options() @options ||= {} end
+
+ def file() send_file(file_path, options) end
+ def data() send_data(file_data, options) end
+
+ def rescue_action(e) raise end
+end
+
+SendFileController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class SendFileTest < Test::Unit::TestCase
+ include TestFileUtils
+
+ Mime::Type.register "image/png", :png unless defined? Mime::PNG
+
+ def setup
+ @controller = SendFileController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_file_nostream
+ @controller.options = { :stream => false }
+ response = nil
+ assert_nothing_raised { response = process('file') }
+ assert_not_nil response
+ assert_kind_of String, response.body
+ assert_equal file_data, response.body
+ end
+
+ def test_file_stream
+ response = nil
+ assert_nothing_raised { response = process('file') }
+ assert_not_nil response
+ assert_kind_of Proc, response.body
+
+ require 'stringio'
+ output = StringIO.new
+ output.binmode
+ assert_nothing_raised { response.body.call(response, output) }
+ assert_equal file_data, output.string
+ end
+
+ def test_file_url_based_filename
+ @controller.options = { :url_based_filename => true }
+ response = nil
+ assert_nothing_raised { response = process('file') }
+ assert_not_nil response
+ assert_equal "attachment", response.headers["Content-Disposition"]
+ end
+
+ def test_data
+ response = nil
+ assert_nothing_raised { response = process('data') }
+ assert_not_nil response
+
+ assert_kind_of String, response.body
+ assert_equal file_data, response.body
+ end
+
+ def test_headers_after_send_shouldnt_include_charset
+ response = process('data')
+ assert_equal "application/octet-stream", response.content_type
+
+ response = process('file')
+ assert_equal "application/octet-stream", response.content_type
+ end
+
+ # Test that send_file_headers! is setting the correct HTTP headers.
+ def test_send_file_headers!
+ options = {
+ :length => 1,
+ :type => Mime::PNG,
+ :disposition => 'disposition',
+ :filename => 'filename'
+ }
+
+ # Do it a few times: the resulting headers should be identical
+ # no matter how many times you send with the same options.
+ # Test resolving Ticket #458.
+ @controller.headers = {}
+ @controller.send(:send_file_headers!, options)
+ @controller.send(:send_file_headers!, options)
+ @controller.send(:send_file_headers!, options)
+
+ h = @controller.headers
+ 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']
+
+ # test overriding Cache-Control: no-cache header to fix IE open/save dialog
+ @controller.headers = { 'Cache-Control' => 'no-cache' }
+ @controller.send(:send_file_headers!, options)
+ h = @controller.headers
+ assert_equal 'private', h['Cache-Control']
+ 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']
+ 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']
+ end
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/session/cookie_store_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/session/cookie_store_test.rb
new file mode 100755
index 000000000..b2655c72d
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/session/cookie_store_test.rb
@@ -0,0 +1,246 @@
+require "#{File.dirname(__FILE__)}/../../abstract_unit"
+require 'action_controller/cgi_process'
+require 'action_controller/cgi_ext'
+
+require 'stringio'
+
+
+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)
+ 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
+ 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 }
+ 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%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
+ end
+
+ def setup
+ ENV.delete('HTTP_COOKIE')
+ 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
+ end
+
+ def test_raises_argument_error_if_missing_secret
+ [nil, ''].each do |blank|
+ assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
+ end
+ 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 }
+ 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_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
+ 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
+ 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)
+ 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']
+ 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
+ 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 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)
+
+ 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
+ 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
+
+
+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%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/session/mem_cache_store_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/session/mem_cache_store_test.rb
new file mode 100644
index 000000000..3afb7a8ea
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/session/mem_cache_store_test.rb
@@ -0,0 +1,182 @@
+require "#{File.dirname(__FILE__)}/../../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
+ end
+ return cache
+ end
+
+ CACHE = get_mem_cache_if_available
+
+
+ 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)
+ end
+ 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)
+ 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
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/session_fixation_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/session_fixation_test.rb
new file mode 100644
index 000000000..34a7aa2d0
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/session_fixation_test.rb
@@ -0,0 +1,89 @@
+require File.dirname(__FILE__) + '/../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
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/session_management_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/session_management_test.rb
new file mode 100644
index 000000000..44fb93104
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/session_management_test.rb
@@ -0,0 +1,156 @@
+require File.dirname(__FILE__) + '/../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 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_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
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/test_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/test_test.rb
new file mode 100644
index 000000000..11e48da91
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/test_test.rb
@@ -0,0 +1,623 @@
+require "#{File.dirname(__FILE__)}/../abstract_unit"
+require "#{File.dirname(__FILE__)}/fake_controllers"
+require "action_controller/test_case"
+
+class TestTest < Test::Unit::TestCase
+ class TestController < ActionController::Base
+ def set_flash
+ flash["test"] = ">#{flash["test"]}<"
+ render :text => 'ignore me'
+ end
+
+ def render_raw_post
+ raise Test::Unit::AssertionFailedError, "#raw_post is blank" if request.raw_post.blank?
+ render :text => request.raw_post
+ end
+
+ def render_body
+ render :text => request.body.read
+ end
+
+ def test_params
+ render :text => params.inspect
+ end
+
+ def test_uri
+ render :text => request.request_uri
+ end
+
+ def test_query_string
+ render :text => request.query_string
+ end
+
+ def test_html_output
+ render :text => <<HTML
+<html>
+ <body>
+ <a href="/"><img src="/images/button.png" /></a>
+ <div id="foo">
+ <ul>
+ <li class="item">hello</li>
+ <li class="item">goodbye</li>
+ </ul>
+ </div>
+ <div id="bar">
+ <form action="/somewhere">
+ Name: <input type="text" name="person[name]" id="person_name" />
+ </form>
+ </div>
+ </body>
+</html>
+HTML
+ end
+
+ def test_xml_output
+ response.content_type = "application/xml"
+ render :text => <<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <area>area is an empty tag in HTML, raising an error if not in xml mode</area>
+</root>
+XML
+ end
+
+ def test_only_one_param
+ render :text => (params[:left] && params[:right]) ? "EEP, Both here!" : "OK"
+ end
+
+ def test_remote_addr
+ render :text => (request.remote_addr || "not specified")
+ end
+
+ def test_file_upload
+ render :text => params[:file].size
+ end
+
+ def test_send_file
+ send_file(File.expand_path(__FILE__))
+ end
+
+ def redirect_to_same_controller
+ redirect_to :controller => 'test', :action => 'test_uri', :id => 5
+ end
+
+ def redirect_to_different_controller
+ redirect_to :controller => 'fail', :id => 5
+ end
+
+ def create
+ head :created, :location => 'created resource'
+ end
+
+ private
+ def rescue_action(e)
+ raise e
+ end
+
+ def generate_url(opts)
+ url_for(opts.merge(:action => "test_uri"))
+ end
+ end
+
+ def setup
+ @controller = TestController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ ActionController::Routing::Routes.reload
+ ActionController::Routing.use_controllers! %w(content admin/user test_test/test)
+ end
+
+ def teardown
+ ActionController::Routing::Routes.reload
+ end
+
+ def test_raw_post_handling
+ params = {:page => {:name => 'page name'}, 'some key' => 123}
+ post :render_raw_post, params.dup
+
+ assert_equal params.to_query, @response.body
+ end
+
+ def test_body_stream
+ params = { :page => { :name => 'page name' }, 'some key' => 123 }
+
+ post :render_body, params.dup
+
+ assert_equal params.to_query, @response.body
+ end
+
+ def test_process_without_flash
+ process :set_flash
+ assert_equal '><', flash['test']
+ end
+
+ def test_process_with_flash
+ process :set_flash, nil, nil, { "test" => "value" }
+ assert_equal '>value<', flash['test']
+ end
+
+ def test_process_with_request_uri_with_no_params
+ process :test_uri
+ assert_equal "/test_test/test/test_uri", @response.body
+ end
+
+ def test_process_with_request_uri_with_params
+ process :test_uri, :id => 7
+ assert_equal "/test_test/test/test_uri/7", @response.body
+ end
+
+ def test_process_with_request_uri_with_params_with_explicit_uri
+ @request.set_REQUEST_URI "/explicit/uri"
+ process :test_uri, :id => 7
+ assert_equal "/explicit/uri", @response.body
+ end
+
+ def test_process_with_query_string
+ process :test_query_string, :q => 'test'
+ assert_equal "q=test", @response.body
+ end
+
+ def test_process_with_query_string_with_explicit_uri
+ @request.set_REQUEST_URI "/explicit/uri?q=test?extra=question"
+ process :test_query_string
+ assert_equal "q=test?extra=question", @response.body
+ end
+
+ def test_multiple_calls
+ process :test_only_one_param, :left => true
+ assert_equal "OK", @response.body
+ process :test_only_one_param, :right => true
+ assert_equal "OK", @response.body
+ end
+
+ def test_assert_tag_tag
+ process :test_html_output
+
+ # there is a 'form' tag
+ assert_tag :tag => 'form'
+ # there is not an 'hr' tag
+ assert_no_tag :tag => 'hr'
+ end
+
+ def test_assert_tag_attributes
+ process :test_html_output
+
+ # there is a tag with an 'id' of 'bar'
+ assert_tag :attributes => { :id => "bar" }
+ # there is no tag with a 'name' of 'baz'
+ assert_no_tag :attributes => { :name => "baz" }
+ end
+
+ def test_assert_tag_parent
+ process :test_html_output
+
+ # there is a tag with a parent 'form' tag
+ assert_tag :parent => { :tag => "form" }
+ # there is no tag with a parent of 'input'
+ assert_no_tag :parent => { :tag => "input" }
+ end
+
+ def test_assert_tag_child
+ process :test_html_output
+
+ # there is a tag with a child 'input' tag
+ assert_tag :child => { :tag => "input" }
+ # there is no tag with a child 'strong' tag
+ assert_no_tag :child => { :tag => "strong" }
+ end
+
+ def test_assert_tag_ancestor
+ process :test_html_output
+
+ # there is a 'li' tag with an ancestor having an id of 'foo'
+ assert_tag :ancestor => { :attributes => { :id => "foo" } }, :tag => "li"
+ # there is no tag of any kind with an ancestor having an href matching 'foo'
+ assert_no_tag :ancestor => { :attributes => { :href => /foo/ } }
+ end
+
+ def test_assert_tag_descendant
+ process :test_html_output
+
+ # there is a tag with a descendant 'li' tag
+ assert_tag :descendant => { :tag => "li" }
+ # there is no tag with a descendant 'html' tag
+ assert_no_tag :descendant => { :tag => "html" }
+ end
+
+ def test_assert_tag_sibling
+ process :test_html_output
+
+ # there is a tag with a sibling of class 'item'
+ assert_tag :sibling => { :attributes => { :class => "item" } }
+ # there is no tag with a sibling 'ul' tag
+ assert_no_tag :sibling => { :tag => "ul" }
+ end
+
+ def test_assert_tag_after
+ process :test_html_output
+
+ # there is a tag following a sibling 'div' tag
+ assert_tag :after => { :tag => "div" }
+ # there is no tag following a sibling tag with id 'bar'
+ assert_no_tag :after => { :attributes => { :id => "bar" } }
+ end
+
+ def test_assert_tag_before
+ process :test_html_output
+
+ # there is a tag preceding a tag with id 'bar'
+ assert_tag :before => { :attributes => { :id => "bar" } }
+ # there is no tag preceding a 'form' tag
+ assert_no_tag :before => { :tag => "form" }
+ end
+
+ def test_assert_tag_children_count
+ process :test_html_output
+
+ # there is a tag with 2 children
+ assert_tag :children => { :count => 2 }
+ # in particular, there is a <ul> tag with two children (a nameless pair of <li>s)
+ assert_tag :tag => 'ul', :children => { :count => 2 }
+ # there is no tag with 4 children
+ assert_no_tag :children => { :count => 4 }
+ end
+
+ def test_assert_tag_children_less_than
+ process :test_html_output
+
+ # there is a tag with less than 5 children
+ assert_tag :children => { :less_than => 5 }
+ # there is no 'ul' tag with less than 2 children
+ assert_no_tag :children => { :less_than => 2 }, :tag => "ul"
+ end
+
+ def test_assert_tag_children_greater_than
+ process :test_html_output
+
+ # there is a 'body' tag with more than 1 children
+ assert_tag :children => { :greater_than => 1 }, :tag => "body"
+ # there is no tag with more than 10 children
+ assert_no_tag :children => { :greater_than => 10 }
+ end
+
+ def test_assert_tag_children_only
+ process :test_html_output
+
+ # there is a tag containing only one child with an id of 'foo'
+ assert_tag :children => { :count => 1,
+ :only => { :attributes => { :id => "foo" } } }
+ # there is no tag containing only one 'li' child
+ assert_no_tag :children => { :count => 1, :only => { :tag => "li" } }
+ end
+
+ def test_assert_tag_content
+ process :test_html_output
+
+ # the output contains the string "Name"
+ assert_tag :content => /Name/
+ # the output does not contain the string "test"
+ assert_no_tag :content => /test/
+ end
+
+ def test_assert_tag_multiple
+ process :test_html_output
+
+ # there is a 'div', id='bar', with an immediate child whose 'action'
+ # attribute matches the regexp /somewhere/.
+ assert_tag :tag => "div", :attributes => { :id => "bar" },
+ :child => { :attributes => { :action => /somewhere/ } }
+
+ # there is no 'div', id='foo', with a 'ul' child with more than
+ # 2 "li" children.
+ assert_no_tag :tag => "div", :attributes => { :id => "foo" },
+ :child => {
+ :tag => "ul",
+ :children => { :greater_than => 2,
+ :only => { :tag => "li" } } }
+ end
+
+ def test_assert_tag_children_without_content
+ process :test_html_output
+
+ # there is a form tag with an 'input' child which is a self closing tag
+ assert_tag :tag => "form",
+ :children => { :count => 1,
+ :only => { :tag => "input" } }
+
+ # the body tag has an 'a' child which in turn has an 'img' child
+ assert_tag :tag => "body",
+ :children => { :count => 1,
+ :only => { :tag => "a",
+ :children => { :count => 1,
+ :only => { :tag => "img" } } } }
+ end
+
+ def test_should_not_impose_childless_html_tags_in_xml
+ process :test_xml_output
+
+ begin
+ $stderr = StringIO.new
+ assert_select 'area' #This will cause a warning if content is processed as HTML
+ $stderr.rewind && err = $stderr.read
+ ensure
+ $stderr = STDERR
+ end
+
+ assert err.empty?
+ end
+
+ def test_assert_tag_attribute_matching
+ @response.body = '<input type="text" name="my_name">'
+ assert_tag :tag => 'input',
+ :attributes => { :name => /my/, :type => 'text' }
+ assert_no_tag :tag => 'input',
+ :attributes => { :name => 'my', :type => 'text' }
+ assert_no_tag :tag => 'input',
+ :attributes => { :name => /^my$/, :type => 'text' }
+ end
+
+ def test_assert_tag_content_matching
+ @response.body = "<p>hello world</p>"
+ assert_tag :tag => "p", :content => "hello world"
+ assert_tag :tag => "p", :content => /hello/
+ assert_no_tag :tag => "p", :content => "hello"
+ end
+
+ def test_assert_generates
+ assert_generates 'controller/action/5', :controller => 'controller', :action => 'action', :id => '5'
+ assert_generates 'controller/action/7', {:id => "7"}, {:controller => "controller", :action => "action"}
+ assert_generates 'controller/action/5', {:controller => "controller", :action => "action", :id => "5", :name => "bob"}, {}, {:name => "bob"}
+ assert_generates 'controller/action/7', {:id => "7", :name => "bob"}, {:controller => "controller", :action => "action"}, {:name => "bob"}
+ assert_generates 'controller/action/7', {:id => "7"}, {:controller => "controller", :action => "action", :name => "bob"}, {}
+ end
+
+ def test_assert_routing
+ assert_routing 'content', :controller => 'content', :action => 'index'
+ end
+
+ def test_assert_routing_in_module
+ assert_routing 'admin/user', :controller => 'admin/user', :action => 'index'
+ end
+
+ def test_params_passing
+ get :test_params, :page => {:name => "Page name", :month => '4', :year => '2004', :day => '6'}
+ parsed_params = eval(@response.body)
+ assert_equal(
+ {'controller' => 'test_test/test', 'action' => 'test_params',
+ 'page' => {'name' => "Page name", 'month' => '4', 'year' => '2004', 'day' => '6'}},
+ parsed_params
+ )
+ end
+
+ def test_id_converted_to_string
+ get :test_params, :id => 20, :foo => Object.new
+ assert_kind_of String, @request.path_parameters['id']
+ end
+
+ def test_array_path_parameter_handled_properly
+ with_routing do |set|
+ set.draw do |map|
+ map.connect 'file/*path', :controller => 'test_test/test', :action => 'test_params'
+ map.connect ':controller/:action/:id'
+ end
+
+ get :test_params, :path => ['hello', 'world']
+ assert_equal ['hello', 'world'], @request.path_parameters['path']
+ assert_equal 'hello/world', @request.path_parameters['path'].to_s
+ end
+ end
+
+ def test_assert_realistic_path_parameters
+ get :test_params, :id => 20, :foo => Object.new
+
+ # All elements of path_parameters should use string keys
+ @request.path_parameters.keys.each do |key|
+ assert_kind_of String, key
+ end
+ end
+
+ def test_with_routing_places_routes_back
+ assert ActionController::Routing::Routes
+ routes_id = ActionController::Routing::Routes.object_id
+
+ begin
+ with_routing { raise 'fail' }
+ fail 'Should not be here.'
+ rescue RuntimeError
+ end
+
+ assert ActionController::Routing::Routes
+ assert_equal routes_id, ActionController::Routing::Routes.object_id
+ end
+
+ def test_remote_addr
+ get :test_remote_addr
+ assert_equal "0.0.0.0", @response.body
+
+ @request.remote_addr = "192.0.0.1"
+ get :test_remote_addr
+ assert_equal "192.0.0.1", @response.body
+ end
+
+ def test_header_properly_reset_after_remote_http_request
+ xhr :get, :test_params
+ assert_nil @request.env['HTTP_X_REQUESTED_WITH']
+ end
+
+ def test_header_properly_reset_after_get_request
+ get :test_params
+ @request.recycle!
+ assert_nil @request.instance_variable_get("@request_method")
+ 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
+ remove_instance_variable "@#{variable}"
+ begin
+ send(method, :test_remote_addr)
+ assert false, "expected RuntimeError, got nothing"
+ rescue RuntimeError => error
+ assert true
+ assert_match %r{@#{variable} is nil}, error.message
+ rescue => error
+ assert false, "expected RuntimeError, got #{error.class}"
+ end
+ end
+ end
+ end
+
+ FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
+
+ def test_test_uploaded_file
+ filename = 'mona_lisa.jpg'
+ path = "#{FILES_DIR}/#{filename}"
+ content_type = 'image/png'
+
+ file = ActionController::TestUploadedFile.new(path, content_type)
+ assert_equal filename, file.original_filename
+ assert_equal content_type, file.content_type
+ assert_equal file.path, file.local_path
+ assert_equal File.read(path), file.read
+ end
+
+ def test_test_uploaded_file_with_binary
+ filename = 'mona_lisa.jpg'
+ path = "#{FILES_DIR}/#{filename}"
+ content_type = 'image/png'
+
+ binary_uploaded_file = ActionController::TestUploadedFile.new(path, content_type, :binary)
+ assert_equal File.open(path, 'rb').read, binary_uploaded_file.read
+
+ plain_uploaded_file = ActionController::TestUploadedFile.new(path, content_type)
+ assert_equal File.open(path, 'r').read, plain_uploaded_file.read
+ end
+
+ def test_fixture_file_upload_with_binary
+ filename = 'mona_lisa.jpg'
+ path = "#{FILES_DIR}/#{filename}"
+ content_type = 'image/jpg'
+
+ binary_file_upload = fixture_file_upload(path, content_type, :binary)
+ assert_equal File.open(path, 'rb').read, binary_file_upload.read
+
+ plain_file_upload = fixture_file_upload(path, content_type)
+ assert_equal File.open(path, 'r').read, plain_file_upload.read
+ end
+
+ def test_fixture_file_upload
+ post :test_file_upload, :file => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
+ assert_equal '159528', @response.body
+ end
+
+ def test_test_uploaded_file_exception_when_file_doesnt_exist
+ assert_raise(RuntimeError) { ActionController::TestUploadedFile.new('non_existent_file') }
+ end
+
+ def test_assert_follow_redirect_to_same_controller
+ with_foo_routing do |set|
+ get :redirect_to_same_controller
+ assert_response :redirect
+ assert_redirected_to :controller => 'test_test/test', :action => 'test_uri', :id => 5
+ assert_nothing_raised { follow_redirect }
+ end
+ end
+
+ def test_assert_follow_redirect_to_different_controller
+ with_foo_routing do |set|
+ get :redirect_to_different_controller
+ assert_response :redirect
+ assert_redirected_to :controller => 'fail', :id => 5
+ assert_raise(RuntimeError) { follow_redirect }
+ end
+ end
+
+ def test_redirect_url_only_cares_about_location_header
+ get :create
+ assert_response :created
+
+ # Redirect url doesn't care that it wasn't a :redirect response.
+ assert_equal 'created resource', @response.redirect_url
+ assert_equal @response.redirect_url, redirect_to_url
+
+ # Must be a :redirect response.
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_redirected_to 'created resource'
+ end
+ end
+
+ def test_binary_content_works_with_send_file
+ get :test_send_file
+ assert_nothing_raised(NoMethodError) { @response.binary_content }
+ end
+
+ protected
+ def with_foo_routing
+ with_routing do |set|
+ set.draw do |map|
+ map.generate_url 'foo', :controller => 'test'
+ map.connect ':controller/:action/:id'
+ end
+ yield set
+ end
+ end
+end
+
+
+class CleanBacktraceTest < Test::Unit::TestCase
+ def test_should_reraise_the_same_object
+ exception = Test::Unit::AssertionFailedError.new('message')
+ clean_backtrace { raise exception }
+ rescue => caught
+ assert_equal exception.object_id, caught.object_id
+ assert_equal exception.message, caught.message
+ end
+
+ 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.set_backtrace ["#{path}/abc", "#{path}/assertions/def"]
+ clean_backtrace { raise exception }
+ rescue => caught
+ assert_equal ["#{path}/abc"], caught.backtrace
+ end
+
+ def test_should_only_clean_assertion_failure_errors
+ clean_backtrace do
+ raise "can't touch this", [File.expand_path("#{File.dirname(__FILE__)}/../../lib/action_controller/assertions/abc")]
+ end
+ rescue => caught
+ assert !caught.backtrace.empty?
+ end
+end
+
+class InferringClassNameTest < Test::Unit::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
+ end
+
+ def test_determine_controller_class_with_sensible_name_where_no_controller_exists
+ assert_raises ActionController::NonInferrableControllerError do
+ determine_class("NoControllerWithThisNameTest")
+ end
+ end
+
+ private
+ def determine_class(name)
+ ActionController::TestCase.determine_default_controller_class(name)
+ end
+end
+
+class CrazyNameTest < ActionController::TestCase
+ tests ContentController
+ def test_controller_class_can_be_set_manually_not_just_inferred
+ assert_equal ContentController, self.class.controller_class
+ end
+end
+
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/url_rewriter_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/url_rewriter_test.rb
new file mode 100644
index 000000000..75497c832
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/url_rewriter_test.rb
@@ -0,0 +1,246 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+ActionController::UrlRewriter
+
+class UrlRewriterTests < Test::Unit::TestCase
+ def setup
+ @request = ActionController::TestRequest.new
+ @params = {}
+ @rewriter = ActionController::UrlRewriter.new(@request, @params)
+ end
+
+ def test_port
+ assert_equal('http://test.host:1271/c/a/i',
+ @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :port => 1271)
+ )
+ end
+
+ def test_protocol_with_and_without_separator
+ assert_equal('https://test.host/c/a/i',
+ @rewriter.rewrite(:protocol => 'https', :controller => 'c', :action => 'a', :id => 'i')
+ )
+
+ assert_equal('https://test.host/c/a/i',
+ @rewriter.rewrite(:protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i')
+ )
+ end
+
+ def test_user_name_and_password
+ assert_equal(
+ 'http://david:secret@test.host/c/a/i',
+ @rewriter.rewrite(:user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i')
+ )
+ end
+
+ def test_user_name_and_password_with_escape_codes
+ assert_equal(
+ 'http://openid.aol.com%2Fnextangler:one+two%3F@test.host/c/a/i',
+ @rewriter.rewrite(:user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i')
+ )
+ end
+
+ def test_anchor
+ assert_equal(
+ 'http://test.host/c/a/i#anchor',
+ @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor')
+ )
+ end
+
+ def test_overwrite_params
+ @params[:controller] = 'hi'
+ @params[:action] = 'bye'
+ @params[:id] = '2'
+
+ assert_equal '/hi/hi/2', @rewriter.rewrite(:only_path => true, :overwrite_params => {:action => 'hi'})
+ u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:action => 'hi'})
+ assert_match %r(/hi/hi/2$), u
+ end
+
+ def test_overwrite_removes_original
+ @params[:controller] = 'search'
+ @params[:action] = 'list'
+ @params[:list_page] = 1
+
+ assert_equal '/search/list?list_page=2', @rewriter.rewrite(:only_path => true, :overwrite_params => {"list_page" => 2})
+ u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:list_page => 2})
+ assert_equal 'http://test.host/search/list?list_page=2', u
+ end
+
+ def test_to_str
+ @params[:controller] = 'hi'
+ @params[:action] = 'bye'
+ @request.parameters[:id] = '2'
+
+ assert_equal 'http://, test.host, /, hi, bye, {"id"=>"2"}', @rewriter.to_str
+ end
+
+ def test_trailing_slash
+ options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true}
+ assert_equal '/foo/bar/3', @rewriter.rewrite(options)
+ assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(options.merge({:query => 'string'}))
+ options.update({:trailing_slash => true})
+ assert_equal '/foo/bar/3/', @rewriter.rewrite(options)
+ options.update({:query => 'string'})
+ assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(options)
+ end
+end
+
+class UrlWriterTests < Test::Unit::TestCase
+
+ class W
+ include ActionController::UrlWriter
+ end
+
+ def teardown
+ W.default_url_options.clear
+ end
+
+ def add_host!
+ W.default_url_options[:host] = 'www.basecamphq.com'
+ end
+
+ def test_exception_is_thrown_without_host
+ assert_raises RuntimeError do
+ W.new.url_for :controller => 'c', :action => 'a', :id => 'i'
+ end
+ end
+
+ def test_anchor
+ assert_equal('/c/a#anchor',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => 'anchor')
+ )
+ end
+
+ def test_default_host
+ add_host!
+ assert_equal('http://www.basecamphq.com/c/a/i',
+ W.new.url_for(:controller => 'c', :action => 'a', :id => 'i')
+ )
+ end
+
+ def test_host_may_be_overridden
+ add_host!
+ assert_equal('http://37signals.basecamphq.com/c/a/i',
+ W.new.url_for(:host => '37signals.basecamphq.com', :controller => 'c', :action => 'a', :id => 'i')
+ )
+ end
+
+ def test_port
+ add_host!
+ assert_equal('http://www.basecamphq.com:3000/c/a/i',
+ W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :port => 3000)
+ )
+ end
+
+ def test_protocol
+ add_host!
+ assert_equal('https://www.basecamphq.com/c/a/i',
+ W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https')
+ )
+ end
+
+ def test_protocol_with_and_without_separator
+ add_host!
+ assert_equal('https://www.basecamphq.com/c/a/i',
+ W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https')
+ )
+ assert_equal('https://www.basecamphq.com/c/a/i',
+ W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https://')
+ )
+ end
+
+ def test_named_route
+ ActionController::Routing::Routes.draw do |map|
+ map.no_args '/this/is/verbose', :controller => 'home', :action => 'index'
+ map.home '/home/sweet/home/:user', :controller => 'home', :action => 'index'
+ 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 }
+ controller = kls.new
+ assert controller.respond_to?(:home_url)
+ assert_equal 'http://www.basecamphq.com/home/sweet/home/again',
+ controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again')
+
+ assert_equal("/home/sweet/home/alabama", controller.send(:home_path, :user => 'alabama', :host => 'unused'))
+ assert_equal("http://www.basecamphq.com/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'www.basecamphq.com'))
+ assert_equal("http://www.basecamphq.com/this/is/verbose", controller.send(:no_args_url, :host=>'www.basecamphq.com'))
+ ensure
+ ActionController::Routing::Routes.load!
+ end
+
+ def test_only_path
+ ActionController::Routing::Routes.draw do |map|
+ map.home '/home/sweet/home/:user', :controller => 'home', :action => 'index'
+ 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 }
+ controller = kls.new
+ assert controller.respond_to?(:home_url)
+ assert_equal '/brave/new/world',
+ controller.send(:url_for, :controller => 'brave', :action => 'new', :id => 'world', :only_path => true)
+
+ assert_equal("/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'unused', :only_path => true))
+ assert_equal("/home/sweet/home/alabama", controller.send(:home_path, 'alabama'))
+ ensure
+ ActionController::Routing::Routes.load!
+ end
+
+ def test_one_parameter
+ assert_equal('/c/a?param=val',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val')
+ )
+ end
+
+ def test_two_parameters
+ url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2')
+ params = extract_params(url)
+ assert_equal params[0], { :p1 => 'X1' }.to_query
+ assert_equal params[1], { :p2 => 'Y2' }.to_query
+ end
+
+ def test_hash_parameter
+ url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'})
+ params = extract_params(url)
+ assert_equal params[0], { 'query[category]' => 'prof' }.to_query
+ assert_equal params[1], { 'query[name]' => 'Bob' }.to_query
+ end
+
+ def test_array_parameter
+ url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof'])
+ params = extract_params(url)
+ assert_equal params[0], { 'query[]' => 'Bob' }.to_query
+ assert_equal params[1], { 'query[]' => 'prof' }.to_query
+ end
+
+ def test_hash_recursive_parameters
+ url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'})
+ params = extract_params(url)
+ assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query
+ assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query
+ assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query
+ end
+
+ def test_hash_recursive_and_array_parameters
+ url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'})
+ assert_match %r(^/c/a/101), url
+ params = extract_params(url)
+ assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query
+ assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query
+ assert_equal params[2], { 'query[person][position][]' => 'prof' }.to_query
+ assert_equal params[3], { 'query[person][position][]' => 'art director' }.to_query
+ end
+
+ def test_path_generation_for_symbol_parameter_keys
+ assert_generates("/image", :controller=> :image)
+ end
+
+ private
+ def extract_params(url)
+ url.split('?', 2).last.split('&')
+ end
+
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/verification_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/verification_test.rb
new file mode 100644
index 000000000..e61bd5ccc
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/verification_test.rb
@@ -0,0 +1,253 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class VerificationTest < Test::Unit::TestCase
+ class TestController < ActionController::Base
+ verify :only => :guarded_one, :params => "one",
+ :add_flash => { :error => 'unguarded' },
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_two, :params => %w( one two ),
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_with_flash, :params => "one",
+ :add_flash => { :notice => "prereqs failed" },
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_in_session, :session => "one",
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => [:multi_one, :multi_two], :session => %w( one two ),
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_by_method, :method => :post,
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_by_xhr, :xhr => true,
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :guarded_by_not_xhr, :xhr => false,
+ :redirect_to => { :action => "unguarded" }
+
+ before_filter :unconditional_redirect, :only => :two_redirects
+ verify :only => :two_redirects, :method => :post,
+ :redirect_to => { :action => "unguarded" }
+
+ verify :only => :must_be_post, :method => :post, :render => { :status => 405, :text => "Must be post" }, :add_headers => { "Allow" => "POST" }
+
+ verify :only => :guarded_one_for_named_route_test, :params => "one",
+ :redirect_to => :foo_url
+
+ verify :only => :no_default_action, :params => "santa"
+
+ def guarded_one
+ render :text => "#{params[:one]}"
+ end
+
+ def guarded_one_for_named_route_test
+ render :text => "#{params[:one]}"
+ end
+
+ def guarded_with_flash
+ render :text => "#{params[:one]}"
+ end
+
+ def guarded_two
+ render :text => "#{params[:one]}:#{params[:two]}"
+ end
+
+ def guarded_in_session
+ render :text => "#{session["one"]}"
+ end
+
+ def multi_one
+ render :text => "#{session["one"]}:#{session["two"]}"
+ end
+
+ def multi_two
+ render :text => "#{session["two"]}:#{session["one"]}"
+ end
+
+ def guarded_by_method
+ render :text => "#{request.method}"
+ end
+
+ def guarded_by_xhr
+ render :text => "#{request.xhr?}"
+ end
+
+ def guarded_by_not_xhr
+ render :text => "#{request.xhr?}"
+ end
+
+ def unguarded
+ render :text => "#{params[:one]}"
+ end
+
+ def two_redirects
+ render :nothing => true
+ end
+
+ def must_be_post
+ render :text => "Was a post!"
+ end
+
+ def no_default_action
+ # Will never run
+ end
+
+ protected
+ def rescue_action(e) raise end
+
+ def unconditional_redirect
+ redirect_to :action => "unguarded"
+ end
+ end
+
+ def setup
+ @controller = TestController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ ActionController::Routing::Routes.add_named_route :foo, '/foo', :controller => 'test', :action => 'foo'
+ end
+
+ def test_no_deprecation_warning_for_named_route
+ assert_not_deprecated do
+ get :guarded_one_for_named_route_test, :two => "not one"
+ assert_redirected_to '/foo'
+ end
+ end
+
+ def test_guarded_one_with_prereqs
+ get :guarded_one, :one => "here"
+ assert_equal "here", @response.body
+ end
+
+ def test_guarded_one_without_prereqs
+ get :guarded_one
+ assert_redirected_to :action => "unguarded"
+ assert_equal 'unguarded', flash[:error]
+ end
+
+ def test_guarded_with_flash_with_prereqs
+ get :guarded_with_flash, :one => "here"
+ assert_equal "here", @response.body
+ assert flash.empty?
+ end
+
+ def test_guarded_with_flash_without_prereqs
+ get :guarded_with_flash
+ assert_redirected_to :action => "unguarded"
+ assert_equal "prereqs failed", flash[:notice]
+ end
+
+ def test_guarded_two_with_prereqs
+ get :guarded_two, :one => "here", :two => "there"
+ assert_equal "here:there", @response.body
+ end
+
+ def test_guarded_two_without_prereqs_one
+ get :guarded_two, :two => "there"
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_two_without_prereqs_two
+ get :guarded_two, :one => "here"
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_two_without_prereqs_both
+ get :guarded_two
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_unguarded_with_params
+ get :unguarded, :one => "here"
+ assert_equal "here", @response.body
+ end
+
+ def test_unguarded_without_params
+ get :unguarded
+ assert_equal "", @response.body
+ end
+
+ def test_guarded_in_session_with_prereqs
+ get :guarded_in_session, {}, "one" => "here"
+ assert_equal "here", @response.body
+ end
+
+ def test_guarded_in_session_without_prereqs
+ get :guarded_in_session
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_multi_one_with_prereqs
+ get :multi_one, {}, "one" => "here", "two" => "there"
+ assert_equal "here:there", @response.body
+ end
+
+ def test_multi_one_without_prereqs
+ get :multi_one
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_multi_two_with_prereqs
+ get :multi_two, {}, "one" => "here", "two" => "there"
+ assert_equal "there:here", @response.body
+ end
+
+ def test_multi_two_without_prereqs
+ get :multi_two
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_by_method_with_prereqs
+ post :guarded_by_method
+ assert_equal "post", @response.body
+ end
+
+ def test_guarded_by_method_without_prereqs
+ get :guarded_by_method
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_by_xhr_with_prereqs
+ xhr :post, :guarded_by_xhr
+ assert_equal "true", @response.body
+ end
+
+ def test_guarded_by_xhr_without_prereqs
+ get :guarded_by_xhr
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_by_not_xhr_with_prereqs
+ get :guarded_by_not_xhr
+ assert_equal "false", @response.body
+ end
+
+ def test_guarded_by_not_xhr_without_prereqs
+ xhr :post, :guarded_by_not_xhr
+ assert_redirected_to :action => "unguarded"
+ end
+
+ def test_guarded_post_and_calls_render_succeeds
+ post :must_be_post
+ assert_equal "Was a post!", @response.body
+ end
+
+ def test_default_failure_should_be_a_bad_request
+ post :no_default_action
+ assert_response :bad_request
+ end
+
+ def test_guarded_post_and_calls_render_fails_and_sets_allow_header
+ get :must_be_post
+ assert_response 405
+ assert_equal "Must be post", @response.body
+ assert_equal "POST", @response.headers["Allow"]
+ end
+
+ def test_second_redirect
+ assert_nothing_raised { get :two_redirects }
+ end
+end
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/view_paths_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/view_paths_test.rb
new file mode 100644
index 000000000..e29e2b9f3
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/view_paths_test.rb
@@ -0,0 +1,137 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+class ViewLoadPathsTest < Test::Unit::TestCase
+
+ LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
+
+ ActionController::Base.view_paths = [ LOAD_PATH_ROOT ]
+
+ class TestController < ActionController::Base
+ def self.controller_path() "test" end
+ def rescue_action(e) raise end
+
+ before_filter :add_view_path, :only => :hello_world_at_request_time
+
+ def hello_world() end
+ def hello_world_at_request_time() render(:action => 'hello_world') end
+ private
+ def add_view_path
+ self.class.view_paths.unshift "#{LOAD_PATH_ROOT}/override"
+ end
+ end
+
+ class Test::SubController < ActionController::Base
+ layout 'test/sub'
+ def hello_world; render(:template => 'test/hello_world'); end
+ end
+
+ def setup
+ TestController.view_paths = nil
+ ActionView::Base.cache_template_extensions = false
+ @controller = TestController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ # Track the last warning.
+ @old_behavior = ActiveSupport::Deprecation.behavior
+ @last_message = nil
+ ActiveSupport::Deprecation.behavior = Proc.new { |message, callback| @last_message = message }
+ end
+
+ def teardown
+ ActiveSupport::Deprecation.behavior = @old_behavior
+ ActionView::Base.cache_template_extensions = true
+ end
+
+ def test_template_load_path_was_set_correctly
+ assert_equal [ LOAD_PATH_ROOT ], @controller.view_paths
+ end
+
+ def test_controller_appends_view_path_correctly
+ TestController.append_view_path 'foo'
+ assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
+
+ TestController.append_view_path(%w(bar baz))
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+ end
+
+ def test_controller_prepends_view_path_correctly
+ TestController.prepend_view_path 'baz'
+ assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
+
+ TestController.prepend_view_path(%w(foo bar))
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+ end
+
+ def test_template_appends_view_path_correctly
+ @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
+ class_view_paths = TestController.view_paths
+
+ @controller.append_view_path 'foo'
+ assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
+
+ @controller.append_view_path(%w(bar baz))
+ assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+ assert_equal class_view_paths, TestController.view_paths
+ end
+
+ def test_template_prepends_view_path_correctly
+ @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
+ class_view_paths = TestController.view_paths
+
+ @controller.prepend_view_path 'baz'
+ assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
+
+ @controller.prepend_view_path(%w(foo bar))
+ assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+ assert_equal class_view_paths, TestController.view_paths
+ end
+
+ def test_view_paths
+ get :hello_world
+ assert_response :success
+ assert_equal "Hello world!", @response.body
+ end
+
+ def test_view_paths_override
+ TestController.view_paths.unshift "#{LOAD_PATH_ROOT}/override"
+ get :hello_world
+ assert_response :success
+ assert_equal "Hello overridden world!", @response.body
+ end
+
+ def test_view_paths_override_for_layouts_in_controllers_with_a_module
+ @controller = Test::SubController.new
+ Test::SubController.view_paths = [ "#{LOAD_PATH_ROOT}/override", LOAD_PATH_ROOT, "#{LOAD_PATH_ROOT}/override2" ]
+ get :hello_world
+ assert_response :success
+ assert_equal "layout: Hello overridden world!", @response.body
+ end
+
+ def test_view_paths_override_at_request_time
+ get :hello_world_at_request_time
+ assert_response :success
+ assert_equal "Hello overridden world!", @response.body
+ end
+
+ def test_inheritance
+ original_load_paths = ActionController::Base.view_paths
+
+ self.class.class_eval %{
+ class A < ActionController::Base; end
+ class B < A; end
+ class C < ActionController::Base; end
+ }
+
+ A.view_paths = [ 'a/path' ]
+
+ assert_equal [ 'a/path' ], A.view_paths
+ 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
+ end
+
+end \ No newline at end of file
diff --git a/vendor/rails-2.0.2/actionpack/test/controller/webservice_test.rb b/vendor/rails-2.0.2/actionpack/test/controller/webservice_test.rb
new file mode 100644
index 000000000..d89de5c8f
--- /dev/null
+++ b/vendor/rails-2.0.2/actionpack/test/controller/webservice_test.rb
@@ -0,0 +1,184 @@
+require File.dirname(__FILE__) + '/../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 TestController < ActionController::Base
+ session :off
+
+ def assign_parameters
+ if params[:full]
+ render :text => dump_params_keys
+ else
+ render :text => (params.keys - ['controller', 'action']).sort.join(", ")
+ end
+ end
+
+ def dump_params_keys(hash=params)
+ hash.keys.sort.inject("") do |s, k|
+ value = hash[k]
+ value = Hash === value ? "(#{dump_params_keys(value)})" : ""
+ s << ", " unless s.empty?
+ s << "#{k}#{value}"
+ end
+ end
+
+ def rescue_action(e) raise end
+ end
+
+ def setup
+ @controller = TestController.new
+ @default_param_parsers = ActionController::Base.param_parsers.dup
+ end
+
+ def teardown
+ ActionController::Base.param_parsers = @default_param_parsers
+ end
+
+ def test_check_parameters
+ process('GET')
+ assert_equal '', @controller.response.body
+ 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']
+ end
+
+ def test_put_xml
+ process('PUT', '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']
+ 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"]
+ 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"]
+ 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"]
+ 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
+ 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]
+ 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]
+ 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]
+ 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]
+ 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
+
+end