From 97c277b9f465e354d84f7a79eb4710e22242aedc Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 12 Jun 2025 12:04:50 +0300 Subject: [PATCH 1/6] chore: do for each group in event mapGroupColorFromGroupIdentifiers --- .../hei/haapi/endpoint/rest/mapper/EventMapper.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/school/hei/haapi/endpoint/rest/mapper/EventMapper.java b/src/main/java/school/hei/haapi/endpoint/rest/mapper/EventMapper.java index d0af356c9d..61965aad6d 100644 --- a/src/main/java/school/hei/haapi/endpoint/rest/mapper/EventMapper.java +++ b/src/main/java/school/hei/haapi/endpoint/rest/mapper/EventMapper.java @@ -29,10 +29,11 @@ public class EventMapper { public school.hei.haapi.model.Event toDomain(CreateEvent createEvent) { List groupIdentifiers = Objects.requireNonNull(createEvent.getGroups()); List groups = - groupService.getAllById(groupIdentifiers.stream().map(GroupIdentifier::getId).toList()); - groups.stream() - .map(group -> mapGroupColorFromGroupIdentifiers(group, groupIdentifiers)) - .toList(); + groupService + .getAllById(groupIdentifiers.stream().map(GroupIdentifier::getId).toList()) + .stream() + .map(group -> mapGroupColorFromGroupIdentifiers(group, groupIdentifiers)) + .toList(); List mappedGroup = groupService.saveDomainGroup(groups); return Event.builder() From 6bf73d0086c23d7a193cb2d5aa435d1eb36baf2a Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 12 Jun 2025 13:38:52 +0300 Subject: [PATCH 2/6] chore: AttendanceMapper throw if optional is empty --- .../haapi/endpoint/rest/mapper/AttendanceMapper.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/school/hei/haapi/endpoint/rest/mapper/AttendanceMapper.java b/src/main/java/school/hei/haapi/endpoint/rest/mapper/AttendanceMapper.java index f891c52ad4..88f8094a9a 100644 --- a/src/main/java/school/hei/haapi/endpoint/rest/mapper/AttendanceMapper.java +++ b/src/main/java/school/hei/haapi/endpoint/rest/mapper/AttendanceMapper.java @@ -42,15 +42,17 @@ public StudentAttendanceMovement toRestMovement(school.hei.haapi.model.StudentAt } public StudentAttendance toDomain(CreateAttendanceMovement toCreate) { - if (userRepository.findById(toCreate.getStudentId()).isEmpty()) { - throw new NotFoundException( - "the student with #" + toCreate.getStudentId() + " doesn't exist"); - } return StudentAttendance.builder() .attendanceMovementType(toCreate.getAttendanceMovementType()) .place(toCreate.getPlace()) .createdAt(toCreate.getCreatedAt()) - .student(userRepository.findById(toCreate.getStudentId()).get()) + .student( + userRepository + .findById(toCreate.getStudentId()) + .orElseThrow( + () -> + new NotFoundException( + "the student with #" + toCreate.getStudentId() + " doesn't exist"))) .build(); } From 81846b91e514ef80b58bf8f573800060aae5fb11 Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 12 Jun 2025 13:43:07 +0300 Subject: [PATCH 3/6] chore: GradeMapper remove double unboxing --- .../java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java index b6fe654caa..ee28cbaf42 100644 --- a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java +++ b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java @@ -37,7 +37,7 @@ public Grade toRest(school.hei.haapi.model.Grade grade) { return new Grade() .id(grade.getId()) .createdAt(grade.getCreationDatetime()) - .score(grade.getScore().doubleValue()) + .score(grade.getScore()) .updateDate(grade.getCreationDatetime()); } From 67bfde8eca52c228497b8f3e99a98055e935bf50 Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 12 Jun 2025 15:20:57 +0300 Subject: [PATCH 4/6] chore: GradeMapper throw if student have no grade for the exam --- .../endpoint/rest/mapper/GradeMapper.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java index ee28cbaf42..7a633de4cd 100644 --- a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java +++ b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java @@ -1,7 +1,6 @@ package school.hei.haapi.endpoint.rest.mapper; import java.util.List; -import java.util.Optional; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; import school.hei.haapi.endpoint.rest.model.CrupdateGrade; @@ -10,6 +9,7 @@ import school.hei.haapi.endpoint.rest.validator.GradeValidator; import school.hei.haapi.model.Exam; import school.hei.haapi.model.User; +import school.hei.haapi.model.exception.NotFoundException; import school.hei.haapi.repository.GradeRepository; import school.hei.haapi.service.ExamService; import school.hei.haapi.service.GradeService; @@ -52,26 +52,20 @@ public StudentGrade toRestStudentGrade(school.hei.haapi.model.Grade grade) { } public StudentGrade toRestStudentExamGrade(User student, Exam exam) { - Optional optionalGrade = - exam.getGrades().stream() - .filter(grade -> grade.getStudent().getId().equals(student.getId())) - .findFirst(); - school.hei.haapi.model.Grade grade = optionalGrade.get(); - var getStudentGrade = new StudentGrade().grade(toRest(grade)); - getStudentGrade.setStudent(userMapper.toRestStudent(student)); - return getStudentGrade; + return new StudentGrade() + .grade( + toRest( + exam.getGrades().stream() + .filter(grade -> grade.getStudent().getId().equals(student.getId())) + .findFirst() + .orElseThrow( + () -> + new NotFoundException( + "Student %s have no grade for the exam %s" + .formatted(student.getId(), exam.getId()))))) + .student(userMapper.toRestStudent(student)); } - // public ExamDetail toRestExamDetail(Exam exam, List grades) { - // return new ExamDetail() - // .id(exam.getId()) - // .coefficient(exam.getCoefficient()) - // .title(exam.getTitle()) - // .examinationDate(exam.getExaminationDate().atZone(ZoneId.systemDefault()).toInstant()) - // .participants( - // grades.stream().map(grade -> this.toRestStudentGrade(grade)).collect(toList())); - // } - public school.hei.haapi.model.Grade toDomain( CrupdateGrade grade, String examId, String studentRef) { validator.accept(grade); From 248a7121cd20a499d05a60c2ed81ea4f052f8cf1 Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 12 Jun 2025 15:58:32 +0300 Subject: [PATCH 5/6] chore: FileService::useHttpClientToGet don't catch exception --- .../hei/haapi/service/aws/FileService.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/school/hei/haapi/service/aws/FileService.java b/src/main/java/school/hei/haapi/service/aws/FileService.java index 28e4cc6688..e7b17812f1 100644 --- a/src/main/java/school/hei/haapi/service/aws/FileService.java +++ b/src/main/java/school/hei/haapi/service/aws/FileService.java @@ -95,25 +95,22 @@ public static String getFormattedBucketKey(User user, FileType fileType, String } /* Use the JDK HttpClient (since v11) class to do the download. */ - public byte[] useHttpClientToGet(String presignedUrlString) { + public byte[] useHttpClientToGet(String presignedUrlString) + throws URISyntaxException, IOException, InterruptedException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array. HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(); HttpClient httpClient = HttpClient.newHttpClient(); - try { - URL presignedUrl = new URL(presignedUrlString); - HttpResponse response = - httpClient.send( - requestBuilder.uri(presignedUrl.toURI()).GET().build(), - HttpResponse.BodyHandlers.ofInputStream()); + URL presignedUrl = new URL(presignedUrlString); + HttpResponse response = + httpClient.send( + requestBuilder.uri(presignedUrl.toURI()).GET().build(), + HttpResponse.BodyHandlers.ofInputStream()); - IoUtils.copy(response.body(), byteArrayOutputStream); + IoUtils.copy(response.body(), byteArrayOutputStream); - logger.info("HTTP response code is " + response.statusCode()); - } catch (URISyntaxException | InterruptedException | IOException e) { - logger.error(e.getMessage(), e); - } + logger.info("HTTP response code is " + response.statusCode()); return byteArrayOutputStream.toByteArray(); } } From da107b9733b5b9606eeb30008d9a04a503b04c31 Mon Sep 17 00:00:00 2001 From: tendryAxel Date: Thu, 19 Jun 2025 16:28:06 +0300 Subject: [PATCH 6/6] chore: test GradeMapper --- .../endpoint/rest/mapper/GradeMapper.java | 18 +---- .../school/hei/haapi/integration/GradeIT.java | 4 ++ .../unit/objectMapper/GradeMapperTest.java | 66 +++++++++++++++++++ 3 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 src/test/java/school/hei/haapi/unit/objectMapper/GradeMapperTest.java diff --git a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java index 7a633de4cd..9d50ded54e 100644 --- a/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java +++ b/src/main/java/school/hei/haapi/endpoint/rest/mapper/GradeMapper.java @@ -25,14 +25,6 @@ public class GradeMapper { private final GradeValidator validator; private final GradeRepository gradeRepository; - // todo: to review all class - public school.hei.haapi.model.Grade toDomain(Grade grade) { - return school.hei.haapi.model.Grade.builder() - .score(grade.getScore()) - .creationDatetime(grade.getCreatedAt()) - .build(); - } - public Grade toRest(school.hei.haapi.model.Grade grade) { return new Grade() .id(grade.getId()) @@ -42,9 +34,6 @@ public Grade toRest(school.hei.haapi.model.Grade grade) { } public StudentGrade toRestStudentGrade(school.hei.haapi.model.Grade grade) { - if (grade == null) { - return null; - } var getStudentGrade = new StudentGrade().grade(toRest(grade)); getStudentGrade.setStudent(userMapper.toRestStudent(grade.getStudent())); @@ -71,11 +60,6 @@ public school.hei.haapi.model.Grade toDomain( validator.accept(grade); Exam exam = examService.getExamById(examId); - double scoreFinal = 0.0; - - if (exam.getCoefficient() > 0 && grade.getScore() != null && grade.getScore() >= 0) { - scoreFinal = grade.getScore() * exam.getCoefficient(); - } school.hei.haapi.model.Grade resultGrade = gradeRepository @@ -88,7 +72,7 @@ public school.hei.haapi.model.Grade toDomain( exam, userService.findByRef(studentRef)))) .getFirst()); - resultGrade.setScore(scoreFinal); + resultGrade.setScore(grade.getScore() * exam.getCoefficient()); return resultGrade; } } diff --git a/src/test/java/school/hei/haapi/integration/GradeIT.java b/src/test/java/school/hei/haapi/integration/GradeIT.java index bb66c59fd5..e2e88989d5 100644 --- a/src/test/java/school/hei/haapi/integration/GradeIT.java +++ b/src/test/java/school/hei/haapi/integration/GradeIT.java @@ -34,12 +34,14 @@ import school.hei.haapi.endpoint.rest.api.TeachingApi; import school.hei.haapi.endpoint.rest.client.ApiClient; import school.hei.haapi.endpoint.rest.client.ApiException; +import school.hei.haapi.endpoint.rest.mapper.GradeMapper; import school.hei.haapi.endpoint.rest.model.AwardedCourseExam; import school.hei.haapi.endpoint.rest.model.CrupdateGrade; import school.hei.haapi.endpoint.rest.model.StudentGrade; import school.hei.haapi.integration.conf.FacadeITMockedThirdParties; import school.hei.haapi.integration.conf.TestUtils; import school.hei.haapi.model.User; +import school.hei.haapi.repository.GradeRepository; import school.hei.haapi.repository.UserRepository; import school.hei.haapi.service.UserService; @@ -49,6 +51,8 @@ class GradeIT extends FacadeITMockedThirdParties { @Autowired UserRepository userRepository; @Autowired UserService userService; + @Autowired GradeRepository gradeRepository; + @Autowired GradeMapper gradeMapper; private ApiClient anApiClient(String token) { return TestUtils.anApiClient(token, localPort); diff --git a/src/test/java/school/hei/haapi/unit/objectMapper/GradeMapperTest.java b/src/test/java/school/hei/haapi/unit/objectMapper/GradeMapperTest.java new file mode 100644 index 0000000000..cdd9582f42 --- /dev/null +++ b/src/test/java/school/hei/haapi/unit/objectMapper/GradeMapperTest.java @@ -0,0 +1,66 @@ +package school.hei.haapi.unit.objectMapper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import school.hei.haapi.endpoint.rest.mapper.GradeMapper; +import school.hei.haapi.endpoint.rest.model.CrupdateGrade; +import school.hei.haapi.model.Exam; +import school.hei.haapi.model.Grade; +import school.hei.haapi.model.User; +import school.hei.haapi.model.exception.NotFoundException; +import school.hei.haapi.repository.GradeRepository; +import school.hei.haapi.service.ExamService; +import school.hei.haapi.service.GradeService; + +class GradeMapperTest { + GradeMapper subject; + ExamService examService; + GradeRepository gradeRepository; + GradeService gradeService; + + @BeforeEach + void setUp() { + gradeService = mock(); + examService = mock(); + gradeRepository = mock(); + subject = new GradeMapper(mock(), gradeService, examService, mock(), mock(), gradeRepository); + } + + @Test + void combine_student_with_bad_exam_to_get_grade_ko() { + User student1 = new User(); + student1.setId("student1"); + User student2 = new User(); + student2.setId("student2"); + Exam exam = new Exam(); + exam.setGrades(List.of(new Grade("", student2, new Exam(), null, null))); + + NotFoundException notFoundException = + assertThrows(NotFoundException.class, () -> subject.toRestStudentExamGrade(student1, exam)); + assertEquals( + "Student %s have no grade for the exam %s".formatted(student1.getId(), exam.getId()), + notFoundException.getMessage()); + } + + @Test + void map_grade_to_grade_or_create_grade() { + when(examService.getExamById(any())).thenReturn(new Exam(null, 1, null, null, null, null)); + when(gradeRepository.getGradeByExamIdAndStudentRef(any(), any())).thenReturn(Optional.empty()); + Grade gradeSaved = new Grade("", new User(), new Exam(), 1., Instant.now()); + when(gradeService.crupdateParticipantGrade(anyList())).thenReturn(List.of(gradeSaved)); + + Grade grade = subject.toDomain(new CrupdateGrade().score(gradeSaved.getScore()), "", ""); + + assertEquals(gradeSaved, grade); + } +}