Skip to content

Commit 3cc3d5c

Browse files
committed
HV-1756 Add a test validating all the messages are properly interpolated
1 parent b833b11 commit 3cc3d5c

File tree

1 file changed

+359
-0
lines changed

1 file changed

+359
-0
lines changed
Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
/*
2+
* Hibernate Validator, declare and validate application constraints
3+
*
4+
* License: Apache License, Version 2.0
5+
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6+
*/
7+
package org.hibernate.validator.test.internal.constraintvalidators;
8+
9+
import static org.hibernate.validator.testutil.ConstraintViolationAssert.violationOf;
10+
11+
import java.math.BigDecimal;
12+
import java.time.Duration;
13+
import java.time.LocalDate;
14+
import java.util.ArrayList;
15+
import java.util.Arrays;
16+
import java.util.Collections;
17+
import java.util.List;
18+
import java.util.Locale;
19+
import java.util.Set;
20+
21+
import javax.money.MonetaryAmount;
22+
import javax.validation.ConstraintViolation;
23+
import javax.validation.Validation;
24+
import javax.validation.Validator;
25+
import javax.validation.constraints.AssertFalse;
26+
import javax.validation.constraints.AssertTrue;
27+
import javax.validation.constraints.DecimalMax;
28+
import javax.validation.constraints.DecimalMin;
29+
import javax.validation.constraints.Digits;
30+
import javax.validation.constraints.Email;
31+
import javax.validation.constraints.Future;
32+
import javax.validation.constraints.FutureOrPresent;
33+
import javax.validation.constraints.Max;
34+
import javax.validation.constraints.Min;
35+
import javax.validation.constraints.Negative;
36+
import javax.validation.constraints.NegativeOrZero;
37+
import javax.validation.constraints.NotBlank;
38+
import javax.validation.constraints.NotEmpty;
39+
import javax.validation.constraints.NotNull;
40+
import javax.validation.constraints.Null;
41+
import javax.validation.constraints.Past;
42+
import javax.validation.constraints.PastOrPresent;
43+
import javax.validation.constraints.Pattern;
44+
import javax.validation.constraints.Positive;
45+
import javax.validation.constraints.PositiveOrZero;
46+
import javax.validation.constraints.Size;
47+
48+
import org.hibernate.validator.HibernateValidator;
49+
import org.hibernate.validator.constraints.CodePointLength;
50+
import org.hibernate.validator.constraints.CreditCardNumber;
51+
import org.hibernate.validator.constraints.Currency;
52+
import org.hibernate.validator.constraints.EAN;
53+
import org.hibernate.validator.constraints.ISBN;
54+
import org.hibernate.validator.constraints.Length;
55+
import org.hibernate.validator.constraints.LuhnCheck;
56+
import org.hibernate.validator.constraints.Mod10Check;
57+
import org.hibernate.validator.constraints.Mod11Check;
58+
import org.hibernate.validator.constraints.ModCheck;
59+
import org.hibernate.validator.constraints.ParameterScriptAssert;
60+
import org.hibernate.validator.constraints.Range;
61+
import org.hibernate.validator.constraints.SafeHtml;
62+
import org.hibernate.validator.constraints.ScriptAssert;
63+
import org.hibernate.validator.constraints.URL;
64+
import org.hibernate.validator.constraints.UniqueElements;
65+
import org.hibernate.validator.constraints.br.CNPJ;
66+
import org.hibernate.validator.constraints.br.CPF;
67+
import org.hibernate.validator.constraints.br.TituloEleitoral;
68+
import org.hibernate.validator.constraints.pl.NIP;
69+
import org.hibernate.validator.constraints.pl.PESEL;
70+
import org.hibernate.validator.constraints.pl.REGON;
71+
import org.hibernate.validator.constraints.time.DurationMax;
72+
import org.hibernate.validator.constraints.time.DurationMin;
73+
import org.hibernate.validator.testutil.ConstraintViolationAssert;
74+
import org.javamoney.moneta.Money;
75+
import org.testng.annotations.Test;
76+
77+
/**
78+
* Test that all the messages of all the constraints are properly interpolated for all the supported locales.
79+
*
80+
* @author Guillaume Smet
81+
*/
82+
@SuppressWarnings("deprecation")
83+
public class MessagePropertiesTest {
84+
85+
private static final List<Locale> ALL_SUPPORTED_LOCALES = Arrays.asList(
86+
Locale.forLanguageTag( "ar" ),
87+
Locale.forLanguageTag( "cs" ),
88+
Locale.forLanguageTag( "da" ),
89+
Locale.forLanguageTag( "de" ),
90+
Locale.forLanguageTag( "en" ),
91+
Locale.forLanguageTag( "es" ),
92+
Locale.forLanguageTag( "fa" ),
93+
Locale.forLanguageTag( "fr" ),
94+
Locale.forLanguageTag( "hu" ),
95+
Locale.forLanguageTag( "it" ),
96+
Locale.forLanguageTag( "ja" ),
97+
Locale.forLanguageTag( "ko" ),
98+
Locale.forLanguageTag( "mn-MN" ),
99+
Locale.forLanguageTag( "nl" ),
100+
Locale.forLanguageTag( "pl" ),
101+
Locale.forLanguageTag( "pt-BR" ),
102+
Locale.forLanguageTag( "ro" ),
103+
Locale.forLanguageTag( "ru" ),
104+
Locale.forLanguageTag( "sk" ),
105+
Locale.forLanguageTag( "tr" ),
106+
Locale.forLanguageTag( "uk" ),
107+
Locale.forLanguageTag( "zh-CN" ),
108+
Locale.forLanguageTag( "zh-TW" ),
109+
Locale.forLanguageTag( "zh" )
110+
);
111+
112+
@Test
113+
public void testMessageProperties() throws NoSuchMethodException, SecurityException {
114+
List<String> invalidMessages = new ArrayList<>();
115+
116+
for ( Locale locale : ALL_SUPPORTED_LOCALES ) {
117+
Validator validator = Validation.byProvider( HibernateValidator.class )
118+
.configure()
119+
.defaultLocale( locale )
120+
.buildValidatorFactory()
121+
.getValidator();
122+
123+
Set<ConstraintViolation<Bean>> violations = validator.validate( new Bean() );
124+
125+
ConstraintViolationAssert.assertThat( violations )
126+
.containsOnlyViolations(
127+
violationOf( AssertFalse.class ),
128+
violationOf( AssertTrue.class ),
129+
violationOf( DecimalMax.class ),
130+
violationOf( DecimalMin.class ),
131+
violationOf( Digits.class ),
132+
violationOf( Email.class ),
133+
violationOf( Future.class ),
134+
violationOf( FutureOrPresent.class ),
135+
violationOf( Max.class ),
136+
violationOf( Min.class ),
137+
violationOf( Negative.class ),
138+
violationOf( NegativeOrZero.class ),
139+
violationOf( NotBlank.class ),
140+
violationOf( NotEmpty.class ),
141+
violationOf( NotNull.class ),
142+
violationOf( Null.class ),
143+
violationOf( Past.class ),
144+
violationOf( PastOrPresent.class ),
145+
violationOf( Pattern.class ),
146+
violationOf( Positive.class ),
147+
violationOf( PositiveOrZero.class ),
148+
violationOf( Size.class ),
149+
violationOf( CreditCardNumber.class ),
150+
violationOf( Currency.class ),
151+
violationOf( EAN.class ),
152+
violationOf( org.hibernate.validator.constraints.Email.class ),
153+
violationOf( ISBN.class ),
154+
violationOf( Length.class ),
155+
violationOf( CodePointLength.class ),
156+
violationOf( LuhnCheck.class ),
157+
violationOf( Mod10Check.class ),
158+
violationOf( Mod11Check.class ),
159+
violationOf( ModCheck.class ),
160+
violationOf( org.hibernate.validator.constraints.NotBlank.class ),
161+
violationOf( org.hibernate.validator.constraints.NotEmpty.class ),
162+
violationOf( Range.class ),
163+
violationOf( SafeHtml.class ),
164+
violationOf( UniqueElements.class ),
165+
violationOf( URL.class ),
166+
violationOf( CNPJ.class ),
167+
violationOf( CPF.class ),
168+
violationOf( TituloEleitoral.class ),
169+
violationOf( REGON.class ),
170+
violationOf( NIP.class ),
171+
violationOf( PESEL.class ),
172+
violationOf( DurationMax.class ),
173+
violationOf( DurationMin.class ),
174+
violationOf( ScriptAssert.class )
175+
);
176+
177+
collectInvalidMessages( locale, invalidMessages, violations );
178+
179+
Set<ConstraintViolation<ParameterScriptAssertBean>> parameterScriptAssertBeanViolations = validator.forExecutables().validateParameters(
180+
new ParameterScriptAssertBean(), ParameterScriptAssertBean.class.getDeclaredMethod( "doTest", boolean.class ), new Object[]{ false } );
181+
182+
ConstraintViolationAssert.assertThat( parameterScriptAssertBeanViolations )
183+
.containsOnlyViolations(
184+
violationOf( ParameterScriptAssert.class ) );
185+
186+
collectInvalidMessages( locale, invalidMessages, parameterScriptAssertBeanViolations );
187+
}
188+
189+
if ( !invalidMessages.isEmpty() ) {
190+
throw new IllegalStateException( "Some messages are invalid:\n\t- " + String.join( "\n\t- ", invalidMessages ) + "\n" );
191+
}
192+
}
193+
194+
private void collectInvalidMessages(Locale locale, List<String> invalidMessages, Set<? extends ConstraintViolation<?>> violations) {
195+
for ( ConstraintViolation<?> violation : violations ) {
196+
if ( violation.getMessage().contains( "{" ) ) {
197+
invalidMessages.add(
198+
"Message for constraint " + violation.getConstraintDescriptor().getAnnotation().annotationType() + " and locale " + locale
199+
+ " contains a curly brace: " + violation.getMessage() );
200+
}
201+
}
202+
}
203+
204+
@ScriptAssert(lang = "groovy", script = "_this.scriptAssert")
205+
private static class Bean {
206+
207+
@AssertFalse
208+
private boolean assertFalse = true;
209+
210+
@AssertTrue
211+
private boolean assertTrue = false;
212+
213+
@DecimalMax("3")
214+
private double decimalMax = 4;
215+
216+
@DecimalMin("3")
217+
private double decimalMin = 2;
218+
219+
@Digits(integer = 1, fraction = 3)
220+
private BigDecimal digits = BigDecimal.valueOf( 13333.3333f );
221+
222+
@Email
223+
private String email = "invalid";
224+
225+
@Future
226+
private LocalDate future = LocalDate.of( 2010, 10, 4 );
227+
228+
@FutureOrPresent
229+
private LocalDate futureOrPresent = LocalDate.of( 2010, 10, 4 );
230+
231+
@Max(4)
232+
private int max = 6;
233+
234+
@Min(4)
235+
private int min = 2;
236+
237+
@Negative
238+
private int negative = 4;
239+
240+
@NegativeOrZero
241+
private int negativeOrZero = 4;
242+
243+
@NotBlank
244+
private String notBlank = "";
245+
246+
@NotEmpty
247+
private List<String> notEmpty = Collections.emptyList();
248+
249+
@NotNull
250+
private String notNull = null;
251+
252+
@Null
253+
private String nullConstraint = "not null";
254+
255+
@Past
256+
private LocalDate past = LocalDate.of( 2890, 10, 4 );
257+
258+
@PastOrPresent
259+
private LocalDate pastOrPresent = LocalDate.of( 2890, 10, 4 );
260+
261+
@Pattern(regexp = "[0-9]+")
262+
private String pattern = "invalid";
263+
264+
@Positive
265+
private int positive = -4;
266+
267+
@PositiveOrZero
268+
private int positiveOrZero = -4;
269+
270+
@Size(min = 2, max = 4)
271+
private String size = "666666";
272+
273+
@CreditCardNumber
274+
private String creditCardNumber = "invalid";
275+
276+
@Currency("EUR")
277+
private MonetaryAmount currency = Money.of( 1000f, "USD" );
278+
279+
@EAN
280+
private String ean = "invalid";
281+
282+
@org.hibernate.validator.constraints.Email
283+
private String hvEmail = "invalid";
284+
285+
@ISBN
286+
private String isbn = "invalid";
287+
288+
@Length(min = 2, max = 4)
289+
private String length = "666666";
290+
291+
@CodePointLength(min = 2, max = 4)
292+
private String codePointLength = "666666";
293+
294+
@LuhnCheck
295+
private String luhnCheck = "4";
296+
297+
@Mod10Check
298+
private String mod10Check = "4";
299+
300+
@Mod11Check
301+
private String mod11Check = "4";
302+
303+
@ModCheck(multiplier = 2, modType = ModCheck.ModType.MOD10)
304+
private String modCheck = "4";
305+
306+
@org.hibernate.validator.constraints.NotBlank
307+
private String hvNotBlank = "";
308+
309+
@org.hibernate.validator.constraints.NotEmpty
310+
private List<String> hvNotEmpty = Collections.emptyList();
311+
312+
@Range(min = 2, max = 4)
313+
private int range = 6;
314+
315+
@SafeHtml
316+
private String safeHtml = "<script></script>";
317+
318+
@UniqueElements
319+
private List<String> uniqueElements = Arrays.asList( "a", "a" );
320+
321+
@URL
322+
private String url = "invalid";
323+
324+
@CNPJ
325+
private String cnpj = "invalid";
326+
327+
@CPF
328+
private String cpf = "invalid";
329+
330+
@TituloEleitoral
331+
private String tituloEleitoral = "invalid";
332+
333+
@REGON
334+
private String regon = "invalid";
335+
336+
@NIP
337+
private String nip = "invalid";
338+
339+
@PESEL
340+
private String pesel = "invalid";
341+
342+
@DurationMax(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4)
343+
private Duration durationMax = Duration.ofDays( 8 );
344+
345+
@DurationMin(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4)
346+
private Duration durationMin = Duration.ofDays( 2 );
347+
348+
@SuppressWarnings("unused")
349+
private boolean scriptAssert = false;
350+
}
351+
352+
private static class ParameterScriptAssertBean {
353+
354+
@ParameterScriptAssert(lang = "groovy", script = "test")
355+
public boolean doTest(boolean test) {
356+
return test;
357+
}
358+
}
359+
}

0 commit comments

Comments
 (0)