1- package io .github .belgif .rest .problem . api ;
1+ package io .github .belgif .rest .problem ;
22
33import static org .assertj .core .api .Assertions .*;
44
55import java .net .URI ;
66import java .util .Collections ;
77
8+ import org .junit .jupiter .api .BeforeAll ;
89import org .junit .jupiter .api .BeforeEach ;
910import org .junit .jupiter .api .Test ;
1011
12+ import com .acme .custom .CustomProblem ;
1113import com .fasterxml .jackson .core .JsonProcessingException ;
1214import com .fasterxml .jackson .databind .ObjectMapper ;
1315import com .fasterxml .jackson .databind .SerializationFeature ;
16+ import com .fasterxml .jackson .databind .cfg .PackageVersion ;
1417
15- import io .github .belgif .rest .problem .BadRequestProblem ;
16- import io .github .belgif .rest .problem .DefaultProblem ;
17- import io .github .belgif .rest .problem .ProblemModule ;
18+ import io .github .belgif .rest .problem .api .InEnum ;
19+ import io .github .belgif .rest .problem .api .Input ;
20+ import io .github .belgif .rest .problem .api .InputValidationIssue ;
21+ import io .github .belgif .rest .problem .api .InputValidationIssues ;
22+ import io .github .belgif .rest .problem .api .Problem ;
1823import io .github .belgif .rest .problem .registry .TestProblemTypeRegistry ;
1924
20- class ProblemTest {
25+ abstract class AbstractJacksonSerializationTest {
2126
2227 private ObjectMapper mapper ;
2328
29+ @ BeforeAll
30+ static void printJacksonVersion () {
31+ print ("jackson version: " + PackageVersion .VERSION );
32+ }
33+
2434 @ BeforeEach
2535 void setUp () {
2636 mapper = new ObjectMapper ();
2737 mapper .enable (SerializationFeature .INDENT_OUTPUT );
2838 TestProblemTypeRegistry registry = new TestProblemTypeRegistry ();
29- registry .registerProblemType (BadRequestProblem .class );
39+ registry .registerProblemType (BadRequestProblem .class , CustomProblem . class , TooManyRequestsProblem . class );
3040 mapper .registerModule (new ProblemModule (registry ));
3141 }
3242
3343 @ Test
34- void jacksonRoundtrip () throws JsonProcessingException {
44+ void badRequestProblem () throws JsonProcessingException {
3545 BadRequestProblem problem = new BadRequestProblem ();
3646 problem .setDetail ("my detail message" );
37- String json = mapper .writeValueAsString (problem );
38- print (json );
39- Problem result = mapper .readValue (json , Problem .class );
40- assertThat (result ).isInstanceOf (BadRequestProblem .class );
41- print (mapper .writeValueAsString (result ));
47+ problem .setAdditionalProperty ("additional" , "property" );
48+ assertSerializationRoundtrip (problem );
4249 }
4350
4451 @ Test
45- void jacksonRoundtripSsinReplaced () throws JsonProcessingException {
52+ void customProblem () throws JsonProcessingException {
53+ CustomProblem problem = new CustomProblem ("custom" );
54+ problem .setAdditionalProperty ("additional" , "property" );
55+ assertSerializationRoundtrip (problem );
56+ }
57+
58+ @ Test
59+ void retryAfterProblem () throws JsonProcessingException {
60+ TooManyRequestsProblem problem = new TooManyRequestsProblem ();
61+ problem .setRetryAfterSec (60L );
62+ problem .setAdditionalProperty ("additional" , "property" );
63+ assertSerializationRoundtrip (problem );
64+ }
65+
66+ @ Test
67+ void badRequestProblemReplacedSsin () throws JsonProcessingException {
4668 BadRequestProblem problem = new BadRequestProblem (
4769 InputValidationIssues .replacedSsin (InEnum .BODY , "parent[1].ssin" , "12345678901" , "23456789012" ));
48- String json = mapper .writeValueAsString (problem );
49- print (json );
50- Problem result = mapper .readValue (json , Problem .class );
51- assertThat (result ).isInstanceOf (BadRequestProblem .class );
52- assertThat (((BadRequestProblem ) result ).getIssues ().get (0 ).getAdditionalProperties ())
53- .containsExactly (entry ("replacedBy" , "23456789012" ));
54- print (mapper .writeValueAsString (result ));
70+ assertSerializationRoundtrip (problem );
5571 }
5672
5773 @ Test
58- void jacksonRoundtripMultipleInputs () throws JsonProcessingException {
74+ void badRequestProblemMultipleInputs () throws JsonProcessingException {
5975 BadRequestProblem problem = new BadRequestProblem ();
6076 problem .setDetail ("my detail message" );
6177 InputValidationIssue issue = new InputValidationIssue ();
6278 issue .setType (URI .create ("urn:problem-type:cbss:input-validation:exactlyOneOfExpected" ));
6379 issue .setTitle ("Exactly one of these inputs is expected" );
6480 issue .setTitle ("Exactly one of inputs [one, two] is expected" );
65- issue .addInput (new Input ( InEnum . QUERY , "one" , 1 ));
66- issue .addInput (new Input ( InEnum . QUERY , "two" , 2 ));
81+ issue .addInput (Input . query ( "one" , 1 ));
82+ issue .addInput (Input . query ( "two" , 2 ));
6783 problem .addIssue (issue );
68- String json = mapper .writeValueAsString (problem );
69- print (json );
70- Problem result = mapper .readValue (json , Problem .class );
71- assertThat (result ).isInstanceOf (BadRequestProblem .class );
72- assertThat (((BadRequestProblem ) result ).getIssues ().get (0 ).getInputs ()).hasSize (2 );
73- print (mapper .writeValueAsString (result ));
84+ assertSerializationRoundtrip (problem );
7485 }
7586
7687 @ Test
77- void jacksonUnmarshallInNameValueWithInputsArray () throws JsonProcessingException {
88+ void badRequestProblemWithInNameValueAndInputsArray () throws JsonProcessingException {
7889 String json = "{\n "
7990 + " \" type\" : \" urn:problem-type:belgif:badRequest\" ,\n "
8091 + " \" href\" : \" https://www.belgif.be/specification/rest/api-guide/problems/badRequest.html\" ,\n "
@@ -101,21 +112,22 @@ void jacksonUnmarshallInNameValueWithInputsArray() throws JsonProcessingExceptio
101112 InputValidationIssue issue = ((BadRequestProblem ) result ).getIssues ().get (0 );
102113 assertThat (issue .getName ()).isEqualTo ("test" );
103114 assertThat (issue .getInputs ().get (0 ).getName ()).isEqualTo ("test" );
104- print (mapper .writeValueAsString (result ));
115+ assertThat (mapper .writeValueAsString (result )). isEqualToIgnoringWhitespace ( json );
105116 }
106117
107118 @ Test
108- void fallbackToDefaultProblemWhenProblemTypeNotMapped () throws JsonProcessingException {
119+ void unmappedProblem () throws JsonProcessingException {
109120 mapper = new ObjectMapper ();
110121 mapper .enable (SerializationFeature .INDENT_OUTPUT );
111122
112123 BadRequestProblem problem = new BadRequestProblem ();
113124 problem .setDetail ("my detail message" );
125+ problem .setAdditionalProperty ("additional" , "property" );
114126 String json = mapper .writeValueAsString (problem );
115127 print (json );
116128 Problem result = mapper .readValue (json , Problem .class );
117129 assertThat (result ).isInstanceOf (DefaultProblem .class );
118- print (mapper .writeValueAsString (result ));
130+ assertThat (mapper .writeValueAsString (result )). isEqualTo ( json );
119131 }
120132
121133 @ Test
@@ -137,7 +149,8 @@ void legacyInvalidParamProblem() throws JsonProcessingException {
137149 Problem problem = mapper .readValue (json , Problem .class );
138150 assertThat (problem ).isInstanceOf (BadRequestProblem .class );
139151 BadRequestProblem badRequestProblem = (BadRequestProblem ) problem ;
140- InvalidParam invalidParam = badRequestProblem .getInvalidParams ().get (0 );
152+ assertThat (badRequestProblem .getInvalidParams ()).isNotEmpty ();
153+ assertThat (mapper .writeValueAsString (badRequestProblem )).isEqualToIgnoringWhitespace (json );
141154 }
142155
143156 @ Test
@@ -159,6 +172,30 @@ void unknownProblemWithMessage() throws JsonProcessingException {
159172 entry ("message" , "552-Id Value is invalid" ));
160173 }
161174
175+ @ Test
176+ void additionalExceptionProperties () throws JsonProcessingException {
177+ BadRequestProblem problem = new BadRequestProblem ();
178+ problem .setAdditionalProperty ("cause" , "cause" );
179+ problem .setAdditionalProperty ("stackTrace" , "stackTrace" );
180+ problem .setAdditionalProperty ("suppressed" , "suppressed" );
181+ problem .setAdditionalProperty ("message" , "message" );
182+ problem .setAdditionalProperty ("localizedMessage" , "localizedMessage" );
183+ assertSerializationRoundtrip (problem );
184+ }
185+
186+ void assertSerializationRoundtrip (Problem problem ) throws JsonProcessingException {
187+ String json = mapper .writeValueAsString (problem );
188+ print (json );
189+ Problem result = mapper .readValue (json , Problem .class );
190+ assertThat (result ).withRepresentation (p -> {
191+ try {
192+ return mapper .writeValueAsString (p );
193+ } catch (JsonProcessingException e ) {
194+ throw new RuntimeException (e );
195+ }
196+ }).isEqualTo (problem );
197+ }
198+
162199 private static void print (String value ) {
163200 System .out .println (value ); // SUPPRESS CHECKSTYLE
164201 }
0 commit comments