From 018b79dd36d054d87fdc408d38dc9ac7f1b1500d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 3 Oct 2009 21:05:51 -0500 Subject: File extra test folders into controller, dispatch, or template --- actionpack/Rakefile | 2 +- actionpack/test/controller/new_base/base_test.rb | 68 +++++ .../new_base/content_negotiation_test.rb | 18 ++ .../test/controller/new_base/content_type_test.rb | 111 +++++++ actionpack/test/controller/new_base/etag_test.rb | 46 +++ actionpack/test/controller/new_base/metal_test.rb | 43 +++ .../test/controller/new_base/middleware_test.rb | 77 +++++ .../test/controller/new_base/render_action_test.rb | 320 +++++++++++++++++++++ .../test/controller/new_base/render_file_test.rb | 110 +++++++ .../new_base/render_implicit_action_test.rb | 28 ++ .../test/controller/new_base/render_layout_test.rb | 101 +++++++ .../controller/new_base/render_partial_test.rb | 27 ++ .../test/controller/new_base/render_rjs_test.rb | 50 ++++ .../controller/new_base/render_template_test.rb | 170 +++++++++++ actionpack/test/controller/new_base/render_test.rb | 85 ++++++ .../test/controller/new_base/render_text_test.rb | 137 +++++++++ .../test/controller/new_base/render_xml_test.rb | 11 + actionpack/test/html-scanner/cdata_node_test.rb | 15 - actionpack/test/html-scanner/document_test.rb | 148 ---------- actionpack/test/html-scanner/node_test.rb | 89 ------ actionpack/test/html-scanner/sanitizer_test.rb | 273 ------------------ actionpack/test/html-scanner/tag_node_test.rb | 238 --------------- actionpack/test/html-scanner/text_node_test.rb | 50 ---- actionpack/test/html-scanner/tokenizer_test.rb | 131 --------- actionpack/test/javascript/ajax_test.rb | 115 -------- actionpack/test/new_base/base_test.rb | 68 ----- .../test/new_base/content_negotiation_test.rb | 18 -- actionpack/test/new_base/content_type_test.rb | 111 ------- actionpack/test/new_base/etag_test.rb | 46 --- actionpack/test/new_base/metal_test.rb | 43 --- actionpack/test/new_base/middleware_test.rb | 77 ----- actionpack/test/new_base/render_action_test.rb | 320 --------------------- actionpack/test/new_base/render_file_test.rb | 110 ------- .../test/new_base/render_implicit_action_test.rb | 28 -- actionpack/test/new_base/render_layout_test.rb | 101 ------- actionpack/test/new_base/render_partial_test.rb | 27 -- actionpack/test/new_base/render_rjs_test.rb | 50 ---- actionpack/test/new_base/render_template_test.rb | 170 ----------- actionpack/test/new_base/render_test.rb | 85 ------ actionpack/test/new_base/render_text_test.rb | 137 --------- actionpack/test/new_base/render_xml_test.rb | 11 - actionpack/test/template/ajax_test.rb | 114 ++++++++ .../test/template/html-scanner/cdata_node_test.rb | 15 + .../test/template/html-scanner/document_test.rb | 148 ++++++++++ actionpack/test/template/html-scanner/node_test.rb | 89 ++++++ .../test/template/html-scanner/sanitizer_test.rb | 273 ++++++++++++++++++ .../test/template/html-scanner/tag_node_test.rb | 238 +++++++++++++++ .../test/template/html-scanner/text_node_test.rb | 50 ++++ .../test/template/html-scanner/tokenizer_test.rb | 131 +++++++++ actionpack/test/template/test_case_test.rb | 172 +++++++++++ actionpack/test/view/test_case_test.rb | 172 ----------- 51 files changed, 2633 insertions(+), 2634 deletions(-) create mode 100644 actionpack/test/controller/new_base/base_test.rb create mode 100644 actionpack/test/controller/new_base/content_negotiation_test.rb create mode 100644 actionpack/test/controller/new_base/content_type_test.rb create mode 100644 actionpack/test/controller/new_base/etag_test.rb create mode 100644 actionpack/test/controller/new_base/metal_test.rb create mode 100644 actionpack/test/controller/new_base/middleware_test.rb create mode 100644 actionpack/test/controller/new_base/render_action_test.rb create mode 100644 actionpack/test/controller/new_base/render_file_test.rb create mode 100644 actionpack/test/controller/new_base/render_implicit_action_test.rb create mode 100644 actionpack/test/controller/new_base/render_layout_test.rb create mode 100644 actionpack/test/controller/new_base/render_partial_test.rb create mode 100644 actionpack/test/controller/new_base/render_rjs_test.rb create mode 100644 actionpack/test/controller/new_base/render_template_test.rb create mode 100644 actionpack/test/controller/new_base/render_test.rb create mode 100644 actionpack/test/controller/new_base/render_text_test.rb create mode 100644 actionpack/test/controller/new_base/render_xml_test.rb delete mode 100644 actionpack/test/html-scanner/cdata_node_test.rb delete mode 100644 actionpack/test/html-scanner/document_test.rb delete mode 100644 actionpack/test/html-scanner/node_test.rb delete mode 100644 actionpack/test/html-scanner/sanitizer_test.rb delete mode 100644 actionpack/test/html-scanner/tag_node_test.rb delete mode 100644 actionpack/test/html-scanner/text_node_test.rb delete mode 100644 actionpack/test/html-scanner/tokenizer_test.rb delete mode 100644 actionpack/test/javascript/ajax_test.rb delete mode 100644 actionpack/test/new_base/base_test.rb delete mode 100644 actionpack/test/new_base/content_negotiation_test.rb delete mode 100644 actionpack/test/new_base/content_type_test.rb delete mode 100644 actionpack/test/new_base/etag_test.rb delete mode 100644 actionpack/test/new_base/metal_test.rb delete mode 100644 actionpack/test/new_base/middleware_test.rb delete mode 100644 actionpack/test/new_base/render_action_test.rb delete mode 100644 actionpack/test/new_base/render_file_test.rb delete mode 100644 actionpack/test/new_base/render_implicit_action_test.rb delete mode 100644 actionpack/test/new_base/render_layout_test.rb delete mode 100644 actionpack/test/new_base/render_partial_test.rb delete mode 100644 actionpack/test/new_base/render_rjs_test.rb delete mode 100644 actionpack/test/new_base/render_template_test.rb delete mode 100644 actionpack/test/new_base/render_test.rb delete mode 100644 actionpack/test/new_base/render_text_test.rb delete mode 100644 actionpack/test/new_base/render_xml_test.rb create mode 100644 actionpack/test/template/ajax_test.rb create mode 100644 actionpack/test/template/html-scanner/cdata_node_test.rb create mode 100644 actionpack/test/template/html-scanner/document_test.rb create mode 100644 actionpack/test/template/html-scanner/node_test.rb create mode 100644 actionpack/test/template/html-scanner/sanitizer_test.rb create mode 100644 actionpack/test/template/html-scanner/tag_node_test.rb create mode 100644 actionpack/test/template/html-scanner/text_node_test.rb create mode 100644 actionpack/test/template/html-scanner/tokenizer_test.rb create mode 100644 actionpack/test/template/test_case_test.rb delete mode 100644 actionpack/test/view/test_case_test.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index af39175047..547e74b5a1 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -34,7 +34,7 @@ end desc "Run all unit tests" task :test => [:test_action_pack, :test_active_record_integration] -TESTS_GLOB = "test/{abstract,controller,dispatch,new_base,template,html-scanner,view}/**/*_test.rb" +TESTS_GLOB = "test/{abstract,controller,dispatch,template}/**/*_test.rb" Rake::TestTask.new(:test_action_pack) do |t| t.libs << 'test' diff --git a/actionpack/test/controller/new_base/base_test.rb b/actionpack/test/controller/new_base/base_test.rb new file mode 100644 index 0000000000..effde324bc --- /dev/null +++ b/actionpack/test/controller/new_base/base_test.rb @@ -0,0 +1,68 @@ +require 'abstract_unit' + +# Tests the controller dispatching happy path +module Dispatching + class SimpleController < ActionController::Base + def index + render :text => "success" + end + + def modify_response_body + self.response_body = "success" + end + + def modify_response_body_twice + ret = (self.response_body = "success") + self.response_body = "#{ret}!" + end + + def modify_response_headers + end + end + + class EmptyController < ActionController::Base ; end + + module Submodule + class ContainedEmptyController < ActionController::Base ; end + end + + class BaseTest < SimpleRouteCase + # :api: plugin + test "simple dispatching" do + get "/dispatching/simple/index" + + assert_body "success" + assert_status 200 + assert_content_type "text/html; charset=utf-8" + end + + # :api: plugin + test "directly modifying response body" do + get "/dispatching/simple/modify_response_body" + + assert_body "success" + end + + # :api: plugin + test "directly modifying response body twice" do + get "/dispatching/simple/modify_response_body_twice" + + assert_body "success!" + end + + test "controller path" do + assert_equal 'dispatching/empty', EmptyController.controller_path + assert_equal EmptyController.controller_path, EmptyController.new.controller_path + end + + test "namespaced controller path" do + assert_equal 'dispatching/submodule/contained_empty', Submodule::ContainedEmptyController.controller_path + assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path + end + + test "controller name" do + assert_equal 'empty', EmptyController.controller_name + assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name + end + end +end diff --git a/actionpack/test/controller/new_base/content_negotiation_test.rb b/actionpack/test/controller/new_base/content_negotiation_test.rb new file mode 100644 index 0000000000..c43cb677f8 --- /dev/null +++ b/actionpack/test/controller/new_base/content_negotiation_test.rb @@ -0,0 +1,18 @@ +require 'abstract_unit' + +module ContentNegotiation + + # This has no layout and it works + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "content_negotiation/basic/hello.html.erb" => "Hello world <%= request.formats %>!" + )] + end + + class TestContentNegotiation < SimpleRouteCase + test "A */* Accept header will return HTML" do + get "/content_negotiation/basic/hello", {}, "HTTP_ACCEPT" => "*/*" + assert_body "Hello world */*!" + end + end +end diff --git a/actionpack/test/controller/new_base/content_type_test.rb b/actionpack/test/controller/new_base/content_type_test.rb new file mode 100644 index 0000000000..898d0bb9f3 --- /dev/null +++ b/actionpack/test/controller/new_base/content_type_test.rb @@ -0,0 +1,111 @@ +require 'abstract_unit' + +module ContentType + class BaseController < ActionController::Base + def index + render :text => "Hello world!" + end + + def set_on_response_obj + response.content_type = Mime::RSS + render :text => "Hello world!" + end + + def set_on_render + render :text => "Hello world!", :content_type => Mime::RSS + end + end + + class ImpliedController < ActionController::Base + # Template's mime type is used if no content_type is specified + + self.view_paths = [ActionView::FixtureResolver.new( + "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", + "content_type/implied/i_am_xml_erb.xml.erb" => "Hello world!", + "content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'", + "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'" + )] + + def i_am_html_erb() end + def i_am_xml_erb() end + def i_am_html_builder() end + def i_am_xml_builder() end + end + + class CharsetController < ActionController::Base + def set_on_response_obj + response.charset = "utf-16" + render :text => "Hello world!" + end + + def set_as_nil_on_response_obj + response.charset = nil + render :text => "Hello world!" + end + end + + class ExplicitContentTypeTest < SimpleRouteCase + test "default response is HTML and UTF8" do + get "/content_type/base" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "setting the content type of the response directly on the response object" do + get "/content_type/base/set_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + + test "setting the content type of the response as an option to render" do + get "/content_type/base/set_on_render" + + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + end + + class ImpliedContentTypeTest < SimpleRouteCase + test "sets Content-Type as text/html when rendering *.html.erb" do + get "/content_type/implied/i_am_html_erb" + + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "sets Content-Type as application/xml when rendering *.xml.erb" do + get "/content_type/implied/i_am_xml_erb", "format" => "xml" + + assert_header "Content-Type", "application/xml; charset=utf-8" + end + + test "sets Content-Type as text/html when rendering *.html.builder" do + get "/content_type/implied/i_am_html_builder" + + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "sets Content-Type as application/xml when rendering *.xml.builder" do + get "/content_type/implied/i_am_xml_builder", "format" => "xml" + + assert_header "Content-Type", "application/xml; charset=utf-8" + end + end + + class ExplicitCharsetTest < SimpleRouteCase + test "setting the charset of the response directly on the response object" do + get "/content_type/charset/set_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-16" + end + + test "setting the charset of the response as nil directly on the response object" do + get "/content_type/charset/set_as_nil_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" + end + end +end diff --git a/actionpack/test/controller/new_base/etag_test.rb b/actionpack/test/controller/new_base/etag_test.rb new file mode 100644 index 0000000000..d5b7942ab6 --- /dev/null +++ b/actionpack/test/controller/new_base/etag_test.rb @@ -0,0 +1,46 @@ +require 'abstract_unit' + +module Etags + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "etags/basic/base.html.erb" => "Hello from without_layout.html.erb", + "layouts/etags.html.erb" => "teh <%= yield %> tagz" + )] + + def without_layout + render :action => "base" + end + + def with_layout + render :action => "base", :layout => "etags" + end + end + + class EtagTest < SimpleRouteCase + describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text" + + test "an action without a layout" do + get "/etags/basic/without_layout" + + body = "Hello from without_layout.html.erb" + assert_body body + assert_header "Etag", etag_for(body) + assert_status 200 + end + + test "an action with a layout" do + get "/etags/basic/with_layout" + + body = "teh Hello from without_layout.html.erb tagz" + assert_body body + assert_header "Etag", etag_for(body) + assert_status 200 + end + + private + + def etag_for(text) + %("#{Digest::MD5.hexdigest(text)}") + end + end +end diff --git a/actionpack/test/controller/new_base/metal_test.rb b/actionpack/test/controller/new_base/metal_test.rb new file mode 100644 index 0000000000..e1d46b906e --- /dev/null +++ b/actionpack/test/controller/new_base/metal_test.rb @@ -0,0 +1,43 @@ +require 'abstract_unit' + +module MetalTest + class MetalMiddleware < ActionController::Middleware + def call(env) + if env["PATH_INFO"] =~ /authed/ + app.call(env) + else + [401, headers, "Not authed!"] + end + end + end + + class Endpoint + def call(env) + [200, {}, "Hello World"] + end + end + + class TestMiddleware < ActiveSupport::TestCase + def setup + @app = Rack::Builder.new do + use MetalMiddleware + run Endpoint.new + end.to_app + end + + test "it can call the next app by using @app" do + env = Rack::MockRequest.env_for("/authed") + response = @app.call(env) + + assert_equal "Hello World", response[2] + end + + test "it can return a response using the normal AC::Metal techniques" do + env = Rack::MockRequest.env_for("/") + response = @app.call(env) + + assert_equal "Not authed!", response[2] + assert_equal 401, response[0] + end + end +end diff --git a/actionpack/test/controller/new_base/middleware_test.rb b/actionpack/test/controller/new_base/middleware_test.rb new file mode 100644 index 0000000000..ada0215b1a --- /dev/null +++ b/actionpack/test/controller/new_base/middleware_test.rb @@ -0,0 +1,77 @@ +require 'abstract_unit' + +module MiddlewareTest + class MyMiddleware + def initialize(app) + @app = app + end + + def call(env) + result = @app.call(env) + result[1]["Middleware-Test"] = "Success" + result[1]["Middleware-Order"] = "First" + result + end + end + + class ExclaimerMiddleware + def initialize(app) + @app = app + end + + def call(env) + result = @app.call(env) + result[1]["Middleware-Order"] << "!" + result + end + end + + class MyController < ActionController::Metal + use MyMiddleware + + middleware.insert_before MyMiddleware, ExclaimerMiddleware + + def index + self.response_body = "Hello World" + end + end + + class InheritedController < MyController + end + + module MiddlewareTests + extend ActiveSupport::Testing::Declarative + + test "middleware that is 'use'd is called as part of the Rack application" do + result = @app.call(env_for("/")) + assert_equal "Hello World", result[2] + assert_equal "Success", result[1]["Middleware-Test"] + end + + test "the middleware stack is exposed as 'middleware' in the controller" do + result = @app.call(env_for("/")) + assert_equal "First!", result[1]["Middleware-Order"] + end + end + + class TestMiddleware < ActiveSupport::TestCase + include MiddlewareTests + + def setup + @app = MyController.action(:index) + end + + def env_for(url) + Rack::MockRequest.env_for(url) + end + end + + class TestInheritedMiddleware < TestMiddleware + def setup + @app = InheritedController.action(:index) + end + + test "middleware inherits" do + end + end +end diff --git a/actionpack/test/controller/new_base/render_action_test.rb b/actionpack/test/controller/new_base/render_action_test.rb new file mode 100644 index 0000000000..d5896c1ebd --- /dev/null +++ b/actionpack/test/controller/new_base/render_action_test.rb @@ -0,0 +1,320 @@ +require 'abstract_unit' + +module RenderAction + # This has no layout and it works + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "render_action/basic/hello_world.html.erb" => "Hello world!" + )] + + def hello_world + render :action => "hello_world" + end + + def hello_world_as_string + render "hello_world" + end + + def hello_world_as_string_with_options + render "hello_world", :status => 404 + end + + def hello_world_as_symbol + render :hello_world + end + + def hello_world_with_symbol + render :action => :hello_world + end + + def hello_world_with_layout + render :action => "hello_world", :layout => true + end + + def hello_world_with_layout_false + render :action => "hello_world", :layout => false + end + + def hello_world_with_layout_nil + render :action => "hello_world", :layout => nil + end + + def hello_world_with_custom_layout + render :action => "hello_world", :layout => "greetings" + end + + end + + class RenderActionTest < SimpleRouteCase + test "rendering an action using :action => " do + get "/render_action/basic/hello_world" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using ''" do + get "/render_action/basic/hello_world_as_string" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using '' and options" do + get "/render_action/basic/hello_world_as_string_with_options" + + assert_body "Hello world!" + assert_status 404 + end + + test "rendering an action using :action" do + get "/render_action/basic/hello_world_as_symbol" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using :action => :hello_world" do + get "/render_action/basic/hello_world_with_symbol" + + assert_body "Hello world!" + assert_status 200 + end + end + + class RenderLayoutTest < SimpleRouteCase + describe "Both .html.erb and application.html.erb are missing" + + test "rendering with layout => true" do + assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do + get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false + end + end + + test "rendering with layout => false" do + get "/render_action/basic/hello_world_with_layout_false" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action/basic/hello_world_with_layout_nil" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering with layout => 'greetings'" do + assert_raise(ActionView::MissingTemplate) do + get "/render_action/basic/hello_world_with_custom_layout", {}, "action_dispatch.show_exceptions" => false + end + end + end +end + +module RenderActionWithApplicationLayout + # # ==== Render actions with layouts ==== + class BasicController < ::ApplicationController + # Set the view path to an application view structure with layouts + self.view_paths = self.view_paths = [ActionView::FixtureResolver.new( + "render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!", + "render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'", + "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", + "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai", + "layouts/builder.html.builder" => "xml.html do\n xml << yield\nend" + )] + + def hello_world + render :action => "hello_world" + end + + def hello_world_with_layout + render :action => "hello_world", :layout => true + end + + def hello_world_with_layout_false + render :action => "hello_world", :layout => false + end + + def hello_world_with_layout_nil + render :action => "hello_world", :layout => nil + end + + def hello_world_with_custom_layout + render :action => "hello_world", :layout => "greetings" + end + + def with_builder_and_layout + render :action => "hello", :layout => "builder" + end + end + + class LayoutTest < SimpleRouteCase + describe "Only application.html.erb is present and .html.erb is missing" + + test "rendering implicit application.html.erb as layout" do + get "/render_action_with_application_layout/basic/hello_world" + + assert_body "OHAI Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_application_layout/basic/hello_world_with_layout" + + assert_body "OHAI Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_application_layout/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_application_layout/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => 'greetings'" do + get "/render_action_with_application_layout/basic/hello_world_with_custom_layout" + + assert_body "Greetings Hello World! Bai" + assert_status 200 + end + end + + class TestLayout < SimpleRouteCase + testing BasicController + + test "builder works with layouts" do + get :with_builder_and_layout + assert_response "\n

Omg

\n\n" + end + end + +end + +module RenderActionWithControllerLayout + class BasicController < ActionController::Base + self.view_paths = self.view_paths = [ActionView::FixtureResolver.new( + "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", + "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" + )] + + def hello_world + render :action => "hello_world" + end + + def hello_world_with_layout + render :action => "hello_world", :layout => true + end + + def hello_world_with_layout_false + render :action => "hello_world", :layout => false + end + + def hello_world_with_layout_nil + render :action => "hello_world", :layout => nil + end + + def hello_world_with_custom_layout + render :action => "hello_world", :layout => "greetings" + end + end + + class ControllerLayoutTest < SimpleRouteCase + describe "Only .html.erb is present and application.html.erb is missing" + + test "render hello_world and implicitly use .html.erb as a layout." do + get "/render_action_with_controller_layout/basic/hello_world" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end + end +end + +module RenderActionWithBothLayouts + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new({ + "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", + "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", + "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" + })] + + def hello_world + render :action => "hello_world" + end + + def hello_world_with_layout + render :action => "hello_world", :layout => true + end + + def hello_world_with_layout_false + render :action => "hello_world", :layout => false + end + + def hello_world_with_layout_nil + render :action => "hello_world", :layout => nil + end + end + + class ControllerLayoutTest < SimpleRouteCase + describe "Both .html.erb and application.html.erb are present" + + test "rendering implicitly use .html.erb over application.html.erb as a layout" do + get "/render_action_with_both_layouts/basic/hello_world" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end + end +end diff --git a/actionpack/test/controller/new_base/render_file_test.rb b/actionpack/test/controller/new_base/render_file_test.rb new file mode 100644 index 0000000000..1c52d2b37d --- /dev/null +++ b/actionpack/test/controller/new_base/render_file_test.rb @@ -0,0 +1,110 @@ +require 'abstract_unit' + +module RenderFile + + class BasicController < ActionController::Base + self.view_paths = File.dirname(__FILE__) + + def index + render :file => File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world]) + end + + def with_instance_variables + @secret = 'in the sauce' + render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb') + end + + def without_file_key + render File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world]) + end + + def without_file_key_with_instance_variable + @secret = 'in the sauce' + render File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb') + end + + def relative_path + @secret = 'in the sauce' + render :file => '../../fixtures/test/render_file_with_ivar' + end + + def relative_path_with_dot + @secret = 'in the sauce' + render :file => '../../fixtures/test/dot.directory/render_file_with_ivar' + end + + def pathname + @secret = 'in the sauce' + render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar.erb]) + end + + def 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 without_file_key_with_locals + path = File.expand_path('../../fixtures/test/render_file_with_locals.erb') + render path, :locals => {:secret => 'in the sauce'} + end + end + + class TestBasic < SimpleRouteCase + testing RenderFile::BasicController + + def setup + @old_pwd = Dir.pwd + Dir.chdir(File.dirname(__FILE__)) + end + + def teardown + Dir.chdir(@old_pwd) + end + + test "rendering simple template" do + get :index + assert_response "Hello world!" + end + + test "rendering template with ivar" do + get :with_instance_variables + assert_response "The secret is in the sauce\n" + end + + test "rendering path without specifying the :file key" do + get :without_file_key + assert_response "Hello world!" + end + + test "rendering path without specifying the :file key with ivar" do + get :without_file_key_with_instance_variable + assert_response "The secret is in the sauce\n" + end + + test "rendering a relative path" do + get :relative_path + assert_response "The secret is in the sauce\n" + end + + test "rendering a relative path with dot" do + get :relative_path_with_dot + assert_response "The secret is in the sauce\n" + end + + test "rendering a Pathname" do + get :pathname + assert_response "The secret is in the sauce\n" + end + + test "rendering file with locals" do + get :with_locals + assert_response "The secret is in the sauce\n" + end + + test "rendering path without specifying the :file key with locals" do + get :without_file_key_with_locals + assert_response "The secret is in the sauce\n" + end + end + +end diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb new file mode 100644 index 0000000000..2b78fa7d4f --- /dev/null +++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb @@ -0,0 +1,28 @@ +require 'abstract_unit' + +module RenderImplicitAction + class SimpleController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" + )] + + def hello_world() end + end + + class RenderImplicitActionTest < SimpleRouteCase + test "render a simple action with new explicit call to render" do + get "/render_implicit_action/simple/hello_world" + + assert_body "Hello world!" + assert_status 200 + end + + test "render an action with a missing method and has special characters" do + get "/render_implicit_action/simple/hyphen-ated" + + assert_body "Hello hyphen-ated!" + assert_status 200 + end + end +end diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb new file mode 100644 index 0000000000..f840a47ecf --- /dev/null +++ b/actionpack/test/controller/new_base/render_layout_test.rb @@ -0,0 +1,101 @@ +require 'abstract_unit' + +module ControllerLayouts + class ImplicitController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", + "layouts/override.html.erb" => "Override! <%= yield %>", + "basic.html.erb" => "Hello world!", + "controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)" + )] + + def index + render :template => "basic" + end + + def override + render :template => "basic", :layout => "override" + end + + def layout_false + render :layout => false + end + + def builder_override + end + end + + class ImplicitNameController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", + "basic.html.erb" => "Hello world!" + )] + + def index + render :template => "basic" + end + end + + class RenderLayoutTest < SimpleRouteCase + test "rendering a normal template, but using the implicit layout" do + get "/controller_layouts/implicit/index" + + assert_body "OMG Hello world! KTHXBAI" + assert_status 200 + end + + test "rendering a normal template, but using an implicit NAMED layout" do + get "/controller_layouts/implicit_name/index" + + assert_body "OMGIMPLICIT Hello world! KTHXBAI" + assert_status 200 + end + + test "overriding an implicit layout with render :layout option" do + get "/controller_layouts/implicit/override" + assert_body "Override! Hello world!" + end + + end + + class LayoutOptionsTest < SimpleRouteCase + testing ControllerLayouts::ImplicitController + + test "rendering with :layout => false leaves out the implicit layout" do + get :layout_false + assert_response "hai(layout_false.html.erb)" + end + end + + class MismatchFormatController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "layouts/application.html.erb" => "<%= yield %>", + "controller_layouts/mismatch_format/index.js.rjs" => "page[:test].omg", + "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].omg" + )] + + def explicit + render :layout => "application" + end + end + + class MismatchFormatTest < SimpleRouteCase + testing ControllerLayouts::MismatchFormatController + + test "if JS is selected, an HTML template is not also selected" do + get :index, "format" => "js" + assert_response "$(\"test\").omg();" + end + + test "if JS is implicitly selected, an HTML template is not also selected" do + get :implicit + assert_response "$(\"test\").omg();" + end + + test "if an HTML template is explicitly provides for a JS template, an error is raised" do + assert_raises ActionView::MissingTemplate do + get :explicit, {}, "action_dispatch.show_exceptions" => false + end + end + end +end diff --git a/actionpack/test/controller/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb new file mode 100644 index 0000000000..7c2c20e1c7 --- /dev/null +++ b/actionpack/test/controller/new_base/render_partial_test.rb @@ -0,0 +1,27 @@ +require 'abstract_unit' + +module RenderPartial + + class BasicController < ActionController::Base + + self.view_paths = [ActionView::FixtureResolver.new( + "render_partial/basic/_basic.html.erb" => "OMG!", + "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>" + )] + + def changing + @test_unchanged = 'hello' + render :action => "basic" + end + end + + class TestPartial < SimpleRouteCase + testing BasicController + + test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do + get :changing + assert_response("goodbyeOMG!goodbye") + end + end + +end diff --git a/actionpack/test/controller/new_base/render_rjs_test.rb b/actionpack/test/controller/new_base/render_rjs_test.rb new file mode 100644 index 0000000000..7b76c54ab9 --- /dev/null +++ b/actionpack/test/controller/new_base/render_rjs_test.rb @@ -0,0 +1,50 @@ +require 'abstract_unit' + +module RenderRjs + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "render_rjs/basic/index.js.rjs" => "page[:customer].replace_html render(:partial => 'customer')", + "render_rjs/basic/index_html.js.rjs" => "page[:customer].replace_html :partial => 'customer'", + "render_rjs/basic/_customer.js.erb" => "JS Partial", + "render_rjs/basic/_customer.html.erb" => "HTML Partial", + "render_rjs/basic/index_locale.js.rjs" => "page[:customer].replace_html :partial => 'customer'", + "render_rjs/basic/_customer.da.html.erb" => "Danish HTML Partial", + "render_rjs/basic/_customer.da.js.erb" => "Danish JS Partial" + )] + + def index + render + end + + def index_locale + old_locale, I18n.locale = I18n.locale, :da + end + end + + class TestBasic < SimpleRouteCase + testing BasicController + + def setup + @old_locale = I18n.locale + end + + def teardown + I18n.locale = @old_locale + end + + test "rendering a partial in an RJS template should pick the JS template over the HTML one" do + get :index, "format" => "js" + assert_response("$(\"customer\").update(\"JS Partial\");") + end + + test "replacing an element with a partial in an RJS template should pick the HTML template over the JS one" do + get :index_html, "format" => "js" + assert_response("$(\"customer\").update(\"HTML Partial\");") + end + + test "replacing an element with a partial in an RJS template with a locale should pick the localed HTML template" do + get :index_locale, "format" => "js" + assert_response("$(\"customer\").update(\"Danish HTML Partial\");") + end + end +end diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb new file mode 100644 index 0000000000..3b24c2d75a --- /dev/null +++ b/actionpack/test/controller/new_base/render_template_test.rb @@ -0,0 +1,170 @@ +require 'abstract_unit' + +module RenderTemplate + class WithoutLayoutController < ActionController::Base + + self.view_paths = [ActionView::FixtureResolver.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica", + "locals.html.erb" => "The secret is <%= secret %>", + "xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend" + )] + + def index + render :template => "test/basic" + end + + def index_without_key + render "test/basic" + end + + def in_top_directory + render :template => 'shared' + end + + def in_top_directory_with_slash + render :template => '/shared' + end + + def in_top_directory_with_slash_without_key + render '/shared' + end + + def with_locals + render :template => "locals", :locals => { :secret => 'area51' } + end + + def builder_template + render :template => "xml_template" + end + end + + class TestWithoutLayout < SimpleRouteCase + testing RenderTemplate::WithoutLayoutController + + test "rendering a normal template with full path without layout" do + get :index + assert_response "Hello from basic.html.erb" + end + + test "rendering a normal template with full path without layout without key" do + get :index_without_key + assert_response "Hello from basic.html.erb" + end + + test "rendering a template not in a subdirectory" do + get :in_top_directory + assert_response "Elastica" + end + + test "rendering a template not in a subdirectory with a leading slash" do + get :in_top_directory_with_slash + assert_response "Elastica" + end + + test "rendering a template not in a subdirectory with a leading slash without key" do + get :in_top_directory_with_slash_without_key + assert_response "Elastica" + end + + test "rendering a template with local variables" do + get :with_locals + assert_response "The secret is area51" + end + + test "rendering a builder template" do + get :builder_template, "format" => "xml" + assert_response "\n

Hello

\n\n" + end + end + + class WithLayoutController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica", + "layouts/application.html.erb" => "<%= yield %>, I'm here!", + "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." + )] + + def index + render :template => "test/basic" + end + + def with_layout + render :template => "test/basic", :layout => true + end + + def with_layout_false + render :template => "test/basic", :layout => false + end + + def with_layout_nil + render :template => "test/basic", :layout => nil + end + + def with_custom_layout + render :template => "test/basic", :layout => "greetings" + end + end + + class TestWithLayout < SimpleRouteCase + describe "Rendering with :template using implicit or explicit layout" + + test "rendering with implicit layout" do + get "/render_template/with_layout" + + assert_body "Hello from basic.html.erb, I'm here!" + assert_status 200 + end + + test "rendering with layout => :true" do + get "/render_template/with_layout/with_layout" + + assert_body "Hello from basic.html.erb, I'm here!" + assert_status 200 + end + + test "rendering with layout => :false" do + get "/render_template/with_layout/with_layout_false" + + assert_body "Hello from basic.html.erb" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_template/with_layout/with_layout_nil" + + assert_body "Hello from basic.html.erb" + assert_status 200 + end + + test "rendering layout => 'greetings'" do + get "/render_template/with_layout/with_custom_layout" + + assert_body "Hello from basic.html.erb, I wish thee well." + assert_status 200 + end + end + + module Compatibility + class WithoutLayoutController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica" + )] + + def with_forward_slash + render :template => "/test/basic" + end + end + + class TestTemplateRenderWithForwardSlash < SimpleRouteCase + test "rendering a normal template with full path starting with a leading slash" do + get "/render_template/compatibility/without_layout/with_forward_slash" + + assert_body "Hello from basic.html.erb" + assert_status 200 + end + end + end +end diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb new file mode 100644 index 0000000000..804be79d17 --- /dev/null +++ b/actionpack/test/controller/new_base/render_test.rb @@ -0,0 +1,85 @@ +require 'abstract_unit' + +module Render + class BlankRenderController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "render/blank_render/index.html.erb" => "Hello world!", + "render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>", + "render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>", + "render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>" + )] + + def index + render + end + + def access_request + render :action => "access_request" + end + + def render_action_name + render :action => "access_action_name" + end + + private + + def secretz + render :text => "FAIL WHALE!" + end + end + + class DoubleRenderController < ActionController::Base + def index + render :text => "hello" + render :text => "world" + end + end + + class RenderTest < SimpleRouteCase + test "render with blank" do + get "/render/blank_render" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering more than once raises an exception" do + assert_raises(AbstractController::DoubleRenderError) do + get "/render/double_render", {}, "action_dispatch.show_exceptions" => false + end + end + end + + class TestOnlyRenderPublicActions < SimpleRouteCase + describe "Only public methods on actual controllers are callable actions" + + test "raises an exception when a method of Object is called" do + assert_raises(AbstractController::ActionNotFound) do + get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false + end + end + + test "raises an exception when a private method is called" do + assert_raises(AbstractController::ActionNotFound) do + get "/render/blank_render/secretz", {}, "action_dispatch.show_exceptions" => false + end + end + end + + class TestVariousObjectsAvailableInView < SimpleRouteCase + test "The request object is accessible in the view" do + get "/render/blank_render/access_request" + assert_body "The request: GET" + end + + test "The action_name is accessible in the view" do + get "/render/blank_render/render_action_name" + assert_body "Action Name: render_action_name" + end + + test "The controller_name is accessible in the view" do + get "/render/blank_render/access_controller_name" + assert_body "Controller Name: blank_render" + end + end +end diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb new file mode 100644 index 0000000000..f5839ee16f --- /dev/null +++ b/actionpack/test/controller/new_base/render_text_test.rb @@ -0,0 +1,137 @@ +require 'abstract_unit' + +module RenderText + class SimpleController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new] + + def index + render :text => "hello david" + end + end + + class WithLayoutController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "layouts/application.html.erb" => "<%= yield %>, I'm here!", + "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.", + "layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>" + )] + + def index + render :text => "hello david" + end + + def custom_code + render :text => "hello world", :status => 404 + end + + def with_custom_code_as_string + render :text => "hello world", :status => "404 Not Found" + end + + def with_nil + render :text => nil + end + + def with_nil_and_status + render :text => nil, :status => 403 + end + + def with_false + render :text => false + end + + def with_layout_true + render :text => "hello world", :layout => true + end + + def with_layout_false + render :text => "hello world", :layout => false + end + + def with_layout_nil + render :text => "hello world", :layout => nil + end + + def with_custom_layout + render :text => "hello world", :layout => "greetings" + end + + def with_ivar_in_layout + @ivar = "hello world" + render :text => "hello world", :layout => "ivar" + end + end + + class RenderTextTest < SimpleRouteCase + describe "Rendering text using render :text" + + test "rendering text from a action with default options renders the text with the layout" do + get "/render_text/simple" + assert_body "hello david" + assert_status 200 + end + + test "rendering text from a action with default options renders the text without the layout" do + get "/render_text/with_layout" + + assert_body "hello david" + assert_status 200 + end + + test "rendering text, while also providing a custom status code" do + get "/render_text/with_layout/custom_code" + + assert_body "hello world" + assert_status 404 + end + + test "rendering text with nil returns an empty body padded for Safari" do + get "/render_text/with_layout/with_nil" + + assert_body " " + assert_status 200 + end + + test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do + get "/render_text/with_layout/with_nil_and_status" + + assert_body " " + assert_status 403 + end + + test "rendering text with false returns the string 'false'" do + get "/render_text/with_layout/with_false" + + assert_body "false" + assert_status 200 + end + + test "rendering text with :layout => true" do + get "/render_text/with_layout/with_layout_true" + + assert_body "hello world, I'm here!" + assert_status 200 + end + + test "rendering text with :layout => 'greetings'" do + get "/render_text/with_layout/with_custom_layout" + + assert_body "hello world, I wish thee well." + assert_status 200 + end + + test "rendering text with :layout => false" do + get "/render_text/with_layout/with_layout_false" + + assert_body "hello world" + assert_status 200 + end + + test "rendering text with :layout => nil" do + get "/render_text/with_layout/with_layout_nil" + + assert_body "hello world" + assert_status 200 + end + end +end diff --git a/actionpack/test/controller/new_base/render_xml_test.rb b/actionpack/test/controller/new_base/render_xml_test.rb new file mode 100644 index 0000000000..d044738a78 --- /dev/null +++ b/actionpack/test/controller/new_base/render_xml_test.rb @@ -0,0 +1,11 @@ +require 'abstract_unit' + +module RenderXml + + # This has no layout and it works + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "render_xml/basic/with_render_erb" => "Hello world!" + )] + end +end diff --git a/actionpack/test/html-scanner/cdata_node_test.rb b/actionpack/test/html-scanner/cdata_node_test.rb deleted file mode 100644 index 1822cc565a..0000000000 --- a/actionpack/test/html-scanner/cdata_node_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'abstract_unit' - -class CDATANodeTest < Test::Unit::TestCase - def setup - @node = HTML::CDATA.new(nil, 0, 0, "

howdy

") - end - - def test_to_s - assert_equal "howdy

]]>", @node.to_s - end - - def test_content - assert_equal "

howdy

", @node.content - end -end diff --git a/actionpack/test/html-scanner/document_test.rb b/actionpack/test/html-scanner/document_test.rb deleted file mode 100644 index c68f04fa75..0000000000 --- a/actionpack/test/html-scanner/document_test.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'abstract_unit' - -class DocumentTest < Test::Unit::TestCase - def test_handle_doctype - doc = nil - assert_nothing_raised do - doc = HTML::Document.new <<-HTML.strip - - - - HTML - end - assert_equal 3, doc.root.children.length - assert_equal %{}, 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 - assert doc.find(:tag=>"img", :attributes=>{"src"=>"hello.gif"}) - end - - def test_find_all - doc = HTML::Document.new <<-HTML.strip - - -

-
-

something

-

here is more

-
- - - 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 - - -

Some text

- - - 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("", true, true) } - assert_nothing_raised { HTML::Document.new("something", true, true) } - end - - def test_parse_document - doc = HTML::Document.new(<<-HTML) -
-

blah

- -
-
- 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("") - assert_equal "", doc.root.to_s - end - - def test_tag_nesting_space_to_s - doc = HTML::Document.new(" ") - assert_equal " ", doc.root.to_s - end - - def test_tag_nesting_text_to_s - doc = HTML::Document.new("text") - assert_equal "text", doc.root.to_s - end - - def test_tag_nesting_tag_to_s - doc = HTML::Document.new("") - assert_equal "", doc.root.to_s - end - - def test_parse_cdata - doc = HTML::Document.new(<<-HTML) - - - - <![CDATA[<br>]]> - - -

this document has <br> for a title

- - -HTML - - assert_nil doc.find(:tag => "title", :descendant => { :tag => "br" }) - assert doc.find(:tag => "title", :child => "
") - end - - def test_find_empty_tag - doc = HTML::Document.new("
") - 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 - - def test_parse_invalid_document - assert_nothing_raised do - doc = HTML::Document.new(" - - - - -
About Us
- ") - end - end - - def test_invalid_document_raises_exception_when_strict - assert_raise RuntimeError do - doc = HTML::Document.new(" - - - - -
About Us
- ", true) - end - end - -end diff --git a/actionpack/test/html-scanner/node_test.rb b/actionpack/test/html-scanner/node_test.rb deleted file mode 100644 index b0df36877e..0000000000 --- a/actionpack/test/html-scanner/node_test.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'abstract_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 = "" - assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) } - end - - def test_parse_relaxed - s = "" - 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 = "" - node = HTML::Node.parse(nil,0,0,s) - assert node.attributes.has_key?("foo") - assert node.attributes.has_key?("bar") - assert "", node.to_s - end - - def test_parse_with_unclosed_tag - s = "contents', node.content - end - - def test_parse_strict_with_unterminated_cdata_section - s = "")) - assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me")) - assert_equal("This is a test.", sanitizer.sanitize("

This is a test.

")) - assert_equal("Weirdos", sanitizer.sanitize("Wei<a onclick='alert(document.cookie);'/>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( - %{This is <b>a <a href="" target="_blank">test</a></b>.\n\n\n\n

It no longer contains any HTML.

\n})) - assert_equal "This has a here.", sanitizer.sanitize("This has a here.") - assert_equal "This has a here.", sanitizer.sanitize("This has a ]]> here.") - assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed ]] 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("on my mind\nall day long") - assert_equal "0wn3d", sanitizer.sanitize("0wn3d") - assert_equal "Magic", sanitizer.sanitize("Magic") - assert_equal "FrrFox", sanitizer.sanitize("FrrFox") - assert_equal "My mind\nall day long", sanitizer.sanitize("My mind\nall day long") - assert_equal "all day long", sanitizer.sanitize("<a href='hello'>all day long</a>") - - assert_equal "", '' - end - - def test_sanitize_plaintext - raw = "<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_with_trailing_space - raw = "display:block; " - expected = "display: block;" - 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 - - def test_should_sanitize_cdata_section - assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>" - end - - def test_should_sanitize_unterminated_cdata_section - assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>" - end - - def test_should_not_mangle_urls_with_ampersand - assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>} - end - -protected - def assert_sanitized(input, expected = nil) - @sanitizer ||= HTML::WhiteListSanitizer.new - if input - assert_dom_equal expected || input, @sanitizer.sanitize(input) - else - assert_nil @sanitizer.sanitize(input) - end - end - - def sanitize_css(input) - (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input) - end -end diff --git a/actionpack/test/html-scanner/tag_node_test.rb b/actionpack/test/html-scanner/tag_node_test.rb deleted file mode 100644 index d1d4667378..0000000000 --- a/actionpack/test/html-scanner/tag_node_test.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'abstract_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/actionpack/test/html-scanner/text_node_test.rb b/actionpack/test/html-scanner/text_node_test.rb deleted file mode 100644 index 1ab3f4454e..0000000000 --- a/actionpack/test/html-scanner/text_node_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'abstract_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 diff --git a/actionpack/test/html-scanner/tokenizer_test.rb b/actionpack/test/html-scanner/tokenizer_test.rb deleted file mode 100644 index a001bcbbad..0000000000 --- a/actionpack/test/html-scanner/tokenizer_test.rb +++ /dev/null @@ -1,131 +0,0 @@ -require 'abstract_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_unterminated_cdata_tag - tokenize %{<content:encoded><![CDATA[ neverending...} - assert_next %{<content:encoded>} - assert_next %{<![CDATA[ neverending...} - 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/actionpack/test/javascript/ajax_test.rb b/actionpack/test/javascript/ajax_test.rb deleted file mode 100644 index b67a91dad3..0000000000 --- a/actionpack/test/javascript/ajax_test.rb +++ /dev/null @@ -1,115 +0,0 @@ -require "abstract_unit" - -class AjaxTestCase < ActiveSupport::TestCase - include ActionView::Helpers::AjaxHelper - include ActionView::Helpers::TagHelper - - def assert_html(html, matches) - matches.each do |match| - assert_match Regexp.new(Regexp.escape(match)), html - end - end - - def self.assert_callbacks_work(&blk) - define_method(:assert_callbacks_work, &blk) - - [:complete, :failure, :success, :interactive, :loaded, :loading, 404].each do |callback| - test "#{callback} callback" do - markup = assert_callbacks_work(callback) - assert_html markup, %W(data-#{callback}-code="undoRequestCompleted\(request\)") - end - end - end -end - -class LinkToRemoteTest < AjaxTestCase - def url_for(hash) - "/blog/destroy/4" - end - - def link(options = {}) - link_to_remote("Delete this post", "/blog/destroy/3", options) - end - - test "with no update" do - assert_html link, %w(href="/blog/destroy/3" Delete\ this\ post data-remote="true") - end - - test "basic" do - assert_html link(:update => "#posts"), - %w(data-update-success="#posts") - end - - test "using a url hash" do - link = link_to_remote("Delete this post", {:controller => :blog}, :update => "#posts") - assert_html link, %w(href="/blog/destroy/4" data-update-success="#posts") - end - - test "with :html options" do - expected = %{<a href="/blog/destroy/3" data-custom="me" data-update-success="#posts">Delete this post</a>} - assert_equal expected, link(:update => "#posts", :html => {"data-custom" => "me"}) - end - - test "with a hash for :update" do - link = link(:update => {:success => "#posts", :failure => "#error"}) - assert_match /data-update-success="#posts"/, link - assert_match /data-update-failure="#error"/, link - end - - test "with positional parameters" do - link = link(:position => :top, :update => "#posts") - assert_match /data\-update\-position="top"/, link - end - - test "with an optional method" do - link = link(:method => "delete") - assert_match /data-method="delete"/, link - end - - class LegacyLinkToRemoteTest < AjaxTestCase - include ActionView::Helpers::AjaxHelper::Rails2Compatibility - - def link(options) - link_to_remote("Delete this post", "/blog/destroy/3", options) - end - - test "basic link_to_remote with :url =>" do - expected = %{<a href="/blog/destroy/3" data-update-success="#posts">Delete this post</a>} - assert_equal expected, - link_to_remote("Delete this post", :url => "/blog/destroy/3", :update => "#posts") - end - - assert_callbacks_work do |callback| - link(callback => "undoRequestCompleted(request)") - end - end -end - -class ButtonToRemoteTest < AjaxTestCase - def button(options, html = {}) - button_to_remote("Remote outpost", options, html) - end - - def url_for(*) - "/whatnot" - end - - class StandardTest < ButtonToRemoteTest - test "basic" do - button = button({:url => {:action => "whatnot"}}, {:class => "fine"}) - [/input/, /class="fine"/, /type="button"/, /value="Remote outpost"/, - /data-url="\/whatnot"/].each do |match| - assert_match match, button - end - end - end - - class LegacyButtonToRemoteTest < ButtonToRemoteTest - include ActionView::Helpers::AjaxHelper::Rails2Compatibility - - assert_callbacks_work do |callback| - button(callback => "undoRequestCompleted(request)") - end - end - -end \ No newline at end of file diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb deleted file mode 100644 index effde324bc..0000000000 --- a/actionpack/test/new_base/base_test.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'abstract_unit' - -# Tests the controller dispatching happy path -module Dispatching - class SimpleController < ActionController::Base - def index - render :text => "success" - end - - def modify_response_body - self.response_body = "success" - end - - def modify_response_body_twice - ret = (self.response_body = "success") - self.response_body = "#{ret}!" - end - - def modify_response_headers - end - end - - class EmptyController < ActionController::Base ; end - - module Submodule - class ContainedEmptyController < ActionController::Base ; end - end - - class BaseTest < SimpleRouteCase - # :api: plugin - test "simple dispatching" do - get "/dispatching/simple/index" - - assert_body "success" - assert_status 200 - assert_content_type "text/html; charset=utf-8" - end - - # :api: plugin - test "directly modifying response body" do - get "/dispatching/simple/modify_response_body" - - assert_body "success" - end - - # :api: plugin - test "directly modifying response body twice" do - get "/dispatching/simple/modify_response_body_twice" - - assert_body "success!" - end - - test "controller path" do - assert_equal 'dispatching/empty', EmptyController.controller_path - assert_equal EmptyController.controller_path, EmptyController.new.controller_path - end - - test "namespaced controller path" do - assert_equal 'dispatching/submodule/contained_empty', Submodule::ContainedEmptyController.controller_path - assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path - end - - test "controller name" do - assert_equal 'empty', EmptyController.controller_name - assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name - end - end -end diff --git a/actionpack/test/new_base/content_negotiation_test.rb b/actionpack/test/new_base/content_negotiation_test.rb deleted file mode 100644 index c43cb677f8..0000000000 --- a/actionpack/test/new_base/content_negotiation_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'abstract_unit' - -module ContentNegotiation - - # This has no layout and it works - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "content_negotiation/basic/hello.html.erb" => "Hello world <%= request.formats %>!" - )] - end - - class TestContentNegotiation < SimpleRouteCase - test "A */* Accept header will return HTML" do - get "/content_negotiation/basic/hello", {}, "HTTP_ACCEPT" => "*/*" - assert_body "Hello world */*!" - end - end -end diff --git a/actionpack/test/new_base/content_type_test.rb b/actionpack/test/new_base/content_type_test.rb deleted file mode 100644 index 898d0bb9f3..0000000000 --- a/actionpack/test/new_base/content_type_test.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'abstract_unit' - -module ContentType - class BaseController < ActionController::Base - def index - render :text => "Hello world!" - end - - def set_on_response_obj - response.content_type = Mime::RSS - render :text => "Hello world!" - end - - def set_on_render - render :text => "Hello world!", :content_type => Mime::RSS - end - end - - class ImpliedController < ActionController::Base - # Template's mime type is used if no content_type is specified - - self.view_paths = [ActionView::FixtureResolver.new( - "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", - "content_type/implied/i_am_xml_erb.xml.erb" => "<xml>Hello world!</xml>", - "content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'", - "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'" - )] - - def i_am_html_erb() end - def i_am_xml_erb() end - def i_am_html_builder() end - def i_am_xml_builder() end - end - - class CharsetController < ActionController::Base - def set_on_response_obj - response.charset = "utf-16" - render :text => "Hello world!" - end - - def set_as_nil_on_response_obj - response.charset = nil - render :text => "Hello world!" - end - end - - class ExplicitContentTypeTest < SimpleRouteCase - test "default response is HTML and UTF8" do - get "/content_type/base" - - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-8" - end - - test "setting the content type of the response directly on the response object" do - get "/content_type/base/set_on_response_obj" - - assert_body "Hello world!" - assert_header "Content-Type", "application/rss+xml; charset=utf-8" - end - - test "setting the content type of the response as an option to render" do - get "/content_type/base/set_on_render" - - assert_body "Hello world!" - assert_header "Content-Type", "application/rss+xml; charset=utf-8" - end - end - - class ImpliedContentTypeTest < SimpleRouteCase - test "sets Content-Type as text/html when rendering *.html.erb" do - get "/content_type/implied/i_am_html_erb" - - assert_header "Content-Type", "text/html; charset=utf-8" - end - - test "sets Content-Type as application/xml when rendering *.xml.erb" do - get "/content_type/implied/i_am_xml_erb", "format" => "xml" - - assert_header "Content-Type", "application/xml; charset=utf-8" - end - - test "sets Content-Type as text/html when rendering *.html.builder" do - get "/content_type/implied/i_am_html_builder" - - assert_header "Content-Type", "text/html; charset=utf-8" - end - - test "sets Content-Type as application/xml when rendering *.xml.builder" do - get "/content_type/implied/i_am_xml_builder", "format" => "xml" - - assert_header "Content-Type", "application/xml; charset=utf-8" - end - end - - class ExplicitCharsetTest < SimpleRouteCase - test "setting the charset of the response directly on the response object" do - get "/content_type/charset/set_on_response_obj" - - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-16" - end - - test "setting the charset of the response as nil directly on the response object" do - get "/content_type/charset/set_as_nil_on_response_obj" - - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-8" - end - end -end diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/new_base/etag_test.rb deleted file mode 100644 index d5b7942ab6..0000000000 --- a/actionpack/test/new_base/etag_test.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'abstract_unit' - -module Etags - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "etags/basic/base.html.erb" => "Hello from without_layout.html.erb", - "layouts/etags.html.erb" => "teh <%= yield %> tagz" - )] - - def without_layout - render :action => "base" - end - - def with_layout - render :action => "base", :layout => "etags" - end - end - - class EtagTest < SimpleRouteCase - describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text" - - test "an action without a layout" do - get "/etags/basic/without_layout" - - body = "Hello from without_layout.html.erb" - assert_body body - assert_header "Etag", etag_for(body) - assert_status 200 - end - - test "an action with a layout" do - get "/etags/basic/with_layout" - - body = "teh Hello from without_layout.html.erb tagz" - assert_body body - assert_header "Etag", etag_for(body) - assert_status 200 - end - - private - - def etag_for(text) - %("#{Digest::MD5.hexdigest(text)}") - end - end -end diff --git a/actionpack/test/new_base/metal_test.rb b/actionpack/test/new_base/metal_test.rb deleted file mode 100644 index e1d46b906e..0000000000 --- a/actionpack/test/new_base/metal_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'abstract_unit' - -module MetalTest - class MetalMiddleware < ActionController::Middleware - def call(env) - if env["PATH_INFO"] =~ /authed/ - app.call(env) - else - [401, headers, "Not authed!"] - end - end - end - - class Endpoint - def call(env) - [200, {}, "Hello World"] - end - end - - class TestMiddleware < ActiveSupport::TestCase - def setup - @app = Rack::Builder.new do - use MetalMiddleware - run Endpoint.new - end.to_app - end - - test "it can call the next app by using @app" do - env = Rack::MockRequest.env_for("/authed") - response = @app.call(env) - - assert_equal "Hello World", response[2] - end - - test "it can return a response using the normal AC::Metal techniques" do - env = Rack::MockRequest.env_for("/") - response = @app.call(env) - - assert_equal "Not authed!", response[2] - assert_equal 401, response[0] - end - end -end diff --git a/actionpack/test/new_base/middleware_test.rb b/actionpack/test/new_base/middleware_test.rb deleted file mode 100644 index ada0215b1a..0000000000 --- a/actionpack/test/new_base/middleware_test.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'abstract_unit' - -module MiddlewareTest - class MyMiddleware - def initialize(app) - @app = app - end - - def call(env) - result = @app.call(env) - result[1]["Middleware-Test"] = "Success" - result[1]["Middleware-Order"] = "First" - result - end - end - - class ExclaimerMiddleware - def initialize(app) - @app = app - end - - def call(env) - result = @app.call(env) - result[1]["Middleware-Order"] << "!" - result - end - end - - class MyController < ActionController::Metal - use MyMiddleware - - middleware.insert_before MyMiddleware, ExclaimerMiddleware - - def index - self.response_body = "Hello World" - end - end - - class InheritedController < MyController - end - - module MiddlewareTests - extend ActiveSupport::Testing::Declarative - - test "middleware that is 'use'd is called as part of the Rack application" do - result = @app.call(env_for("/")) - assert_equal "Hello World", result[2] - assert_equal "Success", result[1]["Middleware-Test"] - end - - test "the middleware stack is exposed as 'middleware' in the controller" do - result = @app.call(env_for("/")) - assert_equal "First!", result[1]["Middleware-Order"] - end - end - - class TestMiddleware < ActiveSupport::TestCase - include MiddlewareTests - - def setup - @app = MyController.action(:index) - end - - def env_for(url) - Rack::MockRequest.env_for(url) - end - end - - class TestInheritedMiddleware < TestMiddleware - def setup - @app = InheritedController.action(:index) - end - - test "middleware inherits" do - end - end -end diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb deleted file mode 100644 index d5896c1ebd..0000000000 --- a/actionpack/test/new_base/render_action_test.rb +++ /dev/null @@ -1,320 +0,0 @@ -require 'abstract_unit' - -module RenderAction - # This has no layout and it works - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "render_action/basic/hello_world.html.erb" => "Hello world!" - )] - - def hello_world - render :action => "hello_world" - end - - def hello_world_as_string - render "hello_world" - end - - def hello_world_as_string_with_options - render "hello_world", :status => 404 - end - - def hello_world_as_symbol - render :hello_world - end - - def hello_world_with_symbol - render :action => :hello_world - end - - def hello_world_with_layout - render :action => "hello_world", :layout => true - end - - def hello_world_with_layout_false - render :action => "hello_world", :layout => false - end - - def hello_world_with_layout_nil - render :action => "hello_world", :layout => nil - end - - def hello_world_with_custom_layout - render :action => "hello_world", :layout => "greetings" - end - - end - - class RenderActionTest < SimpleRouteCase - test "rendering an action using :action => <String>" do - get "/render_action/basic/hello_world" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering an action using '<action>'" do - get "/render_action/basic/hello_world_as_string" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering an action using '<action>' and options" do - get "/render_action/basic/hello_world_as_string_with_options" - - assert_body "Hello world!" - assert_status 404 - end - - test "rendering an action using :action" do - get "/render_action/basic/hello_world_as_symbol" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering an action using :action => :hello_world" do - get "/render_action/basic/hello_world_with_symbol" - - assert_body "Hello world!" - assert_status 200 - end - end - - class RenderLayoutTest < SimpleRouteCase - describe "Both <controller_path>.html.erb and application.html.erb are missing" - - test "rendering with layout => true" do - assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do - get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false - end - end - - test "rendering with layout => false" do - get "/render_action/basic/hello_world_with_layout_false" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering with layout => :nil" do - get "/render_action/basic/hello_world_with_layout_nil" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering with layout => 'greetings'" do - assert_raise(ActionView::MissingTemplate) do - get "/render_action/basic/hello_world_with_custom_layout", {}, "action_dispatch.show_exceptions" => false - end - end - end -end - -module RenderActionWithApplicationLayout - # # ==== Render actions with layouts ==== - class BasicController < ::ApplicationController - # Set the view path to an application view structure with layouts - self.view_paths = self.view_paths = [ActionView::FixtureResolver.new( - "render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!", - "render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'", - "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", - "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai", - "layouts/builder.html.builder" => "xml.html do\n xml << yield\nend" - )] - - def hello_world - render :action => "hello_world" - end - - def hello_world_with_layout - render :action => "hello_world", :layout => true - end - - def hello_world_with_layout_false - render :action => "hello_world", :layout => false - end - - def hello_world_with_layout_nil - render :action => "hello_world", :layout => nil - end - - def hello_world_with_custom_layout - render :action => "hello_world", :layout => "greetings" - end - - def with_builder_and_layout - render :action => "hello", :layout => "builder" - end - end - - class LayoutTest < SimpleRouteCase - describe "Only application.html.erb is present and <controller_path>.html.erb is missing" - - test "rendering implicit application.html.erb as layout" do - get "/render_action_with_application_layout/basic/hello_world" - - assert_body "OHAI Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => true" do - get "/render_action_with_application_layout/basic/hello_world_with_layout" - - assert_body "OHAI Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => false" do - get "/render_action_with_application_layout/basic/hello_world_with_layout_false" - - assert_body "Hello World!" - assert_status 200 - end - - test "rendering with layout => :nil" do - get "/render_action_with_application_layout/basic/hello_world_with_layout_nil" - - assert_body "Hello World!" - assert_status 200 - end - - test "rendering with layout => 'greetings'" do - get "/render_action_with_application_layout/basic/hello_world_with_custom_layout" - - assert_body "Greetings Hello World! Bai" - assert_status 200 - end - end - - class TestLayout < SimpleRouteCase - testing BasicController - - test "builder works with layouts" do - get :with_builder_and_layout - assert_response "<html>\n<p>Omg</p>\n</html>\n" - end - end - -end - -module RenderActionWithControllerLayout - class BasicController < ActionController::Base - self.view_paths = self.view_paths = [ActionView::FixtureResolver.new( - "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", - "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" - )] - - def hello_world - render :action => "hello_world" - end - - def hello_world_with_layout - render :action => "hello_world", :layout => true - end - - def hello_world_with_layout_false - render :action => "hello_world", :layout => false - end - - def hello_world_with_layout_nil - render :action => "hello_world", :layout => nil - end - - def hello_world_with_custom_layout - render :action => "hello_world", :layout => "greetings" - end - end - - class ControllerLayoutTest < SimpleRouteCase - describe "Only <controller_path>.html.erb is present and application.html.erb is missing" - - test "render hello_world and implicitly use <controller_path>.html.erb as a layout." do - get "/render_action_with_controller_layout/basic/hello_world" - - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => true" do - get "/render_action_with_controller_layout/basic/hello_world_with_layout" - - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => false" do - get "/render_action_with_controller_layout/basic/hello_world_with_layout_false" - - assert_body "Hello World!" - assert_status 200 - end - - test "rendering with layout => :nil" do - get "/render_action_with_controller_layout/basic/hello_world_with_layout_nil" - - assert_body "Hello World!" - assert_status 200 - end - end -end - -module RenderActionWithBothLayouts - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new({ - "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", - "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", - "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" - })] - - def hello_world - render :action => "hello_world" - end - - def hello_world_with_layout - render :action => "hello_world", :layout => true - end - - def hello_world_with_layout_false - render :action => "hello_world", :layout => false - end - - def hello_world_with_layout_nil - render :action => "hello_world", :layout => nil - end - end - - class ControllerLayoutTest < SimpleRouteCase - describe "Both <controller_path>.html.erb and application.html.erb are present" - - test "rendering implicitly use <controller_path>.html.erb over application.html.erb as a layout" do - get "/render_action_with_both_layouts/basic/hello_world" - - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => true" do - get "/render_action_with_both_layouts/basic/hello_world_with_layout" - - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - test "rendering with layout => false" do - get "/render_action_with_both_layouts/basic/hello_world_with_layout_false" - - assert_body "Hello World!" - assert_status 200 - end - - test "rendering with layout => :nil" do - get "/render_action_with_both_layouts/basic/hello_world_with_layout_nil" - - assert_body "Hello World!" - assert_status 200 - end - end -end diff --git a/actionpack/test/new_base/render_file_test.rb b/actionpack/test/new_base/render_file_test.rb deleted file mode 100644 index c4098855e6..0000000000 --- a/actionpack/test/new_base/render_file_test.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'abstract_unit' - -module RenderFile - - class BasicController < ActionController::Base - self.view_paths = File.dirname(__FILE__) - - def index - render :file => File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world]) - end - - def with_instance_variables - @secret = 'in the sauce' - render :file => File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb') - end - - def without_file_key - render File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world]) - end - - def without_file_key_with_instance_variable - @secret = 'in the sauce' - render File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb') - end - - def relative_path - @secret = 'in the sauce' - render :file => '../fixtures/test/render_file_with_ivar' - end - - def relative_path_with_dot - @secret = 'in the sauce' - render :file => '../fixtures/test/dot.directory/render_file_with_ivar' - end - - def pathname - @secret = 'in the sauce' - render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. fixtures test dot.directory render_file_with_ivar.erb]) - end - - def 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 without_file_key_with_locals - path = File.expand_path('../fixtures/test/render_file_with_locals.erb') - render path, :locals => {:secret => 'in the sauce'} - end - end - - class TestBasic < SimpleRouteCase - testing RenderFile::BasicController - - def setup - @old_pwd = Dir.pwd - Dir.chdir(File.dirname(__FILE__)) - end - - def teardown - Dir.chdir(@old_pwd) - end - - test "rendering simple template" do - get :index - assert_response "Hello world!" - end - - test "rendering template with ivar" do - get :with_instance_variables - assert_response "The secret is in the sauce\n" - end - - test "rendering path without specifying the :file key" do - get :without_file_key - assert_response "Hello world!" - end - - test "rendering path without specifying the :file key with ivar" do - get :without_file_key_with_instance_variable - assert_response "The secret is in the sauce\n" - end - - test "rendering a relative path" do - get :relative_path - assert_response "The secret is in the sauce\n" - end - - test "rendering a relative path with dot" do - get :relative_path_with_dot - assert_response "The secret is in the sauce\n" - end - - test "rendering a Pathname" do - get :pathname - assert_response "The secret is in the sauce\n" - end - - test "rendering file with locals" do - get :with_locals - assert_response "The secret is in the sauce\n" - end - - test "rendering path without specifying the :file key with locals" do - get :without_file_key_with_locals - assert_response "The secret is in the sauce\n" - end - end - -end diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb deleted file mode 100644 index 2b78fa7d4f..0000000000 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'abstract_unit' - -module RenderImplicitAction - class SimpleController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", - "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" - )] - - def hello_world() end - end - - class RenderImplicitActionTest < SimpleRouteCase - test "render a simple action with new explicit call to render" do - get "/render_implicit_action/simple/hello_world" - - assert_body "Hello world!" - assert_status 200 - end - - test "render an action with a missing method and has special characters" do - get "/render_implicit_action/simple/hyphen-ated" - - assert_body "Hello hyphen-ated!" - assert_status 200 - end - end -end diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb deleted file mode 100644 index f840a47ecf..0000000000 --- a/actionpack/test/new_base/render_layout_test.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'abstract_unit' - -module ControllerLayouts - class ImplicitController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", - "layouts/override.html.erb" => "Override! <%= yield %>", - "basic.html.erb" => "Hello world!", - "controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)" - )] - - def index - render :template => "basic" - end - - def override - render :template => "basic", :layout => "override" - end - - def layout_false - render :layout => false - end - - def builder_override - end - end - - class ImplicitNameController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", - "basic.html.erb" => "Hello world!" - )] - - def index - render :template => "basic" - end - end - - class RenderLayoutTest < SimpleRouteCase - test "rendering a normal template, but using the implicit layout" do - get "/controller_layouts/implicit/index" - - assert_body "OMG Hello world! KTHXBAI" - assert_status 200 - end - - test "rendering a normal template, but using an implicit NAMED layout" do - get "/controller_layouts/implicit_name/index" - - assert_body "OMGIMPLICIT Hello world! KTHXBAI" - assert_status 200 - end - - test "overriding an implicit layout with render :layout option" do - get "/controller_layouts/implicit/override" - assert_body "Override! Hello world!" - end - - end - - class LayoutOptionsTest < SimpleRouteCase - testing ControllerLayouts::ImplicitController - - test "rendering with :layout => false leaves out the implicit layout" do - get :layout_false - assert_response "hai(layout_false.html.erb)" - end - end - - class MismatchFormatController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "layouts/application.html.erb" => "<html><%= yield %></html>", - "controller_layouts/mismatch_format/index.js.rjs" => "page[:test].omg", - "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].omg" - )] - - def explicit - render :layout => "application" - end - end - - class MismatchFormatTest < SimpleRouteCase - testing ControllerLayouts::MismatchFormatController - - test "if JS is selected, an HTML template is not also selected" do - get :index, "format" => "js" - assert_response "$(\"test\").omg();" - end - - test "if JS is implicitly selected, an HTML template is not also selected" do - get :implicit - assert_response "$(\"test\").omg();" - end - - test "if an HTML template is explicitly provides for a JS template, an error is raised" do - assert_raises ActionView::MissingTemplate do - get :explicit, {}, "action_dispatch.show_exceptions" => false - end - end - end -end diff --git a/actionpack/test/new_base/render_partial_test.rb b/actionpack/test/new_base/render_partial_test.rb deleted file mode 100644 index 7c2c20e1c7..0000000000 --- a/actionpack/test/new_base/render_partial_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'abstract_unit' - -module RenderPartial - - class BasicController < ActionController::Base - - self.view_paths = [ActionView::FixtureResolver.new( - "render_partial/basic/_basic.html.erb" => "OMG!", - "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>" - )] - - def changing - @test_unchanged = 'hello' - render :action => "basic" - end - end - - class TestPartial < SimpleRouteCase - testing BasicController - - test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do - get :changing - assert_response("goodbyeOMG!goodbye") - end - end - -end diff --git a/actionpack/test/new_base/render_rjs_test.rb b/actionpack/test/new_base/render_rjs_test.rb deleted file mode 100644 index 7b76c54ab9..0000000000 --- a/actionpack/test/new_base/render_rjs_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'abstract_unit' - -module RenderRjs - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "render_rjs/basic/index.js.rjs" => "page[:customer].replace_html render(:partial => 'customer')", - "render_rjs/basic/index_html.js.rjs" => "page[:customer].replace_html :partial => 'customer'", - "render_rjs/basic/_customer.js.erb" => "JS Partial", - "render_rjs/basic/_customer.html.erb" => "HTML Partial", - "render_rjs/basic/index_locale.js.rjs" => "page[:customer].replace_html :partial => 'customer'", - "render_rjs/basic/_customer.da.html.erb" => "Danish HTML Partial", - "render_rjs/basic/_customer.da.js.erb" => "Danish JS Partial" - )] - - def index - render - end - - def index_locale - old_locale, I18n.locale = I18n.locale, :da - end - end - - class TestBasic < SimpleRouteCase - testing BasicController - - def setup - @old_locale = I18n.locale - end - - def teardown - I18n.locale = @old_locale - end - - test "rendering a partial in an RJS template should pick the JS template over the HTML one" do - get :index, "format" => "js" - assert_response("$(\"customer\").update(\"JS Partial\");") - end - - test "replacing an element with a partial in an RJS template should pick the HTML template over the JS one" do - get :index_html, "format" => "js" - assert_response("$(\"customer\").update(\"HTML Partial\");") - end - - test "replacing an element with a partial in an RJS template with a locale should pick the localed HTML template" do - get :index_locale, "format" => "js" - assert_response("$(\"customer\").update(\"Danish HTML Partial\");") - end - end -end diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb deleted file mode 100644 index 3b24c2d75a..0000000000 --- a/actionpack/test/new_base/render_template_test.rb +++ /dev/null @@ -1,170 +0,0 @@ -require 'abstract_unit' - -module RenderTemplate - class WithoutLayoutController < ActionController::Base - - self.view_paths = [ActionView::FixtureResolver.new( - "test/basic.html.erb" => "Hello from basic.html.erb", - "shared.html.erb" => "Elastica", - "locals.html.erb" => "The secret is <%= secret %>", - "xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend" - )] - - def index - render :template => "test/basic" - end - - def index_without_key - render "test/basic" - end - - def in_top_directory - render :template => 'shared' - end - - def in_top_directory_with_slash - render :template => '/shared' - end - - def in_top_directory_with_slash_without_key - render '/shared' - end - - def with_locals - render :template => "locals", :locals => { :secret => 'area51' } - end - - def builder_template - render :template => "xml_template" - end - end - - class TestWithoutLayout < SimpleRouteCase - testing RenderTemplate::WithoutLayoutController - - test "rendering a normal template with full path without layout" do - get :index - assert_response "Hello from basic.html.erb" - end - - test "rendering a normal template with full path without layout without key" do - get :index_without_key - assert_response "Hello from basic.html.erb" - end - - test "rendering a template not in a subdirectory" do - get :in_top_directory - assert_response "Elastica" - end - - test "rendering a template not in a subdirectory with a leading slash" do - get :in_top_directory_with_slash - assert_response "Elastica" - end - - test "rendering a template not in a subdirectory with a leading slash without key" do - get :in_top_directory_with_slash_without_key - assert_response "Elastica" - end - - test "rendering a template with local variables" do - get :with_locals - assert_response "The secret is area51" - end - - test "rendering a builder template" do - get :builder_template, "format" => "xml" - assert_response "<html>\n <p>Hello</p>\n</html>\n" - end - end - - class WithLayoutController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "test/basic.html.erb" => "Hello from basic.html.erb", - "shared.html.erb" => "Elastica", - "layouts/application.html.erb" => "<%= yield %>, I'm here!", - "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." - )] - - def index - render :template => "test/basic" - end - - def with_layout - render :template => "test/basic", :layout => true - end - - def with_layout_false - render :template => "test/basic", :layout => false - end - - def with_layout_nil - render :template => "test/basic", :layout => nil - end - - def with_custom_layout - render :template => "test/basic", :layout => "greetings" - end - end - - class TestWithLayout < SimpleRouteCase - describe "Rendering with :template using implicit or explicit layout" - - test "rendering with implicit layout" do - get "/render_template/with_layout" - - assert_body "Hello from basic.html.erb, I'm here!" - assert_status 200 - end - - test "rendering with layout => :true" do - get "/render_template/with_layout/with_layout" - - assert_body "Hello from basic.html.erb, I'm here!" - assert_status 200 - end - - test "rendering with layout => :false" do - get "/render_template/with_layout/with_layout_false" - - assert_body "Hello from basic.html.erb" - assert_status 200 - end - - test "rendering with layout => :nil" do - get "/render_template/with_layout/with_layout_nil" - - assert_body "Hello from basic.html.erb" - assert_status 200 - end - - test "rendering layout => 'greetings'" do - get "/render_template/with_layout/with_custom_layout" - - assert_body "Hello from basic.html.erb, I wish thee well." - assert_status 200 - end - end - - module Compatibility - class WithoutLayoutController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "test/basic.html.erb" => "Hello from basic.html.erb", - "shared.html.erb" => "Elastica" - )] - - def with_forward_slash - render :template => "/test/basic" - end - end - - class TestTemplateRenderWithForwardSlash < SimpleRouteCase - test "rendering a normal template with full path starting with a leading slash" do - get "/render_template/compatibility/without_layout/with_forward_slash" - - assert_body "Hello from basic.html.erb" - assert_status 200 - end - end - end -end diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb deleted file mode 100644 index 804be79d17..0000000000 --- a/actionpack/test/new_base/render_test.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'abstract_unit' - -module Render - class BlankRenderController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "render/blank_render/index.html.erb" => "Hello world!", - "render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>", - "render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>", - "render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>" - )] - - def index - render - end - - def access_request - render :action => "access_request" - end - - def render_action_name - render :action => "access_action_name" - end - - private - - def secretz - render :text => "FAIL WHALE!" - end - end - - class DoubleRenderController < ActionController::Base - def index - render :text => "hello" - render :text => "world" - end - end - - class RenderTest < SimpleRouteCase - test "render with blank" do - get "/render/blank_render" - - assert_body "Hello world!" - assert_status 200 - end - - test "rendering more than once raises an exception" do - assert_raises(AbstractController::DoubleRenderError) do - get "/render/double_render", {}, "action_dispatch.show_exceptions" => false - end - end - end - - class TestOnlyRenderPublicActions < SimpleRouteCase - describe "Only public methods on actual controllers are callable actions" - - test "raises an exception when a method of Object is called" do - assert_raises(AbstractController::ActionNotFound) do - get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false - end - end - - test "raises an exception when a private method is called" do - assert_raises(AbstractController::ActionNotFound) do - get "/render/blank_render/secretz", {}, "action_dispatch.show_exceptions" => false - end - end - end - - class TestVariousObjectsAvailableInView < SimpleRouteCase - test "The request object is accessible in the view" do - get "/render/blank_render/access_request" - assert_body "The request: GET" - end - - test "The action_name is accessible in the view" do - get "/render/blank_render/render_action_name" - assert_body "Action Name: render_action_name" - end - - test "The controller_name is accessible in the view" do - get "/render/blank_render/access_controller_name" - assert_body "Controller Name: blank_render" - end - end -end diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb deleted file mode 100644 index f5839ee16f..0000000000 --- a/actionpack/test/new_base/render_text_test.rb +++ /dev/null @@ -1,137 +0,0 @@ -require 'abstract_unit' - -module RenderText - class SimpleController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new] - - def index - render :text => "hello david" - end - end - - class WithLayoutController < ::ApplicationController - self.view_paths = [ActionView::FixtureResolver.new( - "layouts/application.html.erb" => "<%= yield %>, I'm here!", - "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.", - "layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>" - )] - - def index - render :text => "hello david" - end - - def custom_code - render :text => "hello world", :status => 404 - end - - def with_custom_code_as_string - render :text => "hello world", :status => "404 Not Found" - end - - def with_nil - render :text => nil - end - - def with_nil_and_status - render :text => nil, :status => 403 - end - - def with_false - render :text => false - end - - def with_layout_true - render :text => "hello world", :layout => true - end - - def with_layout_false - render :text => "hello world", :layout => false - end - - def with_layout_nil - render :text => "hello world", :layout => nil - end - - def with_custom_layout - render :text => "hello world", :layout => "greetings" - end - - def with_ivar_in_layout - @ivar = "hello world" - render :text => "hello world", :layout => "ivar" - end - end - - class RenderTextTest < SimpleRouteCase - describe "Rendering text using render :text" - - test "rendering text from a action with default options renders the text with the layout" do - get "/render_text/simple" - assert_body "hello david" - assert_status 200 - end - - test "rendering text from a action with default options renders the text without the layout" do - get "/render_text/with_layout" - - assert_body "hello david" - assert_status 200 - end - - test "rendering text, while also providing a custom status code" do - get "/render_text/with_layout/custom_code" - - assert_body "hello world" - assert_status 404 - end - - test "rendering text with nil returns an empty body padded for Safari" do - get "/render_text/with_layout/with_nil" - - assert_body " " - assert_status 200 - end - - test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do - get "/render_text/with_layout/with_nil_and_status" - - assert_body " " - assert_status 403 - end - - test "rendering text with false returns the string 'false'" do - get "/render_text/with_layout/with_false" - - assert_body "false" - assert_status 200 - end - - test "rendering text with :layout => true" do - get "/render_text/with_layout/with_layout_true" - - assert_body "hello world, I'm here!" - assert_status 200 - end - - test "rendering text with :layout => 'greetings'" do - get "/render_text/with_layout/with_custom_layout" - - assert_body "hello world, I wish thee well." - assert_status 200 - end - - test "rendering text with :layout => false" do - get "/render_text/with_layout/with_layout_false" - - assert_body "hello world" - assert_status 200 - end - - test "rendering text with :layout => nil" do - get "/render_text/with_layout/with_layout_nil" - - assert_body "hello world" - assert_status 200 - end - end -end diff --git a/actionpack/test/new_base/render_xml_test.rb b/actionpack/test/new_base/render_xml_test.rb deleted file mode 100644 index d044738a78..0000000000 --- a/actionpack/test/new_base/render_xml_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'abstract_unit' - -module RenderXml - - # This has no layout and it works - class BasicController < ActionController::Base - self.view_paths = [ActionView::FixtureResolver.new( - "render_xml/basic/with_render_erb" => "Hello world!" - )] - end -end diff --git a/actionpack/test/template/ajax_test.rb b/actionpack/test/template/ajax_test.rb new file mode 100644 index 0000000000..670ba92697 --- /dev/null +++ b/actionpack/test/template/ajax_test.rb @@ -0,0 +1,114 @@ +require "abstract_unit" + +class AjaxTestCase < ActiveSupport::TestCase + include ActionView::Helpers::AjaxHelper + include ActionView::Helpers::TagHelper + + def assert_html(html, matches) + matches.each do |match| + assert_match Regexp.new(Regexp.escape(match)), html + end + end + + def self.assert_callbacks_work(&blk) + define_method(:assert_callbacks_work, &blk) + + [:complete, :failure, :success, :interactive, :loaded, :loading, 404].each do |callback| + test "#{callback} callback" do + markup = assert_callbacks_work(callback) + assert_html markup, %W(data-#{callback}-code="undoRequestCompleted\(request\)") + end + end + end +end + +class LinkToRemoteTest < AjaxTestCase + def url_for(hash) + "/blog/destroy/4" + end + + def link(options = {}) + link_to_remote("Delete this post", "/blog/destroy/3", options) + end + + test "with no update" do + assert_html link, %w(href="/blog/destroy/4" Delete\ this\ post data-remote="true") + end + + test "basic" do + assert_html link(:update => "#posts"), + %w(data-update-success="#posts") + end + + test "using a url hash" do + link = link_to_remote("Delete this post", {:controller => :blog}, :update => "#posts") + assert_html link, %w(href="/blog/destroy/4" data-update-success="#posts") + end + + test "with :html options" do + expected = %{<a href="/blog/destroy/4" data-custom="me" data-remote="true" data-update-success="#posts">Delete this post</a>} + assert_equal expected, link(:update => "#posts", :html => {"data-custom" => "me"}) + end + + test "with a hash for :update" do + link = link(:update => {:success => "#posts", :failure => "#error"}) + assert_match /data-update-success="#posts"/, link + assert_match /data-update-failure="#error"/, link + end + + test "with positional parameters" do + link = link(:position => :top, :update => "#posts") + assert_match /data\-update\-position="top"/, link + end + + test "with an optional method" do + link = link(:method => "delete") + assert_match /data-method="delete"/, link + end + + class LegacyLinkToRemoteTest < AjaxTestCase + include ActionView::Helpers::AjaxHelper::Rails2Compatibility + + def link(options) + link_to_remote("Delete this post", "/blog/destroy/3", options) + end + + test "basic link_to_remote with :url =>" do + expected = %{<a href="/blog/destroy/3" data-remote="true" data-update-success="#posts">Delete this post</a>} + assert_equal expected, + link_to_remote("Delete this post", :url => "/blog/destroy/3", :update => "#posts") + end + + assert_callbacks_work do |callback| + link(callback => "undoRequestCompleted(request)") + end + end +end + +class ButtonToRemoteTest < AjaxTestCase + def button(options, html = {}) + button_to_remote("Remote outpost", options, html) + end + + def url_for(*) + "/whatnot" + end + + class StandardTest < ButtonToRemoteTest + test "basic" do + button = button({:url => {:action => "whatnot"}}, {:class => "fine"}) + [/input/, /class="fine"/, /type="button"/, /value="Remote outpost"/, + /data-url="\/whatnot"/].each do |match| + assert_match match, button + end + end + end + + class LegacyButtonToRemoteTest < ButtonToRemoteTest + include ActionView::Helpers::AjaxHelper::Rails2Compatibility + + assert_callbacks_work do |callback| + button(callback => "undoRequestCompleted(request)") + end + end +end diff --git a/actionpack/test/template/html-scanner/cdata_node_test.rb b/actionpack/test/template/html-scanner/cdata_node_test.rb new file mode 100644 index 0000000000..1822cc565a --- /dev/null +++ b/actionpack/test/template/html-scanner/cdata_node_test.rb @@ -0,0 +1,15 @@ +require 'abstract_unit' + +class CDATANodeTest < Test::Unit::TestCase + def setup + @node = HTML::CDATA.new(nil, 0, 0, "<p>howdy</p>") + end + + def test_to_s + assert_equal "<![CDATA[<p>howdy</p>]]>", @node.to_s + end + + def test_content + assert_equal "<p>howdy</p>", @node.content + end +end diff --git a/actionpack/test/template/html-scanner/document_test.rb b/actionpack/test/template/html-scanner/document_test.rb new file mode 100644 index 0000000000..c68f04fa75 --- /dev/null +++ b/actionpack/test/template/html-scanner/document_test.rb @@ -0,0 +1,148 @@ +require 'abstract_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 + + def test_parse_invalid_document + assert_nothing_raised do + doc = HTML::Document.new("<html> + <table> + <tr> + <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td> + </tr> + </table> + </html>") + end + end + + def test_invalid_document_raises_exception_when_strict + assert_raise RuntimeError do + doc = HTML::Document.new("<html> + <table> + <tr> + <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td> + </tr> + </table> + </html>", true) + end + end + +end diff --git a/actionpack/test/template/html-scanner/node_test.rb b/actionpack/test/template/html-scanner/node_test.rb new file mode 100644 index 0000000000..b0df36877e --- /dev/null +++ b/actionpack/test/template/html-scanner/node_test.rb @@ -0,0 +1,89 @@ +require 'abstract_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 + + def test_parse_with_valid_cdata_section + s = "<![CDATA[<span>contents</span>]]>" + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert_kind_of HTML::CDATA, node + assert_equal '<span>contents</span>', node.content + end + + def test_parse_strict_with_unterminated_cdata_section + s = "<![CDATA[neverending..." + assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) } + end + + def test_parse_relaxed_with_unterminated_cdata_section + s = "<![CDATA[neverending..." + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert_kind_of HTML::CDATA, node + assert_equal 'neverending...', node.content + end +end diff --git a/actionpack/test/template/html-scanner/sanitizer_test.rb b/actionpack/test/template/html-scanner/sanitizer_test.rb new file mode 100644 index 0000000000..e85a5c7abf --- /dev/null +++ b/actionpack/test/template/html-scanner/sanitizer_test.rb @@ -0,0 +1,273 @@ +require 'abstract_unit' + +class SanitizerTest < ActionController::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.") + assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.") + assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...") + [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_with_trailing_space + raw = "display:block; " + expected = "display: block;" + 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 + + def test_should_sanitize_cdata_section + assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>" + end + + def test_should_sanitize_unterminated_cdata_section + assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>" + end + + def test_should_not_mangle_urls_with_ampersand + assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>} + end + +protected + def assert_sanitized(input, expected = nil) + @sanitizer ||= HTML::WhiteListSanitizer.new + if input + assert_dom_equal expected || input, @sanitizer.sanitize(input) + else + assert_nil @sanitizer.sanitize(input) + end + end + + def sanitize_css(input) + (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input) + end +end diff --git a/actionpack/test/template/html-scanner/tag_node_test.rb b/actionpack/test/template/html-scanner/tag_node_test.rb new file mode 100644 index 0000000000..d1d4667378 --- /dev/null +++ b/actionpack/test/template/html-scanner/tag_node_test.rb @@ -0,0 +1,238 @@ +require 'abstract_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/actionpack/test/template/html-scanner/text_node_test.rb b/actionpack/test/template/html-scanner/text_node_test.rb new file mode 100644 index 0000000000..1ab3f4454e --- /dev/null +++ b/actionpack/test/template/html-scanner/text_node_test.rb @@ -0,0 +1,50 @@ +require 'abstract_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 diff --git a/actionpack/test/template/html-scanner/tokenizer_test.rb b/actionpack/test/template/html-scanner/tokenizer_test.rb new file mode 100644 index 0000000000..a001bcbbad --- /dev/null +++ b/actionpack/test/template/html-scanner/tokenizer_test.rb @@ -0,0 +1,131 @@ +require 'abstract_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_unterminated_cdata_tag + tokenize %{<content:encoded><![CDATA[ neverending...} + assert_next %{<content:encoded>} + assert_next %{<![CDATA[ neverending...} + 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/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb new file mode 100644 index 0000000000..5db42c4d68 --- /dev/null +++ b/actionpack/test/template/test_case_test.rb @@ -0,0 +1,172 @@ +require 'abstract_unit' +require 'controller/fake_controllers' + +module ActionView + class TestCase + module ATestHelper + end + + module AnotherTestHelper + def from_another_helper + 'Howdy!' + end + end + + module ASharedTestHelper + def from_shared_helper + 'Holla!' + end + end + helper ASharedTestHelper + + module SharedTests + def self.included(test_case) + test_case.class_eval do + test "helpers defined on ActionView::TestCase are available" do + assert test_case.ancestors.include?(ASharedTestHelper) + assert 'Holla!', from_shared_helper + end + end + end + end + + class GeneralViewTest < ActionView::TestCase + include SharedTests + test_case = self + + test "works without testing a helper module" do + assert_equal 'Eloy', render('developers/developer', :developer => stub(:name => 'Eloy')) + end + + helper AnotherTestHelper + test "additional helper classes can be specified as in a controller" do + assert test_case.ancestors.include?(AnotherTestHelper) + assert 'Howdy!', from_another_helper + end + end + + class ClassMethodsTest < ActionView::TestCase + include SharedTests + test_case = self + + tests ATestHelper + test "tests the specified helper module" do + assert_equal ATestHelper, test_case.helper_class + assert test_case.ancestors.include?(ATestHelper) + end + + helper AnotherTestHelper + test "additional helper classes can be specified as in a controller" do + assert test_case.ancestors.include?(AnotherTestHelper) + assert 'Howdy!', from_another_helper + + test_case.helper_class.module_eval do + def render_from_helper + from_another_helper + end + end + assert 'Howdy!', render(:partial => 'test/from_helper') + end + end + + class ATestHelperTest < ActionView::TestCase + include SharedTests + test_case = self + + test "inflects the name of the helper module to test from the test case class" do + assert_equal ATestHelper, test_case.helper_class + assert test_case.ancestors.include?(ATestHelper) + end + + test "a configured test controller is available" do + assert_kind_of ActionController::Base, controller + assert_equal '', controller.controller_path + end + + test "helper class that is being tested is always included in view instance" do + self.class.helper_class.module_eval do + def render_from_helper + render :partial => 'customer', :collection => @customers + end + end + + TestController.stubs(:controller_path).returns('test') + + @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] + assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') + end + + test "no additional helpers should shared across test cases" do + assert !test_case.ancestors.include?(AnotherTestHelper) + assert_raise(NoMethodError) { send :from_another_helper } + end + + test "is able to use routes" do + controller.request.assign_parameters('foo', 'index') + assert_equal '/foo', url_for + assert_equal '/bar', url_for(:controller => 'bar') + end + + test "is able to use named routes" do + with_routing do |set| + set.draw { |map| map.resources :contents } + assert_equal 'http://test.host/contents/new', new_content_url + assert_equal 'http://test.host/contents/1', content_url(:id => 1) + end + end + + test "named routes can be used from helper included in view" do + with_routing do |set| + set.draw { |map| map.resources :contents } + _helpers.module_eval do + def render_from_helper + new_content_url + end + end + + assert_equal 'http://test.host/contents/new', render(:partial => 'test/from_helper') + end + end + + test "is able to render partials with local variables" do + assert_equal 'Eloy', render('developers/developer', :developer => stub(:name => 'Eloy')) + assert_equal 'Eloy', render(:partial => 'developers/developer', + :locals => { :developer => stub(:name => 'Eloy') }) + end + + test "is able to render partials from templates and also use instance variables" do + TestController.stubs(:controller_path).returns('test') + + @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] + assert_match /Hello: EloyHello: Manfred/, render(:file => 'test/list') + end + + test "is able to make methods available to the view" do + _helpers.module_eval do + def render_from_helper; from_test_case end + end + assert_equal 'Word!', render(:partial => 'test/from_helper') + end + + def from_test_case; 'Word!'; end + helper_method :from_test_case + end + + class AssertionsTest < ActionView::TestCase + def render_from_helper + form_tag('/foo') do + concat render(:text => '<ul><li>foo</li></ul>') + end + end + helper_method :render_from_helper + + test "uses the output_buffer for assert_select" do + render(:partial => 'test/from_helper') + + assert_select 'form' do + assert_select 'li', :text => 'foo' + end + end + end + end +end diff --git a/actionpack/test/view/test_case_test.rb b/actionpack/test/view/test_case_test.rb deleted file mode 100644 index 5db42c4d68..0000000000 --- a/actionpack/test/view/test_case_test.rb +++ /dev/null @@ -1,172 +0,0 @@ -require 'abstract_unit' -require 'controller/fake_controllers' - -module ActionView - class TestCase - module ATestHelper - end - - module AnotherTestHelper - def from_another_helper - 'Howdy!' - end - end - - module ASharedTestHelper - def from_shared_helper - 'Holla!' - end - end - helper ASharedTestHelper - - module SharedTests - def self.included(test_case) - test_case.class_eval do - test "helpers defined on ActionView::TestCase are available" do - assert test_case.ancestors.include?(ASharedTestHelper) - assert 'Holla!', from_shared_helper - end - end - end - end - - class GeneralViewTest < ActionView::TestCase - include SharedTests - test_case = self - - test "works without testing a helper module" do - assert_equal 'Eloy', render('developers/developer', :developer => stub(:name => 'Eloy')) - end - - helper AnotherTestHelper - test "additional helper classes can be specified as in a controller" do - assert test_case.ancestors.include?(AnotherTestHelper) - assert 'Howdy!', from_another_helper - end - end - - class ClassMethodsTest < ActionView::TestCase - include SharedTests - test_case = self - - tests ATestHelper - test "tests the specified helper module" do - assert_equal ATestHelper, test_case.helper_class - assert test_case.ancestors.include?(ATestHelper) - end - - helper AnotherTestHelper - test "additional helper classes can be specified as in a controller" do - assert test_case.ancestors.include?(AnotherTestHelper) - assert 'Howdy!', from_another_helper - - test_case.helper_class.module_eval do - def render_from_helper - from_another_helper - end - end - assert 'Howdy!', render(:partial => 'test/from_helper') - end - end - - class ATestHelperTest < ActionView::TestCase - include SharedTests - test_case = self - - test "inflects the name of the helper module to test from the test case class" do - assert_equal ATestHelper, test_case.helper_class - assert test_case.ancestors.include?(ATestHelper) - end - - test "a configured test controller is available" do - assert_kind_of ActionController::Base, controller - assert_equal '', controller.controller_path - end - - test "helper class that is being tested is always included in view instance" do - self.class.helper_class.module_eval do - def render_from_helper - render :partial => 'customer', :collection => @customers - end - end - - TestController.stubs(:controller_path).returns('test') - - @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] - assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') - end - - test "no additional helpers should shared across test cases" do - assert !test_case.ancestors.include?(AnotherTestHelper) - assert_raise(NoMethodError) { send :from_another_helper } - end - - test "is able to use routes" do - controller.request.assign_parameters('foo', 'index') - assert_equal '/foo', url_for - assert_equal '/bar', url_for(:controller => 'bar') - end - - test "is able to use named routes" do - with_routing do |set| - set.draw { |map| map.resources :contents } - assert_equal 'http://test.host/contents/new', new_content_url - assert_equal 'http://test.host/contents/1', content_url(:id => 1) - end - end - - test "named routes can be used from helper included in view" do - with_routing do |set| - set.draw { |map| map.resources :contents } - _helpers.module_eval do - def render_from_helper - new_content_url - end - end - - assert_equal 'http://test.host/contents/new', render(:partial => 'test/from_helper') - end - end - - test "is able to render partials with local variables" do - assert_equal 'Eloy', render('developers/developer', :developer => stub(:name => 'Eloy')) - assert_equal 'Eloy', render(:partial => 'developers/developer', - :locals => { :developer => stub(:name => 'Eloy') }) - end - - test "is able to render partials from templates and also use instance variables" do - TestController.stubs(:controller_path).returns('test') - - @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] - assert_match /Hello: EloyHello: Manfred/, render(:file => 'test/list') - end - - test "is able to make methods available to the view" do - _helpers.module_eval do - def render_from_helper; from_test_case end - end - assert_equal 'Word!', render(:partial => 'test/from_helper') - end - - def from_test_case; 'Word!'; end - helper_method :from_test_case - end - - class AssertionsTest < ActionView::TestCase - def render_from_helper - form_tag('/foo') do - concat render(:text => '<ul><li>foo</li></ul>') - end - end - helper_method :render_from_helper - - test "uses the output_buffer for assert_select" do - render(:partial => 'test/from_helper') - - assert_select 'form' do - assert_select 'li', :text => 'foo' - end - end - end - end -end -- cgit v1.2.3