diff --git a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/constraints/DefaultConstraintDescriptions.properties b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/constraints/DefaultConstraintDescriptions.properties index 699b900e..042db1c0 100644 --- a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/constraints/DefaultConstraintDescriptions.properties +++ b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/constraints/DefaultConstraintDescriptions.properties @@ -20,13 +20,18 @@ jakarta.validation.constraints.Pattern.description=Must match the regular expres jakarta.validation.constraints.Positive.description=Must be positive jakarta.validation.constraints.PositiveOrZero.description=Must be positive or zero jakarta.validation.constraints.Size.description=Size must be between ${min} and ${max} inclusive +org.hibernate.validator.constraints.BitcoinAddress.description=Must be a well-formed Bitcoin address org.hibernate.validator.constraints.CodePointLength.description=Code point length 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.Currency.description=Must be in an accepted currency unit (${value}) org.hibernate.validator.constraints.EAN.description=Must be a well-formed ${type} number +org.hibernate.validator.constraints.ISBN.description=Must be a well-formed ISBN 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.Normalized.description=Must be normalized using Unicode normalization form ${form} org.hibernate.validator.constraints.Range.description=Must be at least ${min} and at most ${max} -org.hibernate.validator.constraints.URL.description=Must be a well-formed URL \ No newline at end of file +org.hibernate.validator.constraints.URL.description=Must be a well-formed URL +org.hibernate.validator.constraints.UUID.description=Must be a well-formed UUID +org.hibernate.validator.constraints.UniqueElements.description=Must only contain unique elements \ No newline at end of file diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java index 5bbf4dfe..a67802af 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/constraints/ResourceBundleConstraintDescriptionResolverTests.java @@ -20,6 +20,7 @@ import java.lang.reflect.Field; import java.math.BigDecimal; import java.net.URL; +import java.text.Normalizer; import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -54,15 +55,20 @@ import jakarta.validation.constraints.Positive; import jakarta.validation.constraints.PositiveOrZero; import jakarta.validation.constraints.Size; +import org.hibernate.validator.constraints.BitcoinAddress; import org.hibernate.validator.constraints.CodePointLength; import org.hibernate.validator.constraints.CreditCardNumber; import org.hibernate.validator.constraints.Currency; import org.hibernate.validator.constraints.EAN; +import org.hibernate.validator.constraints.ISBN; 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.Normalized; import org.hibernate.validator.constraints.Range; +import org.hibernate.validator.constraints.UUID; +import org.hibernate.validator.constraints.UniqueElements; import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; @@ -255,6 +261,32 @@ void defaultMessageUrl() { assertThat(constraintDescriptionForField("url")).isEqualTo("Must be a well-formed URL"); } + @Test + void defaultMessageBitcoinAddress() { + assertThat(constraintDescriptionForField("bitcoinAddress")).isEqualTo("Must be a well-formed Bitcoin address"); + } + + @Test + void defaultMessageIsbn() { + assertThat(constraintDescriptionForField("isbn")).isEqualTo("Must be a well-formed ISBN"); + } + + @Test + void defaultMessageNormalized() { + assertThat(constraintDescriptionForField("normalized")) + .isEqualTo("Must be normalized using Unicode normalization form NFKC"); + } + + @Test + void defaultMessageUniqueElements() { + assertThat(constraintDescriptionForField("uniqueElements")).isEqualTo("Must only contain unique elements"); + } + + @Test + void defaultMessageUuid() { + assertThat(constraintDescriptionForField("uuid")).isEqualTo("Must be a well-formed UUID"); + } + @Test void customMessage() { Thread.currentThread().setContextClassLoader(new ClassLoader() { @@ -441,6 +473,21 @@ private static final class Constrained { @org.hibernate.validator.constraints.URL private @Nullable String url; + @BitcoinAddress + private @Nullable String bitcoinAddress; + + @ISBN + private @Nullable String isbn; + + @Normalized(form = Normalizer.Form.NFKC) + private @Nullable String normalized; + + @UniqueElements + private @Nullable List uniqueElements; + + @UUID + private @Nullable String uuid; + } } diff --git a/spring-restdocs-docs/src/docs/antora/modules/reference/pages/documenting-your-api/constraints.adoc b/spring-restdocs-docs/src/docs/antora/modules/reference/pages/documenting-your-api/constraints.adoc index edd1a51e..e6a24283 100644 --- a/spring-restdocs-docs/src/docs/antora/modules/reference/pages/documenting-your-api/constraints.adoc +++ b/spring-restdocs-docs/src/docs/antora/modules/reference/pages/documenting-your-api/constraints.adoc @@ -55,21 +55,26 @@ Default descriptions are provided for all of Bean Validation 3.1's constraints: Default descriptions are also provided for the following constraints from Hibernate Validator: +* `BitcoinAddress` * `CodePointLength` * `CreditCardNumber` * `Currency` * `EAN` * `Email` +* `ISBN` * `Length` * `LuhnCheck` * `Mod10Check` * `Mod11Check` +* `Normalized` * `NotBlank` * `NotEmpty` * `Currency` * `Range` * `SafeHtml` +* `UniqueElements` * `URL` +* `UUID` To override the default descriptions or to provide a new description, you can create a resource bundle with a base name of `org.springframework.restdocs.constraints.ConstraintDescriptions`. The Spring HATEOAS-based sample contains {samples}/restful-notes-spring-hateoas/src/test/resources/org/springframework/restdocs/constraints/ConstraintDescriptions.properties[an example of such a resource bundle].