diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/messaging/jetstream/FetchGradStudentRecordSubscriber.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/messaging/jetstream/FetchGradStudentRecordSubscriber.java index ea6b66fd..3d47f72a 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/messaging/jetstream/FetchGradStudentRecordSubscriber.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/messaging/jetstream/FetchGradStudentRecordSubscriber.java @@ -66,10 +66,12 @@ public void onMessage(Message message) { private String getResponse(GradStudentRecord studentRecord) throws JsonProcessingException { GradStudentRecordPayload gradStudentRecordPayload = GradStudentRecordPayload.builder() + .studentID(String.valueOf(studentRecord.getStudentID())) .program(studentRecord.getProgram()) .programCompletionDate(studentRecord.getProgramCompletionDate() != null ? EducGradStudentApiUtils.formatDate(studentRecord.getProgramCompletionDate()) : null) .schoolOfRecord(studentRecord.getSchoolOfRecord()) .studentStatusCode(studentRecord.getStudentStatusCode()) + .graduated(studentRecord.getGraduated().toString()) .build(); return JsonUtil.getJsonStringFromObject(gradStudentRecordPayload); } @@ -83,7 +85,7 @@ private String getErrorResponse(Exception e) { return JsonUtil.getJsonStringFromObject(gradStudentRecordPayload); } catch (JsonProcessingException exc) { log.error("Error while serializing error response", exc); - return "{\"program\": \"\", \"programCompletionDate\": \"\", \"schoolOfRecord\": \"\", \"studentStatusCode\": \"\", \"exception\": \"JSON Parsing exception\"}"; + return "{\"studentID\": \"\", \"program\": \"\", \"programCompletionDate\": \"\", \"schoolOfRecord\": \"\", \"studentStatusCode\": \"\", \"graduated\": \"\", \"exception\": \"JSON Parsing exception\"}"; } } } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dc/GradStudentRecordPayload.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dc/GradStudentRecordPayload.java index 4ff72da9..256b477e 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dc/GradStudentRecordPayload.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dc/GradStudentRecordPayload.java @@ -7,10 +7,12 @@ @Builder public class GradStudentRecordPayload { + private String studentID; private String exception; private String program; private String programCompletionDate; private String schoolOfRecord; private String studentStatusCode; + private String graduated; } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/messaging/GradStudentRecord.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/messaging/GradStudentRecord.java index 95c3e222..30b8a805 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/messaging/GradStudentRecord.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/messaging/GradStudentRecord.java @@ -17,5 +17,7 @@ public class GradStudentRecord { private Date programCompletionDate; private String schoolOfRecord; private String studentStatusCode; + private String studentProjectedGradData; + private Boolean graduated; } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentService.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentService.java index 8cfc0896..3d736f16 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentService.java @@ -9,6 +9,8 @@ import ca.bc.gov.educ.api.gradstudent.repository.GraduationStudentRecordRepository; import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiConstants; import ca.bc.gov.educ.api.gradstudent.util.ThreadLocalStateUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.resilience4j.retry.annotation.Retry; import jakarta.transaction.Transactional; @@ -432,8 +434,22 @@ public List getStudentIDsBySearchCriteriaOrAll(StudentSearchRequest search public GradStudentRecord getGraduationStudentRecord(UUID studentID) { GradStudentRecord response = graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class); if (response != null) { + response.setGraduated(parseGraduationStatus(response.getStudentProjectedGradData())); return response; } throw new EntityNotFoundException(String.format(STD_NOT_FOUND_MSG, studentID)); } + + public Boolean parseGraduationStatus(String studentProjectedGradData) { + if (studentProjectedGradData == null || studentProjectedGradData.isEmpty()) { + return false; + } + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(studentProjectedGradData); + return jsonNode.get("graduated").asBoolean(); + } catch (JsonProcessingException e) { + return false; + } + } } diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentServiceTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentServiceTest.java index 27d85214..7d1829ea 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/GradStudentServiceTest.java @@ -44,8 +44,7 @@ import java.util.function.Function; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; +import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -863,7 +862,7 @@ public void testGetGraduationStudentRecord_GivenValidProgramCompletionDate_Expec UUID studentID = UUID.randomUUID(); GraduationStudentRecordEntity graduationStudentRecordEntity = new GraduationStudentRecordEntity(); graduationStudentRecordEntity.setProgramCompletionDate(new java.util.Date()); - when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(new GradStudentRecord(studentID, "2018-EN", new java.util.Date(), "schoolOfRecord", "studentStatusCode")); + when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(new GradStudentRecord(studentID, "2018-EN", new java.util.Date(), "schoolOfRecord", "studentStatusCode", "{\"nonGradReasons\":null,\"graduated\":true}", Boolean.TRUE)); GradStudentRecord result = gradStudentService.getGraduationStudentRecord(studentID); assertNotNull(result); } @@ -877,6 +876,95 @@ public void testGetGraduationStudentRecord_givenNotFound_ExpectEntityNotFoundExc }); } + @Test + public void testGetGraduationStudentRecord_GivenGraduatedTrue_ExpectGraduated() { + UUID studentID = UUID.randomUUID(); + GradStudentRecord mockRecord = new GradStudentRecord( + studentID, + "2018-EN", + new java.util.Date(), + "schoolOfRecord", + "studentStatusCode", + "{\"nonGradReasons\":null,\"graduated\":true}", + true + ); + when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(mockRecord); + + GradStudentRecord result = gradStudentService.getGraduationStudentRecord(studentID); + + assertNotNull(result); + assertTrue(result.getGraduated()); + } + + @Test + public void testGetGraduationStudentRecord_GivenGraduatedFalse_ExpectNotGraduated() { + UUID studentID = UUID.randomUUID(); + GradStudentRecord mockRecord = new GradStudentRecord( + studentID, + "2018-EN", + new java.util.Date(), + "schoolOfRecord", + "studentStatusCode", + "{\"nonGradReasons\":[],\"graduated\":false}", + false + ); + when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(mockRecord); + + GradStudentRecord result = gradStudentService.getGraduationStudentRecord(studentID); + + assertNotNull(result); + assertFalse(result.getGraduated()); + } + + @Test + public void testGetGraduationStudentRecord_GivenNullCLOBData_ExpectNotGraduated() { + UUID studentID = UUID.randomUUID(); + GradStudentRecord mockRecord = new GradStudentRecord( + studentID, + "2018-EN", + new java.util.Date(), + "schoolOfRecord", + "studentStatusCode", + null, + false + ); + when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(mockRecord); + + GradStudentRecord result = gradStudentService.getGraduationStudentRecord(studentID); + + assertNotNull(result); + assertFalse(result.getGraduated()); + } + + @Test + public void testGetGraduationStudentRecord_GivenRecordNotFound_ExpectEntityNotFoundException() { + UUID studentID = UUID.randomUUID(); + when(graduationStatusRepository.findByStudentID(studentID, GradStudentRecord.class)).thenReturn(null); + + assertThrows(EntityNotFoundException.class, () -> gradStudentService.getGraduationStudentRecord(studentID)); + } + + @Test + public void testParseGraduationStatus_GivenNullInput_ExpectFalse() { + String studentProjectedGradData = null; + Boolean result = gradStudentService.parseGraduationStatus(studentProjectedGradData); + assertFalse("Expected false for null input", result); + } + + @Test + public void testParseGraduationStatus_GivenEmptyInput_ExpectFalse() { + String studentProjectedGradData = ""; + Boolean result = gradStudentService.parseGraduationStatus(studentProjectedGradData); + assertFalse("Expected false for empty input", result); + } + + @Test + public void testParseGraduationStatus_GivenMalformedJson_ExpectFalse() { + String malformedJson = "{invalid-json}"; + Boolean result = gradStudentService.parseGraduationStatus(malformedJson); + assertFalse("Expected false for malformed JSON", result); + } + @SneakyThrows protected Object createDataObjectFromJson(String jsonPath, Class clazz) { String json = readFile(jsonPath);