22
33import static org .assertj .core .api .Assertions .assertThat ;
44
5+ import java .net .URI ;
56import java .util .Arrays ;
67import java .util .Collection ;
8+ import java .util .Collections ;
79import java .util .HashMap ;
810import java .util .Map ;
911import org .junit .jupiter .api .Test ;
12+ import org .junit .jupiter .params .ParameterizedTest ;
13+ import org .junit .jupiter .params .provider .NullSource ;
14+ import org .junit .jupiter .params .provider .ValueSource ;
1015
1116class ProblemBuilderImplTests {
1217
@@ -18,6 +23,48 @@ void givenNullProblemStatus_shouldNotSetTitleOrStatus() {
1823 assertThat (problem .getTitle ()).isNull ();
1924 }
2025
26+ @ Test
27+ void givenProblemStatusWithNoTitle_shouldSetBothStatusAndTitle () {
28+ Problem problem = Problem .builder ().status (ProblemStatus .BAD_REQUEST ).build ();
29+
30+ assertThat (problem .getStatus ()).isEqualTo (400 );
31+ assertThat (problem .getTitle ()).isEqualTo ("Bad Request" );
32+ }
33+
34+ @ Test
35+ void givenProblemStatusWithCustomTitle_shouldNotOverrideTitle () {
36+ Problem problem =
37+ Problem .builder ().title ("Custom Title" ).status (ProblemStatus .BAD_REQUEST ).build ();
38+
39+ assertThat (problem .getStatus ()).isEqualTo (400 );
40+ assertThat (problem .getTitle ()).isEqualTo ("Custom Title" );
41+ }
42+
43+ @ Test
44+ void givenSecondProblemStatusWithMatchingTitle_shouldUpdateTitle () {
45+ Problem problem =
46+ Problem .builder ().status (ProblemStatus .BAD_REQUEST ).status (ProblemStatus .NOT_FOUND ).build ();
47+
48+ assertThat (problem .getStatus ()).isEqualTo (404 );
49+ assertThat (problem .getTitle ()).isEqualTo ("Not Found" );
50+ }
51+
52+ @ Test
53+ void givenNumericStatusAfterProblemStatus_shouldNotAffectTitle () {
54+ Problem problem = Problem .builder ().status (ProblemStatus .BAD_REQUEST ).status (404 ).build ();
55+
56+ assertThat (problem .getStatus ()).isEqualTo (404 );
57+ assertThat (problem .getTitle ()).isEqualTo ("Bad Request" );
58+ }
59+
60+ @ Test
61+ void givenProblemStatusAfterNumericStatus_shouldSetBothStatusAndTitle () {
62+ Problem problem = Problem .builder ().status (404 ).status (ProblemStatus .BAD_REQUEST ).build ();
63+
64+ assertThat (problem .getStatus ()).isEqualTo (400 );
65+ assertThat (problem .getTitle ()).isEqualTo ("Bad Request" );
66+ }
67+
2168 @ Test
2269 void givenNullNameExtension_shouldIgnoreIt () {
2370 Problem problem = Problem .builder ().extension (null , "value" ).build ();
@@ -78,4 +125,145 @@ void givenCollectionWithNullElement_shouldIgnoreNullElement() {
78125
79126 assertThat (problem .getExtensions ()).containsExactlyInAnyOrder ("x" , "y" );
80127 }
128+
129+ @ Test
130+ void givenNullUriType_shouldIgnoreIt () {
131+ Problem problem = Problem .builder ().type ((URI ) null ).build ();
132+
133+ assertThat (problem .getType ()).isEqualTo (Problem .BLANK_TYPE );
134+ }
135+
136+ @ Test
137+ void givenNullStringType_shouldIgnoreIt () {
138+ Problem problem = Problem .builder ().type ((String ) null ).build ();
139+
140+ assertThat (problem .getType ()).isEqualTo (Problem .BLANK_TYPE );
141+ }
142+
143+ @ ParameterizedTest
144+ @ ValueSource (strings = "/instances/valid" )
145+ @ NullSource
146+ void givenNullUriInstance_shouldIgnoreIt (URI instance ) {
147+ Problem problem = Problem .builder ().instance (instance ).instance ((String ) null ).build ();
148+
149+ assertThat (problem .getInstance ()).isEqualTo (instance );
150+ }
151+
152+ @ ParameterizedTest
153+ @ ValueSource (strings = "/instances/valid" )
154+ @ NullSource
155+ void givenNullStringInstance_shouldIgnoreIt (URI instance ) {
156+ Problem problem = Problem .builder ().instance (instance ).instance ((String ) null ).build ();
157+
158+ assertThat (problem .getInstance ()).isEqualTo (instance );
159+ }
160+
161+ @ Test
162+ void givenNullMap_whenExtension_thenIgnoresIt () {
163+ Problem problem = Problem .builder ().extension ((Map <String , Object >) null ).build ();
164+
165+ assertThat (problem .getExtensions ()).isEmpty ();
166+ }
167+
168+ @ Test
169+ void givenEmptyMap_whenExtension_thenIgnoresIt () {
170+ Problem problem = Problem .builder ().extension (Collections .emptyMap ()).build ();
171+
172+ assertThat (problem .getExtensions ()).isEmpty ();
173+ }
174+
175+ @ Test
176+ void givenMapWithExistingExtensions_whenNullMap_thenKeepsExisting () {
177+ Problem problem =
178+ Problem .builder ()
179+ .extension ("existing" , "value" )
180+ .extension ((Map <String , Object >) null )
181+ .build ();
182+
183+ assertThat (problem .getExtensions ()).containsExactly ("existing" );
184+ assertThat (problem .getExtensionValue ("existing" )).isEqualTo ("value" );
185+ }
186+
187+ @ Test
188+ void givenMapWithExistingExtensions_whenEmptyMap_thenKeepsExisting () {
189+ Problem problem =
190+ Problem .builder ().extension ("existing" , "value" ).extension (Collections .emptyMap ()).build ();
191+
192+ assertThat (problem .getExtensions ()).containsExactly ("existing" );
193+ assertThat (problem .getExtensionValue ("existing" )).isEqualTo ("value" );
194+ }
195+
196+ @ Test
197+ void givenMapWithNullKey_whenExtension_thenIgnoresNullKey () {
198+ Map <String , Object > map = new HashMap <>();
199+ map .put (null , "value" );
200+ map .put ("valid" , "value2" );
201+
202+ Problem problem = Problem .builder ().extension (map ).build ();
203+
204+ assertThat (problem .getExtensions ()).containsExactly ("valid" );
205+ assertThat (problem .getExtensionValue ("valid" )).isEqualTo ("value2" );
206+ }
207+
208+ @ Test
209+ void givenMapWithNullValue_whenExtension_thenAcceptsNullValue () {
210+ Map <String , Object > map = new HashMap <>();
211+ map .put ("key" , null );
212+
213+ Problem problem = Problem .builder ().extension (map ).build ();
214+
215+ assertThat (problem .getExtensions ()).containsExactly ("key" );
216+ assertThat (problem .getExtensionValue ("key" )).isNull ();
217+ }
218+
219+ @ Test
220+ void givenMapWithMixedValues_whenExtension_thenAcceptsAllValidEntries () {
221+ Map <String , Object > map = new HashMap <>();
222+ map .put (null , "ignored" );
223+ map .put ("nullValue" , null );
224+ map .put ("valid" , "value" );
225+ map .put ("number" , 42 );
226+
227+ Problem problem = Problem .builder ().extension (map ).build ();
228+
229+ assertThat (problem .getExtensions ()).containsExactlyInAnyOrder ("nullValue" , "valid" , "number" );
230+ assertThat (problem .getExtensionValue ("nullValue" )).isNull ();
231+ assertThat (problem .getExtensionValue ("valid" )).isEqualTo ("value" );
232+ assertThat (problem .getExtensionValue ("number" )).isEqualTo (42 );
233+ }
234+
235+ @ Test
236+ void givenManuallySetTitleMatchingStatus_whenNewStatus_thenKeepTitle () {
237+ Problem problem =
238+ Problem .builder ()
239+ .status (ProblemStatus .BAD_REQUEST )
240+ .title ("Bad Request" )
241+ .status (ProblemStatus .NOT_FOUND )
242+ .build ();
243+
244+ assertThat (problem .getStatus ()).isEqualTo (404 );
245+ assertThat (problem .getTitle ()).isEqualTo ("Bad Request" );
246+ }
247+
248+ @ Test
249+ void givenStatusTitleNotManuallySet_whenNewStatus_thenUpdateTitle () {
250+ Problem problem =
251+ Problem .builder ().status (ProblemStatus .BAD_REQUEST ).status (ProblemStatus .NOT_FOUND ).build ();
252+
253+ assertThat (problem .getStatus ()).isEqualTo (404 );
254+ assertThat (problem .getTitle ()).isEqualTo ("Not Found" );
255+ }
256+
257+ @ Test
258+ void givenManuallySetTitleDifferentFromStatus_whenNewStatus_thenKeepTitle () {
259+ Problem problem =
260+ Problem .builder ()
261+ .status (ProblemStatus .BAD_REQUEST )
262+ .title ("Custom Error" )
263+ .status (ProblemStatus .NOT_FOUND )
264+ .build ();
265+
266+ assertThat (problem .getStatus ()).isEqualTo (404 );
267+ assertThat (problem .getTitle ()).isEqualTo ("Custom Error" );
268+ }
81269}
0 commit comments