1- package gov .cms .qpp .conversion .api .controllers . v1 ;
1+ package gov .cms .qpp .conversion .api .exceptions ;
22
33import com .amazonaws .AmazonServiceException ;
44import com .google .common .truth .Truth ;
5+ import gov .cms .qpp .conversion .ConversionReport ;
6+ import gov .cms .qpp .conversion .Converter ;
7+ import gov .cms .qpp .conversion .PathSource ;
8+ import gov .cms .qpp .conversion .api .controllers .v1 .QrdaControllerV1 ;
9+ import gov .cms .qpp .conversion .api .helper .AdvancedApmHelper ;
10+ import gov .cms .qpp .conversion .api .model .Constants ;
11+ import gov .cms .qpp .conversion .api .services .AuditService ;
12+ import gov .cms .qpp .conversion .api .services .QrdaService ;
13+ import gov .cms .qpp .conversion .api .services .ValidationService ;
14+ import gov .cms .qpp .conversion .model .error .AllErrors ;
15+ import gov .cms .qpp .conversion .model .error .QppValidationException ;
16+ import gov .cms .qpp .conversion .model .error .TransformException ;
17+ import gov .cms .qpp .test .MockitoExtension ;
18+ import gov .cms .qpp .test .logging .LoggerContract ;
519import org .apache .commons .lang3 .ArrayUtils ;
620import org .junit .jupiter .api .BeforeAll ;
721import org .junit .jupiter .api .BeforeEach ;
822import org .junit .jupiter .api .Test ;
923import org .junit .jupiter .api .extension .ExtendWith ;
10- import org .mockito .ArgumentMatchers ;
1124import org .mockito .InjectMocks ;
1225import org .mockito .Mock ;
1326import org .mockito .Mockito ;
2033import org .springframework .test .web .servlet .request .MockMvcRequestBuilders ;
2134import org .springframework .test .web .servlet .setup .MockMvcBuilders ;
2235
23- import gov .cms .qpp .conversion .ConversionReport ;
24- import gov .cms .qpp .conversion .Converter ;
25- import gov .cms .qpp .conversion .PathSource ;
26- import gov .cms .qpp .conversion .api .exceptions .InvalidFileTypeException ;
27- import gov .cms .qpp .conversion .api .exceptions .InvalidPurposeException ;
28- import gov .cms .qpp .conversion .api .exceptions .NoFileInDatabaseException ;
29- import gov .cms .qpp .conversion .api .helper .AdvancedApmHelper ;
30- import gov .cms .qpp .conversion .api .services .AuditService ;
31- import gov .cms .qpp .conversion .model .error .AllErrors ;
32- import gov .cms .qpp .conversion .model .error .QppValidationException ;
33- import gov .cms .qpp .conversion .model .error .TransformException ;
34- import gov .cms .qpp .test .MockitoExtension ;
35- import gov .cms .qpp .test .logging .LoggerContract ;
36-
3736import java .nio .file .Path ;
3837import java .util .UUID ;
3938import java .util .concurrent .CompletableFuture ;
4039
4140import static com .google .common .truth .Truth .assertThat ;
4241import static com .google .common .truth .Truth .assertWithMessage ;
4342import static org .mockito .ArgumentMatchers .any ;
44- import static org .mockito .ArgumentMatchers .anyString ;
4543import static org .mockito .Mockito .when ;
4644
47-
4845@ ExtendWith (MockitoExtension .class )
49- class ExceptionHandlerControllerV1Test implements LoggerContract {
46+ class GlobalExceptionHandlerTest implements LoggerContract {
5047
5148 private static ConversionReport report ;
52- private static AllErrors allErrors = new AllErrors ();
49+ private static final AllErrors allErrors = new AllErrors ();
5350
5451 @ InjectMocks
55- private ExceptionHandlerControllerV1 objectUnderTest ;
52+ private GlobalExceptionHandler objectUnderTest ;
5653
5754 @ Mock
5855 private AuditService auditService ;
5956
6057 @ BeforeAll
6158 static void setup () {
59+ // NOTE: If this path is flaky in CI, move the file to src/test/resources and load via classpath.
6260 Path path = Path .of ("../qrda-files/valid-QRDA-III-latest.xml" );
6361 report = new Converter (new PathSource (path )).getReport ();
6462 report .setReportDetails (allErrors );
@@ -68,6 +66,8 @@ static void setup() {
6866 void before () {
6967 when (auditService .failConversion (any (ConversionReport .class )))
7068 .thenReturn (CompletableFuture .completedFuture (null ));
69+ when (auditService .failValidation (any (ConversionReport .class )))
70+ .thenReturn (CompletableFuture .completedFuture (null ));
7171 }
7272
7373 @ Test
@@ -99,13 +99,14 @@ void testTransformExceptionBody() {
9999 new TransformException ("test transform exception" , new NullPointerException (), report );
100100
101101 ResponseEntity <AllErrors > responseEntity = objectUnderTest .handleTransformException (exception );
102+
102103 assertThat (responseEntity .getBody ()).isEqualTo (allErrors );
103104 }
104105
105106 @ Test
106107 void testQppValidationExceptionStatusCode () {
107108 QppValidationException exception =
108- new QppValidationException ("test transform exception" , new NullPointerException (), report );
109+ new QppValidationException ("test validation exception" , new NullPointerException (), report );
109110
110111 ResponseEntity <AllErrors > responseEntity = objectUnderTest .handleQppValidationException (exception );
111112
@@ -117,7 +118,7 @@ void testQppValidationExceptionStatusCode() {
117118 @ Test
118119 void testQppValidationExceptionHeaderContentType () {
119120 QppValidationException exception =
120- new QppValidationException ("test transform exception" , new NullPointerException (), report );
121+ new QppValidationException ("test validation exception" , new NullPointerException (), report );
121122
122123 ResponseEntity <AllErrors > responseEntity = objectUnderTest .handleQppValidationException (exception );
123124
@@ -128,9 +129,10 @@ void testQppValidationExceptionHeaderContentType() {
128129 @ Test
129130 void testQppValidationExceptionBody () {
130131 QppValidationException exception =
131- new QppValidationException ("test transform exception" , new NullPointerException (), report );
132+ new QppValidationException ("test validation exception" , new NullPointerException (), report );
132133
133134 ResponseEntity <AllErrors > responseEntity = objectUnderTest .handleQppValidationException (exception );
135+
134136 assertThat (responseEntity .getBody ()).isEqualTo (allErrors );
135137 }
136138
@@ -141,7 +143,7 @@ void testFileNotFoundExceptionStatusCode() {
141143
142144 ResponseEntity <String > responseEntity = objectUnderTest .handleFileNotFoundException (exception );
143145
144- assertWithMessage ("The response entity's status code must be 422 ." )
146+ assertWithMessage ("The response entity's status code must be 404 ." )
145147 .that (responseEntity .getStatusCode ())
146148 .isEqualTo (HttpStatus .NOT_FOUND );
147149 }
@@ -163,6 +165,7 @@ void testFileNotFoundExceptionBody() {
163165 new NoFileInDatabaseException (AdvancedApmHelper .FILE_NOT_FOUND );
164166
165167 ResponseEntity <String > responseEntity = objectUnderTest .handleFileNotFoundException (exception );
168+
166169 assertThat (responseEntity .getBody ()).isEqualTo (AdvancedApmHelper .FILE_NOT_FOUND );
167170 }
168171
@@ -173,7 +176,7 @@ void testInvalidFileTypeExceptionStatusCode() {
173176
174177 ResponseEntity <String > responseEntity = objectUnderTest .handleInvalidFileTypeException (exception );
175178
176- assertWithMessage ("The response entity's status code must be 422 ." )
179+ assertWithMessage ("The response entity's status code must be 404 ." )
177180 .that (responseEntity .getStatusCode ())
178181 .isEqualTo (HttpStatus .NOT_FOUND );
179182 }
@@ -195,6 +198,7 @@ void testInvalidFileTypeExceptionBody() {
195198 new InvalidFileTypeException (AdvancedApmHelper .FILE_NOT_FOUND );
196199
197200 ResponseEntity <String > responseEntity = objectUnderTest .handleInvalidFileTypeException (exception );
201+
198202 assertThat (responseEntity .getBody ()).isEqualTo (AdvancedApmHelper .FILE_NOT_FOUND );
199203 }
200204
@@ -208,15 +212,6 @@ void testHandleAmazonExceptionStatusCode() {
208212 Truth .assertThat (response .getStatusCodeValue ()).isEqualTo (404 );
209213 }
210214
211- // @Test
212- // void testHandleAmazonExceptionResponseBody() {
213- // AmazonServiceException exception = new AmazonServiceException("some message");
214- //
215- // ResponseEntity<String> response = objectUnderTest.handleAmazonException(exception);
216- //
217- // Truth.assertThat(response.getBody()).contains("some message");
218- // }
219-
220215 @ Test
221216 void testHandleInvalidPurposeExceptionExceptionResponseBody () {
222217 InvalidPurposeException exception = new InvalidPurposeException ("some message" );
@@ -228,23 +223,32 @@ void testHandleInvalidPurposeExceptionExceptionResponseBody() {
228223
229224 @ Test
230225 void testHandleInvalidPurposeExceptionResponseBodyDoesInterception () throws Exception {
231- QrdaControllerV1 mock = Mockito .mock (QrdaControllerV1 .class );
232- MockMvc mvc = MockMvcBuilders .standaloneSetup (mock )
233- .setControllerAdvice (new ExceptionHandlerControllerV1 (auditService ))
226+ // Use a real controller instance (with mocked deps) so Spring MVC can route to it reliably.
227+ QrdaService qrdaService = Mockito .mock (QrdaService .class );
228+ ValidationService validationService = Mockito .mock (ValidationService .class );
229+
230+ QrdaControllerV1 controller = new QrdaControllerV1 (qrdaService , validationService , auditService );
231+
232+ MockMvc mvc = MockMvcBuilders .standaloneSetup (controller )
233+ .setControllerAdvice (new GlobalExceptionHandler (auditService ))
234234 .build ();
235- when (mock .uploadQrdaFile (ArgumentMatchers .any (), ArgumentMatchers .anyString ())).thenCallRealMethod ();
236235
237236 String purpose = "this is an invalid purpose because it's too long" + UUID .randomUUID ();
237+
238238 RequestBuilder builder = MockMvcRequestBuilders .multipart ("/" )
239- .file ("file" , ArrayUtils .EMPTY_BYTE_ARRAY )
240- .header ("Purpose" , purpose );
239+ .file ("file" , ArrayUtils .EMPTY_BYTE_ARRAY )
240+ .header ("Purpose" , purpose )
241+ .header ("Accept" , Constants .V1_API_ACCEPT );
242+
241243 MvcResult result = mvc .perform (builder ).andReturn ();
242- Truth .assertThat (result .getResponse ().getContentAsString ()).isEqualTo ("Given Purpose (header) is too large. Max length is "
243- + "25, yours was " + purpose .length ());
244+
245+ Truth .assertThat (result .getResponse ().getStatus ()).isEqualTo (400 );
246+ Truth .assertThat (result .getResponse ().getContentAsString ())
247+ .isEqualTo ("Given Purpose (header) is too large. Max length is 25, yours was " + purpose .length ());
244248 }
245249
246250 @ Override
247251 public Class <?> getLoggerType () {
248- return ExceptionHandlerControllerV1 .class ;
252+ return GlobalExceptionHandler .class ;
249253 }
250254}
0 commit comments