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..a1272fb7 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java @@ -0,0 +1,13 @@ +package org.unilab.uniplan.room; + +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(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..3081e5a3 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/CustomRoomRepositoryImpl.java @@ -0,0 +1,76 @@ +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.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/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/RoomController.java b/src/main/java/org/unilab/uniplan/room/RoomController.java index 20b3f1a6..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; @@ -18,7 +16,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; @@ -28,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/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/RoomRepository.java b/src/main/java/org/unilab/uniplan/room/RoomRepository.java index 0597aa71..9cfc386b 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomRepository.java +++ b/src/main/java/org/unilab/uniplan/room/RoomRepository.java @@ -5,6 +5,6 @@ import org.springframework.stereotype.Repository; @Repository -public interface RoomRepository extends JpaRepository { +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 5dbd29ac..b2f4d59f 100644 --- a/src/main/java/org/unilab/uniplan/room/RoomService.java +++ b/src/main/java/org/unilab/uniplan/room/RoomService.java @@ -1,65 +1,44 @@ 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.exception.ResourceNotFoundException; -import org.unilab.uniplan.room.dto.RoomDto; +import org.unilab.uniplan.common.model.BaseService; +import org.unilab.uniplan.room.dto.RoomResponseDto; @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); + public List getAllRoomResponses() { + return roomRepository.findAllRoomResponses(); } - private RoomDto saveEntityAndConvertToDto(final Room entity) { - final Room savedEntity = roomRepository.save(entity); - return roomMapper.toDto(savedEntity); + 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 new file mode 100644 index 00000000..b2cab683 --- /dev/null +++ b/src/main/java/org/unilab/uniplan/room/RoomWebFacade.java @@ -0,0 +1,63 @@ +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.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.ROOM_NOT_FOUND; + +@Component +@Slf4j +@RequiredArgsConstructor +public class RoomWebFacade { + + private final RoomMapper roomMapper; + private final 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 createRoom(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 roomService.getAllRoomResponses(); + } + + @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) { + return roomService.getRoomResponseById(id) + .orElseThrow(() -> new ResourceNotFoundException(ROOM_NOT_FOUND.getMessage( + String.valueOf(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/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/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/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java index b5cf53fe..e0a2df5b 100644 --- a/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java +++ b/src/main/java/org/unilab/uniplan/room/dto/RoomResponseDto.java @@ -1,19 +1,15 @@ package org.unilab.uniplan.room.dto; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import java.util.UUID; 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 -) { + 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 new file mode 100644 index 00000000..c496883b --- /dev/null +++ b/src/test/java/org/unilab/uniplan/room/RoomMapperTest.java @@ -0,0 +1,105 @@ +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, 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(); + } + + @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); + } + + @Test + void toResponseDto_shouldSetCategoryIdToNull_whenMappingFromRoomEntity() { + RoomResponseDto result = roomMapper.toResponseDto(room1); + + assertThat(result.categoryId()).isNull(); + } +} \ No newline at end of file diff --git a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java index 26d1d931..eec17445 100644 --- a/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java +++ b/src/test/java/org/unilab/uniplan/room/RoomServiceTest.java @@ -1,13 +1,8 @@ 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; - import java.util.List; import java.util.Optional; import java.util.UUID; @@ -17,114 +12,59 @@ import org.mockito.InjectMocks; 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 { @Mock private RoomRepository roomRepository; - - @Mock - private RoomMapper roomMapper; - @InjectMocks private RoomService roomService; - + private Room room; 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(); + room = new Room(); } @Test - void testCreateRoomShouldSaveAndReturnDto() { - when(roomMapper.toEntity(dto)).thenReturn(entity); - when(roomRepository.save(entity)).thenReturn(entity); - when(roomMapper.toDto(entity)).thenReturn(dto); + void save_shouldSaveEntity() { + when(roomRepository.save(room)).thenReturn(room); - RoomDto result = roomService.createRoom(dto); + roomService.save(room); - assertEquals(dto, result); + verify(roomRepository).save(room); } @Test - void testGetAllRoomsShouldReturnListOfRoomDtos() { - List entities = List.of(entity); - List dtos = List.of(dto); - - when(roomRepository.findAll()).thenReturn(entities); - when(roomMapper.toDtoList(entities)).thenReturn(dtos); + void findAll_shouldReturnListOfEntities() { + List rooms = List.of(room); + when(roomRepository.findAll()).thenReturn(List.of(room)); - List result = roomService.getAllRooms(); + List result = roomService.getAll(); - assertEquals(dtos, result); + verify(roomRepository).findAll(); + assertEquals(result, rooms); } @Test - void testGetRoomByIdShouldReturnRoomDtoIfFound() { - when(roomRepository.findById(id)).thenReturn(Optional.of(entity)); - when(roomMapper.toDto(entity)).thenReturn(dto); + void findById_shouldReturnEntity_whenRoomExists() { + Optional expected = Optional.of(room); + when(roomRepository.findById(id)).thenReturn(expected); - RoomDto result = roomService.getRoomById(id); + Optional result = roomService.getById(id); - assertEquals(dto, result); + verify(roomRepository).findById(id); + assertEquals(expected, result); } @Test - void testGetRoomByIdShouldReturnEmptyOptionalIfRoomNotFound() { - when(roomRepository.findById(id)).thenReturn(Optional.empty()); - - ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, () -> roomService.getRoomById(id)); + void delete_shouldDeleteEntity_whenFacultyExists() { + roomService.delete(room); - assertTrue(exception.getMessage().contains(String.valueOf(id))); + verify(roomRepository).delete(room); } - @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))); - } } 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..e57e7234 --- /dev/null +++ b/src/test/java/org/unilab/uniplan/room/RoomWebFacadeTest.java @@ -0,0 +1,128 @@ +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; + 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, + "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, categoryId); + } + + @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); + when(roomService.getAllRoomResponses()).thenReturn(rooms); + + List results = roomWebFacade.getAllRooms(); + + assertEquals(rooms, results); + assertThat(results.getFirst().categoryId()).isEqualTo(categoryId); + verify(roomService).getAllRoomResponses(); + } + + @Test + void getRoomById_shouldReturnResponseDto_whenRoomExists() { + when(roomService.getRoomResponseById(id)).thenReturn(Optional.of(responseDto)); + + RoomResponseDto result = roomWebFacade.getRoomById(id); + + assertEquals(result, responseDto); + verify(roomService).getRoomResponseById(id); + } + + @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 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()); + } +}