require File.join(File.dirname(__FILE__), "test_helper")
class SelectFormTest < Test::Unit::TestCase
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::TagHelper
def setup
@controller = TestController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_select_form
render_html %Q{
}
assert_select "form#?", "test"
form = select_form "test"
assert_equal FormTestHelper::Form, form.class
assert_raise(Test::Unit::AssertionFailedError) do
select_form 'nonexistent'
end
end
def test_select_form_when_enclosed
render_html %Q{}
select_form "test"
end
def test_select_form_by_action
render_html %Q{}
select_form "/test"
end
def test_select_only_form
render_html %Q{}
select_form
render_html %Q{}
assert_raise(Test::Unit::AssertionFailedError) { select_form }
end
def test_selected_form_submits_to_action
render_rhtml %Q{<%= form_tag({:action => 'create'}) + submit_tag + "" %>}
form = select_form "/test/create"
form.submit
assert_action_name :create
assert_equal :post, @request.method
end
def test_selected_form_submits_to_self_when_no_action
render_html %Q{}
form = select_form "self"
@controller.response_with = "Form submitted."
form.submit_without_clicking_button
assert_action_name :html
assert_equal "Form submitted.", @response.body
assert_equal :get, @request.method # Firefox uses GET when no method specified
end
def test_selected_form_submits_with_restful_request_method
render_rhtml %Q{<%= form_tag({:action => "destroy"}, {:method => :delete}) %>}
form = select_form "/test/destroy"
form.submit_without_clicking_button
assert_response :success
assert_action_name :destroy
assert_equal :delete, @request.method
end
def test_submit_to_another_controller
render_rhtml <<-EOD
<%= form_tag(:controller => 'other') %>
<%= submit_tag %>
EOD
select_form.submit
end
def test_form_has_fields_hash
render_rhtml <<-EOD
<%= form_tag %>
<%= text_field_tag "person[address][city]", "Anytown" %>
EOD
form = select_form
assert_not_nil form.fields_hash
assert_kind_of FormTestHelper::FieldsHash, form.fields_hash[:person]
assert_equal form.fields_hash[:person], form.fields_hash["person"]
assert_kind_of FormTestHelper::FieldsHash, form.fields_hash[:person][:address]
assert_equal "Anytown", form.fields_hash[:person][:address][:city].value
assert_kind_of FormTestHelper::Field, form.fields_hash[:person][:address][:city]
end
def test_fields_accessible_by_methods_on_form
render_rhtml <<-EOD
<%= form_tag %>
<%= text_field_tag "person[address][city]", "Anytown" %>
EOD
form = select_form
assert_not_nil form.fields_hash
assert_kind_of FormTestHelper::FieldsHash, form.person
assert_kind_of FormTestHelper::FieldsHash, form.person.address
assert_equal "Anytown", form.person.address.city
assert_kind_of String, form.person.address.city
form.person.address.city = 'Managua'
assert_raise(FormTestHelper::FieldsHash::FieldNotFoundError) { form.person.name }
end
def test_fields_accessible_by_methods_on_form_act_as_proxy
render_rhtml <<-EOD
<%= form_tag %>
<%= text_field_tag "person[address][city]" %>
<%= select_tag 'number[]', %q{}, :multiple => true %>
EOD
form = select_form
assert_kind_of String, form.person.address.city
assert_nothing_raised { form.person.address.city.tag }
assert_kind_of Array, form.number
assert_nothing_raised { form.number.tag }
end
def test_reset_form
render_rhtml <<-EOD
<%= form_tag %>
<%= text_field_tag "text", "1" %>
EOD
form = select_form
form['text'] = '2'
assert_equal '2', form['text'].value
form.reset
assert_equal '1', form['text'].value
end
def test_reset_field
render_rhtml <<-EOD
<%= form_tag %>
<%= check_box_tag "checkbox", "1", false %>
<%= text_field_tag "text", "0" %>
EOD
form = select_form
form['text'] = '1'
form['checkbox'] = '1'
assert_equal '1', form['text'].value
assert_equal '1', form['checkbox'].value
form['text'].reset
assert_equal '0', form['text'].value
assert_equal '1', form['checkbox'].value
end
def test_field_passes_methods_to_tag
render_rhtml <<-EOD
<%= form_tag %>
<%= text_field_tag "name", "Jason", :class => 'field' %>
EOD
form = select_form
assert_equal "field", form['name'].attributes['class']
end
def test_fields
render_rhtml <<-EOD
<%= form_tag %>
<%= text_area_tag "textarea", "value" %>
<%= text_field_tag "text", "value" %>
<%= select_tag "people", "" %>
EOD
form = select_form
assert_equal 4, form.fields.size
end
def test_missing_field
render_rhtml <<-EOD
<%= form_tag %>
EOD
assert_raise(FormTestHelper::Form::FieldNotFoundError) { select_form['username'] }
assert_raise(FormTestHelper::Form::FieldNotFoundError) { select_form.username }
end
def test_missing_field_when_updating_value
render_rhtml <<-EOD
<%= form_tag %>
EOD
assert_raise(FormTestHelper::Form::FieldNotFoundError) { select_form['username'] = 'bob' }
assert_raise(FormTestHelper::Form::FieldNotFoundError) { select_form.username = 'bob' }
end
def test_submit
value = "jason"
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "#{value}" %>
<%= submit_tag %>
EOD
form = select_form
form.submit
assert_response :success
assert_equal value, @controller.params[:username]
assert_equal({"commit"=>"Save changes", "username"=>value, "action"=>"create", "controller"=>@controller.controller_name}, @controller.params)
end
def test_submit_to_namespaced_controller
@controller = Admin::NamespacedController.new
value = "jason"
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "#{value}" %>
<%= submit_tag %>
EOD
submit_form
assert_response :success
assert_equal value, @controller.params[:username]
end
def test_submit_requires_submit_tag
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "jason" %>
EOD
assert_raise(FormTestHelper::Form::MissingSubmitError) { submit_form }
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
EOD
assert_nothing_raised { submit_form }
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
EOD
assert_nothing_raised { submit_form }
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= image_submit_tag 'image.png' %>
EOD
assert_nothing_raised { submit_form }
end
def test_submit_accepts_and_updates_field_values
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "jason" %>
<%= text_field_tag "account[status]", "closed" %>
<%= submit_tag %>
EOD
form = select_form
new_value = 'brent'
form.submit :username => new_value
assert_response :success
assert_equal new_value, @controller.params[:username]
form.submit :account => {:status => 'open'}
assert_response :success
assert_equal 'open', @controller.params[:account][:status]
end
def render_for_xhr
render_rhtml <<-EOD
<% form_remote_tag :url => {:action => 'create'} do -%>
<%= text_field_tag "username", "jason" %>
<%= submit_tag %>
<% end -%>
EOD
end
def check_xhr_responses(new_value)
assert_response :success
assert_match 'xhr', @response.body
assert_equal new_value, @controller.params[:username]
end
def test_submit_by_xhr
render_for_xhr
form = select_form
new_value = 'brent'
form.submit :username => new_value, :xhr => true
check_xhr_responses new_value
end
def test_submit_by_xhr_using_a_block
render_for_xhr
new_value = 'brent'
submit_form :xhr => true do | form |
form['username'] = new_value
end
check_xhr_responses new_value
end
def test_accessing_simple_field_by_method_call
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "jason" %>
<%= submit_tag %>
EOD
new_value = 'brent'
submit_form do |form|
assert_equal 'jason', form.username
form.username = new_value
end
assert_response :success
assert_equal new_value, @controller.params[:username]
end
def test_accessing_deep_field_by_method_call
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "user[username]", "jason" %>
<%= submit_tag %>
EOD
new_value = 'brent'
submit_form do |form|
assert_equal 'jason', form.user.username
form.user.username = new_value
end
assert_response :success
assert_equal new_value, @controller.params[:user][:username]
end
def test_with_object
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field :book, :name %>
<%= select :book, :category, [['Mining', 1], ['Programming', 2]] %>
<%= check_box :book, :classic %>
<%= submit_tag %>
EOD
submit_form do |form|
form.with_object(:book) do |book|
book.name = 'Pickaxe'
book.category = 'Programming'
book.classic.check
end
end
assert_response :success
assert_equal 'Pickaxe', @controller.params[:book][:name]
end
def test_updating_fields_with_hash
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field :book, :name %>
<%= select :book, :category, [['Mining', 1], ['Programming', 2]] %>
<%= check_box :book, :classic %>
<%= submit_tag %>
EOD
new_book = {
:name => 'Pickaxe',
:category => '2', # Could assign "Programming", but then it won't equal 2 in the params.
:classic => '1'
}
submit_form do |form|
form.book.update(new_book)
end
assert_response :success
new_book.each do |attribute,expects|
assert_equal expects, @controller.params[:book][attribute]
end
end
def test_text_field
assert_select_form_works_with "article[name]", "My article" do |name, value|
text_field_tag name, value
end
end
def test_text_area
assert_select_form_works_with "article[body]", "This is great!" do |name, value|
text_area_tag name, value
end
end
def test_hidden_value_is_protected
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= submit_tag %>
EOD
form = select_form
assert_raise(TypeError) { form["key"] = "9876" }
form["key"].set_value("6789")
form.submit
assert_response :success
assert_equal({"commit"=>"Save changes", "key"=>"6789", "action"=>"create", "controller"=>@controller.controller_name}, @controller.params)
end
def test_checkbox_tag
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
EOD
form = select_form
form.submit_without_clicking_button
assert_nil @controller.params["ok"] # Checkboxes are nil when unchecked unless they have a hidden field by the same name
form["ok"].check
form.submit_without_clicking_button
assert_equal "1", @controller.params["ok"]
end
def test_check_box_takes_boolean_values
# @article is an object set up in test_helper.rb
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= check_box "article", "published" %>
<%= submit_tag %>
EOD
form = select_form
form.submit("article" => {"published" => true})
assert_equal "1", @controller.params["article"]['published']
form.submit("article" => {"published" => false})
assert_equal "0", @controller.params["article"]['published']
end
def test_check_box_prevents_setting_nonexistent_values
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= check_box "article", "published" %>
<%= submit_tag %>
EOD
form = select_form
assert_raise(RuntimeError) { form.article.published = "perhaps" }
assert_raise(RuntimeError) { form.submit("article" => {"published" => "perhaps"}) }
end
def test_check_box_initially_checked
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= check_box "article", "written" %>
EOD
assert_equal true, assigns(:article).written
form = select_form
form.submit_without_clicking_button
assert_equal "1", @controller.params["article"]['written']
form["article[written]"].uncheck
form.submit_without_clicking_button
assert_equal "0", @controller.params["article"]["written"]
end
def test_check_box_unchecked
# The check_box_tag helper creates both a checkbox and a hidden field
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= check_box "article", "published" %>
EOD
assert_equal false, assigns(:article).published
form = select_form
form.submit_without_clicking_button
assert_equal "0", @controller.params["article"]['published']
form["article[published]"].check
form.submit_without_clicking_button
assert_equal "1", @controller.params["article"]['published']
end
def test_radio_button
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= radio_button_tag "gender", "female", true %>
<%= radio_button_tag "gender", "male" %>
EOD
form = select_form
assert_equal %w(female male), form['gender'].options
assert_equal 'female', form['gender'].value
form['gender'] = 'male'
form.submit_without_clicking_button
assert_equal 'male', @controller.params['gender']
end
def test_radio_buttons_when_none_checked
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= radio_button_tag "gender", "female" %>
<%= radio_button_tag "gender", "male" %>
EOD
form = select_form
assert_equal %w(female male), form['gender'].options
form.submit_without_clicking_button
assert_nil @controller.params["gender"]
end
def test_radio_buttons_when_multiple_checked
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= radio_button_tag "gender", "female", true %>
<%= radio_button_tag "gender", "male", true %>
EOD
form = select_form
assert_equal %w(female male), form['gender'].options
assert_equal form['gender'].options.last, form['gender'].value
form.submit_without_clicking_button
assert_equal 'male', @controller.params['gender']
end
def test_radio_buttons_prevent_setting_nonexistent_values
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= radio_button_tag "gender", "female", true %>
<%= radio_button_tag "gender", "male" %>
<%= submit_tag %>
EOD
form = select_form
assert_equal %w(female male), form['gender'].options
assert_raise(RuntimeError) { form.gender = "neuter" }
assert_raise(RuntimeError) { form.submit('gender' => "neuter") }
end
def test_select
assert_select_form_works_with("people", "0") do |name, value|
select_tag name, %q{}
end
end
def test_select_multiple_requires_square_brackets
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= select_tag 'defunct_multiple_select', '', :multiple => true %>
EOD
assert_raise(FormTestHelper::SelectMultiple::NameMissingSquareBracketsError) { select_form.defunct_multiple_select }
end
def test_select_multiple_can_be_found_with_square_brackets
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= select_tag 'multiple_select[]', '', :multiple => true %>
EOD
form = select_form
assert_equal ['0'], form['multiple_select[]'].value # The field's name is "multiple_select" but this works for convenience
assert_equal ['0'], form['multiple_select'].value
assert_equal ['0'], form.multiple_select
end
def test_initially_selected_value_of_select_multiple
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= select_tag 'none_selected[]', %q{}, :multiple => true %>
<%= select_tag 'one_selected[]', %q{}, :multiple => true %>
<%= select_tag 'all_selected[]', %q{}, :multiple => true %>
EOD
form = select_form
[:none_selected, :one_selected, :all_selected].each do |field_name|
assert_equal %w(0 1), form[field_name].options
end
assert_equal [], form.none_selected
assert_equal %w(0), form.one_selected
assert_equal %w(0 1), form.all_selected
form.submit_without_clicking_button
assert_nil @controller.params[:none_selected]
assert_equal %w(0), @controller.params[:one_selected]
assert_equal %w(0 1), @controller.params[:all_selected]
end
def test_can_set_select_multiple_value_with_array
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= select_tag 'number[]', %q{}, :multiple => true %>
EOD
form = select_form
assert_equal %w(0 1), form.number.options
form.number = form.number.options
assert_equal %w(0 1), form.number
form.submit_without_clicking_button
assert_equal %w(0 1), @controller.params['number']
end
def test_select_with_multiple_initially_selected_but_not_allowed
render_rhtml <<-EOD
<%= form_tag %>
#{select_tag 'number', %q{}}
EOD
form = select_form
assert_equal %w(0 1), form['number'].options
assert_equal '1', form['number'].value # Browsers generally pick the last when multiple selected
end
def test_select_with_labeled_options_by_label
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
#{select_tag 'person_id', %q{}}
EOD
form = select_form
assert_equal [['Jason', '1'], ['Brent', '2']], form['person_id'].options
assert_equal '1', form['person_id'].value
form['person_id'] = "Brent"
assert_equal '2', form['person_id'].value
form.submit_without_clicking_button
assert_equal '2', @controller.params['person_id']
end
def test_select_with_labeled_options_by_value
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
#{select_tag 'person_id', %q{}}
EOD
form = select_form
form['person_id'] = 2
assert_equal '2', form['person_id'].value
form.submit_without_clicking_button
assert_equal '2', @controller.params['person_id']
end
def test_select_default_with_labeled_options
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
#{select_tag 'person_id', %q{}}
EOD
form = select_form
assert_equal '1', form['person_id'].value
form.submit_without_clicking_button
assert_equal '1', @controller.params['person_id']
end
def test_select_with_identically_labeled_options
render_rhtml <<-EOD
<%= form_tag %>
#{select_tag 'country', %q{}}
EOD
form = select_form
assert_equal ['US', 'Canada'], form['country'].options
end
def test_select_form_accepts_block
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "jason" %>
<%= submit_tag %>
EOD
new_value = 'brent'
select_form do |form|
form['username'] = new_value
end
assert_response :success
assert_equal new_value, @controller.params[:username]
end
def test_submit_form_accepts_block
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
<%= text_field_tag "username", "jason" %>
<%= submit_tag %>
EOD
new_value = 'brent'
submit_form do |form|
form['username'] = new_value
end
assert_response :success
assert_equal new_value, @controller.params[:username]
end
def test_submit_form_without_block_selects_and_submits
html = <<-EOD
<%= form_tag({:action => 'create'}, {:id => :test}) %>
<%= text_field_tag "username", "jason" %>
<%= submit_tag %>
EOD
render_rhtml html
submit_form
assert_response :success
assert_equal 'jason', @controller.params[:username]
render_rhtml html
assert_select "form#?", "test"
new_value = 'brent'
submit_form "test", :username => new_value
assert_response :success
assert_equal new_value, @controller.params[:username]
render_rhtml html
new_value = 'david'
submit_form :username => new_value
assert_response :success
assert_equal new_value, @controller.params[:username]
end
def test_submit_form_sets_referrer_header
render_rhtml <<-EOD
<%= form_tag(:action => 'redirect_to_back') %>
<%= submit_tag %>
EOD
submit_form
assert_response :redirect
assert_redirected_to :action => 'rhtml'
end
protected
def assert_select_form_works_with(name, value)
render_rhtml <<-EOD
<%= form_tag(:action => 'create') %>
#{yield name, value}
<%= submit_tag %>
EOD
form = select_form
assert_equal 2, form.fields.size
assert_kind_of(FormTestHelper::Field, form[name])
assert_equal value, form[name].initial_value
assert_equal value, form[name].value
assert_equal value, form.send(name)
new_value = "1"
form[name] = new_value
assert_equal new_value, form[name].value
form.submit
assert_response :success
expected_params = {"commit"=>"Save changes", "action"=>"create", "controller"=>@controller.controller_name}
if name =~ /(.*)\[(.*)\]/
object = $1
method = $2
expected_params.merge!(object=>{method => new_value})
else
expected_params.merge!(name => new_value)
end
assert_equal(expected_params, @controller.params)
end
end