org.hdiv.web.servlet.tags.form.SelectTagTests.java Source code

Java tutorial

Introduction

Here is the source code for org.hdiv.web.servlet.tags.form.SelectTagTests.java

Source

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed 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.hdiv.web.servlet.tags.form;

import java.beans.PropertyEditor;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.hdiv.beans.TestBean;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.tags.form.SelectTag;
import org.springframework.web.servlet.tags.form.TagWriter;

/**
 * @author Gorka Vicente
 * @since 2.0.6
 */
public class SelectTagTests extends AbstractFormTagTests {

    private static final Locale LOCALE_AT = new Locale("de", "AT");
    private static final Locale LOCALE_NL = new Locale("nl", "NL");

    private SelectTagHDIV tag;

    private TestBean bean;

    private boolean confidentiality;

    protected void onSetUp() {
        this.tag = new SelectTagHDIV() {
            protected TagWriter createTagWriter() {
                return new TagWriter(getWriter());
            }
        };
        this.tag.setPageContext(getPageContext());

        confidentiality = ((Boolean) getHdivContext().getBean("confidentiality")).booleanValue();
    }

    public void testEmptyItems() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems(Collections.EMPTY_LIST);

        this.tag.setItemValue("isoCode");
        this.tag.setItemLabel("name");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        assertEquals("<select id=\"country\" name=\"country\"></select>", output);
    }

    public void testNullItems() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems(null);

        this.tag.setItemValue("isoCode");
        this.tag.setItemLabel("name");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        assertEquals("<select id=\"country\" name=\"country\"></select>", output);
    }

    public void testWithList() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems(Country.getCountries());
        assertList(true);
    }

    public void testWithResolvedList() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems("${countries}");
        assertList(true);
    }

    public void testWithOtherValue() throws Exception {
        TestBean tb = getTestBean();
        tb.setCountry("AT");
        this.tag.setPath("country");
        this.tag.setItems(Country.getCountries());
        assertList(false);
    }

    public void testWithNullValue() throws Exception {
        TestBean tb = getTestBean();
        tb.setCountry(null);
        this.tag.setPath("country");
        this.tag.setItems(Country.getCountries());
        assertList(false);
    }

    public void testWithListAndNoLabel() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems("${countries}");
        this.tag.setItemValue("isoCode");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);
        validateOutput(getWriter().toString(), true);
    }

    public void testWithMap() throws Exception {
        this.tag.setPath("sex");
        this.tag.setItems("${sexes}");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);
    }

    public void testWithInvalidList() throws Exception {
        this.tag.setPath("country");
        this.tag.setItems("${other}");
        this.tag.setItemValue("isoCode");
        try {
            this.tag.doStartTag();
            fail("Must not be able to use a non-Collection typed value as the value of 'items'");
        } catch (JspException expected) {
            String message = expected.getMessage();
            assertTrue(message.indexOf("items") > -1);
            assertTrue(message.indexOf("org.hdiv.beans.TestBean") > -1);
        }
    }

    public void testWithNestedOptions() throws Exception {
        this.tag.setPath("country");
        int result = this.tag.doStartTag();
        assertEquals(Tag.EVAL_BODY_INCLUDE, result);

        BindStatus value = (BindStatus) getPageContext().getAttribute(SelectTag.LIST_VALUE_PAGE_ATTRIBUTE);
        assertEquals("Selected country not exposed in page context", "UK", value.getValue());

        result = this.tag.doEndTag();
        assertEquals(Tag.EVAL_PAGE, result);
        this.tag.doFinally();

        String output = getWriter().toString();

        assertTrue(output.startsWith("<select "));
        assertTrue(output.endsWith("</select>"));
        assertContainsAttribute(output, "name", "country");
    }

    public void testWithStringArray() throws Exception {
        this.tag.setPath("name");
        this.tag.setItems(getNames());
        assertStringArray();
    }

    public void testWithResolvedStringArray() throws Exception {
        this.tag.setPath("name");
        this.tag.setItems("${names}");
        assertStringArray();
    }

    public void testWithIntegerArray() throws Exception {
        this.tag.setPath("someIntegerArray");
        Integer[] array = new Integer[50];
        for (int i = 0; i < array.length; i++) {
            array[i] = new Integer(i);
        }
        this.tag.setItems(array);
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        output = "<doc>" + output + "</doc>";

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals(2, rootElement.elements().size());

        Element selectElement = rootElement.element("select");
        assertEquals("select", selectElement.getName());
        assertEquals("someIntegerArray", selectElement.attribute("name").getValue());

        List children = selectElement.elements();
        assertEquals("Incorrect number of children", array.length, children.size());

        Element e = (Element) selectElement.selectSingleNode("option[text() = '12']");
        assertEquals("'12' node not selected", "selected", e.attribute("selected").getValue());

        e = (Element) selectElement.selectSingleNode("option[text() = '34']");
        assertEquals("'34' node not selected", "selected", e.attribute("selected").getValue());
    }

    public void testWithFloatCustom() throws Exception {
        PropertyEditor propertyEditor = new SimpleFloatEditor();
        BeanPropertyBindingResult errors = new BeanPropertyBindingResult(getTestBean(), COMMAND_NAME);
        errors.getPropertyAccessor().registerCustomEditor(Float.class, propertyEditor);
        exposeBindingResult(errors);

        this.tag.setPath("myFloat");

        Float[] array = new Float[] { new Float("12.30"), new Float("12.32"), new Float("12.34"),
                new Float("12.36"), new Float("12.38"), new Float("12.40"), new Float("12.42"), new Float("12.44"),
                new Float("12.46"), new Float("12.48") };

        this.tag.setItems(array);
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        assertTrue(output.startsWith("<select "));
        assertTrue(output.endsWith("</select>"));

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals("select", rootElement.getName());
        assertEquals("myFloat", rootElement.attribute("name").getValue());
        List children = rootElement.elements();
        assertEquals("Incorrect number of children", array.length, children.size());

        Element e = (Element) rootElement.selectSingleNode("option[text() = '12.34f']");
        assertEquals("'12.34' node not selected", "selected", e.attribute("selected").getValue());

        e = (Element) rootElement.selectSingleNode("option[text() = '12.32f']");
        assertNull("'12.32' node incorrectly selected", e.attribute("selected"));
    }

    public void testWithMultiList() throws Exception {
        List list = new ArrayList();
        list.add(Country.COUNTRY_UK);
        list.add(Country.COUNTRY_AT);
        this.bean.setSomeList(list);

        this.tag.setPath("someList");
        this.tag.setItems("${countries}");
        this.tag.setItemValue("isoCode");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        output = "<doc>" + output + "</doc>";

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals(2, rootElement.elements().size());

        Element selectElement = rootElement.element("select");
        assertEquals("select", selectElement.getName());
        assertEquals("someList", selectElement.attribute("name").getValue());

        List children = selectElement.elements();
        assertEquals("Incorrect number of children", 4, children.size());

        String hdivValue = this.confidentiality ? "3" : "UK";
        Element e = (Element) selectElement.selectSingleNode("option[@value = '" + hdivValue + "']");
        assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());

        hdivValue = this.confidentiality ? "1" : "AT";
        e = (Element) selectElement.selectSingleNode("option[@value = '" + hdivValue + "']");
        assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
    }

    public void testWithMultiMap() throws Exception {
        Map someMap = new HashMap();
        someMap.put("M", "Male");
        someMap.put("F", "Female");
        this.bean.setSomeMap(someMap);

        this.tag.setPath("someMap");
        this.tag.setItems("${sexes}");

        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        output = "<doc>" + output + "</doc>";

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals(2, rootElement.elements().size());

        Element selectElement = rootElement.element("select");
        assertEquals("select", selectElement.getName());
        assertEquals("someMap", selectElement.attribute("name").getValue());

        List children = selectElement.elements();
        assertEquals("Incorrect number of children", 2, children.size());

        String hdivValue = this.confidentiality ? "1" : "M";
        Element e = (Element) selectElement.selectSingleNode("option[@value = '" + hdivValue + "']");
        assertEquals("M node not selected", "selected", e.attribute("selected").getValue());

        hdivValue = this.confidentiality ? "2" : "F";
        e = (Element) selectElement.selectSingleNode("option[@value = '" + hdivValue + "']");
        assertEquals("F node not selected", "selected", e.attribute("selected").getValue());
    }

    public void testMultiWithEmptyCollection() throws Exception {
        this.bean.setSomeList(new ArrayList());

        this.tag.setPath("someList");
        this.tag.setItems("${countries}");
        this.tag.setItemValue("isoCode");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        output = "<doc>" + output + "</doc>";

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals(2, rootElement.elements().size());

        Element selectElement = rootElement.element("select");
        assertEquals("select", selectElement.getName());
        assertEquals("someList", selectElement.attribute("name").getValue());
        assertEquals("multiple", selectElement.attribute("multiple").getValue());

        List children = selectElement.elements();
        assertEquals("Incorrect number of children", 4, children.size());

        Element inputElement = rootElement.element("input");
        assertNotNull(inputElement);
    }

    private void assertStringArray() throws JspException, DocumentException {
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();
        assertTrue(output.startsWith("<select "));
        assertTrue(output.endsWith("</select>"));

        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals("select", rootElement.getName());
        assertEquals("name", rootElement.attribute("name").getValue());

        List children = rootElement.elements();
        assertEquals("Incorrect number of children", 4, children.size());

        Element e = (Element) rootElement.selectSingleNode("option[text() = 'Rob']");
        assertEquals("Rob node not selected", "selected", e.attribute("selected").getValue());
    }

    private String[] getNames() {
        return new String[] { "Rod", "Rob", "Juergen", "Adrian" };
    }

    private Map getSexes() {
        Map sexes = new HashMap();
        sexes.put("F", "Female");
        sexes.put("M", "Male");
        return sexes;
    }

    protected void extendRequest(MockHttpServletRequest request) {
        super.extendRequest(request);
        request.setAttribute("countries", Country.getCountries());
        request.setAttribute("sexes", getSexes());
        request.setAttribute("other", new TestBean());
        request.setAttribute("names", getNames());
    }

    private void assertList(boolean selected) throws JspException, DocumentException {
        this.tag.setItemValue("isoCode");
        this.tag.setItemLabel("name");
        this.tag.setSize("5");
        int result = this.tag.doStartTag();
        assertEquals(Tag.SKIP_BODY, result);

        String output = getWriter().toString();

        validateOutput(output, selected);
        assertContainsAttribute(output, "size", "5");
    }

    private void validateOutput(String output, boolean selected) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new StringReader(output));
        Element rootElement = document.getRootElement();
        assertEquals("select", rootElement.getName());
        assertEquals("country", rootElement.attribute("name").getValue());

        List children = rootElement.elements();
        assertEquals("Incorrect number of children", 4, children.size());

        String hdivValue = this.confidentiality ? "3" : "UK";

        Element e = (Element) rootElement.selectSingleNode("option[@value = '" + hdivValue + "']");
        Attribute selectedAttr = e.attribute("selected");
        if (selected) {
            assertTrue(selectedAttr != null && "selected".equals(selectedAttr.getValue()));
        } else {
            assertNull(selectedAttr);
        }
    }

    protected TestBean createTestBean() {
        this.bean = new TestBean();
        this.bean.setName("Rob");
        this.bean.setCountry("UK");
        this.bean.setSex("M");
        this.bean.setMyFloat(new Float("12.34"));
        this.bean.setSomeIntegerArray(new Integer[] { new Integer(12), new Integer(34) });
        return this.bean;
    }

    private TestBean getTestBean() {
        return (TestBean) getPageContext().getRequest().getAttribute(COMMAND_NAME);
    }

}