Package org.apache.click.control

Source Code of org.apache.click.control.FormTest$Div

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.control;

import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.click.MockContext;
import org.apache.click.Page;
import org.apache.click.servlet.MockRequest;

/**
* Test Form behavior.
*/
public class FormTest extends TestCase {

    /**
     * Test that it is not possible to add a duplicate SUBMIT_CHECK
     * HiddenField.
     *
     * CLK-267.
     */
    public void testDuplicateOnSubmitCheck() {
        MockContext context = MockContext.initContext("test-form.htm");
        MockRequest request = (MockRequest) context.getMockRequest();
        request.setParameter("form_name", "form");

        Page page = new Page();

        // Set the page to stateful
        page.setStateful(true);
        Form form = new Form("form");

        // Construct name of submit token
        String submitCheckName = Form.SUBMIT_CHECK + form.getName() + "_" + context.getResourcePath();

        // Simulate a submit check
        boolean valid = form.onSubmitCheck(page, "/invalid-submit.html");
        Assert.assertTrue(valid);

        // Assert that the submitCheck hidden field was created
        Field submitCheckField = form.getField(submitCheckName);
        Assert.assertNotNull(submitCheckField);

        // Add submitCheckField as a request parameter
        request.getParameterMap().put(Form.SUBMIT_CHECK + form.getName() + "_" + context.getResourcePath(), submitCheckField.getValue());
       
        // Simulate a second submit check.
        valid = form.onSubmitCheck(page, "/invalid-submit.html");
       
        // Assert the second onSubmitCheck did succeed as well.
        Assert.assertTrue(valid);
    }

    /**
     * Test Form#onSubmitCheck when the SUBMIT_CHECK parameter is
     * missing.
     *
     * CLK-289.
     */
    public void testOnSubmitCheckMissingParam() {
        MockContext context = (MockContext) MockContext.initContext("test-form.htm");
        MockRequest request = (MockRequest) context.getMockRequest();
        request.getParameterMap().put("form_name", "form");
        Page page = new Page();
        Form form = new Form("form");

        // Construct name of submit token
        String submitTokenName = Form.SUBMIT_CHECK + form.getName() + "_" + context.getResourcePath();

        // Ensure there are no submitCheck hidden field yet
        Field submitCheckField = form.getField(submitTokenName);
        Assert.assertNull(submitCheckField);

        // Simulate a submit check
        boolean valid = form.onSubmitCheck(page, "/invalid-submit.html");
        Assert.assertTrue(valid);

        // Add the submitCheckField name and value to the parameters.
        submitCheckField = form.getField(submitTokenName);
        request.setParameter(submitTokenName, submitCheckField.getValue());

        // If we submit again, the assert should be true because the submit
        // token is set in the request parameters.
        valid = form.onSubmitCheck(page, "/invalid-submit.html");
        Assert.assertTrue(valid);
       
        // Now imagine the SUBMIT_CHECK token is removed by a hacker. To simulate
        // such a scenario we remove the submitTokenName from the request paramters.
        request.removeParameter(submitTokenName);
        valid = form.onSubmitCheck(page, "/invalid-submit.html");
        Assert.assertFalse(valid);
    }

    /**
     * Test that form processing binds a request parameter to a field value.
     */
    public void testFormOnProcessRequestBinding() {
        // Create a mock context
        MockContext context = (MockContext) MockContext.initContext("test-form.htm");
        MockRequest request = (MockRequest) context.getMockRequest();

        // The request value that should be set as the textField value
        String requestValue = "one";

        // Set form name and field name parameters
        request.setParameter("form_name", "form");
        request.setParameter("name", requestValue);

        // Create form and fields
        Form form = new Form("form");
        TextField nameField = new TextField("name");
        form.add(nameField);

        // Check that nameField value is null
        Assert.assertNull(nameField.getValueObject());

        // Simulate a form onProcess callback
        form.onProcess();
       
        // Check that nameField value is now bound to request value
        Assert.assertEquals(requestValue, nameField.getValueObject());
    }

    /**
     * Check that Form processes controls even if their names is not defined.
     *
     * CLK-463 
     */
    public void testProcessControlWhenNameIsNull() {
        MockContext context = MockContext.initContext();
        context.getMockRequest().setParameter("form_name", "form");
        String fieldValue = "test";
        context.getMockRequest().setParameter("field", fieldValue);
       
        Form form = new Form("form");
        Panel panel = new Panel();
        TextField textField = new TextField("field");
        panel.add(textField);
        form.add(panel);

        assertEquals("", textField.getValue());
       
        form.onProcess();
       
        assertEquals(fieldValue, textField.getValue());
    }

    /** Form which index position to test. */
    private Form form;
   
    /** Field which position is tracked in the Form. */
    private HiddenField trackField;

    /**
     * Setup the form and trackField instances for testing the Control index
     * positions after being added or inserted.
     */
    public void setUp() {
        // Create form.
        form = new Form("form");
       
        // Form automatically creates and adds a HiddenField for storing the
        // form name between requests. This field is at index 0 at the start
        // of each test.
        // The tests below checks the trackField index position in the Form
        // for the lists Form#controls, Form#fieldList and Form#buttonList
        trackField = (HiddenField) form.getField(Form.FORM_NAME);

        // trackField index: #controls=0
        assertTrue(form.getControls().indexOf(trackField) == 0);
        // trackField index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(trackField) == 0);
    }

    /**
     * Test that Form#add(Control) inserts field at the correct index.
     *
     * The Form#controls list should be affected by the insert index, while
     * Form#fieldList should not.
     */
    public void testInsertOrderAfterAddingField() {
        TextField nameField = new TextField("name");

        // Add new field
        form.add(nameField);

        // nameField index: #controls=0
        assertTrue(form.getControls().indexOf(nameField) == 0);
        // nameField index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(nameField) == 0);
       
        // trackField index: #controls=1
        assertTrue(form.getControls().indexOf(trackField) == 1);
        // trackField index: #fieldList=1
        assertTrue(form.getFieldList().indexOf(trackField) == 1);
    }

    /**
     * Test that Form#insert(Control, int) inserts field at the correct index.
     *
     * The Form#controls list should be affected by the insert index, while
     * Form#fieldList should not.
     */
    public void testInsertOrderAfterInsertingField() {
        TextField nameField = new TextField("name");

        // Insert field at index 0
        form.insert(nameField, 0);

        // nameField index: #controls=0
        assertTrue(form.getControls().indexOf(nameField) == 0);
        // nameField index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(nameField) == 0);
       
        // trackField index: #controls=1
        assertTrue(form.getControls().indexOf(trackField) == 1);
        // trackField index: #fieldList=1
        assertTrue(form.getFieldList().indexOf(trackField) == 1);
    }

    /**
     * Test that Form#insert(Control, int) inserts table at the correct index.
     *
     * The Form#controls list should be affected by the insert index, while
     * Form#fieldList should not contain table as Table is not a Field.
     */
    public void testInsertOrderAfterInsertingTable() {
        Table table = new Table("table");

        // Insert table at index 0
        form.insert(table, 0);

        // table index: #controls=0
        assertTrue(form.getControls().indexOf(table) == 0);
        // table index: #fieldList=-1
        assertTrue(form.getFieldList().indexOf(table) == -1);
       
        // trackField index: #controls=1
        assertTrue(form.getControls().indexOf(trackField) == 1);
        // trackField index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(trackField) == 0);
    }

    /**
     * Test that Form#insert(Control, int) inserts Button at the correct index.
     *
     * The Form#controls list should be affected by the insert index, while
     * Form#buttonList should not.
     */
    public void testInsertOrderAfterInsertingButton() {
        // Check that the fieldList includes only trackField thus its size is 1
        assertTrue(form.getFieldList().size() == 1);

        Button button = new Button("button1");

        form.insert(button, 0);

        // button index: #controls=0
        assertTrue(form.getControls().indexOf(button) == 0);
        // button index: #buttonList=0
        assertTrue(form.getButtonList().indexOf(button) == 0);
        // Check that button was not added to fieldList accidentally
        assertTrue(form.getFieldList().size() == 1);
    }

    /**
     * Test that Form#insert(Control, int) inserts HiddenField at the correct index.
     *
     * The Form#controls list should be affected by the insert index, while
     * Form#fieldList should not.
     */
    public void testInsertOrderAfterInsertingHiddenField() {
        HiddenField hidden = new HiddenField("hidden", Boolean.class);

        // Insert hidden at index 0
        form.insert(hidden, 0);

        // hidden index: #controls=0
        assertTrue(form.getControls().indexOf(hidden) == 0);
        // hidden index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(hidden) == 0);
       
        // trackField index: #controls=1
        assertTrue(form.getControls().indexOf(trackField) == 1);
        // trackField index: #fieldList=1
        assertTrue(form.getFieldList().indexOf(trackField) == 1);
    }

    /**
     * Test that Form#remove(Control) properly cleans up.
     */
    public void testRemove() {
        TextField field = new TextField("field");

        form.insert(field, 0);

        // field index: #controls=0
        assertTrue(form.getControls().indexOf(field) == 0);
        // field index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(field) == 0);

        // trackField index: #controls=1
        assertTrue(form.getControls().indexOf(trackField) == 1);
        // trackField index: #fieldList=1
        assertTrue(form.getFieldList().indexOf(trackField) == 1);
       
        int expectedSize = 2;
        // Check the list sizes to be 2
        assertTrue(form.getControls().size() == expectedSize);
        assertTrue(form.getFieldList().size() == expectedSize);
       
        // Removing field should shift up trackField index
        form.remove(field);

        expectedSize = 1;
        // Check the list sizes to be 1
        assertTrue(form.getControls().size() == expectedSize);
        assertTrue(form.getFieldList().size() == expectedSize);
       
        // trackField index: #controls=0
        assertTrue(form.getControls().indexOf(trackField) == 0);
        // trackField index: #fieldList=0
        assertTrue(form.getFieldList().indexOf(trackField) == 0);
    }

    /**
     * Test that Form#add(Control, int) and Form#remove(Control) properly
     * sets and removes the fieldWidth for a Field.
     */
    public void testFieldWidthForField() {
        TextField field = new TextField("field");

        // Check that fieldWidth is empty
        assertTrue(form.getFieldWidths().isEmpty());
           
        int colspan = 4;
        form.add(field, colspan);

        // Check that fieldWidth has entry for field
        assertTrue(form.getFieldWidths().size() == 1);
       
        Integer width = (Integer) form.getFieldWidths().get(field.getName());
        assertEquals(4, width.intValue());

        form.remove(field);
       
        // Check that fieldWidth is empty
        assertTrue(form.getFieldWidths().isEmpty());
    }

    /**
     * Test that Form#add(Control, int) and Form#remove(Control) properly
     * sets and removes the fieldWidth for a Control.
     */
    public void testFieldWidthForTable() {
        Table table = new Table("table");

        // Check that fieldWidth is empty
        assertTrue(form.getFieldWidths().isEmpty());
           
        int colspan = 4;
        form.add(table, colspan);

        // Check that fieldWidth has entry for table
        assertTrue(form.getFieldWidths().size() == 1);
       
        Integer width = (Integer) form.getFieldWidths().get(table.getName());
        assertEquals(4, width.intValue());

        form.remove(table);
       
        // Check that fieldWidth is empty
        assertTrue(form.getFieldWidths().isEmpty());
    }

    /**
     * Test that Form.getFieldList() return only Fields directly added to the
     * field list. The list should include FieldSets but exclude Buttons.
     *
     * The main use case for Form.getFieldList() is that it enables one to use
     * Velocity to render Fields e.g.:
     *
     * #foreach ($field in $form.fieldList)
     *   <td>$field.label:</td> <td>$field</td>
     * #end
     *
     * Also check that Form.getFieldList() returns a cached List so that access
     * to Form.getFieldList() is fast.
     *
     * Q: Why not include fields recursively?
     * A: Its not really needed for Velocity usage. For example one would rarely
     *    wrap a field inside a "border container" when the rendering will be
     *    done with Velocity. Instead one would rather wrap the field inside
     *    a "border container" in the Velocity template e.g. wrapping it inside a
     *    span element.
     *        <span>$field</span>
     *
     *    If recursive fields are needed users can use ContainerUtils.getFields().
     */
    public void testGetFieldList() {
        Form form = new Form("form");

        // Assemble Fields
        TextField nameField = new TextField("name");
        form.add(nameField);

        Div div = new Div("div");
        form.add(div);

        Button button = new Button("button");
        form.add(button);

        // Assemble FieldSet
        FieldSet fieldSet = new FieldSet("fieldSet");
        form.add(fieldSet);

        // Add Field to FieldSet
        TextField fieldSetField = new TextField("fieldSetField");
        fieldSet.add(fieldSetField);

        // Check that list contains TextField
        assertTrue(form.getFieldList().contains(nameField));

        // Check that list contains FieldSet
        assertTrue(form.getFieldList().contains(fieldSet));
       
        // Check that list does *not* contains the FieldSet's Field
        assertFalse(form.getFieldList().contains(fieldSetField));

        // Check that list does *not* contain Div
        assertFalse(form.getFieldList().contains(div));
       
        // Check that list does *not* contain Button
        assertFalse(form.getFieldList().contains(button));

        // Check that field list is cached
        assertSame(form.getFieldList(), form.getFieldList());
    }

    /**
     * Test that Form.getButtonList() return only Buttons directly added to
     * Form and exclude all other Controls.
     *
     * The main use case for Form.getButtonList() is that it enables one to use
     * Velocity to render Buttons e.g.:
     *
     * #foreach ($button in $form.buttonList)
     *   $button
     * #end
     *
     * Also check that Form.getButtonList() returns a cached List so that access
     * to Form.getButtonList() is fast.
     *
     * Q: Why not include buttons recursively?
     * A: Its not really needed for Velocity usage. For example one would rarely
     *    wrap a button inside a "border container" when the rendering will be
     *    done with Velocity. Instead one would rather wrap the button inside
     *    a "border container" in the Velocity template e.g. wrapping it inside a
     *    span element:
     *        <span>$button</span>
     *
     *    If recursive buttons are needed users can use ContainerUtils.getButtons().
     */
    public void testGetButtonList() {
        Form form = new Form("form");

        // Assemble Fields
        TextField nameField = new TextField("name");
        form.add(nameField);

        Div div = new Div("div");
        form.add(div);

        Button button = new Button("button");
        form.add(button);

        // Assemble FieldSet
        FieldSet fieldSet = new FieldSet("fieldSet");
        form.add(fieldSet);

        // Add Field to FieldSet
        TextField fieldSetField = new TextField("fieldSetField");
        fieldSet.add(fieldSetField);
       
        // Add Button to FieldSet
        Button fieldSetButton = new Button("fieldSetButton");
        fieldSet.add(fieldSetButton);

        // Check that button list does *not* contains TextField
        assertFalse(form.getButtonList().contains(nameField));

        // Check that button list does *not* contains FieldSet
        assertFalse(form.getButtonList().contains(fieldSet));
       
        // Check that button list does *not* contains the FieldSet's Field
        assertFalse(form.getButtonList().contains(fieldSetField));

        // Check that button list does *not* contain Div
        assertFalse(form.getButtonList().contains(div));
       
        // Check that button list does contain Button
        assertTrue(form.getButtonList().contains(button));
       
        // Check that button list does *not* contain FieldSetButton since that
        // button was not directly added to Form
        assertFalse(form.getButtonList().contains(fieldSetButton));

        // Check that button list is cached
        assertSame(form.getButtonList(), form.getButtonList());
    }

    /**
     * Test that Form.getFields() return all Controls by delegating to
     * AbstractContainer#getControlMap().
     *
     * The main use case for Form.getFields() is that it enables one to use
     * Velocity to render Controls and Fields e.g.:
     *
     * $form.fields.name   <- name this is a TextField
     * $form.fields.div    <- div is a AbstractContainer
     * $form.fields.button <- button is a Submit
     *
     * Also check that Form.getFields() returns a cached Map so that access to
     * Form.getFields() is fast.
     *
     * Q: Why not return Fields only?
     * A: Form will then have to maintain another map besides #controlMap.
     *    However it could lead to issues when users iterate the map and receive
     *    ClassCastExceptions when casting to Field. In future release this issue
     *    could be revisited.
     */
    public void testGetFields() {
        Form form = new Form("form");

        // Assemble Fields
        String fieldName = "name";
        form.add(new TextField(fieldName));

        String divName = "div";
        form.add(new Div(divName));

        String buttonName = "button";
        form.add(new Button(buttonName));
       
        // Assemble FieldSet
        String fieldSetName = "fieldSet";
        FieldSet fieldSet = new FieldSet(fieldSetName);
        form.add(fieldSet);

        // Add Field to FieldSet
        String fieldSetFieldName = "fieldSetField";
        fieldSet.add(new TextField(fieldSetFieldName));

        // Check that map contains both TextField, Button and Div
        assertTrue(form.getFields().containsKey(fieldName));
        assertTrue(form.getFields().containsKey(divName));
        assertTrue(form.getFields().containsKey(buttonName));
       
        // Check that map contains FieldSet
        assertTrue(form.getFields().containsKey(fieldSetName));
       
        // Check that map does *not* contain the FieldSet's Field
        assertFalse(form.getFields().containsKey(fieldSetFieldName));

        // Check that field map is cached
        assertSame(form.getFields(), form.getFields());
        assertSame(form.getFields(), form.getControlMap());
    }

    /**
     * Test that insert(int, Control) works properly.
     */
    public void testInsert() {
        Form form = new Form("form");
       
        int defaultFieldSize = 17;
        form.setDefaultFieldSize(defaultFieldSize);
       
        TextField field = new TextField("name");
       
        // Assert that defaultFieldSize is not equal to field size
        assertFalse(defaultFieldSize == field.getSize());

        form.add(field);
       
        // Assert that after adding field, defaultFieldSize is equal to field size
        assertTrue(defaultFieldSize == field.getSize());
    }

    /**
     * Test that add(Control) works properly.
     */
    public void testAdd() {
        Form form = new Form("form");
        form.add(new TextField("name"), 1);

        // Check that add does not allow null arguments
        try {
            form.add(null);
            fail("Control cannot be null");
        } catch (Exception expected) {
        }

        // Check that field can be added
        try {
            form.add(new TextField("field"));
        } catch (Exception e) {
            fail("TextField can be added");
        }

        // Check that button can be added
        try {
            form.add(new Button("button"));
        } catch (Exception e) {
            fail("Button can be added");
        }
       
        // Check that table can be added
        try {
            form.add(new Table("table"));
        } catch (Exception e) {
            fail("Table can be added");
        }
    }
   
    /**
     * Test that add(Control, int) works properly.
     */
    public void testAddWidth() {
        Form form = new Form("form");
        form.add(new TextField("name"), 1);

        // Check that add does not allow null arguments
        try {
            form.add(null, 1);
            fail("Control cannot be null");
        } catch (Exception expected) {
        }

        // Check that field can be added
        try {
            form.add(new TextField("field"), 1);
        } catch (Exception e) {
            fail("TextField can be added");
        }
       
        // Check that table can be added
        try {
            form.add(new Table("table"), 1);
        } catch (Exception e) {
            fail("Table can be added");
        }

        // Check that add fails when width is less than 1
        try {
            form.add(new TextField("name"), 0);
            fail("Width cannot be less than 1");
        } catch (Exception expected) {
        }

        // Check that add fails when button is added
        try {
            form.add(new Button("button"), 1);
            fail("Button cannot have width set");
        } catch (Exception expected) {
        }
    }

    /**
     * Tests the Form insert performance.
     *
     * Creating 100 000 forms with 20 fields takes 1034 ms -> 1934 inserts per ms.
     *
     * System used: Sun JDK 1.4, Dual core, 2.16GHz, 2.00GB RAM, Windows XP
     */
    public void testInsertPerf() {
        // Specify the amount of text fields to create
        int textFieldCount = 15;
       
        // Number of times to populate a form with fields
        int loops = 100000;
       
        long time = 0;
        for (int i = 0; i < loops; i++) {
            Form form = new Form("form");

            long start = System.currentTimeMillis();
            populateForm(textFieldCount, form);
            time += System.currentTimeMillis() - start;
        }
        System.out.println("Time :" + time);
    }

    /**
     * Test the isDisabled() for a child component. Intent is to ensure that a
     * child component of the Form is disabled when the Form is itself disabled.
     */
    public void testIsDisabled() {
        // Form is not disabled.
        assertFalse(this.form.isDisabled());

        // Hiddenfield inside is not disabled.
        assertFalse(this.trackField.isDisabled());

        // Change form state.
        this.form.setDisabled(true);

        // Hiddenfield is now disabled too.
        assertTrue(this.trackField.isDisabled());
    }

    /**
     * Test the isReadonly() for a child component. Intent is to ensure that a
     * child component of the Form is disabled when the Form is itself disabled.
     */
    public void testIsReadonly() {
        // Form is not disabled.
        assertFalse(this.form.isReadonly());

        // Hiddenfield inside is not disabled.
        assertFalse(this.trackField.isReadonly());

        // Change form state.
        this.form.setReadonly(true);

        // Hiddenfield is now disabled too.
        assertTrue(this.trackField.isReadonly());
    }

    /**
     * Populate the given Form with hidden fields.
     *
     * @param count the number of hidden fields to add
     * @param form the form to add hidden fields to
     */
    public void populateForm(int count, Form form) {
        // Add 5 hidden fields
        form.add(new HiddenField("-1", Boolean.class));
        form.add(new HiddenField("-2", Boolean.class));
        form.add(new HiddenField("-3", Boolean.class));
        form.add(new HiddenField("-4", Boolean.class));
        form.add(new HiddenField("-5", Boolean.class));
        for (int i = 0; i < count; i++) {
            form.add(new TextField(String.valueOf(i)));
        }
    }

    /**
     * Div container used for testing.
     */
    static class Div extends AbstractContainer {

        /**
         * Constructor.
         */
        public Div(String name) {
            super(name);
        }

        /**
         * @return div tag
         */
        public String getTag() {
            return "div";
        }
    }
}
TOP

Related Classes of org.apache.click.control.FormTest$Div

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.