Skip to content

Commit 50a752d

Browse files
committed
HV-1591 Test for deprecated use of Value annotation
A user must apply `@Value` to the argument(s) of a container type. If they don't, there should be message in the logs warning them.
1 parent 4bedfc5 commit 50a752d

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package org.hibernate.validator.test.constraints.annotations.hv;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Set;
8+
9+
import org.apache.logging.log4j.Level;
10+
import org.apache.logging.log4j.core.Logger;
11+
import org.apache.logging.log4j.core.LoggerContext;
12+
import org.apache.logging.log4j.core.config.Configurator;
13+
14+
import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder;
15+
import org.hibernate.validator.test.constraints.annotations.AbstractConstrainedTest;
16+
import org.hibernate.validator.test.internal.engine.serialization.Email;
17+
import org.hibernate.validator.testutils.ListAppender;
18+
19+
import org.testng.annotations.AfterTest;
20+
import org.testng.annotations.BeforeMethod;
21+
import org.testng.annotations.BeforeTest;
22+
import org.testng.annotations.Test;
23+
24+
import jakarta.validation.Valid;
25+
26+
public class ValidAnnotationTest extends AbstractConstrainedTest {
27+
28+
private ListAppender logAppender;
29+
private Level originalLogLevel;
30+
private Logger targetLogger;
31+
32+
/**
33+
* @return true if the string matches the expected log message for deprecated use of @Value.
34+
*/
35+
private static boolean deprecatedUsedOfValueCode(String s) {
36+
return s.startsWith("HV000270");
37+
}
38+
39+
@BeforeTest
40+
public void setUpLogger() {
41+
logAppender = new ListAppender(ValidAnnotationTest.class.getSimpleName());
42+
logAppender.start();
43+
44+
LoggerContext context = LoggerContext.getContext(false);
45+
targetLogger = context.getLogger(CascadingMetaDataBuilder.class.getName());
46+
targetLogger.addAppender(logAppender);
47+
48+
// Set level of log messages to WARN (if they are not already enabled)
49+
if (targetLogger.getLevel().isMoreSpecificThan(Level.WARN)) {
50+
// Store the original log level to restore it later
51+
originalLogLevel = targetLogger.getLevel();
52+
53+
// Override the log level for this test class only
54+
// Default tests will only print the error messages, we need to override it
55+
// so that we can capture the deprecated warning message
56+
Configurator.setLevel(CascadingMetaDataBuilder.class.getName(), Level.WARN);
57+
context.updateLoggers();
58+
}
59+
}
60+
61+
@BeforeMethod
62+
public void cleanLogger() {
63+
logAppender.clear();
64+
}
65+
66+
@AfterTest
67+
public void tearDownLogger() {
68+
targetLogger.removeAppender(logAppender);
69+
logAppender.stop();
70+
71+
// Restore the original log level
72+
if (originalLogLevel != null) {
73+
Configurator.setLevel(CascadingMetaDataBuilder.class.getName(), originalLogLevel);
74+
// Update the logger context to apply changes
75+
LoggerContext context = LoggerContext.getContext(false);
76+
context.updateLoggers();
77+
}
78+
}
79+
80+
@Test
81+
public void twiceWithList() {
82+
class Foo {
83+
84+
@Valid
85+
private List<@Valid String> prop;
86+
87+
public Foo(List<String> prop) {
88+
this.prop = prop;
89+
}
90+
}
91+
92+
Foo foo = new Foo(List.of("K1"));
93+
validator.validate(foo);
94+
95+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
96+
}
97+
98+
@Test
99+
public void onTheContainerWithList() {
100+
class Foo {
101+
102+
@Valid
103+
private List<MyBean> prop;
104+
105+
public Foo(List<MyBean> prop) {
106+
this.prop = prop;
107+
}
108+
}
109+
110+
Foo foo = new Foo(List.of(new MyBean( "[email protected]" )));
111+
validator.validate(foo);
112+
113+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
114+
}
115+
116+
@Test
117+
public void twiceWithSet() {
118+
class Foo {
119+
120+
@Valid
121+
private Set<@Valid String> prop;
122+
123+
public Foo(Set<String> prop) {
124+
this.prop = prop;
125+
}
126+
}
127+
128+
Foo foo = new Foo(Set.of("K1"));
129+
validator.validate(foo);
130+
131+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
132+
}
133+
134+
@Test
135+
public void onTheContainerWithSet() {
136+
class Foo {
137+
138+
@Valid
139+
private Set<MyBean> prop;
140+
141+
public Foo(Set<MyBean> prop) {
142+
this.prop = prop;
143+
}
144+
}
145+
146+
Foo foo = new Foo(Set.of(new MyBean("[email protected]")));
147+
validator.validate(foo);
148+
149+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
150+
}
151+
152+
@Test
153+
public void twiceWithMap() {
154+
class Foo {
155+
156+
@Valid
157+
private Map<String, @Valid String> prop;
158+
159+
public Foo(Map<String, String> prop) {
160+
this.prop = prop;
161+
}
162+
}
163+
164+
Foo foo = new Foo(Map.of("K1", "V1"));
165+
validator.validate(foo);
166+
167+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
168+
}
169+
170+
@Test
171+
public void onContainerWithMap() {
172+
class Foo {
173+
174+
@Valid
175+
private Map<String, MyBean> prop;
176+
177+
public Foo(Map<String, MyBean> prop) {
178+
this.prop = prop;
179+
}
180+
}
181+
182+
Foo foo = new Foo(Map.of("K1", new MyBean("[email protected]")));
183+
validator.validate(foo);
184+
185+
assertThat(logAppender.getMessages()).hasSize(1).allMatch(ValidAnnotationTest::deprecatedUsedOfValueCode);
186+
}
187+
188+
private static class MyBean {
189+
@Email
190+
private String email;
191+
192+
public MyBean(String email) {
193+
this.email = email;
194+
}
195+
196+
public String getEmail() {
197+
return email;
198+
}
199+
200+
public void setEmail(String email) {
201+
this.email = email;
202+
}
203+
}
204+
}

0 commit comments

Comments
 (0)