package org.springframework.webflow.mvc.view; import java.beans.PropertyEditor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.springframework.binding.convert.converters.StringToObject; import org.springframework.binding.convert.service.DefaultConversionService; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.mapping.Mapping; import org.springframework.binding.mapping.MappingResult; import org.springframework.binding.mapping.impl.DefaultMappingResults; import org.springframework.binding.mapping.results.TypeConversionError; import org.springframework.binding.message.DefaultMessageContext; import org.springframework.binding.message.MessageBuilder; import org.springframework.validation.FieldError; import org.springframework.webflow.TestBean; import org.springframework.webflow.engine.builder.BinderConfiguration; import org.springframework.webflow.engine.builder.BinderConfiguration.Binding; public abstract class AbstractBindingModelTests extends TestCase { BindingModel model; DefaultMessageContext messages; DefaultConversionService conversionService; TestBean testBean; ExpressionParser expressionParser; public void setUp() { testBean = new TestBean(); messages = new DefaultMessageContext(); conversionService = new DefaultConversionService(); expressionParser = getExpressionParser(); model = new BindingModel("testBean", testBean, expressionParser, conversionService, messages); } protected abstract ExpressionParser getExpressionParser(); public void testInitialState() { assertEquals(0, model.getErrorCount()); assertEquals(0, model.getFieldErrorCount()); assertEquals(0, model.getFieldErrorCount("datum1")); assertEquals(0, model.getGlobalErrorCount()); assertEquals(0, model.getAllErrors().size()); assertEquals(0, model.getFieldErrors().size()); assertNull(model.getFieldError("datum1")); assertEquals(String.class, model.getFieldType("datum1")); } public void testGetValue() { testBean.datum1 = "test"; assertEquals("test", model.getFieldValue("datum1")); } public void testGetConvertedValue() { testBean.datum2 = 3; assertEquals("3", model.getFieldValue("datum2")); } public void testGetRawValue() { testBean.datum2 = 3; assertEquals(new Integer(3), model.getRawFieldValue("datum2")); } @SuppressWarnings("deprecation") public void testGetFieldValueConvertedWithCustomConverter() { testBean.datum2 = 3; conversionService.addConverter("customConverter", new StringToObject(Integer.class) { protected Object toObject(String string, Class<?> targetClass) throws Exception { return Integer.valueOf(string); } protected String toString(Object object) throws Exception { return "$" + object; } }); BinderConfiguration binder = new BinderConfiguration(); binder.addBinding(new Binding("datum2", "customConverter", true)); model.setBinderConfiguration(binder); assertEquals("$3", model.getFieldValue("datum2")); } public void testGetFieldValueError() { Map<String, String> source = new HashMap<String, String>(); source.put("datum2", "bogus"); List<MappingResult> mappingResults = new ArrayList<MappingResult>(); Mapping mapping = new Mapping() { public Expression getSourceExpression() { return expressionParser.parseExpression("datum2", null); } public Expression getTargetExpression() { return expressionParser.parseExpression("datum2", null); } public boolean isRequired() { return true; } }; mappingResults.add(new TypeConversionError(mapping, "bogus", null)); DefaultMappingResults results = new DefaultMappingResults(source, testBean, mappingResults); model.setMappingResults(results); assertEquals("bogus", model.getFieldValue("datum2")); // not offically an error until an actual error message is associated with field assertEquals(0, model.getErrorCount()); assertEquals(0, model.getFieldErrorCount()); } public void testGetFieldError() { messages.addMessage(new MessageBuilder().source("datum2").error().defaultText("Error").build()); assertEquals(1, model.getErrorCount()); assertEquals(1, model.getFieldErrorCount()); assertEquals(0, model.getGlobalErrorCount()); FieldError error = model.getFieldError("datum2"); assertEquals(null, error.getCode()); assertEquals(null, error.getCodes()); assertEquals(null, error.getArguments()); assertEquals("Error", error.getDefaultMessage()); // we dont track this assertEquals(null, error.getRejectedValue()); assertTrue(!error.isBindingFailure()); FieldError error2 = model.getFieldErrors().get(0); assertEquals(error, error2); } public void testGetFieldErrorsWildcard() { messages.addMessage(new MessageBuilder().source("datum2").error().defaultText("Error").build()); assertEquals(1, model.getFieldErrorCount("da*")); FieldError error = model.getFieldError("da*"); assertEquals(null, error.getCode()); assertEquals(null, error.getCodes()); assertEquals(null, error.getArguments()); assertEquals("Error", error.getDefaultMessage()); } public void testFindPropertyEditor() { PropertyEditor editor = model.findEditor("datum2", Integer.class); assertNotNull(editor); editor.setAsText((String) model.getFieldValue("datum2")); assertEquals("0", editor.getAsText()); } public void testNestedPath() { model = new BindingModel("nestedPathBean", new NestedPathBean(), expressionParser, conversionService, messages); model.pushNestedPath("nestedBean"); assertEquals("test", model.getFieldValue("datum1")); assertEquals("0", model.getFieldValue("datum2")); Class<?> clazz = model.getFieldType("datum2"); assertTrue(int.class.equals(clazz) || Integer.class.equals(clazz)); messages.addMessage(new MessageBuilder().source("nestedBean.datum2").error().defaultText("Error").build()); assertNotNull(model.getFieldErrors("datum2").get(0)); model.popNestedPath(); assertEquals("", model.getFieldValue("datum1")); } public static class NestedPathBean { private String datum1 = ""; private NestedBean nestedBean = new NestedBean(); public String getDatum1() { return datum1; } public void setDatum1(String datum1) { this.datum1 = datum1; } public NestedBean getNestedBean() { return nestedBean; } public void setNestedBean(NestedBean nestedBean) { this.nestedBean = nestedBean; } public static class NestedBean { private String datum1 = "test"; private int datum2; public int getDatum2() { return datum2; } public void setDatum2(int datum2) { this.datum2 = datum2; } public String getDatum1() { return datum1; } public void setDatum1(String datum1) { this.datum1 = datum1; } } } }