From a1a5d287c1df7c2b398067eedc34304e7622218c Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Thu, 12 Sep 2024 16:39:17 -0700 Subject: [PATCH] More coverage to provide more test cases & also remove unused codes. More coverage to provide more test cases & also remove unused codes. --- .../api/batchgraduation/rest/RESTService.java | 89 +++-------------- .../api/batchgraduation/rest/RestUtils.java | 11 +-- .../util/RESTServiceDeleteTest.java | 97 +++++++++++++++++++ .../util/RESTServiceGetTest.java | 93 ++++++++++++++++-- .../util/RESTServicePostTest.java | 54 +++++++---- .../util/RESTServicePutTest.java | 94 ++++++++++++++++++ .../batchgraduation/util/RestUtilsTest.java | 6 +- 7 files changed, 331 insertions(+), 113 deletions(-) create mode 100644 api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceDeleteTest.java create mode 100644 api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePutTest.java diff --git a/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RESTService.java b/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RESTService.java index 47b775fa..1daca895 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RESTService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RESTService.java @@ -110,40 +110,6 @@ public T get(String url, Class clazz) { return obj; } - public T get(String url, MultiValueMap queryParams, Class clazz) { - T obj; - try { - obj = this.batchWebClient - .get() - .uri(uriBuilder -> uriBuilder - .path(url).queryParams(queryParams) - .build() - ) - .headers(h -> h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) - .retrieve() - // if 5xx errors, throw Service error - .onStatus(HttpStatusCode::is5xxServerError, - clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, ERROR_MESSAGE1), clientResponse.statusCode().value()))) - .bodyToMono(clazz) - // only does retry if initial error was 5xx as service may be temporarily down - // 4xx errors will always happen if 404, 401, 403 etc., so does not retry - .retryWhen(reactor.util.retry.Retry.backoff(constants.getDefaultRetryMaxAttempts(), Duration.ofSeconds(constants.getDefaultRetryWaitDurationSeconds())) - .filter(ServiceException.class::isInstance) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new ServiceException(getErrorMessage(url, ERROR_MESSAGE2), HttpStatus.SERVICE_UNAVAILABLE.value()); - })) - .block(); - } catch (Exception e) { - // catches IOExceptions and the like - throw new ServiceException(getErrorMessage( - url, - e.getLocalizedMessage()), - (e instanceof WebClientResponseException) ? ((WebClientResponseException) e).getStatusCode().value() : HttpStatus.SERVICE_UNAVAILABLE.value(), - e); - } - return obj; - } - /** * Generic POST call out to services. Uses blocking webclient and will throw * runtime exceptions. Will attempt retries if 5xx errors are encountered. @@ -158,7 +124,7 @@ public T get(String url, MultiValueMap queryParams, Class public T post(String url, Object body, Class clazz, String accessToken) { T obj; try { - obj = webClient.post() + obj = this.webClient.post() .uri(url) .headers(h -> { h.setBearerAuth(accessToken); h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()); }) .body(BodyInserters.fromValue(body)) @@ -186,7 +152,7 @@ public T post(String url, Object body, Class clazz, String accessToken) { public T post(String url, Object body, Class clazz) { T obj; try { - obj = batchWebClient.post() + obj = this.batchWebClient.post() .uri(url) .headers(h -> h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) .body(BodyInserters.fromValue(body)) @@ -218,42 +184,13 @@ public T post(String url, Object body, Class clazz) { * @param url the url you are calling * @param body the body you are requesting * @param clazz the return type you are expecting - * @param accessToken access token * @return return type * @param expected return type */ - public T put(String url, Object body, Class clazz, String accessToken) { - T obj; - try { - obj = this.webClient.put() - .uri(url) - .headers(h -> { h.setBearerAuth(accessToken); h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()); }) - .body(BodyInserters.fromValue(body)) - .retrieve() - .onStatus(HttpStatusCode::is5xxServerError, - clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, ERROR_MESSAGE1), clientResponse.statusCode().value()))) - .bodyToMono(clazz) - .retryWhen(reactor.util.retry.Retry.backoff(constants.getDefaultRetryMaxAttempts(), Duration.ofSeconds(constants.getDefaultRetryWaitDurationSeconds())) - .filter(ServiceException.class::isInstance) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new ServiceException(getErrorMessage(url, ERROR_MESSAGE2), HttpStatus.SERVICE_UNAVAILABLE.value()); - })) - .block(); - } catch (Exception e) { - // catches IOExceptions and the like - throw new ServiceException(getErrorMessage( - url, - e.getLocalizedMessage()), - (e instanceof WebClientResponseException) ? ((WebClientResponseException) e).getStatusCode().value() : HttpStatus.SERVICE_UNAVAILABLE.value(), - e); - } - return obj; - } - public T put(String url, Object body, Class clazz) { T obj; try { - obj = this.webClient.put() + obj = this.batchWebClient.put() .uri(url) .headers(h -> h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) .body(BodyInserters.fromValue(body)) @@ -278,11 +215,19 @@ public T put(String url, Object body, Class clazz) { return obj; } - public T delete(String url, Class boundClass, String accessToken) { + /** + * Generic DELETE call out to services. Uses blocking webclient and will throw + * runtime exceptions. Will attempt retries if 5xx errors are encountered. + * You can catch Exception in calling method. + * @param url the url you are calling + * @return return type + * @param expected return type + */ + public T delete(String url, Class boundClass) { T obj; try { - obj = webClient.delete().uri(url) - .headers(h -> { h.setBearerAuth(accessToken); h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()); }) + obj = this.batchWebClient.delete().uri(url) + .headers(h -> h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) .retrieve().bodyToMono(boundClass).block(); } catch(Exception e) { // catches IOExceptions and the like @@ -295,12 +240,6 @@ public T delete(String url, Class boundClass, String accessToken) { return obj; } - protected String parseUrlParameters(String url, String... params) { - List l = Arrays.asList(params); - l.replaceAll(t-> Objects.isNull(t) ? "" : t); - return String.format(url, l.toArray()); - } - private String getErrorMessage(String url, String errorMessage) { return "Service failed to process at url: " + url + " due to: " + errorMessage; } diff --git a/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RestUtils.java b/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RestUtils.java index fea9f269..4d6b438e 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RestUtils.java +++ b/api/src/main/java/ca/bc/gov/educ/api/batchgraduation/rest/RestUtils.java @@ -437,8 +437,7 @@ public void updateSchoolReportRecord(String schoolOfRecord, String reportTypeCod public void deleteSchoolReportRecord(String schoolOfRecord, String reportTypeCode) { ThreadLocalStateUtil.setCorrelationID(UUID.randomUUID().toString()); - String accessToken = getAccessToken(); - restService.delete(String.format(constants.getUpdateSchoolReport(),schoolOfRecord,reportTypeCode), Boolean.class, accessToken); + restService.delete(String.format(constants.getUpdateSchoolReport(),schoolOfRecord,reportTypeCode), Boolean.class); } public List getStudentsForUserReqDisRun(String credentialType, StudentSearchRequest req) { @@ -469,21 +468,17 @@ public void updateStudentGradRecord(UUID studentID, Long batchId,String activity } } - public void updateStudentGradRecordHistory(List studentIDs, Long batchId, String accessToken, String userName, String activityCode) { + public void updateStudentGradRecordHistory(List studentIDs, Long batchId, String userName, String activityCode) { try { if (batchId != null) { String url = String.format(constants.getUpdateStudentRecordHistory(), batchId, userName, activityCode); - restService.put(url,studentIDs, GraduationStudentRecord.class, accessToken); + restService.put(url,studentIDs, GraduationStudentRecord.class); } } catch (Exception e) { LOGGER.error("Unable to update student record history {}", e.getLocalizedMessage()); } } - public void updateStudentGradRecordHistory(List studentIDs, Long batchId, String userName, String activityCode) { - updateStudentGradRecordHistory(studentIDs, batchId, getAccessToken(), userName, activityCode); - } - public String updateStudentFlagReadyForBatch(List studentIds, String batchJobType) { ThreadLocalStateUtil.setCorrelationID(UUID.randomUUID().toString()); StudentList stuList = new StudentList(); diff --git a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceDeleteTest.java b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceDeleteTest.java new file mode 100644 index 00000000..b188c416 --- /dev/null +++ b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceDeleteTest.java @@ -0,0 +1,97 @@ +package ca.bc.gov.educ.api.batchgraduation.util; + +import ca.bc.gov.educ.api.batchgraduation.exception.ServiceException; +import ca.bc.gov.educ.api.batchgraduation.rest.RESTService; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.function.Consumer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@SpringBootTest +@RunWith(SpringRunner.class) +@ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") +public class RESTServiceDeleteTest { + + @Autowired + @InjectMocks + private RESTService restService; + + @Mock + private WebClient.RequestHeadersSpec requestHeadersMock; + @Mock + private WebClient.RequestHeadersUriSpec requestHeadersUriMock; + @Mock + private WebClient.RequestBodySpec requestBodyMock; + @Mock + private WebClient.RequestBodyUriSpec requestBodyUriMock; + @Mock + private WebClient.ResponseSpec responseMock; + + @MockBean + @Qualifier("webClient") + WebClient webClient; + + @MockBean + @Qualifier("batchClient") + WebClient batchWebClient; + + @Mock + private ClientRegistrationRepository clientRegistrationRepositoryMock; + + @Mock + private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepositoryMock; + + private static final String TEST_URL_200 = "https://httpstat.us/200"; + private static final String TEST_URL_403 = "https://httpstat.us/403"; + private static final String TEST_URL_503 = "https://httpstat.us/503"; + private static final String OK_RESPONSE = "200 OK"; + + @Before + public void setUp(){ + when(this.batchWebClient.delete()).thenReturn(this.requestHeadersUriMock); + when(this.requestHeadersUriMock.uri(any(String.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.headers(any(Consumer.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + } + + @Test + public void testDelete_GivenProperData_Expect200Response(){ + when(this.responseMock.bodyToMono(String.class)).thenReturn(Mono.just(OK_RESPONSE)); + String response = this.restService.delete(TEST_URL_200, String.class); + Assert.assertEquals("200 OK", response); + } + + @Test(expected = ServiceException.class) + public void testDelete_Given5xxErrorFromService_ExpectServiceError(){ + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.delete(TEST_URL_503, String.class); + } + + @Test(expected = ServiceException.class) + public void testDelete_Given4xxErrorFromService_ExpectServiceError(){ + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.delete(TEST_URL_403, String.class); + } + +} diff --git a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceGetTest.java b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceGetTest.java index c803460d..67d93973 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceGetTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServiceGetTest.java @@ -1,42 +1,115 @@ package ca.bc.gov.educ.api.batchgraduation.util; +import ca.bc.gov.educ.api.batchgraduation.exception.ServiceException; import ca.bc.gov.educ.api.batchgraduation.rest.RESTService; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.function.Consumer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; @SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) @RunWith(SpringRunner.class) +@ExtendWith(MockitoExtension.class) @ActiveProfiles("test") public class RESTServiceGetTest { @Autowired private RESTService restService; - //@Test + @Mock + private WebClient.RequestHeadersSpec requestHeadersMock; + @Mock + private WebClient.RequestHeadersUriSpec requestHeadersUriMock; + @Mock + private WebClient.RequestBodySpec requestBodyMock; + @Mock + private WebClient.RequestBodyUriSpec requestBodyUriMock; + @Mock + private WebClient.ResponseSpec responseMock; + + @MockBean + @Qualifier("webClient") + WebClient webClient; + + @MockBean + @Qualifier("batchClient") + WebClient batchWebClient; + + @Mock + private ClientRegistrationRepository clientRegistrationRepositoryMock; + + @Mock + private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepositoryMock; + + private static final String TEST_URL_200 = "https://httpstat.us/200"; + private static final String TEST_URL_403 = "https://httpstat.us/403"; + private static final String TEST_URL_503 = "https://httpstat.us/503"; + private static final String OK_RESPONSE = "200 OK"; + + @Before + public void setUp(){ + when(this.webClient.get()).thenReturn(this.requestHeadersUriMock); + when(this.batchWebClient.get()).thenReturn(this.requestHeadersUriMock); + when(this.requestHeadersUriMock.uri(any(String.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.headers(any(Consumer.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + } + + @Test public void testGet_GivenProperData_Expect200Response(){ - String response; - response = this.restService.get("https://httpstat.us/200", String.class, "1234"); + when(this.responseMock.bodyToMono(String.class)).thenReturn(Mono.just(OK_RESPONSE)); + String response = this.restService.get(TEST_URL_200, String.class, "1234"); Assert.assertEquals("200 OK", response); } - //@Test(expected = ServiceException.class) + @Test + public void testGetOverride_GivenProperData_Expect200Response(){ + when(this.responseMock.bodyToMono(String.class)).thenReturn(Mono.just(OK_RESPONSE)); + String response = this.restService.get(TEST_URL_200, String.class); + Assert.assertEquals(OK_RESPONSE, response); + } + + @Test(expected = ServiceException.class) public void testGet_Given5xxErrorFromService_ExpectServiceError(){ - this.restService.get("https://httpstat.us/503", String.class, "1234"); + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.get(TEST_URL_503, String.class, "1234"); + } + + @Test(expected = ServiceException.class) + public void testGetOverride_Given5xxErrorFromService_ExpectServiceError(){ + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.get(TEST_URL_503, String.class); } - //@Test(expected = ServiceException.class) + @Test(expected = ServiceException.class) public void testGet_Given4xxErrorFromService_ExpectServiceError(){ - this.restService.get("https://httpstat.us/403", String.class, "1234"); + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.get(TEST_URL_403, String.class, "1234"); } - @Test - public void testDoNothing() { - Assert.assertTrue(true); + @Test(expected = ServiceException.class) + public void testGetOverride_Given4xxErrorFromService_ExpectServiceError(){ + when(this.responseMock.bodyToMono(ServiceException.class)).thenReturn(Mono.just(new ServiceException())); + this.restService.get(TEST_URL_403, String.class); } } diff --git a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePostTest.java b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePostTest.java index 5406509e..e94e809f 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePostTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePostTest.java @@ -3,6 +3,7 @@ import ca.bc.gov.educ.api.batchgraduation.exception.ServiceException; import ca.bc.gov.educ.api.batchgraduation.rest.RESTService; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.runner.RunWith; @@ -13,6 +14,8 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.reactive.function.BodyInserter; @@ -33,9 +36,12 @@ public class RESTServicePostTest { @Autowired @InjectMocks private RESTService restService; + @Mock private WebClient.RequestHeadersSpec requestHeadersMock; @Mock + private WebClient.RequestHeadersUriSpec requestHeadersUriMock; + @Mock private WebClient.RequestBodySpec requestBodyMock; @Mock private WebClient.RequestBodyUriSpec requestBodyUriMock; @@ -50,38 +56,52 @@ public class RESTServicePostTest { @Qualifier("batchClient") WebClient batchWebClient; + @Mock + private ClientRegistrationRepository clientRegistrationRepositoryMock; + + @Mock + private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepositoryMock; + private static final byte[] TEST_BYTES = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?".getBytes(); + private static final String TEST_BODY = "{test:test}"; + private static final String ACCESS_TOKEN = "123"; + private static final String TEST_URL = "https://fake.url.com"; - @Test - public void testPost_GivenProperData_Expect200Response(){ - String testBody = "test"; + @Before + public void setUp(){ when(this.webClient.post()).thenReturn(this.requestBodyUriMock); + when(this.batchWebClient.post()).thenReturn(this.requestBodyUriMock); when(this.requestBodyUriMock.uri(any(String.class))).thenReturn(this.requestBodyUriMock); when(this.requestBodyUriMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock); when(this.requestBodyMock.contentType(any())).thenReturn(this.requestBodyMock); when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock); when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); - when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(byte[].class)).thenReturn(Mono.just(TEST_BYTES)); - byte[] response = this.restService.post("https://fake.url.com", testBody, byte[].class, "1234"); + } + + @Test + public void testPost_GivenProperData_Expect200Response(){ + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + byte[] response = this.restService.post(TEST_URL, TEST_BODY, byte[].class, ACCESS_TOKEN); + Assert.assertArrayEquals(TEST_BYTES, response); + } + + @Test + public void testPostOverride_GivenProperData_Expect200Response(){ + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + byte[] response = this.restService.post(TEST_URL, TEST_BODY, byte[].class); Assert.assertArrayEquals(TEST_BYTES, response); } @Test(expected = ServiceException.class) public void testPost_Given4xxErrorFromService_ExpectServiceError() { - String testBody = "test"; - when(this.webClient.post()).thenReturn(this.requestBodyUriMock); - when(this.requestBodyUriMock.uri(any(String.class))).thenReturn(this.requestBodyUriMock); - when(this.requestBodyUriMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock); - when(this.requestBodyMock.contentType(any())).thenReturn(this.requestBodyMock); - when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock); - when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); - when(this.responseMock.onStatus(any(), any())).thenThrow(new ServiceException(getErrorMessage(any(String.class), "5xx error."))); - when(this.responseMock.bodyToMono(byte[].class)).thenReturn(Mono.just(TEST_BYTES)); - this.restService.post("https://fake.url.com", testBody, byte[].class, "1234"); + when(this.responseMock.onStatus(any(), any())).thenThrow(new ServiceException()); + this.restService.post(TEST_URL, TEST_BODY, byte[].class, ACCESS_TOKEN); } - private String getErrorMessage(String url, String errorMessage) { - return "Service failed to process at url: " + url + " due to: " + errorMessage; + @Test(expected = ServiceException.class) + public void testPostOverride_Given4xxErrorFromService_ExpectServiceError() { + when(this.responseMock.onStatus(any(), any())).thenThrow(new ServiceException()); + this.restService.post(TEST_URL, TEST_BODY, byte[].class); } } diff --git a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePutTest.java b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePutTest.java new file mode 100644 index 00000000..efd58131 --- /dev/null +++ b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RESTServicePutTest.java @@ -0,0 +1,94 @@ +package ca.bc.gov.educ.api.batchgraduation.util; + +import ca.bc.gov.educ.api.batchgraduation.exception.ServiceException; +import ca.bc.gov.educ.api.batchgraduation.rest.RESTService; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.reactive.function.BodyInserter; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.function.Consumer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@SpringBootTest +@RunWith(SpringRunner.class) +@ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") +public class RESTServicePutTest { + + @Autowired + @InjectMocks + private RESTService restService; + + @Mock + private WebClient.RequestHeadersSpec requestHeadersMock; + @Mock + private WebClient.RequestHeadersUriSpec requestHeadersUriMock; + @Mock + private WebClient.RequestBodySpec requestBodyMock; + @Mock + private WebClient.RequestBodyUriSpec requestBodyUriMock; + @Mock + private WebClient.ResponseSpec responseMock; + + @MockBean + @Qualifier("webClient") + WebClient webClient; + + @MockBean + @Qualifier("batchClient") + WebClient batchWebClient; + + @Mock + private ClientRegistrationRepository clientRegistrationRepositoryMock; + + @Mock + private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepositoryMock; + + private static final byte[] TEST_BYTES = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?".getBytes(); + private static final String TEST_BODY = "{test:test}"; + private static final String ACCESS_TOKEN = "123"; + private static final String TEST_URL = "https://fake.url.com"; + + @Before + public void setUp(){ + when(this.batchWebClient.put()).thenReturn(this.requestBodyUriMock); + when(this.requestBodyUriMock.uri(any(String.class))).thenReturn(this.requestBodyUriMock); + when(this.requestBodyUriMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock); + when(this.requestBodyMock.contentType(any())).thenReturn(this.requestBodyMock); + when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.bodyToMono(byte[].class)).thenReturn(Mono.just(TEST_BYTES)); + } + + @Test + public void testPut_GivenProperData_Expect200Response(){ + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + byte[] response = this.restService.put(TEST_URL, TEST_BODY, byte[].class); + Assert.assertArrayEquals(TEST_BYTES, response); + } + + @Test(expected = ServiceException.class) + public void testPut_Given4xxErrorFromService_ExpectServiceError() { + when(this.responseMock.onStatus(any(), any())).thenThrow(new ServiceException()); + this.restService.put(TEST_URL, TEST_BODY, byte[].class); + } + +} diff --git a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RestUtilsTest.java b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RestUtilsTest.java index 66e799cf..0cacdb1e 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RestUtilsTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/batchgraduation/util/RestUtilsTest.java @@ -1170,7 +1170,7 @@ public void testUpdateStudentGradRecordHistory() { when(this.restService.put(String.format(constants.getUpdateStudentRecordHistory(),studentID, batchId, userName),"{}", GraduationStudentRecord.class)).thenReturn(rec); - this.restUtils.updateStudentGradRecordHistory(List.of(), batchId, accessToken, userName, null); + this.restUtils.updateStudentGradRecordHistory(List.of(), batchId, accessToken, userName); when(this.restService.put(String.format(constants.getUpdateStudentRecordHistory(), batchId, userName, "USERSTUDARC"),"{}", GraduationStudentRecord.class)).thenReturn(new GraduationStudentRecord()); @@ -1193,7 +1193,7 @@ public void testUpdateSchoolReportRecord() { restUtils.updateSchoolReportRecord(mincode,reportTypeCode,null); assertThat(reportTypeCode).isEqualTo("E"); - when(this.restService.delete(String.format(constants.getUpdateSchoolReport(),mincode,reportTypeCode), Boolean.class, "abc")).thenReturn(true); + when(this.restService.delete(String.format(constants.getUpdateSchoolReport(),mincode,reportTypeCode), Boolean.class)).thenReturn(true); restUtils.deleteSchoolReportRecord(mincode,reportTypeCode); assertThat(reportTypeCode).isEqualTo("E"); @@ -1206,7 +1206,7 @@ public void testDeleteSchoolReportRecord() { mockTokenResponseObject(); - when(this.restService.delete(String.format(constants.getUpdateSchoolReport(),mincode,reportTypeCode), Boolean.class, "abc")).thenReturn(true); + when(this.restService.delete(String.format(constants.getUpdateSchoolReport(),mincode,reportTypeCode), Boolean.class)).thenReturn(true); this.restUtils.deleteSchoolReportRecord(mincode,reportTypeCode); assertThat(reportTypeCode).isEqualTo("E");