// $Id: MessageInterpolationTest.java 17620 2009-10-04 19:19:28Z hardy.ferentschik $ /* * JBoss, Home of Professional Open Source * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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.hibernate.jsr303.tck.tests.messageinterpolation; import java.util.Date; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.shared.GwtLocale; import com.google.gwt.i18n.shared.GwtLocaleFactory; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.MessageInterpolator; import javax.validation.Validator; import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; import javax.validation.constraints.Size; import javax.validation.metadata.ConstraintDescriptor; import org.jboss.test.audit.annotations.SpecAssertion; import org.jboss.test.audit.annotations.SpecAssertions; import org.jboss.testharness.AbstractTest; import org.jboss.testharness.impl.packaging.Artifact; import org.jboss.testharness.impl.packaging.ArtifactType; import org.jboss.testharness.impl.packaging.Classes; import org.jboss.testharness.impl.packaging.IntegrationTest; import org.jboss.testharness.impl.packaging.Resource; import org.jboss.testharness.impl.packaging.Resources; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import org.testng.annotations.Test; import org.hibernate.jsr303.tck.util.TestUtil; import static org.hibernate.jsr303.tck.util.TestUtil.assertCorrectConstraintViolationMessages; import static org.hibernate.jsr303.tck.util.TestUtil.assertCorrectNumberOfViolations; import static org.hibernate.jsr303.tck.util.TestUtil.getDefaultMessageInterpolator; import static org.hibernate.jsr303.tck.util.TestUtil.getValidatorUnderTest; /** * Modified by Google: * <ul> * <li>Changed Local to GwtLocale</li> * </ul> * @author Hardy Ferentschik */ @Artifact(artifactType = ArtifactType.JSR303) @Classes({ TestUtil.class, TestUtil.PathImpl.class, TestUtil.NodeImpl.class }) @Resources({ @Resource(source = "ValidationMessages.properties", destination = "WEB-INF/classes/ValidationMessages.properties"), @Resource(source = "ValidationMessages_de.properties", destination = "WEB-INF/classes/ValidationMessages_de.properties") }) @IntegrationTest public class MessageInterpolationTest extends AbstractTest { @Test @SpecAssertion(section = "4.3.1", id = "a") public void testDefaultMessageInterpolatorIsNotNull() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); assertNotNull( interpolator, "Each bean validation provider must provide a default message interpolator." ); } @Test @SpecAssertions({ @SpecAssertion(section = "4.3.1", id = "e"), @SpecAssertion(section = "4.3.1.1", id = "a") }) public void testSuccessfulInterpolationOfValidationMessagesValue() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "replacement worked"; String actual = interpolator.interpolate( "{foo}", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "replacement worked replacement worked"; actual = interpolator.interpolate( "{foo} {foo}", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "This replacement worked just fine"; actual = interpolator.interpolate( "This {foo} just fine", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "{} replacement worked {unknown}"; actual = interpolator.interpolate( "{} {foo} {unknown}", context ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "b") public void testRecursiveMessageInterpolation() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "fubar" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "recursion worked"; String actual = interpolator.interpolate( ( String ) descriptor.getAttributes().get( "message" ), context ); assertEquals( expected, actual, "Expansion should be recursive" ); } @Test @SpecAssertion(section = "4.3.1", id = "d") public void testMessagesCanBeOverriddenAtConstraintLevel() { Validator validator = TestUtil.getValidatorUnderTest(); Set<ConstraintViolation<DummyEntity>> constraintViolations = validator.validateProperty( new DummyEntity(), "snafu" ); assertCorrectNumberOfViolations( constraintViolations, 1 ); assertCorrectConstraintViolationMessages( constraintViolations, "messages can also be overridden at constraint declaration." ); } @Test @SpecAssertions({ @SpecAssertion(section = "4.3.1", id = "f"), @SpecAssertion(section = "4.3.1", id = "g"), @SpecAssertion(section = "4.3.1", id = "h") }) public void testLiteralCurlyBraces() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "{"; String actual = interpolator.interpolate( "\\{", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "}"; actual = interpolator.interpolate( "\\}", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "\\"; actual = interpolator.interpolate( "\\", context ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "a") public void testUnSuccessfulInterpolation() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "foo"; // missing {} String actual = interpolator.interpolate( "foo", context ); assertEquals( actual, expected, "Wrong substitution" ); expected = "#{foo {}"; actual = interpolator.interpolate( "#{foo {}", context ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "a") public void testUnknownTokenInterpolation() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "{bar}"; // unknown token {} String actual = interpolator.interpolate( "{bar}", context ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "c") public void testParametersAreExtractedFromBeanValidationProviderBundle() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( Person.class, "birthday" ); MessageInterpolator.Context context = new TestContext( descriptor ); String key = "{javax.validation.constraints.Past.message}"; // Past is a built-in constraint so the provider must provide a default message String actual = interpolator.interpolate( key, context ); assertFalse( key.equals( actual ), "There should have been a message interpolation from the bean validator provider bundle." ); } @Test @SpecAssertion(section = "4.3.1.1", id = "g") public void testConstraintAttributeValuesAreInterpolated() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "bar" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "size must be between 5 and 10"; String actual = interpolator.interpolate( ( String ) descriptor.getAttributes().get( "message" ), context ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "h") public void testMessageInterpolationWithLocale() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); MessageInterpolator.Context context = new TestContext( descriptor ); String expected = "kann nicht null sein"; // TODO(nchalko) i18n //GwtLocaleFactory localeFactory = GWT.create(GwtLocaleFactory.class); GwtLocale german = null; //localeFactory.fromComponents("de","","",""); String actual = interpolator.interpolate( ( String ) descriptor.getAttributes().get( "message" ), context, german ); assertEquals( actual, expected, "Wrong substitution" ); } @Test @SpecAssertion(section = "4.3.1.1", id = "i") public void testIfNoLocaleIsSpecifiedTheDefaultLocaleIsAssumed() { MessageInterpolator interpolator = getDefaultMessageInterpolator(); ConstraintDescriptor<?> descriptor = getDescriptorFor( DummyEntity.class, "foo" ); String messageTemplate = ( String ) descriptor.getAttributes().get( "message" ); MessageInterpolator.Context context = new TestContext( descriptor ); String messageInterpolatedWithNoLocale = interpolator.interpolate( messageTemplate, context ); // TODO(nchalko) i18n //GwtLocaleFactory localeFactory = GWT.create(GwtLocaleFactory.class); GwtLocale defaultLocale = null; // localeFactory.getDefault(); String messageInterpolatedWithDefaultLocale = interpolator.interpolate( messageTemplate, context,defaultLocale ); assertEquals( messageInterpolatedWithNoLocale, messageInterpolatedWithDefaultLocale, "Wrong substitution" ); } private ConstraintDescriptor<?> getDescriptorFor(Class<?> clazz, String propertyName) { Validator validator = getValidatorUnderTest(); return validator.getConstraintsForClass( clazz ) .getConstraintsForProperty( propertyName ) .getConstraintDescriptors() .iterator() .next(); } public class TestContext implements MessageInterpolator.Context { ConstraintDescriptor<?> descriptor; TestContext(ConstraintDescriptor<?> descriptor) { this.descriptor = descriptor; } public ConstraintDescriptor<?> getConstraintDescriptor() { return descriptor; } public Object getValidatedValue() { return null; } } public class DummyEntity { @NotNull String foo; @Size(min = 5, max = 10, message = "size must be between {min} and {max}") String bar; @Max(value = 10, message = "{replace.in.user.bundle1}") String fubar; @NotNull(message = "messages can also be overridden at constraint declaration.") String snafu; } public class Person { String name; @Past Date birthday; } }