Add default descriptions for Hibernate Validator's constraints
Closes gh-151
This commit is contained in:
@@ -534,6 +534,21 @@ Default descriptions are provided for all of the Bean Validation 1.1's constrain
|
||||
* Pattern
|
||||
* Size
|
||||
|
||||
Default descriptions are also provided for constraints from Hibernate Validator:
|
||||
|
||||
* CreditCardNumber
|
||||
* EAN
|
||||
* Email
|
||||
* Length
|
||||
* LuhnCheck
|
||||
* Mod10Check
|
||||
* Mod11Check
|
||||
* NotBlank
|
||||
* NotEmpty
|
||||
* Range
|
||||
* SafeHtml
|
||||
* URL
|
||||
|
||||
To override the default descriptions, or to provide a new description, create a resource
|
||||
bundle with the base name
|
||||
`org.springframework.restdocs.constraints.ConstraintDescriptions`. The Spring
|
||||
|
||||
@@ -10,4 +10,16 @@ javax.validation.constraints.NotNull.description=Must not be null
|
||||
javax.validation.constraints.Null.description=Must be null
|
||||
javax.validation.constraints.Past.description=Must be in the past
|
||||
javax.validation.constraints.Pattern.description=Must match the regular expression '${regexp}'
|
||||
javax.validation.constraints.Size.description=Size must be between ${min} and ${max} inclusive
|
||||
javax.validation.constraints.Size.description=Size must be between ${min} and ${max} inclusive
|
||||
org.hibernate.validator.constraints.CreditCardNumber.description=Must be a well-formed credit card number
|
||||
org.hibernate.validator.constraints.EAN.description=Must be a well-formed ${type} number
|
||||
org.hibernate.validator.constraints.Email.description=Must be a well-formed email address
|
||||
org.hibernate.validator.constraints.Length.description=Length must be between ${min} and ${max} inclusive
|
||||
org.hibernate.validator.constraints.LuhnCheck.description=Must pass the Luhn Modulo 10 checksum algorithm
|
||||
org.hibernate.validator.constraints.Mod10Check.description=Must pass the Mod10 checksum algorithm
|
||||
org.hibernate.validator.constraints.Mod11Check.description=Must pass the Mod11 checksum algorithm
|
||||
org.hibernate.validator.constraints.NotBlank.description=Must not be blank
|
||||
org.hibernate.validator.constraints.NotEmpty.description=Must not be empty
|
||||
org.hibernate.validator.constraints.Range.description=Must be at least ${min} and at most ${max}
|
||||
org.hibernate.validator.constraints.SafeHtml.description=Must be safe HTML
|
||||
org.hibernate.validator.constraints.URL.description=Must be a well-formed URL
|
||||
@@ -16,11 +16,13 @@
|
||||
|
||||
package org.springframework.restdocs.constraints;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ListResourceBundle;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.validation.constraints.AssertFalse;
|
||||
@@ -37,8 +39,23 @@ import javax.validation.constraints.Past;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.hibernate.validator.constraints.CreditCardNumber;
|
||||
import org.hibernate.validator.constraints.EAN;
|
||||
import org.hibernate.validator.constraints.Email;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import org.hibernate.validator.constraints.LuhnCheck;
|
||||
import org.hibernate.validator.constraints.Mod10Check;
|
||||
import org.hibernate.validator.constraints.Mod11Check;
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
import org.hibernate.validator.constraints.SafeHtml;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -54,111 +71,151 @@ public class ResourceBundleConstraintDescriptionResolverTests {
|
||||
|
||||
@Test
|
||||
public void defaultMessageAssertFalse() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
AssertFalse.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must be false")));
|
||||
assertThat(constraintDescriptionForField("assertFalse"),
|
||||
is(equalTo("Must be false")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageAssertTrue() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
AssertTrue.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must be true")));
|
||||
assertThat(constraintDescriptionForField("assertTrue"),
|
||||
is(equalTo("Must be true")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageDecimalMax() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("value", "9.875");
|
||||
String description = this.resolver.resolveDescription(
|
||||
new Constraint(DecimalMax.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo("Must be at most 9.875")));
|
||||
assertThat(constraintDescriptionForField("decimalMax"),
|
||||
is(equalTo("Must be at most 9.875")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageDecimalMin() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("value", "1.5");
|
||||
String description = this.resolver.resolveDescription(
|
||||
new Constraint(DecimalMin.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo("Must be at least 1.5")));
|
||||
assertThat(constraintDescriptionForField("decimalMin"),
|
||||
is(equalTo("Must be at least 1.5")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageDigits() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("integer", "2");
|
||||
configuration.put("fraction", "5");
|
||||
String description = this.resolver.resolveDescription(
|
||||
new Constraint(Digits.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo(
|
||||
"Must have at most 2 integral digits and 5 " + "fractional digits")));
|
||||
assertThat(constraintDescriptionForField("digits"), is(
|
||||
equalTo("Must have at most 2 integral digits and 5 fractional digits")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageFuture() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
Future.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must be in the future")));
|
||||
assertThat(constraintDescriptionForField("future"),
|
||||
is(equalTo("Must be in the future")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageMax() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("value", 10);
|
||||
String description = this.resolver
|
||||
.resolveDescription(new Constraint(Max.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo("Must be at most 10")));
|
||||
assertThat(constraintDescriptionForField("max"),
|
||||
is(equalTo("Must be at most 10")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageMin() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("value", 10);
|
||||
String description = this.resolver
|
||||
.resolveDescription(new Constraint(Min.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo("Must be at least 10")));
|
||||
assertThat(constraintDescriptionForField("min"),
|
||||
is(equalTo("Must be at least 10")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageNotNull() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
NotNull.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must not be null")));
|
||||
assertThat(constraintDescriptionForField("notNull"),
|
||||
is(equalTo("Must not be null")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageNull() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
Null.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must be null")));
|
||||
assertThat(constraintDescriptionForField("nul"), is(equalTo("Must be null")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessagePast() {
|
||||
String description = this.resolver.resolveDescription(new Constraint(
|
||||
Past.class.getName(), Collections.<String, Object>emptyMap()));
|
||||
assertThat(description, is(equalTo("Must be in the past")));
|
||||
assertThat(constraintDescriptionForField("past"),
|
||||
is(equalTo("Must be in the past")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessagePattern() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("regexp", "[A-Z][a-z]+");
|
||||
String description = this.resolver.resolveDescription(
|
||||
new Constraint(Pattern.class.getName(), configuration));
|
||||
assertThat(description,
|
||||
assertThat(constraintDescriptionForField("pattern"),
|
||||
is(equalTo("Must match the regular expression '[A-Z][a-z]+'")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageSize() {
|
||||
Map<String, Object> configuration = new HashMap<>();
|
||||
configuration.put("min", 2);
|
||||
configuration.put("max", 10);
|
||||
String description = this.resolver
|
||||
.resolveDescription(new Constraint(Size.class.getName(), configuration));
|
||||
assertThat(description, is(equalTo("Size must be between 2 and 10 inclusive")));
|
||||
assertThat(constraintDescriptionForField("size"),
|
||||
is(equalTo("Size must be between 2 and 10 inclusive")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageCreditCardNumber() {
|
||||
assertThat(constraintDescriptionForField("creditCardNumber"),
|
||||
is(equalTo("Must be a well-formed credit card number")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageEan() {
|
||||
assertThat(constraintDescriptionForField("ean"),
|
||||
is(equalTo("Must be a well-formed EAN13 number")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageEmail() {
|
||||
assertThat(constraintDescriptionForField("email"),
|
||||
is(equalTo("Must be a well-formed email address")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageLength() {
|
||||
assertThat(constraintDescriptionForField("length"),
|
||||
is(equalTo("Length must be between 2 and 10 inclusive")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageLuhnCheck() {
|
||||
assertThat(constraintDescriptionForField("luhnCheck"),
|
||||
is(equalTo("Must pass the Luhn Modulo 10 checksum algorithm")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageMod10Check() {
|
||||
assertThat(constraintDescriptionForField("mod10Check"),
|
||||
is(equalTo("Must pass the Mod10 checksum algorithm")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageMod11Check() {
|
||||
assertThat(constraintDescriptionForField("mod11Check"),
|
||||
is(equalTo("Must pass the Mod11 checksum algorithm")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageNotBlank() {
|
||||
assertThat(constraintDescriptionForField("notBlank"),
|
||||
is(equalTo("Must not be blank")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageNotEmpty() {
|
||||
assertThat(constraintDescriptionForField("notEmpty"),
|
||||
is(equalTo("Must not be empty")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageRange() {
|
||||
assertThat(constraintDescriptionForField("range"),
|
||||
is(equalTo("Must be at least 10 and at most 100")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageSafeHtml() {
|
||||
assertThat(constraintDescriptionForField("safeHtml"),
|
||||
is(equalTo("Must be safe HTML")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMessageUrl() {
|
||||
assertThat(constraintDescriptionForField("url"),
|
||||
is(equalTo("Must be a well-formed URL")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,4 +263,94 @@ public class ResourceBundleConstraintDescriptionResolverTests {
|
||||
assertThat(description, is(equalTo("Not null")));
|
||||
}
|
||||
|
||||
private String constraintDescriptionForField(String name) {
|
||||
return this.resolver.resolveDescription(getConstraintFromField(name));
|
||||
}
|
||||
|
||||
private Constraint getConstraintFromField(String name) {
|
||||
Annotation[] annotations = ReflectionUtils.findField(Constrained.class, name)
|
||||
.getAnnotations();
|
||||
Assert.isTrue(annotations.length == 1);
|
||||
return new Constraint(annotations[0].annotationType().getName(),
|
||||
AnnotationUtils.getAnnotationAttributes(annotations[0]));
|
||||
}
|
||||
|
||||
private static class Constrained {
|
||||
|
||||
@AssertFalse
|
||||
private boolean assertFalse;
|
||||
|
||||
@AssertTrue
|
||||
private boolean assertTrue;
|
||||
|
||||
@DecimalMax("9.875")
|
||||
private BigDecimal decimalMax;
|
||||
|
||||
@DecimalMin("1.5")
|
||||
private BigDecimal decimalMin;
|
||||
|
||||
@Digits(integer = 2, fraction = 5)
|
||||
private String digits;
|
||||
|
||||
@Future
|
||||
private Date future;
|
||||
|
||||
@Max(10)
|
||||
private int max;
|
||||
|
||||
@Min(10)
|
||||
private int min;
|
||||
|
||||
@NotNull
|
||||
private String notNull;
|
||||
|
||||
@Null
|
||||
private String nul;
|
||||
|
||||
@Past
|
||||
private Date past;
|
||||
|
||||
@Pattern(regexp = "[A-Z][a-z]+")
|
||||
private String pattern;
|
||||
|
||||
@Size(min = 2, max = 10)
|
||||
private List<String> size;
|
||||
|
||||
@CreditCardNumber
|
||||
private String creditCardNumber;
|
||||
|
||||
@EAN
|
||||
private String ean;
|
||||
|
||||
@Email
|
||||
private String email;
|
||||
|
||||
@Length(min = 2, max = 10)
|
||||
private String length;
|
||||
|
||||
@LuhnCheck
|
||||
private String luhnCheck;
|
||||
|
||||
@Mod10Check
|
||||
private String mod10Check;
|
||||
|
||||
@Mod11Check
|
||||
private String mod11Check;
|
||||
|
||||
@NotBlank
|
||||
private String notBlank;
|
||||
|
||||
@NotEmpty
|
||||
private String notEmpty;
|
||||
|
||||
@Range(min = 10, max = 100)
|
||||
private int range;
|
||||
|
||||
@SafeHtml
|
||||
private String safeHtml;
|
||||
|
||||
@org.hibernate.validator.constraints.URL
|
||||
private String url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user