From 9672935ac8a612830b2dcc4c87b710d1d7789e18 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 12:03:50 +0300 Subject: [PATCH 01/10] add MajorValidator --- .../unilab/uniplan/major/MajorValidator.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/org/unilab/uniplan/major/MajorValidator.java diff --git a/src/main/java/org/unilab/uniplan/major/MajorValidator.java b/src/main/java/org/unilab/uniplan/major/MajorValidator.java new file mode 100644 index 0000000..26aa4fa --- /dev/null +++ b/src/main/java/org/unilab/uniplan/major/MajorValidator.java @@ -0,0 +1,33 @@ +package org.unilab.uniplan.major; + +import static org.unilab.uniplan.utils.ErrorConstants.FACULTY_NOT_FOUND; + +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.unilab.uniplan.exception.ResourceNotFoundException; +import org.unilab.uniplan.faculty.FacultyRepository; +import org.unilab.uniplan.major.dto.MajorRequestDto; + +@Component +@RequiredArgsConstructor +public class MajorValidator { + + private final FacultyRepository facultyRepository; + + public void validateForCreate(final MajorRequestDto requestDto) { + validateFacultyExists(requestDto.facultyId()); + } + + public void validateForUpdate(final MajorRequestDto requestDto) { + validateFacultyExists(requestDto.facultyId()); + } + + private void validateFacultyExists(final UUID facultyId) { + if (!facultyRepository.existsById(facultyId)) { + throw new ResourceNotFoundException( + FACULTY_NOT_FOUND.getMessage(String.valueOf(facultyId)) + ); + } + } +} \ No newline at end of file From acbd514a45ae76c54299ee58932c3ddf00c5664d Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 12:07:49 +0300 Subject: [PATCH 02/10] simplify MajorService --- .../unilab/uniplan/major/MajorService.java | 81 ++++--------------- 1 file changed, 14 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/MajorService.java b/src/main/java/org/unilab/uniplan/major/MajorService.java index 0933024..c2dc7e9 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorService.java +++ b/src/main/java/org/unilab/uniplan/major/MajorService.java @@ -1,88 +1,35 @@ package org.unilab.uniplan.major; -import org.unilab.uniplan.major.dto.MajorCoursesDto; - -import static org.unilab.uniplan.utils.ErrorConstants.MAJOR_NOT_FOUND; - -import jakarta.transaction.Transactional; +import org.unilab.uniplan.common.model.BaseService; import java.util.List; +import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.major.dto.MajorDto; @Service @RequiredArgsConstructor -public class MajorService { +public class MajorService implements BaseService { private final MajorRepository majorRepository; - private final MajorMapper majorMapper; - - @Transactional - public MajorDto createMajor(final MajorDto majorDTO) { - final Major major = majorMapper.toEntity(majorDTO); - return saveEntityAndConvertToDto(major); - } - - public MajorDto findMajorById(final UUID id) { - return majorRepository.findById(id) - .map(majorMapper::toDto) - .orElseThrow(() -> new ResourceNotFoundException( - MAJOR_NOT_FOUND.getMessage(String.valueOf(id)))); - } - - public MajorCoursesDto findMajorWithCoursesById(final UUID id) { - return majorRepository.findById(id) - .map(majorMapper::toFullDto) - .orElseThrow(() -> new ResourceNotFoundException( - MAJOR_NOT_FOUND.getMessage(String.valueOf(id)))); - } - - public List findAll() { - return majorRepository.findAll() - .stream().map(majorMapper::toDto).toList(); - } - public List findAllMajorByFacultyId(final UUID facultyId) { - return majorRepository.findAllByFacultyId(facultyId) - .stream() - .map(majorMapper::toDto) - .toList(); + @Override + public void save(final Major major) { + majorRepository.save(major); } - public List findAllMajorWithCoursesByFacultyId(final UUID facultyId) { - return majorRepository.findAllByFacultyId(facultyId) - .stream() - .map(majorMapper::toFullDto) - .toList(); + @Override + public Optional getById(final UUID id) { + return majorRepository.findById(id); } - @Transactional - public MajorDto updateMajor(final UUID id, final MajorDto majorDTO) { - return majorRepository.findById(id).map(existingMajor -> updateEntityAndConvertToDto( - majorDTO, - existingMajor)) - .orElseThrow(() -> new ResourceNotFoundException(MAJOR_NOT_FOUND.getMessage( - String.valueOf(id)))); + @Override + public List getAll() { + return majorRepository.findAll(); } - @Transactional - public void deleteMajor(final UUID id) { - final Major major = majorRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException( - MAJOR_NOT_FOUND.getMessage(String.valueOf(id)))); + @Override + public void delete(final Major major) { majorRepository.delete(major); } - - private MajorDto updateEntityAndConvertToDto(final MajorDto dto, - final Major entity) { - majorMapper.updateEntityFromDto(dto, entity); - return saveEntityAndConvertToDto(entity); - } - - private MajorDto saveEntityAndConvertToDto(final Major entity) { - final Major savedEntity = majorRepository.save(entity); - return majorMapper.toDto(savedEntity); - } } From 7fb32be5080e90c39c5ae0ab7bd6b91779699023 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 13:10:43 +0300 Subject: [PATCH 03/10] migrate to facade --- .../unilab/uniplan/major/MajorController.java | 36 ++++--- .../org/unilab/uniplan/major/MajorMapper.java | 22 ++--- .../unilab/uniplan/major/MajorRepository.java | 2 + .../unilab/uniplan/major/MajorService.java | 8 ++ .../unilab/uniplan/major/MajorWebFacade.java | 95 +++++++++++++++++++ 5 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 src/main/java/org/unilab/uniplan/major/MajorWebFacade.java diff --git a/src/main/java/org/unilab/uniplan/major/MajorController.java b/src/main/java/org/unilab/uniplan/major/MajorController.java index d3a1654..4bc35b5 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorController.java +++ b/src/main/java/org/unilab/uniplan/major/MajorController.java @@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.unilab.uniplan.major.dto.MajorCoursesResponseDto; -import org.unilab.uniplan.major.dto.MajorDto; import org.unilab.uniplan.major.dto.MajorRequestDto; import org.unilab.uniplan.major.dto.MajorResponseDto; @@ -27,52 +26,51 @@ @Tag(name = "Majors", description = "Manage academic majors (e.g., Informatics, Software Engineering) associated with faculties") public class MajorController { - private final MajorService majorService; - private final MajorMapper majorMapper; + private final MajorWebFacade majorWebFacade; @PostMapping - public ResponseEntity addMajor(@RequestBody @NotNull + public ResponseEntity createMajor(@RequestBody @NotNull @Valid final MajorRequestDto majorRequestDTO) { - final MajorDto majorDTO = majorMapper.toInnerDto(majorRequestDTO); - return ResponseEntity.status(HttpStatus.CREATED) - .body(majorMapper.toResponseDto(majorService.createMajor(majorDTO))); + majorWebFacade.createMajor(majorRequestDTO); + + return ResponseEntity.status(HttpStatus.CREATED).build(); } @GetMapping("/{id}") public ResponseEntity getMajorById(@PathVariable final UUID id) { - return ResponseEntity.ok(majorMapper.toResponseDto(majorService.findMajorById(id))); + return ResponseEntity.ok(majorWebFacade.getMajorById(id)); } @GetMapping("/{id}/courses") public ResponseEntity getMajorWithCoursesById(@PathVariable final UUID id) { - return ResponseEntity.ok(majorMapper.toFullResponseDto(majorService.findMajorWithCoursesById(id))); + return ResponseEntity.ok(majorWebFacade.getMajorWithCoursesById(id)); } @GetMapping("/faculty/{facultyId}") - public List getMajorsByFacultyId(@PathVariable final UUID facultyId) { - return majorMapper.toResponseDtoList(majorService.findAllMajorByFacultyId(facultyId)); + public ResponseEntity> getMajorsByFacultyId(@PathVariable final UUID facultyId) { + return ResponseEntity.ok(majorWebFacade.getMajorsByFacultyId(facultyId)); } @GetMapping("/faculty/{facultyId}/courses") - public List getMajorsWithCoursesByFacultyId(@PathVariable final UUID facultyId) { - return majorMapper.toFullResponseDtoList(majorService.findAllMajorWithCoursesByFacultyId(facultyId)); + public ResponseEntity> getMajorsWithCoursesByFacultyId(@PathVariable final UUID facultyId) { + return ResponseEntity.ok(majorWebFacade.getMajorsWithCoursesByFacultyId(facultyId)); } @GetMapping - public List getAllMajors() { - return majorMapper.toResponseDtoList(majorService.findAll()); + public ResponseEntity> getAllMajors() { + return ResponseEntity.ok(majorWebFacade.getAllMajors()); } @PutMapping("/{id}") - public ResponseEntity updateMajor(@PathVariable final UUID id, + public ResponseEntity updateMajor(@PathVariable final UUID id, @RequestBody @NotNull @Valid MajorRequestDto majorRequestDTO) { - final MajorDto majorDTO = majorMapper.toInnerDto(majorRequestDTO); - return ResponseEntity.ok(majorMapper.toResponseDto(majorService.updateMajor(id, majorDTO))); + majorWebFacade.updateMajor(id, majorRequestDTO); + return ResponseEntity.noContent().build(); } @DeleteMapping("/{id}") public ResponseEntity deleteMajor(@PathVariable final UUID id) { - majorService.deleteMajor(id); + majorWebFacade.deleteMajor(id); return ResponseEntity.noContent().build(); } } \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/major/MajorMapper.java b/src/main/java/org/unilab/uniplan/major/MajorMapper.java index 782457a..0493d0f 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorMapper.java +++ b/src/main/java/org/unilab/uniplan/major/MajorMapper.java @@ -7,7 +7,6 @@ import org.unilab.uniplan.course.CourseMapper; import org.unilab.uniplan.major.dto.MajorCoursesDto; import org.unilab.uniplan.major.dto.MajorCoursesResponseDto; -import org.unilab.uniplan.major.dto.MajorDto; import org.unilab.uniplan.major.dto.MajorRequestDto; import org.unilab.uniplan.major.dto.MajorResponseDto; @@ -15,25 +14,16 @@ public interface MajorMapper { @Mapping(source = "facultyId", target = "faculty.id") - Major toEntity(MajorDto majorDto); - - @Mapping(source = "faculty.id", target = "facultyId") - MajorDto toDto(Major major); - - @Mapping(source = "faculty.id", target = "facultyId") - MajorCoursesDto toFullDto(Major major); + Major toEntity(MajorRequestDto majorRequestDto); @Mapping(source = "facultyId", target = "faculty.id") - void updateEntityFromDto(MajorDto majorDto, @MappingTarget Major major); - - @Mapping(target = "id", ignore = true) - MajorDto toInnerDto(MajorRequestDto requestDto); + void updateEntityFromDto(MajorRequestDto majorRequestDto, @MappingTarget Major major); - MajorResponseDto toResponseDto(MajorDto innerDto); + MajorResponseDto toResponseDto(Major major); - List toResponseDtoList(List majors); + List toResponseDtoList(List majors); - MajorCoursesResponseDto toFullResponseDto(MajorCoursesDto innerDto); + MajorCoursesResponseDto toFullResponseDto(Major major); - List toFullResponseDtoList(List majors); + List toFullResponseDtoList(List majors); } \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/major/MajorRepository.java b/src/main/java/org/unilab/uniplan/major/MajorRepository.java index ba9ffb5..bb0688d 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorRepository.java +++ b/src/main/java/org/unilab/uniplan/major/MajorRepository.java @@ -9,4 +9,6 @@ public interface MajorRepository extends JpaRepository { public List findAllByFacultyId(UUID facultyId); + List findAllMajorByFacultyId(UUID facultyId); + List findAllMajorWithCoursesByFacultyId(UUID facultyId); } diff --git a/src/main/java/org/unilab/uniplan/major/MajorService.java b/src/main/java/org/unilab/uniplan/major/MajorService.java index c2dc7e9..f30498f 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorService.java +++ b/src/main/java/org/unilab/uniplan/major/MajorService.java @@ -32,4 +32,12 @@ public List getAll() { public void delete(final Major major) { majorRepository.delete(major); } + + public List findAllMajorByFacultyId(final UUID facultyId) { + return majorRepository.findAllMajorByFacultyId(facultyId); + } + + public List findAllMajorWithCoursesByFacultyId(final UUID facultyId) { + return majorRepository.findAllMajorWithCoursesByFacultyId(facultyId); + } } diff --git a/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java b/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java new file mode 100644 index 0000000..7a000e1 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java @@ -0,0 +1,95 @@ +package org.unilab.uniplan.major; + +import static org.unilab.uniplan.utils.ErrorConstants.MAJOR_NOT_FOUND; + +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.unilab.uniplan.exception.ResourceNotFoundException; +import org.unilab.uniplan.major.dto.MajorCoursesResponseDto; +import org.unilab.uniplan.major.dto.MajorRequestDto; +import org.unilab.uniplan.major.dto.MajorResponseDto; + +@Component +@Slf4j +@RequiredArgsConstructor +public class MajorWebFacade { + + private final MajorService majorService; + private final MajorMapper majorMapper; + private final MajorValidator majorValidator; + + @Transactional + public void createMajor(final MajorRequestDto requestDto) { + majorValidator.validateForCreate(requestDto); + + final Major major = majorMapper.toEntity(requestDto); + majorService.save(major); + + log.info("Created major with ID: {}", major.getId()); + } + + @Transactional(readOnly = true) + public List getAllMajors() { + return majorMapper.toResponseDtoList(majorService.getAll()); + } + + @Transactional(readOnly = true) + public MajorResponseDto getMajorById(final UUID id) { + final Major major = getMajorOrThrow(id); + + return majorMapper.toResponseDto(major); + } + + @Transactional + public void updateMajor(final UUID id, + final MajorRequestDto requestDto) { + majorValidator.validateForUpdate(requestDto); + + final Major major = getMajorOrThrow(id); + majorMapper.updateEntityFromDto(requestDto, major); + majorService.save(major); + + log.info("Updated major with ID: {}", id); + } + + @Transactional + public void deleteMajor(final UUID id) { + final Major major = getMajorOrThrow(id); + + majorService.delete(major); + + log.info("Deleted major with ID: {}", id); + } + + private Major getMajorOrThrow(final UUID id) { + return majorService.getById(id) + .orElseThrow(() -> new ResourceNotFoundException( + MAJOR_NOT_FOUND.getMessage(String.valueOf(id)) + )); + } + + @Transactional(readOnly = true) + public MajorCoursesResponseDto getMajorWithCoursesById(final UUID id) { + final Major major = getMajorOrThrow(id); + + return majorMapper.toFullResponseDto(major); + } + + @Transactional(readOnly = true) + public List getMajorsByFacultyId(final UUID facultyId) { + return majorMapper.toResponseDtoList( + majorService.findAllMajorByFacultyId(facultyId) + ); + } + + @Transactional(readOnly = true) + public List getMajorsWithCoursesByFacultyId(final UUID facultyId) { + return majorMapper.toFullResponseDtoList( + majorService.findAllMajorWithCoursesByFacultyId(facultyId) + ); + } +} \ No newline at end of file From fdd2a93bbd842953c98c69825f8c364bccd0984a Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 13:34:09 +0300 Subject: [PATCH 04/10] refactor MajorServiceTest --- .../unilab/uniplan/major/MajorService.java | 2 +- .../uniplan/major/MajorServiceTest.java | 174 +++--------------- 2 files changed, 25 insertions(+), 151 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/MajorService.java b/src/main/java/org/unilab/uniplan/major/MajorService.java index f30498f..9e9f067 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorService.java +++ b/src/main/java/org/unilab/uniplan/major/MajorService.java @@ -34,7 +34,7 @@ public void delete(final Major major) { } public List findAllMajorByFacultyId(final UUID facultyId) { - return majorRepository.findAllMajorByFacultyId(facultyId); + return majorRepository.findAllByFacultyId(facultyId); } public List findAllMajorWithCoursesByFacultyId(final UUID facultyId) { diff --git a/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java b/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java index 6430ee9..5d53c8b 100644 --- a/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java +++ b/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java @@ -1,13 +1,7 @@ package org.unilab.uniplan.major; -import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.List; @@ -19,24 +13,16 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.major.dto.MajorCoursesDto; -import org.unilab.uniplan.major.dto.MajorDto; @ExtendWith(MockitoExtension.class) class MajorServiceTest { - @InjectMocks - private MajorService majorService; - @Mock private MajorRepository majorRepository; - @Mock - private MajorMapper majorMapper; + @InjectMocks + private MajorService majorService; - private MajorCoursesDto majorCoursesDto; - private MajorDto majorDTO; private Major major; private UUID majorId; private UUID facultyId; @@ -45,35 +31,26 @@ class MajorServiceTest { void setUp() { majorId = UUID.randomUUID(); facultyId = UUID.randomUUID(); - majorCoursesDto = new MajorCoursesDto(majorId, facultyId, "Informatics", List.of()); - majorDTO = new MajorDto(majorId, facultyId, "Informatics"); major = new Major(); } @Test - void createMajorShouldReturnAndSavedMajorDTO() { - when(majorMapper.toEntity(majorDTO)).thenReturn(major); - when(majorRepository.save(major)).thenReturn(major); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - - MajorDto result = majorService.createMajor(majorDTO); + void saveShouldSaveMajor() { + majorService.save(major); - assertNotNull(result); - assertEquals("Informatics", result.majorName()); - assertEquals(facultyId, result.facultyId()); verify(majorRepository).save(major); } @Test void findAllMajorByFacultyIdShouldReturnListOfMajors() { + final List majors = List.of(major); + when(majorRepository.findAllByFacultyId(facultyId)).thenReturn(List.of(major)); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - List result = majorService.findAllMajorByFacultyId(facultyId); + final List result = majorService.findAllMajorByFacultyId(facultyId); - assertNotNull(result); - assertEquals(1, result.size()); - assertEquals("Informatics", result.getFirst().majorName()); + assertEquals(majors, result); + verify(majorRepository).findAllByFacultyId(facultyId); } @Test @@ -87,143 +64,40 @@ void findAllMajorByFacultyIdShouldReturnEmptyList() { } @Test - void findAllMajorWithCoursesByFacultyIdShouldReturnListOfMajorCoursesDto() { - when(majorRepository.findAllByFacultyId(facultyId)).thenReturn(List.of(major)); - when(majorMapper.toFullDto(major)).thenReturn(majorCoursesDto); - - final List result = majorService.findAllMajorWithCoursesByFacultyId(facultyId); - - assertAll( - () -> assertNotNull(result), - () -> assertEquals(1, result.size()), - () -> assertEquals("Informatics", result.getFirst().majorName()), - () -> assertEquals(List.of(), result.getFirst().courses()) - ); - } - - @Test - void findAllMajorWithCoursesByFacultyIdShouldReturnEmptyList() { - when(majorRepository.findAllByFacultyId(facultyId)).thenReturn(List.of()); - - assertTrue(majorService.findAllMajorWithCoursesByFacultyId(facultyId).isEmpty()); - - verify(majorRepository).findAllByFacultyId(facultyId); - } - - @Test - void findMajorByIdShouldReturnMajorDTOIfFound() { - when(majorRepository.findById(majorId)).thenReturn(Optional.of(major)); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - - MajorDto result = majorService.findMajorById(majorId); - - assertEquals("Informatics", result.majorName()); - } - - @Test - void findMajorByIdShouldReturnEmptyIfNotFound() { - when(majorRepository.findById(majorId)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> majorService.findMajorById(majorId)); - - assertTrue(exception.getMessage().contains(String.valueOf(majorId))); - } - - @Test - void findMajorWithCoursesByIdShouldReturnMajorCoursesDtoIfFound() { + void getByIdShouldReturnMajorOptionalIfMajorExists() { when(majorRepository.findById(majorId)).thenReturn(Optional.of(major)); - when(majorMapper.toFullDto(major)).thenReturn(majorCoursesDto); - final MajorCoursesDto result = majorService.findMajorWithCoursesById(majorId); + Optional result = majorService.getById(majorId); - assertAll( - () -> assertNotNull(result), - () -> assertEquals("Informatics", result.majorName()), - () -> assertEquals(List.of(), result.courses()) - ); + assertEquals(Optional.of(major), result); + verify(majorRepository).findById(majorId); } @Test - void findMajorWithCoursesByIdShouldReturnEmptyIfNotFound() { + void getByIdShouldReturnEmptyOptionalIfMajorDoesNotExist() { when(majorRepository.findById(majorId)).thenReturn(Optional.empty()); - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> majorService.findMajorWithCoursesById(majorId)); + final Optional result = majorService.getById(majorId); - assertTrue(exception.getMessage().contains(String.valueOf(majorId))); + assertEquals(Optional.empty(), result); + verify(majorRepository).findById(majorId); } @Test - void findAllShouldReturnListOfMajorDTOs() { + void getAllShouldReturnListOfMajors() { + final List majors = List.of(major); when(majorRepository.findAll()).thenReturn(List.of(major)); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - List result = majorService.findAll(); + final List result = majorService.getAll(); - assertEquals(1, result.size()); - assertEquals("Informatics", result.getFirst().majorName()); + assertEquals(majors, result); + verify(majorRepository).findAll(); } @Test - void updateMajorShouldReturnUpdatedMajorDTOIfFound() { - when(majorRepository.findById(majorId)).thenReturn(Optional.of(major)); - doNothing().when(majorMapper).updateEntityFromDto(majorDTO, major); - when(majorRepository.save(major)).thenReturn(major); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - - MajorDto result = majorService.updateMajor(majorId, majorDTO); - - assertEquals("Informatics", result.majorName()); - verify(majorRepository).save(major); - } - - @Test - void updateMajorShouldReturnEmptyIfNotFound() { - when(majorRepository.findById(majorId)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> majorService.updateMajor(majorId, majorDTO)); - - assertTrue(exception.getMessage().contains(String.valueOf(majorId))); - verify(majorRepository, never()).save(any()); - } - - @Test - void deleteMajorShouldDeleteIfExists() { - when(majorRepository.findById(majorId)).thenReturn(Optional.of(major)); - - majorService.deleteMajor(majorId); + void deleteShouldDeleteMajor() { + majorService.delete(major); verify(majorRepository).delete(major); } - - @Test - void deleteMajorShouldThrowIfNotExists() { - when(majorRepository.findById(majorId)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, - () -> majorService.deleteMajor(majorId)); - - assertTrue(exception.getMessage().contains("Major with ID")); - verify(majorRepository, never()).delete(any()); - } - - @Test - void findByIdShouldReturnEntityIfExists() { - when(majorRepository.findById(majorId)).thenReturn(Optional.of(major)); - when(majorMapper.toDto(major)).thenReturn(majorDTO); - - MajorDto result = majorService.findMajorById(majorId); - - assertEquals(majorDTO, result); - verify(majorMapper).toDto(major); - } - - @Test - void findByIdShouldReturnEmptyIfNotFound() { - when(majorRepository.findById(majorId)).thenReturn(Optional.empty()); - - org.unilab.uniplan.exception.ResourceNotFoundException exception = assertThrows( - ResourceNotFoundException.class, () -> majorService.findMajorById(majorId)); - - assertTrue(exception.getMessage().contains(String.valueOf(majorId))); - } } From eac357b148a3eedff043ec1c0b774ce083ce2125 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 14:18:18 +0300 Subject: [PATCH 05/10] add MajorValidatorTest and MajorWebFacadeTest --- .../uniplan/major/MajorValidatorTest.java | 77 +++++++ .../uniplan/major/MajorWebFacadeTest.java | 209 ++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java create mode 100644 src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java diff --git a/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java b/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java new file mode 100644 index 0000000..dd8c1e8 --- /dev/null +++ b/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java @@ -0,0 +1,77 @@ +package org.unilab.uniplan.major; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.unilab.uniplan.exception.ResourceNotFoundException; +import org.unilab.uniplan.faculty.FacultyRepository; +import org.unilab.uniplan.major.dto.MajorRequestDto; + +@ExtendWith(MockitoExtension.class) +class MajorValidatorTest { + + @Mock + private FacultyRepository facultyRepository; + + @InjectMocks + private MajorValidator majorValidator; + + private UUID facultyId; + private MajorRequestDto requestDto; + + @BeforeEach + void setUp() { + facultyId = UUID.randomUUID(); + requestDto = mock(MajorRequestDto.class); + + when(requestDto.facultyId()).thenReturn(facultyId); + } + + @Test + void validateForCreateShouldPassWhenFacultyExists() { + when(facultyRepository.existsById(facultyId)).thenReturn(true); + + assertDoesNotThrow(() -> majorValidator.validateForCreate(requestDto)); + + verify(facultyRepository).existsById(facultyId); + } + + @Test + void validateForCreateShouldThrowWhenFacultyDoesNotExist() { + when(facultyRepository.existsById(facultyId)).thenReturn(false); + + assertThrows(ResourceNotFoundException.class, + () -> majorValidator.validateForCreate(requestDto)); + + verify(facultyRepository).existsById(facultyId); + } + + @Test + void validateForUpdateShouldPassWhenFacultyExists() { + when(facultyRepository.existsById(facultyId)).thenReturn(true); + + assertDoesNotThrow(() -> majorValidator.validateForUpdate(requestDto)); + + verify(facultyRepository).existsById(facultyId); + } + + @Test + void validateForUpdateShouldThrowWhenFacultyDoesNotExist() { + when(facultyRepository.existsById(facultyId)).thenReturn(false); + + assertThrows(ResourceNotFoundException.class, + () -> majorValidator.validateForUpdate(requestDto)); + + verify(facultyRepository).existsById(facultyId); + } +} \ No newline at end of file diff --git a/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java b/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java new file mode 100644 index 0000000..984e809 --- /dev/null +++ b/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java @@ -0,0 +1,209 @@ +package org.unilab.uniplan.major; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InOrder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.unilab.uniplan.exception.ResourceNotFoundException; +import org.unilab.uniplan.major.dto.MajorCoursesResponseDto; +import org.unilab.uniplan.major.dto.MajorRequestDto; +import org.unilab.uniplan.major.dto.MajorResponseDto; + +@ExtendWith(MockitoExtension.class) +class MajorWebFacadeTest { + + @Mock + private MajorService majorService; + + @Mock + private MajorMapper majorMapper; + + @Mock + private MajorValidator majorValidator; + + @InjectMocks + private MajorWebFacade majorWebFacade; + + private UUID majorId; + private UUID facultyId; + private Major major; + private MajorRequestDto requestDto; + private MajorResponseDto responseDto; + private MajorCoursesResponseDto coursesResponseDto; + + @BeforeEach + void setUp() { + majorId = UUID.randomUUID(); + facultyId = UUID.randomUUID(); + major = new Major(); + requestDto = mock(MajorRequestDto.class); + responseDto = mock(MajorResponseDto.class); + coursesResponseDto = mock(MajorCoursesResponseDto.class); + } + + @Test + void createMajorShouldValidateMapAndSaveMajor() { + when(majorMapper.toEntity(requestDto)).thenReturn(major); + + majorWebFacade.createMajor(requestDto); + + final InOrder inOrder = inOrder(majorValidator, majorMapper, majorService); + inOrder.verify(majorValidator).validateForCreate(requestDto); + inOrder.verify(majorMapper).toEntity(requestDto); + inOrder.verify(majorService).save(major); + } + + @Test + void getAllMajorsShouldReturnResponseDtoList() { + final List majors = List.of(major); + final List responseDtos = List.of(responseDto); + + when(majorService.getAll()).thenReturn(majors); + when(majorMapper.toResponseDtoList(majors)).thenReturn(responseDtos); + + final List result = majorWebFacade.getAllMajors(); + + assertEquals(responseDtos, result); + verify(majorService).getAll(); + verify(majorMapper).toResponseDtoList(majors); + } + + @Test + void getMajorByIdShouldReturnResponseDtoIfFound() { + when(majorService.getById(majorId)).thenReturn(Optional.of(major)); + when(majorMapper.toResponseDto(major)).thenReturn(responseDto); + + final MajorResponseDto result = majorWebFacade.getMajorById(majorId); + + assertEquals(responseDto, result); + verify(majorService).getById(majorId); + verify(majorMapper).toResponseDto(major); + } + + @Test + void getMajorByIdShouldThrowIfMajorDoesNotExist() { + when(majorService.getById(majorId)).thenReturn(Optional.empty()); + + assertThrows(ResourceNotFoundException.class, + () -> majorWebFacade.getMajorById(majorId)); + + verify(majorService).getById(majorId); + verify(majorMapper, never()).toResponseDto(any(Major.class)); + } + + @Test + void getMajorWithCoursesByIdShouldReturnCoursesResponseDtoIfFound() { + when(majorService.getById(majorId)).thenReturn(Optional.of(major)); + when(majorMapper.toFullResponseDto(major)).thenReturn(coursesResponseDto); + + final MajorCoursesResponseDto result = majorWebFacade.getMajorWithCoursesById(majorId); + + assertEquals(coursesResponseDto, result); + verify(majorService).getById(majorId); + verify(majorMapper).toFullResponseDto(major); + } + + @Test + void getMajorWithCoursesByIdShouldThrowIfMajorDoesNotExist() { + when(majorService.getById(majorId)).thenReturn(Optional.empty()); + + assertThrows(ResourceNotFoundException.class, + () -> majorWebFacade.getMajorWithCoursesById(majorId)); + + verify(majorService).getById(majorId); + verify(majorMapper, never()).toFullResponseDto(any(Major.class)); + } + + @Test + void getMajorsByFacultyIdShouldReturnResponseDtoList() { + final List majors = List.of(major); + final List responseDtos = List.of(responseDto); + + when(majorService.findAllMajorByFacultyId(facultyId)).thenReturn(majors); + when(majorMapper.toResponseDtoList(majors)).thenReturn(responseDtos); + + final List result = majorWebFacade.getMajorsByFacultyId(facultyId); + + assertEquals(responseDtos, result); + verify(majorService).findAllMajorByFacultyId(facultyId); + verify(majorMapper).toResponseDtoList(majors); + } + + @Test + void getMajorsWithCoursesByFacultyIdShouldReturnCoursesResponseDtoList() { + final List majors = List.of(major); + final List responseDtos = List.of(coursesResponseDto); + + when(majorService.findAllMajorWithCoursesByFacultyId(facultyId)).thenReturn(majors); + when(majorMapper.toFullResponseDtoList(majors)).thenReturn(responseDtos); + + final List result = + majorWebFacade.getMajorsWithCoursesByFacultyId(facultyId); + + assertEquals(responseDtos, result); + verify(majorService).findAllMajorWithCoursesByFacultyId(facultyId); + verify(majorMapper).toFullResponseDtoList(majors); + } + + @Test + void updateMajorShouldValidateUpdateMapAndSaveMajorIfFound() { + when(majorService.getById(majorId)).thenReturn(Optional.of(major)); + + majorWebFacade.updateMajor(majorId, requestDto); + + final InOrder inOrder = inOrder(majorValidator, majorService, majorMapper); + inOrder.verify(majorValidator).validateForUpdate(requestDto); + inOrder.verify(majorService).getById(majorId); + inOrder.verify(majorMapper).updateEntityFromDto(requestDto, major); + inOrder.verify(majorService).save(major); + } + + @Test + void updateMajorShouldThrowIfMajorDoesNotExist() { + when(majorService.getById(majorId)).thenReturn(Optional.empty()); + + assertThrows(ResourceNotFoundException.class, + () -> majorWebFacade.updateMajor(majorId, requestDto)); + + verify(majorValidator).validateForUpdate(requestDto); + verify(majorService).getById(majorId); + verify(majorMapper, never()).updateEntityFromDto(any(MajorRequestDto.class), any(Major.class)); + verify(majorService, never()).save(any(Major.class)); + } + + @Test + void deleteMajorShouldDeleteMajorIfFound() { + when(majorService.getById(majorId)).thenReturn(Optional.of(major)); + + majorWebFacade.deleteMajor(majorId); + + verify(majorService).getById(majorId); + verify(majorService).delete(major); + } + + @Test + void deleteMajorShouldThrowIfMajorDoesNotExist() { + when(majorService.getById(majorId)).thenReturn(Optional.empty()); + + assertThrows(ResourceNotFoundException.class, + () -> majorWebFacade.deleteMajor(majorId)); + + verify(majorService).getById(majorId); + verify(majorService, never()).delete(any(Major.class)); + } +} \ No newline at end of file From beeb324dcfebbd827f252e99a6108878a91cb5cb Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 14:19:55 +0300 Subject: [PATCH 06/10] remove validations from MajorResponseDto --- .../java/org/unilab/uniplan/major/dto/MajorResponseDto.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/dto/MajorResponseDto.java b/src/main/java/org/unilab/uniplan/major/dto/MajorResponseDto.java index d823361..1ec656b 100644 --- a/src/main/java/org/unilab/uniplan/major/dto/MajorResponseDto.java +++ b/src/main/java/org/unilab/uniplan/major/dto/MajorResponseDto.java @@ -1,15 +1,10 @@ package org.unilab.uniplan.major.dto; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import java.util.UUID; public record MajorResponseDto( UUID id, - @NotNull UUID facultyId, - @NotNull - @Size(max = 200) String majorName ) { From 5bc5973e2cf4fff49a7c8b66a0cbf47ae3a01dd2 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Thu, 16 Jul 2026 14:24:36 +0300 Subject: [PATCH 07/10] add validation messages to MajorRequestDto --- .../java/org/unilab/uniplan/major/dto/MajorRequestDto.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java b/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java index 632bf96..ea70b01 100644 --- a/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java +++ b/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java @@ -1,14 +1,15 @@ package org.unilab.uniplan.major.dto; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.UUID; public record MajorRequestDto( - @NotNull + @NotNull(message = "Faculty id cannot be null") UUID facultyId, - @NotNull - @Size(max = 200) + @NotBlank(message = "Major name cannot be null") + @Size(max = 200, message = "Major name must be at most 200 characters") String majorName ) { From 89c9b826dfb01bbc549d14d81352dbe67dd63503 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Tue, 28 Jul 2026 11:13:56 +0300 Subject: [PATCH 08/10] combine validation logic for create and update into a single method --- .../unilab/uniplan/major/MajorValidator.java | 6 +---- .../unilab/uniplan/major/MajorWebFacade.java | 4 +-- .../uniplan/major/MajorValidatorTest.java | 27 +++---------------- .../uniplan/major/MajorWebFacadeTest.java | 6 ++--- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/MajorValidator.java b/src/main/java/org/unilab/uniplan/major/MajorValidator.java index 26aa4fa..3c5d5ae 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorValidator.java +++ b/src/main/java/org/unilab/uniplan/major/MajorValidator.java @@ -15,11 +15,7 @@ public class MajorValidator { private final FacultyRepository facultyRepository; - public void validateForCreate(final MajorRequestDto requestDto) { - validateFacultyExists(requestDto.facultyId()); - } - - public void validateForUpdate(final MajorRequestDto requestDto) { + public void validate(final MajorRequestDto requestDto) { validateFacultyExists(requestDto.facultyId()); } diff --git a/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java b/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java index 7a000e1..6d44a98 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java +++ b/src/main/java/org/unilab/uniplan/major/MajorWebFacade.java @@ -24,7 +24,7 @@ public class MajorWebFacade { @Transactional public void createMajor(final MajorRequestDto requestDto) { - majorValidator.validateForCreate(requestDto); + majorValidator.validate(requestDto); final Major major = majorMapper.toEntity(requestDto); majorService.save(major); @@ -47,7 +47,7 @@ public MajorResponseDto getMajorById(final UUID id) { @Transactional public void updateMajor(final UUID id, final MajorRequestDto requestDto) { - majorValidator.validateForUpdate(requestDto); + majorValidator.validate(requestDto); final Major major = getMajorOrThrow(id); majorMapper.updateEntityFromDto(requestDto, major); diff --git a/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java b/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java index dd8c1e8..64c9088 100644 --- a/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java +++ b/src/test/java/org/unilab/uniplan/major/MajorValidatorTest.java @@ -38,39 +38,20 @@ void setUp() { } @Test - void validateForCreateShouldPassWhenFacultyExists() { + void validate_shouldPass_whenFacultyExists() { when(facultyRepository.existsById(facultyId)).thenReturn(true); - assertDoesNotThrow(() -> majorValidator.validateForCreate(requestDto)); + assertDoesNotThrow(() -> majorValidator.validate(requestDto)); verify(facultyRepository).existsById(facultyId); } @Test - void validateForCreateShouldThrowWhenFacultyDoesNotExist() { + void validate_shouldThrow_whenFacultyDoesNotExist() { when(facultyRepository.existsById(facultyId)).thenReturn(false); assertThrows(ResourceNotFoundException.class, - () -> majorValidator.validateForCreate(requestDto)); - - verify(facultyRepository).existsById(facultyId); - } - - @Test - void validateForUpdateShouldPassWhenFacultyExists() { - when(facultyRepository.existsById(facultyId)).thenReturn(true); - - assertDoesNotThrow(() -> majorValidator.validateForUpdate(requestDto)); - - verify(facultyRepository).existsById(facultyId); - } - - @Test - void validateForUpdateShouldThrowWhenFacultyDoesNotExist() { - when(facultyRepository.existsById(facultyId)).thenReturn(false); - - assertThrows(ResourceNotFoundException.class, - () -> majorValidator.validateForUpdate(requestDto)); + () -> majorValidator.validate(requestDto)); verify(facultyRepository).existsById(facultyId); } diff --git a/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java b/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java index 984e809..516f1dc 100644 --- a/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java +++ b/src/test/java/org/unilab/uniplan/major/MajorWebFacadeTest.java @@ -63,7 +63,7 @@ void createMajorShouldValidateMapAndSaveMajor() { majorWebFacade.createMajor(requestDto); final InOrder inOrder = inOrder(majorValidator, majorMapper, majorService); - inOrder.verify(majorValidator).validateForCreate(requestDto); + inOrder.verify(majorValidator).validate(requestDto); inOrder.verify(majorMapper).toEntity(requestDto); inOrder.verify(majorService).save(major); } @@ -167,7 +167,7 @@ void updateMajorShouldValidateUpdateMapAndSaveMajorIfFound() { majorWebFacade.updateMajor(majorId, requestDto); final InOrder inOrder = inOrder(majorValidator, majorService, majorMapper); - inOrder.verify(majorValidator).validateForUpdate(requestDto); + inOrder.verify(majorValidator).validate(requestDto); inOrder.verify(majorService).getById(majorId); inOrder.verify(majorMapper).updateEntityFromDto(requestDto, major); inOrder.verify(majorService).save(major); @@ -180,7 +180,7 @@ void updateMajorShouldThrowIfMajorDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> majorWebFacade.updateMajor(majorId, requestDto)); - verify(majorValidator).validateForUpdate(requestDto); + verify(majorValidator).validate(requestDto); verify(majorService).getById(majorId); verify(majorMapper, never()).updateEntityFromDto(any(MajorRequestDto.class), any(Major.class)); verify(majorService, never()).save(any(Major.class)); From 79cb4921c95c967d174ffd9c2117ffcede0c3ce5 Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Tue, 4 Aug 2026 12:43:16 +0300 Subject: [PATCH 09/10] map facultyId in MajorMapper, remove misleading repository methods --- src/main/java/org/unilab/uniplan/major/MajorMapper.java | 2 ++ src/main/java/org/unilab/uniplan/major/MajorRepository.java | 3 +-- .../java/org/unilab/uniplan/major/dto/MajorRequestDto.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/major/MajorMapper.java b/src/main/java/org/unilab/uniplan/major/MajorMapper.java index 0493d0f..3330c56 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorMapper.java +++ b/src/main/java/org/unilab/uniplan/major/MajorMapper.java @@ -19,10 +19,12 @@ public interface MajorMapper { @Mapping(source = "facultyId", target = "faculty.id") void updateEntityFromDto(MajorRequestDto majorRequestDto, @MappingTarget Major major); + @Mapping(source = "faculty.id", target = "facultyId") MajorResponseDto toResponseDto(Major major); List toResponseDtoList(List majors); + @Mapping(source = "faculty.id", target = "facultyId") MajorCoursesResponseDto toFullResponseDto(Major major); List toFullResponseDtoList(List majors); diff --git a/src/main/java/org/unilab/uniplan/major/MajorRepository.java b/src/main/java/org/unilab/uniplan/major/MajorRepository.java index bb0688d..9306d4e 100644 --- a/src/main/java/org/unilab/uniplan/major/MajorRepository.java +++ b/src/main/java/org/unilab/uniplan/major/MajorRepository.java @@ -8,7 +8,6 @@ @Repository public interface MajorRepository extends JpaRepository { - public List findAllByFacultyId(UUID facultyId); - List findAllMajorByFacultyId(UUID facultyId); + List findAllByFacultyId(UUID facultyId); List findAllMajorWithCoursesByFacultyId(UUID facultyId); } diff --git a/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java b/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java index ea70b01..a69956d 100644 --- a/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java +++ b/src/main/java/org/unilab/uniplan/major/dto/MajorRequestDto.java @@ -8,7 +8,7 @@ public record MajorRequestDto( @NotNull(message = "Faculty id cannot be null") UUID facultyId, - @NotBlank(message = "Major name cannot be null") + @NotBlank(message = "Major is required") @Size(max = 200, message = "Major name must be at most 200 characters") String majorName ) { From 813924a7d958077992142f9ae774c87d7b6c211d Mon Sep 17 00:00:00 2001 From: Djesika Vacheva Date: Wed, 5 Aug 2026 11:56:26 +0300 Subject: [PATCH 10/10] add tests for findAllMajorWithCoursesByFacultyId --- .../uniplan/major/MajorServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java b/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java index 5d53c8b..34c3f6c 100644 --- a/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java +++ b/src/test/java/org/unilab/uniplan/major/MajorServiceTest.java @@ -100,4 +100,25 @@ void deleteShouldDeleteMajor() { verify(majorRepository).delete(major); } + + @Test + void findAllMajorWithCoursesByFacultyIdShouldReturnListOfMajors() { + final List majors = List.of(major); + + when(majorRepository.findAllMajorWithCoursesByFacultyId(facultyId)).thenReturn(List.of(major)); + + final List result = majorService.findAllMajorWithCoursesByFacultyId(facultyId); + + assertEquals(majors, result); + verify(majorRepository).findAllMajorWithCoursesByFacultyId(facultyId); + } + + @Test + void findAllMajorWithCoursesByFacultyIdShouldReturnEmptyList() { + when(majorRepository.findAllMajorWithCoursesByFacultyId(facultyId)).thenReturn(List.of()); + + assertTrue(majorService.findAllMajorWithCoursesByFacultyId(facultyId).isEmpty()); + + verify(majorRepository).findAllMajorWithCoursesByFacultyId(facultyId); + } }