/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.test.internal.engine.messageinterpolation;
import java.io.ByteArrayInputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.validation.Configuration;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator;
import org.hibernate.validator.testutil.TestForIssue;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.testng.Assert.assertEquals;
/**
* @author Hardy Ferentschik
* @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI
*/
public class MessageInterpolationTest {
private Validator validator;
@BeforeClass
public void createValidator() throws Exception {
final StringBuilder lines = new StringBuilder();
lines.append( "bar=Message is \\\\{escaped\\\\}" ).append( "\r\n" );
lines.append( "baz=Message is US\\$ {value}" ).append( "\r\n" );
lines.append( "buz=Message is {values}" ).append( "\r\n" );
lines.append( "qux=Message is {missing}" ).append( "\r\n" );
lines.append( "zap=Message is \\\\${value}" ).append( "\r\n" );
lines.append( "escaped=wrong" ).append( "\r\n" );
final ResourceBundle bundle = new PropertyResourceBundle(
new ByteArrayInputStream( lines.toString().getBytes() )
);
Configuration<?> config = Validation.byDefaultProvider()
.configure()
.messageInterpolator(
new ResourceBundleMessageInterpolator(
new ResourceBundleLocator() {
@Override
public ResourceBundle getResourceBundle(
Locale locale) {
return bundle;
}
}
)
);
ValidatorFactory factory = config.buildValidatorFactory();
validator = factory.getValidator();
}
@Test
@TestForIssue(jiraKey = "HV-184")
public void testCurlyBracesEscapingShouldBeRespected() {
final ConstraintViolation<Foo> violation = validator.validate( new Foo(), Bar.class ).iterator().next();
assertEquals( violation.getMessage(), "Message is {escaped}" );
}
@Test
@TestForIssue(jiraKey = "HV-184")
public void testAppendReplacementNeedsToEscapeBackslashAndDollarSign() {
final ConstraintViolation<Foo> violation = validator.validate( new Foo(), Baz.class ).iterator().next();
assertEquals( violation.getMessage(), "Message is US$ 5" );
}
@Test
@TestForIssue(jiraKey = "HV-184")
public void testUnknownParametersShouldBePreserved() {
final ConstraintViolation<Foo> violation = validator.validate( new Foo(), Qux.class ).iterator().next();
assertEquals( violation.getMessage(), "Message is {missing}" );
}
@Test
@TestForIssue(jiraKey = "HV-506")
public void testInterpolationOfArrayParameter() {
final ConstraintViolation<Foo> violation = validator.validate( new Foo(), Buz.class ).iterator().next();
assertEquals( violation.getMessage(), "Message is [bar, baz, qux]" );
}
@Test
@TestForIssue(jiraKey = "HV-729")
public void testDollarSignEscapingShouldBeRespected() {
final ConstraintViolation<Foo> violation = validator.validate( new Foo(), Zap.class ).iterator().next();
assertEquals( violation.getMessage(), "Message is $10" );
}
public interface Bar {
}
public interface Baz {
}
public interface Buz {
}
public interface Qux {
}
public interface Zap {
}
@Target(METHOD)
@Retention(RUNTIME)
@Constraint(validatedBy = AllowedValuesValidator.class)
public static @interface AllowedValues {
String[] values();
String message() default "{buz}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public static class AllowedValuesValidator implements ConstraintValidator<AllowedValues, String> {
private List<String> values;
@Override
public void initialize(AllowedValues values) {
this.values = Arrays.asList( values.values() );
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ( value == null ) {
return true;
}
return values.contains( value );
}
}
public static class Foo {
@NotNull(message = "{bar}", groups = Bar.class)
public String getBar() {
return null;
}
@Min(value = 5, message = "{baz}", groups = Baz.class)
public int getBaz() {
return 0;
}
@AllowedValues(values = { "bar", "baz", "qux" }, groups = Buz.class)
public String getBuz() {
return "buz";
}
@NotNull(message = "{qux}", groups = Qux.class)
public String getQux() {
return null;
}
@Min(value = 10, message = "{zap}", groups = Zap.class)
public int getZap() {
return 0;
}
}
}