Skip to content

Commit 228bc0e

Browse files
authored
Add tests for Record deserialization regression and related (#3921)
1 parent 3140bb7 commit 228bc0e

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.fasterxml.jackson.databind.failing;
2+
3+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
4+
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
5+
import com.fasterxml.jackson.annotation.JsonCreator;
6+
import com.fasterxml.jackson.annotation.PropertyAccessor;
7+
import com.fasterxml.jackson.core.JsonProcessingException;
8+
import com.fasterxml.jackson.databind.BaseMapTest;
9+
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
11+
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
12+
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
13+
import com.fasterxml.jackson.databind.module.SimpleModule;
14+
15+
/**
16+
* Test case that covers both failing-by-regression tests and passing tests.
17+
* <p>For more details, refer to
18+
* <a href="https://github.com/FasterXML/jackson-databind/issues/3906">
19+
* [databind#3906]: Regression: 2.15.0 breaks deserialization for records when mapper.setVisibility(ALL, NONE);</a>
20+
*/
21+
public class RecordDeserialization3906Test extends BaseMapTest {
22+
23+
/*
24+
/**********************************************************
25+
/* Set up
26+
/**********************************************************
27+
*/
28+
29+
record Record3906(String string, int integer) {
30+
}
31+
32+
@JsonAutoDetect(creatorVisibility = Visibility.NON_PRIVATE)
33+
record Record3906Annotated(String string, int integer) {
34+
}
35+
36+
record Record3906Creator(String string, int integer) {
37+
@JsonCreator
38+
Record3906Creator {
39+
}
40+
}
41+
42+
private record PrivateRecord3906(String string, int integer) {
43+
}
44+
45+
/*
46+
/**********************************************************
47+
/* Failing tests that pass in 2.14 (regression)
48+
/**********************************************************
49+
*/
50+
51+
// minimal config for reproduction
52+
public void testEmptyJsonToRecordMiminal() throws JsonProcessingException {
53+
ObjectMapper mapper = newJsonMapper();
54+
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
55+
56+
Record3906 recordDeser = mapper.readValue("{}", Record3906.class);
57+
58+
assertEquals(new Record3906(null, 0), recordDeser);
59+
}
60+
61+
// actual config used reproduction
62+
public void testEmptyJsonToRecordActualImpl() throws JsonProcessingException {
63+
ObjectMapper mapper = newJsonMapper();
64+
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
65+
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
66+
67+
Record3906 recordDeser = mapper.readValue("{}", Record3906.class);
68+
69+
assertEquals(new Record3906(null, 0), recordDeser);
70+
}
71+
72+
/*
73+
/**********************************************************
74+
/* Passing Tests : Suggested work-arounds
75+
/* for future modifications
76+
/**********************************************************
77+
*/
78+
79+
public void testEmptyJsonToRecordWorkAround() throws JsonProcessingException {
80+
ObjectMapper mapper = newJsonMapper();
81+
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
82+
mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.ANY);
83+
84+
Record3906 recordDeser = mapper.readValue("{}", Record3906.class);
85+
86+
assertEquals(new Record3906(null, 0), recordDeser);
87+
}
88+
89+
public void testEmptyJsonToRecordCreatorsVisibile() throws JsonProcessingException {
90+
ObjectMapper mapper = newJsonMapper();
91+
mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.NON_PRIVATE);
92+
93+
Record3906 recordDeser = mapper.readValue("{}", Record3906.class);
94+
assertEquals(new Record3906(null, 0), recordDeser);
95+
}
96+
97+
public void testEmptyJsonToRecordUsingModule() throws JsonProcessingException {
98+
ObjectMapper mapper = jsonMapperBuilder().addModule(new SimpleModule() {
99+
@Override
100+
public void setupModule(SetupContext context) {
101+
super.setupModule(context);
102+
context.insertAnnotationIntrospector(new NopAnnotationIntrospector() {
103+
@Override
104+
public VisibilityChecker<?> findAutoDetectVisibility(AnnotatedClass ac,
105+
VisibilityChecker<?> checker) {
106+
return ac.getType().isRecordType()
107+
? checker.withCreatorVisibility(JsonAutoDetect.Visibility.NON_PRIVATE)
108+
: checker;
109+
}
110+
});
111+
}
112+
}).build();
113+
114+
Record3906 recordDeser = mapper.readValue("{}", Record3906.class);
115+
assertEquals(new Record3906(null, 0), recordDeser);
116+
}
117+
118+
public void testEmptyJsonToRecordDirectAutoDetectConfig() throws JsonProcessingException {
119+
ObjectMapper mapper = newJsonMapper();
120+
121+
Record3906Annotated recordDeser = mapper.readValue("{}", Record3906Annotated.class);
122+
assertEquals(new Record3906Annotated(null, 0), recordDeser);
123+
}
124+
125+
public void testEmptyJsonToRecordJsonCreator() throws JsonProcessingException {
126+
ObjectMapper mapper = newJsonMapper();
127+
128+
Record3906Creator recordDeser = mapper.readValue("{}", Record3906Creator.class);
129+
assertEquals(new Record3906Creator(null, 0), recordDeser);
130+
}
131+
132+
public void testEmptyJsonToRecordUsingModuleOther() throws JsonProcessingException {
133+
ObjectMapper mapper = jsonMapperBuilder().addModule(
134+
new SimpleModule() {
135+
@Override
136+
public void setupModule(SetupContext context) {
137+
super.setupModule(context);
138+
context.insertAnnotationIntrospector(new NopAnnotationIntrospector() {
139+
@Override
140+
public VisibilityChecker<?> findAutoDetectVisibility(AnnotatedClass ac,
141+
VisibilityChecker<?> checker) {
142+
if (ac.getType() == null) {
143+
return checker;
144+
}
145+
if (!ac.getType().isRecordType()) {
146+
return checker;
147+
}
148+
// If this is a Record, then increase the "creator" visibility again
149+
return checker.withCreatorVisibility(Visibility.ANY);
150+
}
151+
});
152+
}
153+
})
154+
.build();
155+
156+
assertEquals(new Record3906(null, 0),
157+
mapper.readValue("{}", Record3906.class));
158+
assertEquals(new PrivateRecord3906(null, 0),
159+
mapper.readValue("{}", PrivateRecord3906.class));
160+
}
161+
}

0 commit comments

Comments
 (0)