From 5a2598a833c5d574505bdc79889cf006baab0e27 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Tue, 7 Jul 2026 11:43:14 +0300 Subject: [PATCH 01/14] Remove internal dto, update mapper --- .../unilab/uniplan/room/RoomController.java | 1 - .../org/unilab/uniplan/room/RoomMapper.java | 20 ++++++------------- .../org/unilab/uniplan/room/RoomService.java | 1 - .../org/unilab/uniplan/room/dto/RoomDto.java | 19 ------------------ .../uniplan/room/dto/RoomResponseDto.java | 3 --- .../unilab/uniplan/room/RoomServiceTest.java | 1 - 6 files changed, 6 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/org/unilab/uniplan/room/dto/RoomDto.java diff --git a/src/main/java/org/unilab/uniplan/room/RoomController.java b/src/main/java/org/unilab/uniplan/room/RoomController.java index 20b3f1a6..d8eb1d7e 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomController.java +++ b/src/main/java/org/unilab/uniplan/room/RoomController.java @@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import org.unilab.uniplan.room.dto.RoomDto; import org.unilab.uniplan.room.dto.RoomRequestDto; import org.unilab.uniplan.room.dto.RoomResponseDto; diff --git a/src/main/java/org/unilab/uniplan/room/RoomMapper.java b/src/main/java/org/unilab/uniplan/room/RoomMapper.java index a551abaf..c923d684 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomMapper.java +++ b/src/main/java/org/unilab/uniplan/room/RoomMapper.java @@ -4,29 +4,21 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; -import org.unilab.uniplan.room.dto.RoomDto; import org.unilab.uniplan.room.dto.RoomRequestDto; import org.unilab.uniplan.room.dto.RoomResponseDto; @Mapper public interface RoomMapper { - @Mapping(source = "faculty.id", target = "facultyId") - RoomDto toDto(final Room room); - @Mapping(source = "facultyId", target = "faculty.id") - Room toEntity(final RoomDto roomDto); - - @Mapping(target = "id", ignore = true) - RoomDto toInternalDto(final RoomRequestDto roomRequestDto); + Room toEntity(final RoomRequestDto roomRequestDto); - RoomResponseDto toResponseDto(final RoomDto roomDto); + @Mapping(target = "facultyId", source = "faculty.id") + RoomResponseDto toResponseDto(Room room); - List toDtoList(final List rooms); + List toResponseDtoList(final List rooms); - List toResponseDtoList(final List rooms); - - @Mapping(source = "roomDto.facultyId", target = "faculty.id") + @Mapping(source = "facultyId", target = "faculty.id") @Mapping(target = "id", ignore = true) - void updateEntityFromDto(final RoomDto roomDto, @MappingTarget final Room room); + void updateEntityFromDto(final RoomRequestDto roomRequestDto, @MappingTarget final Room room); } diff --git a/src/main/java/org/unilab/uniplan/room/RoomService.java b/src/main/java/org/unilab/uniplan/room/RoomService.java index 5dbd29ac..582a9d5b 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomService.java +++ b/src/main/java/org/unilab/uniplan/room/RoomService.java @@ -8,7 +8,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.room.dto.RoomDto; @Service @RequiredArgsConstructor diff --git a/src/main/java/org/unilab/uniplan/room/dto/RoomDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomDto.java deleted file mode 100644 index 0acf52e4..00000000 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.unilab.uniplan.room.dto; - -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.UUID; - -public record RoomDto( - - UUID id, - - @NotNull(message = "Faculty ID cannot be null") - UUID facultyId, - - @NotNull(message = "Room number cannot be null") - @Size(max = 50, message = "Room number cannot exceed 50 characters") - String roomNumber -) { - -} diff --git a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java index b5cf53fe..184b1844 100644 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java +++ b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java @@ -8,11 +8,8 @@ public record RoomResponseDto( UUID id, - @NotNull(message = "Faculty ID cannot be null") UUID facultyId, - @NotNull(message = "Room number cannot be null") - @Size(max = 50, message = "Room number cannot exceed 50 characters") String roomNumber ) { diff --git a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java index 26d1d931..1e56536d 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java @@ -18,7 +18,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.room.dto.RoomDto; @ExtendWith(MockitoExtension.class) class RoomServiceTest { From 81bd802beaa6cdd85a693a4fb64acef2daf80742 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Tue, 7 Jul 2026 11:48:03 +0300 Subject: [PATCH 02/14] Update roomService by implementing baseService --- .../org/unilab/uniplan/room/RoomService.java | 54 ++++++------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/RoomService.java b/src/main/java/org/unilab/uniplan/room/RoomService.java index 582a9d5b..57a3b7f5 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomService.java +++ b/src/main/java/org/unilab/uniplan/room/RoomService.java @@ -3,62 +3,38 @@ import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND; import java.util.List; +import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.unilab.uniplan.common.model.BaseService; import org.unilab.uniplan.exception.ResourceNotFoundException; +import org.unilab.uniplan.room.dto.RoomRequestDto; @Service @RequiredArgsConstructor -public class RoomService { +public class RoomService implements BaseService { private final RoomRepository roomRepository; - private final RoomMapper roomMapper; - @Transactional - public RoomDto createRoom(final RoomDto roomDto) { - final Room room = roomMapper.toEntity(roomDto); - - return saveEntityAndConvertToDto(room); - } - - public List getAllRooms() { - return roomMapper.toDtoList(roomRepository.findAll()); + @Override + public void save(final Room room) { + roomRepository.save(room); } - public RoomDto getRoomById(final UUID id) { - return roomRepository.findById(id) - .map(roomMapper::toDto) - .orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage( - String.valueOf(id)))); + @Override + public List getAll() { + return roomRepository.findAll(); } - @Transactional - public RoomDto updateRoom(final UUID id, final RoomDto roomDto) { - return roomRepository.findById(id) - .map(existingRoom -> updateEntityAndConvertToDto( - roomDto, - existingRoom)).orElseThrow(() -> new ResourceNotFoundException( - ROOM_NOT_FOUND.getMessage(String.valueOf(id)))); + @Override + public Optional getById(final UUID id) { + return roomRepository.findById(id); } - @Transactional - public void deleteRoom(final UUID id) { - final Room room = roomRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException( - ROOM_NOT_FOUND.getMessage(String.valueOf(id)))); + @Override + public void delete(final Room room) { roomRepository.delete(room); } - - private RoomDto updateEntityAndConvertToDto(final RoomDto dto, - final Room entity) { - roomMapper.updateEntityFromDto(dto, entity); - return saveEntityAndConvertToDto(entity); - } - - private RoomDto saveEntityAndConvertToDto(final Room entity) { - final Room savedEntity = roomRepository.save(entity); - return roomMapper.toDto(savedEntity); - } } From 8527924dc0f273812c638568ca8a0e4629831f0b Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Tue, 7 Jul 2026 11:58:26 +0300 Subject: [PATCH 03/14] Add room facade layer --- .../unilab/uniplan/room/RoomWebFacade.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/org/unilab/uniplan/room/RoomWebFacade.java diff --git a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java new file mode 100644 index 00000000..282ad7e9 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java @@ -0,0 +1,64 @@ +package org.unilab.uniplan.room; + +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.faculty.Faculty; +import org.unilab.uniplan.room.dto.RoomRequestDto; +import org.unilab.uniplan.room.dto.RoomResponseDto; +import java.util.List; +import java.util.UUID; + +import static org.unilab.uniplan.utils.ErrorConstants.FACULTY_NOT_FOUND; +import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND; + +@Component +@Slf4j +@RequiredArgsConstructor +public class RoomWebFacade { + + private RoomMapper roomMapper; + private RoomService roomService; + + private Room getRoomOrThrow(final UUID id) { + return roomService.getById(id) + .orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage( + String.valueOf(id)))); + } + + @Transactional + public void saveRoom(RoomRequestDto roomRequestDto) { + Room room = roomMapper.toEntity(roomRequestDto); + roomService.save(room); + log.info("created room {} with ID: {}", + room.getRoomNumber(), + room.getId()); + } + + @Transactional(readOnly=true) + public List getAllRooms() { + return roomMapper.toResponseDtoList(roomService.getAll()); + } + + @Transactional + public void deleteRoom(final UUID id) { + final Room room = getRoomOrThrow(id); + roomService.delete(room); + log.info("deleted room with id {}", id); + } + + @Transactional(readOnly=true) + public RoomResponseDto getRoomById(final UUID id) { + final Room room = getRoomOrThrow(id); + return roomMapper.toResponseDto(room); + } + + @Transactional + public void updateRoom(final UUID id, final RoomRequestDto roomRequestDto) { + final Room room = getRoomOrThrow(id); + roomService.save(room); + log.info("updated room with id {}", id); + } +} From 5217de6184458d2cd369e785a7c662420af05cd5 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Tue, 7 Jul 2026 12:50:34 +0300 Subject: [PATCH 04/14] Update controller to use facade layer --- .../unilab/uniplan/room/RoomController.java | 27 ++--- .../unilab/uniplan/room/RoomWebFacade.java | 9 +- .../unilab/uniplan/room/RoomServiceTest.java | 103 ------------------ 3 files changed, 13 insertions(+), 126 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/RoomController.java b/src/main/java/org/unilab/uniplan/room/RoomController.java index d8eb1d7e..55206cf6 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomController.java +++ b/src/main/java/org/unilab/uniplan/room/RoomController.java @@ -1,7 +1,5 @@ package org.unilab.uniplan.room; -import static org.springframework.http.ResponseEntity.ok; - import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -27,39 +25,34 @@ @Tag(name = "Rooms", description = "Manage classrooms and lecture halls, including room numbers and assigned faculties") public class RoomController { - private final RoomService roomService; - private final RoomMapper roomMapper; + private final RoomWebFacade roomWebFacade; @PostMapping - public ResponseEntity createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) { - final RoomDto roomDto = roomService.createRoom(roomMapper.toInternalDto(roomRequestDto)); - - return new ResponseEntity<>(roomMapper.toResponseDto(roomDto), HttpStatus.CREATED); + public ResponseEntity createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) { + roomWebFacade.createRoom(roomRequestDto); + return ResponseEntity.status(HttpStatus.CREATED).build(); } @GetMapping - public List getAllRooms() { - return roomMapper.toResponseDtoList(roomService.getAllRooms()); + public ResponseEntity> getAllRooms() { + return ResponseEntity.ok(roomWebFacade.getAllRooms()); } @GetMapping("/{id}") public ResponseEntity getRoomById(@PathVariable final UUID id) { - final RoomDto roomDto = roomService.getRoomById(id); - - return ok(roomMapper.toResponseDto(roomDto)); + return ResponseEntity.ok(roomWebFacade.getRoomById(id)); } @PutMapping("/{id}") public ResponseEntity updateRoom(@PathVariable final UUID id, @Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) { - final RoomDto internalDto = roomMapper.toInternalDto(roomRequestDto); - - return ok(roomMapper.toResponseDto(roomService.updateRoom(id, internalDto))); + roomWebFacade.updateRoom(id, roomRequestDto); + return ResponseEntity.noContent().build(); } @DeleteMapping("/{id}") public ResponseEntity deleteRoom(@PathVariable final UUID id) { - roomService.deleteRoom(id); + roomWebFacade.deleteRoom(id); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java index 282ad7e9..7e04990f 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java +++ b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java @@ -5,13 +5,10 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.faculty.Faculty; import org.unilab.uniplan.room.dto.RoomRequestDto; import org.unilab.uniplan.room.dto.RoomResponseDto; import java.util.List; import java.util.UUID; - -import static org.unilab.uniplan.utils.ErrorConstants.FACULTY_NOT_FOUND; import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND; @Component @@ -19,8 +16,8 @@ @RequiredArgsConstructor public class RoomWebFacade { - private RoomMapper roomMapper; - private RoomService roomService; + private final RoomMapper roomMapper; + private final RoomService roomService; private Room getRoomOrThrow(final UUID id) { return roomService.getById(id) @@ -29,7 +26,7 @@ private Room getRoomOrThrow(final UUID id) { } @Transactional - public void saveRoom(RoomRequestDto roomRequestDto) { + public void createRoom(RoomRequestDto roomRequestDto) { Room room = roomMapper.toEntity(roomRequestDto); roomService.save(room); log.info("created room {} with ID: {}", diff --git a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java index 1e56536d..9ad76785 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java @@ -22,108 +22,5 @@ @ExtendWith(MockitoExtension.class) class RoomServiceTest { - @Mock - private RoomRepository roomRepository; - @Mock - private RoomMapper roomMapper; - - @InjectMocks - private RoomService roomService; - - private UUID id; - private UUID facultyId; - private RoomDto dto; - private Room entity; - - @BeforeEach - void setUp() { - id = UUID.randomUUID(); - facultyId = UUID.randomUUID(); - dto = new RoomDto(id, facultyId, "101"); - entity = new Room(); - } - - @Test - void testCreateRoomShouldSaveAndReturnDto() { - when(roomMapper.toEntity(dto)).thenReturn(entity); - when(roomRepository.save(entity)).thenReturn(entity); - when(roomMapper.toDto(entity)).thenReturn(dto); - - RoomDto result = roomService.createRoom(dto); - - assertEquals(dto, result); - } - - @Test - void testGetAllRoomsShouldReturnListOfRoomDtos() { - List entities = List.of(entity); - List dtos = List.of(dto); - - when(roomRepository.findAll()).thenReturn(entities); - when(roomMapper.toDtoList(entities)).thenReturn(dtos); - - List result = roomService.getAllRooms(); - - assertEquals(dtos, result); - } - - @Test - void testGetRoomByIdShouldReturnRoomDtoIfFound() { - when(roomRepository.findById(id)).thenReturn(Optional.of(entity)); - when(roomMapper.toDto(entity)).thenReturn(dto); - - RoomDto result = roomService.getRoomById(id); - - assertEquals(dto, result); - } - - @Test - void testGetRoomByIdShouldReturnEmptyOptionalIfRoomNotFound() { - when(roomRepository.findById(id)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> roomService.getRoomById(id)); - - assertTrue(exception.getMessage().contains(String.valueOf(id))); - } - - @Test - void testUpdateRoomShouldUpdateAndReturnDtoIfFound() { - when(roomRepository.findById(id)).thenReturn(Optional.of(entity)); - doAnswer(invocation -> null).when(roomMapper).updateEntityFromDto(dto, entity); - when(roomRepository.save(entity)).thenReturn(entity); - when(roomMapper.toDto(entity)).thenReturn(dto); - - RoomDto result = roomService.updateRoom(id, dto); - - assertEquals(dto, result); - } - - @Test - void testUpdateRoomShouldReturnEmptyOptionalIfNotFound() { - when(roomRepository.findById(id)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> roomService.updateRoom(id, dto)); - - assertTrue(exception.getMessage().contains(String.valueOf(id))); - } - - @Test - void testDeleteRoomShouldDeleteRoomIfFound() { - when(roomRepository.findById(id)).thenReturn(Optional.of(entity)); - doAnswer(invocation -> null).when(roomRepository).delete(entity); - - assertDoesNotThrow(() -> roomService.deleteRoom(id)); - verify(roomRepository).delete(entity); - } - - @Test - void testDeleteRoomShouldThrowIfNotFound() { - when(roomRepository.findById(id)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> - roomService.deleteRoom(id)); - - assertTrue(exception.getMessage().contains(String.valueOf(id))); - } } From cd5b74c8d15b58ffde706c9a1d645dd589bd58a0 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Wed, 8 Jul 2026 09:49:30 +0300 Subject: [PATCH 05/14] Add tests for room service --- .../uniplan/room/dto/RoomResponseDto.java | 2 - .../unilab/uniplan/room/RoomServiceTest.java | 55 +++++++++++++++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java index 184b1844..8e243f2e 100644 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java +++ b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java @@ -1,7 +1,5 @@ package org.unilab.uniplan.room.dto; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import java.util.UUID; public record RoomResponseDto( diff --git a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java index 9ad76785..58e3736f 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java @@ -1,10 +1,6 @@ package org.unilab.uniplan.room; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -17,10 +13,59 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.unilab.uniplan.exception.ResourceNotFoundException; @ExtendWith(MockitoExtension.class) class RoomServiceTest { + @Mock + private RoomRepository roomRepository; + @InjectMocks + private RoomService roomService; + private Room room; + private UUID id; + + @BeforeEach + void setUp() { + id = UUID.randomUUID(); + room = new Room(); + } + + @Test + void save_shouldSaveEntity() { + when(roomRepository.save(room)).thenReturn(room); + + roomService.save(room); + + verify(roomRepository).save(room); + } + + @Test + void findAll_shouldReturnListOfEntities() { + List rooms = List.of(room); + when(roomRepository.findAll()).thenReturn(List.of(room)); + + List result = roomService.getAll(); + + verify(roomRepository).findAll(); + assertEquals(result, rooms); + } + + @Test + void findById_shouldReturnEntity_whenRoomExists() { + Optional expected = Optional.of(room); + when(roomRepository.findById(id)).thenReturn(expected); + + Optional result = roomService.getById(id); + + verify(roomRepository).findById(id); + assertEquals(expected, result); + } + + @Test + void delete_shouldDeleteEntity_whenFacultyExists() { + roomService.delete(room); + + verify(roomRepository).delete(room); + } } From 93be8fa46200f6c1d632da7e84df302d333e9456 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Wed, 8 Jul 2026 10:25:54 +0300 Subject: [PATCH 06/14] Add tests for roomMapper --- .../unilab/uniplan/room/RoomMapperTest.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/test/java/org/unilab/uniplan/room/RoomMapperTest.java diff --git a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java new file mode 100644 index 00000000..c7045662 --- /dev/null +++ b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java @@ -0,0 +1,97 @@ +package org.unilab.uniplan.room; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.unilab.uniplan.faculty.Faculty; +import org.unilab.uniplan.room.dto.RoomRequestDto; +import org.unilab.uniplan.room.dto.RoomResponseDto; +import org.unilab.uniplan.university.University; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class RoomMapperTest { + + private final RoomMapper roomMapper = new RoomMapperImpl(); + private Room room1; + private Room room2; + private RoomRequestDto roomRequestDto; + private RoomResponseDto roomResponseDto1; + private RoomResponseDto roomResponseDto2; + + private String roomNumber1; + private UUID facultyId; + + @BeforeEach + void setUp() { + facultyId = UUID.randomUUID(); + + University university = new University("Sofia University", + "Sofia, Bulgaria", + (short) 1888, + "NEAA", + "https://uni-sofia.bg" + ); + Faculty faculty = new Faculty(university, "FMI", "Faculty Name"); + faculty.setId(facultyId); + roomNumber1 = "111"; + String roomNumber2 = "222"; + room1 = new Room(faculty, roomNumber1); + room1.setId(UUID.randomUUID()); + room2 = new Room(faculty, roomNumber2); + room2.setId(UUID.randomUUID()); + roomRequestDto = new RoomRequestDto(facultyId, roomNumber1); + roomResponseDto1 = new RoomResponseDto(room1.getId(), facultyId, roomNumber1); + roomResponseDto2 = new RoomResponseDto(room2.getId(), facultyId, roomNumber2); + + } + + @Test + void toEntity_shouldMapAllFieldsAndIgnoreId_whenRequestDtoIsValid() { + final Room result = roomMapper.toEntity(roomRequestDto); + assertThat(result.getFaculty().getId()).isEqualTo(facultyId); + assertThat(result.getRoomNumber()).isEqualTo(roomNumber1); + assertThat(result.getId()).isNull(); + } + + @Test + void toResponseDto_shouldMapAllFields_whenFacultyIsValid() { + RoomResponseDto result = roomMapper.toResponseDto(room1); + assertThat(result.id()).isEqualTo(room1.getId()); + assertThat(result.facultyId()).isEqualTo(facultyId); + assertThat(result.roomNumber()).isEqualTo(roomNumber1); + } + + @Test + void toResponseDtoList_shouldMapAllElements_whenListIsNotEmpty() { + List rooms = List.of(room1, room2); + List results = roomMapper.toResponseDtoList(rooms); + + assertThat(results.size()).isEqualTo(2); + assertThat(results.get(0)).isEqualTo(roomResponseDto1); + assertThat(results.get(1)).isEqualTo(roomResponseDto2); + } + + @Test + void toResponseDtoList_shouldReturnEmptyList_whenListIsEmpty() { + List rooms = List.of(); + List results = roomMapper.toResponseDtoList(rooms); + + assertThat(results).isEmpty(); + } + + @Test + void updateEntity_shouldUpdateAllFields_whenRequestDtoIsValid() { + roomMapper.updateEntityFromDto(roomRequestDto, room2); + assertThat(room2.getRoomNumber()).isEqualTo(roomNumber1); + } + + @Test + void updateEntity_shouldNotChangeId_whenUpdating() { + UUID id = room2.getId(); + roomMapper.updateEntityFromDto(roomRequestDto, room2); + assertThat(room2.getId()).isEqualTo(id); + } +} \ No newline at end of file From 5745b7711c4a830a8e3adbf36939093f2526d30f Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Wed, 8 Jul 2026 11:16:41 +0300 Subject: [PATCH 07/14] Add tests for RoomWebFacade --- .../unilab/uniplan/room/RoomWebFacade.java | 1 + .../uniplan/room/RoomWebFacadeTest.java | 143 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java diff --git a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java index 7e04990f..706e2f7b 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java +++ b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java @@ -55,6 +55,7 @@ public RoomResponseDto getRoomById(final UUID id) { @Transactional public void updateRoom(final UUID id, final RoomRequestDto roomRequestDto) { final Room room = getRoomOrThrow(id); + roomMapper.updateEntityFromDto(roomRequestDto, room); roomService.save(room); log.info("updated room with id {}", id); } diff --git a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java new file mode 100644 index 00000000..a3dd4b96 --- /dev/null +++ b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java @@ -0,0 +1,143 @@ +package org.unilab.uniplan.room; + +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.Faculty; +import org.unilab.uniplan.room.dto.RoomRequestDto; +import org.unilab.uniplan.room.dto.RoomResponseDto; +import org.unilab.uniplan.university.University; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class RoomWebFacadeTest { + + @Mock + private RoomMapper roomMapper; + @Mock + private RoomService roomService; + @InjectMocks + private RoomWebFacade roomWebFacade; + private RoomRequestDto requestDto; + private Room entity; + private RoomResponseDto responseDto; + private UUID id; + + @BeforeEach + void setUp() { + id = UUID.randomUUID(); + UUID facultyId = UUID.randomUUID(); + University university = new University("Sofia University", + "Sofia, Bulgaria", + (short) 1888, + "NEAA", + "https://uni-sofia.bg" + ); + Faculty faculty = new Faculty(university, "FMI", "Faculty Name"); + faculty.setId(facultyId); + String roomNumber = "111"; + requestDto = new RoomRequestDto(facultyId, "222"); + entity = new Room(faculty, roomNumber); + entity.setId(id); + responseDto = new RoomResponseDto(id, facultyId, roomNumber); + } + + @Test + void createRoom_shouldSaveRoom_whenRequestIsValid() { + when(roomMapper.toEntity(requestDto)).thenReturn(entity); + + roomWebFacade.createRoom(requestDto); + + final var inOrder = inOrder(roomMapper, roomService); + inOrder.verify(roomMapper).toEntity(requestDto); + inOrder.verify(roomService).save(entity); + } + + @Test + void getAllRooms_shouldReturnListOfResponseDtos() { + List rooms = List.of(responseDto); + List roomEntities=List.of(entity); + when(roomService.getAll()).thenReturn(roomEntities); + when(roomMapper.toResponseDtoList(roomEntities)) + .thenReturn(rooms); + + List results = roomWebFacade.getAllRooms(); + + assertEquals(rooms, results); + verify(roomService).getAll(); + verify(roomMapper).toResponseDtoList(roomEntities); + } + + @Test + void deleteRoom_shouldDeleteRoom_whenRoomExists() { + when(roomService.getById(id)).thenReturn(Optional.of(entity)); + + roomWebFacade.deleteRoom(entity.getId()); + + verify(roomService).delete(entity); + } + + @Test + void deleteRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { + when(roomService.getById(id)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> roomWebFacade.deleteRoom(id)) + .isInstanceOf(ResourceNotFoundException.class) + .hasMessageContaining(id.toString()); + } + + @Test + void getRoomById_shouldReturnResponseDto_whenRoomExists() { + when(roomService.getById(id)).thenReturn(Optional.of(entity)); + when(roomMapper.toResponseDto(entity)).thenReturn(responseDto); + + RoomResponseDto result = roomWebFacade.getRoomById(id); + + assertThat(result.roomNumber()).isEqualTo(entity.getRoomNumber()); + verify(roomService).getById(id); + verify(roomMapper).toResponseDto(entity); + } + + @Test + void getRoomById_shouldThrowResourceNotFoundException_whenRoomNotFound() { + when(roomService.getById(id)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> roomWebFacade.getRoomById(id)) + .isInstanceOf(ResourceNotFoundException.class) + .hasMessageContaining(id.toString()); + verify(roomService).getById(id); + } + + @Test + void updateRoom_shouldUpdateRoom_whenRoomExists() { + when(roomService.getById(id)).thenReturn(Optional.of(entity)); + + roomWebFacade.updateRoom(id, requestDto); + + verify(roomMapper).updateEntityFromDto(requestDto, entity); + verify(roomService).save(entity); + } + + @Test + void updateRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { + when(roomService.getById(id)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> roomWebFacade.updateRoom(id, requestDto)) + .isInstanceOf(ResourceNotFoundException.class) + .hasMessageContaining(id.toString()); + } +} From f8fc9aa99ce9542e618dbc43826ca83cbc977c8d Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Wed, 15 Jul 2026 15:14:30 +0300 Subject: [PATCH 08/14] Include category in room response --- .../unilab/uniplan/room/RoomRepository.java | 32 +++++++++++++++++++ .../org/unilab/uniplan/room/RoomService.java | 9 ++++++ .../unilab/uniplan/room/RoomWebFacade.java | 11 ++++--- .../uniplan/room/dto/RoomResponseDto.java | 7 ++-- .../roomcategory/RoomCategoryRepository.java | 4 ++- .../unilab/uniplan/room/RoomMapperTest.java | 4 +-- .../uniplan/room/RoomWebFacadeTest.java | 4 +-- 7 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/RoomRepository.java b/src/main/java/org/unilab/uniplan/room/RoomRepository.java index 0597aa71..62dcc1a8 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/RoomRepository.java @@ -1,10 +1,42 @@ package org.unilab.uniplan.room; + +import java.util.List; +import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.unilab.uniplan.room.dto.RoomResponseDto; @Repository public interface RoomRepository extends JpaRepository { + @Query(""" + SELECT new org.unilab.uniplan.room.dto.RoomResponseDto( + r.id, + r.faculty.id, + r.roomNumber, + c.id + ) + FROM Room r + JOIN RoomCategory rc ON rc.room = r + JOIN rc.category c + """) + List findAllRoomResponses(); + + @Query(""" + SELECT new org.unilab.uniplan.room.dto.RoomResponseDto( + r.id, + r.faculty.id, + r.roomNumber, + c.id + ) + FROM RoomCategory rc + JOIN rc.room r + JOIN rc.category c + WHERE r.id = :id + """) + Optional findRoomResponseById(@Param("id") UUID id); } \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/room/RoomService.java b/src/main/java/org/unilab/uniplan/room/RoomService.java index 57a3b7f5..ee8074e1 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomService.java +++ b/src/main/java/org/unilab/uniplan/room/RoomService.java @@ -11,6 +11,7 @@ import org.unilab.uniplan.common.model.BaseService; import org.unilab.uniplan.exception.ResourceNotFoundException; import org.unilab.uniplan.room.dto.RoomRequestDto; +import org.unilab.uniplan.room.dto.RoomResponseDto; @Service @RequiredArgsConstructor @@ -37,4 +38,12 @@ public Optional getById(final UUID id) { public void delete(final Room room) { roomRepository.delete(room); } + + public List getAllRoomResponses() { + return roomRepository.findAllRoomResponses(); + } + + public Optional getRoomResponseById(final UUID id) { + return roomRepository.findRoomResponseById(id); + } } diff --git a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java index 706e2f7b..b2cab683 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java +++ b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java @@ -34,9 +34,9 @@ public void createRoom(RoomRequestDto roomRequestDto) { room.getId()); } - @Transactional(readOnly=true) + @Transactional(readOnly = true) public List getAllRooms() { - return roomMapper.toResponseDtoList(roomService.getAll()); + return roomService.getAllRoomResponses(); } @Transactional @@ -46,10 +46,11 @@ public void deleteRoom(final UUID id) { log.info("deleted room with id {}", id); } - @Transactional(readOnly=true) + @Transactional(readOnly = true) public RoomResponseDto getRoomById(final UUID id) { - final Room room = getRoomOrThrow(id); - return roomMapper.toResponseDto(room); + return roomService.getRoomResponseById(id) + .orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage( + String.valueOf(id)))); } @Transactional diff --git a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java index 8e243f2e..e0a2df5b 100644 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java +++ b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java @@ -8,7 +8,8 @@ public record RoomResponseDto( UUID facultyId, - String roomNumber -) { + String roomNumber, -} + UUID categoryId + +) { } diff --git a/src/main/java/org/unilab/uniplan/roomcategory/RoomCategoryRepository.java b/src/main/java/org/unilab/uniplan/roomcategory/RoomCategoryRepository.java index 8f8a1f2c..00957015 100644 --- a/src/main/java/org/unilab/uniplan/roomcategory/RoomCategoryRepository.java +++ b/src/main/java/org/unilab/uniplan/roomcategory/RoomCategoryRepository.java @@ -1,9 +1,11 @@ package org.unilab.uniplan.roomcategory; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; @Repository public interface RoomCategoryRepository extends JpaRepository { - } \ No newline at end of file diff --git a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java index c7045662..9d4122ab 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java @@ -13,7 +13,7 @@ public class RoomMapperTest { - +/* private final RoomMapper roomMapper = new RoomMapperImpl(); private Room room1; private Room room2; @@ -93,5 +93,5 @@ void updateEntity_shouldNotChangeId_whenUpdating() { UUID id = room2.getId(); roomMapper.updateEntityFromDto(roomRequestDto, room2); assertThat(room2.getId()).isEqualTo(id); - } + }*/ } \ No newline at end of file diff --git a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java index a3dd4b96..7190b99e 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java @@ -25,7 +25,7 @@ @ExtendWith(MockitoExtension.class) public class RoomWebFacadeTest { - +/* @Mock private RoomMapper roomMapper; @Mock @@ -139,5 +139,5 @@ void updateRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { assertThatThrownBy(() -> roomWebFacade.updateRoom(id, requestDto)) .isInstanceOf(ResourceNotFoundException.class) .hasMessageContaining(id.toString()); - } + }*/ } From 18a22b879a8d8682a61b0c678d571fa8f5219ca6 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Mon, 20 Jul 2026 12:08:18 +0300 Subject: [PATCH 09/14] Change to left join instead of inner --- .../java/org/unilab/uniplan/room/RoomRepository.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/RoomRepository.java b/src/main/java/org/unilab/uniplan/room/RoomRepository.java index 62dcc1a8..1bd453b6 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/RoomRepository.java @@ -20,8 +20,8 @@ public interface RoomRepository extends JpaRepository { c.id ) FROM Room r - JOIN RoomCategory rc ON rc.room = r - JOIN rc.category c + LEFT JOIN RoomCategory rc ON rc.room = r + LEFT JOIN rc.category c """) List findAllRoomResponses(); @@ -32,9 +32,9 @@ public interface RoomRepository extends JpaRepository { r.roomNumber, c.id ) - FROM RoomCategory rc - JOIN rc.room r - JOIN rc.category c + FROM Room r + LEFT JOIN RoomCategory rc ON rc.room = r + LEFT JOIN rc.category c WHERE r.id = :id """) Optional findRoomResponseById(@Param("id") UUID id); From 2109a9e0dbe22e0acfae129033bbd253058023a2 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Mon, 20 Jul 2026 13:19:43 +0300 Subject: [PATCH 10/14] Use Criteria API instead of jpql in room repository --- .../uniplan/room/CustomRoomRepository.java | 14 ++++ .../room/CustomRoomRepositoryImpl.java | 77 +++++++++++++++++++ .../unilab/uniplan/room/RoomRepository.java | 35 +-------- 3 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java create mode 100644 src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java diff --git a/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java new file mode 100644 index 00000000..0202cda3 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java @@ -0,0 +1,14 @@ +package org.unilab.uniplan.room; + +import org.springframework.data.repository.query.Param; +import org.unilab.uniplan.room.dto.RoomResponseDto; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface CustomRoomRepository { + + List findAllRoomResponses(); + + Optional findRoomResponseById(@Param("id") UUID id); +} diff --git a/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java b/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java new file mode 100644 index 00000000..1ddc4014 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java @@ -0,0 +1,77 @@ +package org.unilab.uniplan.room; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.hibernate.query.common.JoinType; +import org.hibernate.query.criteria.HibernateCriteriaBuilder; +import org.hibernate.query.criteria.JpaCriteriaQuery; +import org.hibernate.query.criteria.JpaEntityJoin; +import org.hibernate.query.criteria.JpaRoot; +import org.springframework.data.repository.query.Param; +import org.unilab.uniplan.category.Category; +import org.unilab.uniplan.room.dto.RoomResponseDto; +import org.unilab.uniplan.roomcategory.RoomCategory; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class CustomRoomRepositoryImpl implements CustomRoomRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public List findAllRoomResponses() { + HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder(); + + JpaCriteriaQuery query = cb.createQuery(RoomResponseDto.class); + + JpaRoot room = query.from(Room.class); + + JpaEntityJoin roomCategory = + room.join(RoomCategory.class, JoinType.LEFT); + roomCategory.on(cb.equal(roomCategory.get("room"), room)); + + JpaEntityJoin category = + roomCategory.join(Category.class, JoinType.LEFT); + category.on(cb.equal(category, roomCategory.get("category"))); + + query.select(cb.construct( + RoomResponseDto.class, + room.get("id"), + room.get("faculty").get("id"), + room.get("roomNumber"), + category.get("id") + )); + + return entityManager.createQuery(query).getResultList(); + } + + @Override + public Optional findRoomResponseById(UUID id) { + HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder(); + + JpaCriteriaQuery query = cb.createQuery(RoomResponseDto.class); + + JpaRoot room = query.from(Room.class); + JpaEntityJoin roomCategory = + room.join(RoomCategory.class, JoinType.LEFT); + roomCategory.on(cb.equal(roomCategory.get("room"), room)); + + JpaEntityJoin category = + roomCategory.join(Category.class, JoinType.LEFT); + category.on(cb.equal(category, roomCategory.get("category"))); + + query.select(cb.construct( + RoomResponseDto.class, + room.get("id"), + room.get("faculty").get("id"), + room.get("roomNumber"), + category.get("id") + )).where(cb.equal(room.get("id"), id)); + + return entityManager.createQuery(query) + .getResultStream() + .findFirst(); + } +} \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/room/RoomRepository.java b/src/main/java/org/unilab/uniplan/room/RoomRepository.java index 1bd453b6..268d42de 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/RoomRepository.java @@ -1,42 +1,9 @@ package org.unilab.uniplan.room; - -import java.util.List; -import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import org.unilab.uniplan.room.dto.RoomResponseDto; @Repository -public interface RoomRepository extends JpaRepository { - @Query(""" - SELECT new org.unilab.uniplan.room.dto.RoomResponseDto( - r.id, - r.faculty.id, - r.roomNumber, - c.id - ) - FROM Room r - LEFT JOIN RoomCategory rc ON rc.room = r - LEFT JOIN rc.category c - """) - List findAllRoomResponses(); - - @Query(""" - SELECT new org.unilab.uniplan.room.dto.RoomResponseDto( - r.id, - r.faculty.id, - r.roomNumber, - c.id - ) - FROM Room r - LEFT JOIN RoomCategory rc ON rc.room = r - LEFT JOIN rc.category c - WHERE r.id = :id - """) - Optional findRoomResponseById(@Param("id") UUID id); - +public interface RoomRepository extends JpaRepository, CustomRoomRepository { } \ No newline at end of file From 01bbc6c664caac66898ce766e17a46171b267712 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Mon, 20 Jul 2026 13:26:08 +0300 Subject: [PATCH 11/14] Update mapper test --- .../org/unilab/uniplan/room/RoomMapperTest.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java index 9d4122ab..a658ca0b 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java @@ -13,7 +13,7 @@ public class RoomMapperTest { -/* + private final RoomMapper roomMapper = new RoomMapperImpl(); private Room room1; private Room room2; @@ -27,7 +27,6 @@ public class RoomMapperTest { @BeforeEach void setUp() { facultyId = UUID.randomUUID(); - University university = new University("Sofia University", "Sofia, Bulgaria", (short) 1888, @@ -43,8 +42,8 @@ void setUp() { room2 = new Room(faculty, roomNumber2); room2.setId(UUID.randomUUID()); roomRequestDto = new RoomRequestDto(facultyId, roomNumber1); - roomResponseDto1 = new RoomResponseDto(room1.getId(), facultyId, roomNumber1); - roomResponseDto2 = new RoomResponseDto(room2.getId(), facultyId, roomNumber2); + roomResponseDto1 = new RoomResponseDto(room1.getId(), facultyId, roomNumber1,null); + roomResponseDto2 = new RoomResponseDto(room2.getId(), facultyId, roomNumber2,null); } @@ -93,5 +92,12 @@ void updateEntity_shouldNotChangeId_whenUpdating() { UUID id = room2.getId(); roomMapper.updateEntityFromDto(roomRequestDto, room2); assertThat(room2.getId()).isEqualTo(id); - }*/ + } + + @Test + void toResponseDto_shouldSetCategoryIdToNull_whenMappingFromRoomEntity() { + RoomResponseDto result = roomMapper.toResponseDto(room1); + + assertThat(result.categoryId()).isNull(); + } } \ No newline at end of file From c1969bc898a317653bb5099f3d252490806b2fd7 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Mon, 20 Jul 2026 13:40:23 +0300 Subject: [PATCH 12/14] Update room web facade tests --- .../uniplan/room/RoomWebFacadeTest.java | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java index 7190b99e..c99d6dfa 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java @@ -25,7 +25,6 @@ @ExtendWith(MockitoExtension.class) public class RoomWebFacadeTest { -/* @Mock private RoomMapper roomMapper; @Mock @@ -36,11 +35,13 @@ public class RoomWebFacadeTest { private Room entity; private RoomResponseDto responseDto; private UUID id; +private UUID categoryId; @BeforeEach void setUp() { id = UUID.randomUUID(); UUID facultyId = UUID.randomUUID(); + categoryId = UUID.randomUUID(); University university = new University("Sofia University", "Sofia, Bulgaria", (short) 1888, @@ -53,7 +54,7 @@ void setUp() { requestDto = new RoomRequestDto(facultyId, "222"); entity = new Room(faculty, roomNumber); entity.setId(id); - responseDto = new RoomResponseDto(id, facultyId, roomNumber); + responseDto = new RoomResponseDto(id, facultyId, roomNumber, categoryId); } @Test @@ -70,56 +71,41 @@ void createRoom_shouldSaveRoom_whenRequestIsValid() { @Test void getAllRooms_shouldReturnListOfResponseDtos() { List rooms = List.of(responseDto); - List roomEntities=List.of(entity); - when(roomService.getAll()).thenReturn(roomEntities); - when(roomMapper.toResponseDtoList(roomEntities)) - .thenReturn(rooms); + when(roomService.getAllRoomResponses()).thenReturn(rooms); List results = roomWebFacade.getAllRooms(); assertEquals(rooms, results); - verify(roomService).getAll(); - verify(roomMapper).toResponseDtoList(roomEntities); + assertThat(results.getFirst().categoryId()).isEqualTo(categoryId); + verify(roomService).getAllRoomResponses(); } @Test - void deleteRoom_shouldDeleteRoom_whenRoomExists() { - when(roomService.getById(id)).thenReturn(Optional.of(entity)); + void getRoomById_shouldReturnResponseDto_whenRoomExists() { + when(roomService.getRoomResponseById(id)).thenReturn(Optional.of(responseDto)); - roomWebFacade.deleteRoom(entity.getId()); + RoomResponseDto result = roomWebFacade.getRoomById(id); - verify(roomService).delete(entity); + assertEquals(result, responseDto); + verify(roomService).getRoomResponseById(id); } @Test - void deleteRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { - when(roomService.getById(id)).thenReturn(Optional.empty()); - - assertThatThrownBy(() -> roomWebFacade.deleteRoom(id)) - .isInstanceOf(ResourceNotFoundException.class) - .hasMessageContaining(id.toString()); - } - - @Test - void getRoomById_shouldReturnResponseDto_whenRoomExists() { + void deleteRoom_shouldDeleteRoom_whenRoomExists() { when(roomService.getById(id)).thenReturn(Optional.of(entity)); - when(roomMapper.toResponseDto(entity)).thenReturn(responseDto); - RoomResponseDto result = roomWebFacade.getRoomById(id); + roomWebFacade.deleteRoom(entity.getId()); - assertThat(result.roomNumber()).isEqualTo(entity.getRoomNumber()); - verify(roomService).getById(id); - verify(roomMapper).toResponseDto(entity); + verify(roomService).delete(entity); } @Test - void getRoomById_shouldThrowResourceNotFoundException_whenRoomNotFound() { + void deleteRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { when(roomService.getById(id)).thenReturn(Optional.empty()); - assertThatThrownBy(() -> roomWebFacade.getRoomById(id)) + assertThatThrownBy(() -> roomWebFacade.deleteRoom(id)) .isInstanceOf(ResourceNotFoundException.class) .hasMessageContaining(id.toString()); - verify(roomService).getById(id); } @Test @@ -139,5 +125,5 @@ void updateRoom_shouldThrowResourceNotFoundException_whenRoomNotFound() { assertThatThrownBy(() -> roomWebFacade.updateRoom(id, requestDto)) .isInstanceOf(ResourceNotFoundException.class) .hasMessageContaining(id.toString()); - }*/ + } } From 68610f887302286723c037d23614566f11459709 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Thu, 23 Jul 2026 10:56:27 +0300 Subject: [PATCH 13/14] Change findRoomResponseById signature --- src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java index 0202cda3..cb5d43a4 100644 --- a/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java @@ -10,5 +10,5 @@ public interface CustomRoomRepository { List findAllRoomResponses(); - Optional findRoomResponseById(@Param("id") UUID id); + Optional findRoomResponseById(UUID id); } From 3739522d8a2b6a30d6214fdacaa1360f8f9917e6 Mon Sep 17 00:00:00 2001 From: PIPetkova19 Date: Wed, 29 Jul 2026 10:38:22 +0300 Subject: [PATCH 14/14] Formatted the code in the room module --- .../org/unilab/uniplan/room/CustomRoomRepository.java | 1 - .../unilab/uniplan/room/CustomRoomRepositoryImpl.java | 1 - src/main/java/org/unilab/uniplan/room/Room.java | 2 +- .../java/org/unilab/uniplan/room/RoomRepository.java | 1 + src/main/java/org/unilab/uniplan/room/RoomService.java | 5 ----- .../org/unilab/uniplan/room/dto/RoomRequestDto.java | 4 +--- .../java/org/unilab/uniplan/room/RoomMapperTest.java | 10 ++++++---- .../java/org/unilab/uniplan/room/RoomServiceTest.java | 1 - .../org/unilab/uniplan/room/RoomWebFacadeTest.java | 7 +++---- 9 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java index cb5d43a4..a1272fb7 100644 --- a/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java @@ -1,6 +1,5 @@ package org.unilab.uniplan.room; -import org.springframework.data.repository.query.Param; import org.unilab.uniplan.room.dto.RoomResponseDto; import java.util.List; import java.util.Optional; diff --git a/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java b/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java index 1ddc4014..3081e5a3 100644 --- a/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java @@ -7,7 +7,6 @@ import org.hibernate.query.criteria.JpaCriteriaQuery; import org.hibernate.query.criteria.JpaEntityJoin; import org.hibernate.query.criteria.JpaRoot; -import org.springframework.data.repository.query.Param; import org.unilab.uniplan.category.Category; import org.unilab.uniplan.room.dto.RoomResponseDto; import org.unilab.uniplan.roomcategory.RoomCategory; diff --git a/src/main/java/org/unilab/uniplan/room/Room.java b/src/main/java/org/unilab/uniplan/room/Room.java index afd41137..5291d9ac 100644 --- a/src/main/java/org/unilab/uniplan/room/Room.java +++ b/src/main/java/org/unilab/uniplan/room/Room.java @@ -23,7 +23,7 @@ public class Room extends BaseEntity { @ManyToOne @JoinColumn(name = "faculty_id", referencedColumnName = "id", nullable = false) private Faculty faculty; + @Column(name = "room_number", nullable = false, length = 50) private String roomNumber; - } \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/room/RoomRepository.java b/src/main/java/org/unilab/uniplan/room/RoomRepository.java index 268d42de..9cfc386b 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/RoomRepository.java @@ -6,4 +6,5 @@ @Repository public interface RoomRepository extends JpaRepository, CustomRoomRepository { + } \ No newline at end of file diff --git a/src/main/java/org/unilab/uniplan/room/RoomService.java b/src/main/java/org/unilab/uniplan/room/RoomService.java index ee8074e1..b2f4d59f 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomService.java +++ b/src/main/java/org/unilab/uniplan/room/RoomService.java @@ -1,16 +1,11 @@ package org.unilab.uniplan.room; -import static org.unilab.uniplan.utils.ErrorConstants.ROOM_NOT_FOUND; - import java.util.List; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.unilab.uniplan.common.model.BaseService; -import org.unilab.uniplan.exception.ResourceNotFoundException; -import org.unilab.uniplan.room.dto.RoomRequestDto; import org.unilab.uniplan.room.dto.RoomResponseDto; @Service diff --git a/src/main/java/org/unilab/uniplan/room/dto/RoomRequestDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomRequestDto.java index 9cbe739f..dfc693c3 100644 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomRequestDto.java +++ b/src/main/java/org/unilab/uniplan/room/dto/RoomRequestDto.java @@ -12,6 +12,4 @@ public record RoomRequestDto( @NotNull(message = "Room number cannot be null") @Size(max = 50, message = "Room number cannot exceed 50 characters") String roomNumber -) { - -} +) { } diff --git a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java index a658ca0b..c496883b 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java @@ -11,7 +11,6 @@ import static org.assertj.core.api.Assertions.assertThat; - public class RoomMapperTest { private final RoomMapper roomMapper = new RoomMapperImpl(); @@ -20,7 +19,6 @@ public class RoomMapperTest { private RoomRequestDto roomRequestDto; private RoomResponseDto roomResponseDto1; private RoomResponseDto roomResponseDto2; - private String roomNumber1; private UUID facultyId; @@ -42,14 +40,15 @@ void setUp() { room2 = new Room(faculty, roomNumber2); room2.setId(UUID.randomUUID()); roomRequestDto = new RoomRequestDto(facultyId, roomNumber1); - roomResponseDto1 = new RoomResponseDto(room1.getId(), facultyId, roomNumber1,null); - roomResponseDto2 = new RoomResponseDto(room2.getId(), facultyId, roomNumber2,null); + roomResponseDto1 = new RoomResponseDto(room1.getId(), facultyId, roomNumber1, null); + roomResponseDto2 = new RoomResponseDto(room2.getId(), facultyId, roomNumber2, null); } @Test void toEntity_shouldMapAllFieldsAndIgnoreId_whenRequestDtoIsValid() { final Room result = roomMapper.toEntity(roomRequestDto); + assertThat(result.getFaculty().getId()).isEqualTo(facultyId); assertThat(result.getRoomNumber()).isEqualTo(roomNumber1); assertThat(result.getId()).isNull(); @@ -58,6 +57,7 @@ void toEntity_shouldMapAllFieldsAndIgnoreId_whenRequestDtoIsValid() { @Test void toResponseDto_shouldMapAllFields_whenFacultyIsValid() { RoomResponseDto result = roomMapper.toResponseDto(room1); + assertThat(result.id()).isEqualTo(room1.getId()); assertThat(result.facultyId()).isEqualTo(facultyId); assertThat(result.roomNumber()).isEqualTo(roomNumber1); @@ -84,6 +84,7 @@ void toResponseDtoList_shouldReturnEmptyList_whenListIsEmpty() { @Test void updateEntity_shouldUpdateAllFields_whenRequestDtoIsValid() { roomMapper.updateEntityFromDto(roomRequestDto, room2); + assertThat(room2.getRoomNumber()).isEqualTo(roomNumber1); } @@ -91,6 +92,7 @@ void updateEntity_shouldUpdateAllFields_whenRequestDtoIsValid() { void updateEntity_shouldNotChangeId_whenUpdating() { UUID id = room2.getId(); roomMapper.updateEntityFromDto(roomRequestDto, room2); + assertThat(room2.getId()).isEqualTo(id); } diff --git a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java index 58e3736f..eec17445 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; - import java.util.List; import java.util.Optional; import java.util.UUID; diff --git a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java index c99d6dfa..e57e7234 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java @@ -11,11 +11,9 @@ import org.unilab.uniplan.room.dto.RoomRequestDto; import org.unilab.uniplan.room.dto.RoomResponseDto; import org.unilab.uniplan.university.University; - import java.util.List; import java.util.Optional; import java.util.UUID; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -25,6 +23,7 @@ @ExtendWith(MockitoExtension.class) public class RoomWebFacadeTest { + @Mock private RoomMapper roomMapper; @Mock @@ -35,13 +34,13 @@ public class RoomWebFacadeTest { private Room entity; private RoomResponseDto responseDto; private UUID id; -private UUID categoryId; + private UUID categoryId; @BeforeEach void setUp() { id = UUID.randomUUID(); UUID facultyId = UUID.randomUUID(); - categoryId = UUID.randomUUID(); + categoryId = UUID.randomUUID(); University university = new University("Sofia University", "Sofia, Bulgaria", (short) 1888,