diff --git a/pom.xml b/pom.xml index 543c1aa50..7d8ef717a 100644 --- a/pom.xml +++ b/pom.xml @@ -16,19 +16,19 @@ org.junit.jupiter junit-jupiter - 5.11.4 + 6.0.1 test org.assertj assertj-core - 3.27.3 + 3.27.6 test org.mockito mockito-junit-jupiter - 5.15.2 + 5.21.0 test diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java new file mode 100644 index 000000000..c28e209ee --- /dev/null +++ b/src/test/java/com/example/BookingSystemTest.java @@ -0,0 +1,289 @@ +package com.example; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; + +@ExtendWith(MockitoExtension.class) +class BookingSystemTest { + + @Mock + private TimeProvider timeProvider; + + @Mock + private RoomRepository roomRepository; + + @Mock + private NotificationService notificationService; + + @Mock + private Room room; + + private BookingSystem bookingSystem; + + + @Test + void bookingSystemTestHappyCase() + { + //Preconditions + room = new Room("101", "101"); + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = start.plusHours(1); + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(start); + Mockito.when(roomRepository.findById("101")).thenReturn(Optional.of(room)); + + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + //Execution + bookingSystem.bookRoom("101", start, end); + } + + @Test + void bookingSystemTestUnhappyCaseStartTimeIsNull(){ + + //Preconditions + + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + //Execution + Assertions.assertThrows(IllegalArgumentException.class, () -> bookingSystem.bookRoom("101", null, LocalDateTime.now())); + + } + @Test + void bookingSystemTestUnhappyCaseEndTimeIsNull(){ + + //Preconditions + + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + //Execution + Assertions.assertThrows(IllegalArgumentException.class, () -> bookingSystem.bookRoom("101", LocalDateTime.now(), null)); + + } + @Test + void bookingSystemTestUnhappyCaseRoomIsNull(){ + + //Preconditions + + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + //Execution + Assertions.assertThrows(IllegalArgumentException.class, () -> bookingSystem.bookRoom(null, LocalDateTime.now(), LocalDateTime.now().plusHours(1))); + + } + @Test + void bookingSystemTestUnhappyCaseStartTimeIsBeforeCurrentTime() + { + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = start.plusHours(1); + //Preconditions + room = new Room("101", "101"); + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(start); + + try{ + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.bookRoom("101", start.minusHours(1), end); + } catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Kan inte boka tid i dåtid"); + } + + + } + @Test + void bookingSystemTestUnhappyCaseEndtimeIsBeforeStartTime() + { + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = start.plusHours(-1); + //Preconditions + room = new Room("101", "101"); + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(start); + + try { + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.bookRoom("101", start, end); + //Execution + + } catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Sluttid måste vara efter starttid"); + } + } + @Test + void bookingSystemTestUnhappyCaseRoomDoesNotExist() + { + //Preconditions + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(LocalDateTime.now()); + Mockito.when(roomRepository.findById("101")).thenReturn(Optional.empty()); + + bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + //Execution + Assertions.assertThrows(IllegalArgumentException.class, () ->bookingSystem.bookRoom("101", LocalDateTime.now(), LocalDateTime.now().plusHours(1))); + } + @Test + void bookRoom_roomNotAvailable_returnsFalse() { + + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(LocalDateTime.now()); + + Room room = Mockito.mock(Room.class); + Mockito.when(roomRepository.findById("101")).thenReturn(Optional.of(room)); + Mockito.when(room.isAvailable(any(), any())).thenReturn(false); + + BookingSystem bookingSystem = + new BookingSystem(timeProvider, roomRepository, notificationService); + + + boolean result = bookingSystem.bookRoom("101", LocalDateTime.now(), LocalDateTime.now().plusHours(1)); + + + Assertions.assertFalse(result); + + } + @Test + void bookRoom_roomAvailable_returnsTrue() { + + + Mockito.when(timeProvider.getCurrentTime()).thenReturn(LocalDateTime.now()); + + Room room = Mockito.mock(Room.class); + Mockito.when(roomRepository.findById("101")).thenReturn(Optional.of(room)); + Mockito.when(room.isAvailable(any(), any())).thenReturn(true); + + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + + boolean result = bookingSystem.bookRoom("101", LocalDateTime.now(), LocalDateTime.now().plusHours(1)); + + + Assertions.assertTrue(result); + } + @Test + void getAvailableRooms_startTimeIsNull_throwsException() { + LocalDateTime start = null; + LocalDateTime end = LocalDateTime.of(2026, 1, 1, 12, 0); + try { + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.getAvailableRooms(start, end); + }catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Måste ange både start- och sluttid"); + } + } + @Test + void getAvailableRooms_endTimeIsNull_throwsException() { + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = null; + try { + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.getAvailableRooms(start, end); + }catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Måste ange både start- och sluttid"); + } + } + @Test + void getAvailableRooms_endBeforeStart_throwsException() { + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = start.plusHours(-1); + try { + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.getAvailableRooms(start, end); + }catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Sluttid måste vara efter starttid"); + } + } + @Test + void getAvailableRooms_returnsOnlyRoomsThatAreAvailable() { + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + LocalDateTime end = start.plusHours(1); + + Room availableRoom = Mockito.mock(Room.class); + Room unavailableRoom = Mockito.mock(Room.class); + + Mockito.when(roomRepository.findAll()).thenReturn(List.of(availableRoom, unavailableRoom)); + + Mockito.when(availableRoom.isAvailable(start, end)).thenReturn(true); + Mockito.when(unavailableRoom.isAvailable(start, end)).thenReturn(false); + + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + List result = bookingSystem.getAvailableRooms(start, end); + + Assertions.assertTrue(result.contains(availableRoom)); + Assertions.assertFalse(result.contains(unavailableRoom)); + } + @Test + void cancelBooking_bookingIdIsNull_throwsException() { + + try { + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.cancelBooking(null); + }catch (IllegalArgumentException e) { + Assertions.assertEquals(e.getMessage(), "Boknings-id kan inte vara null"); + } + } + @Test + void cancelBooking_bookingNotFound_returnsFalse() { + + Room room = Mockito.mock(Room.class); + Mockito.when(room.hasBooking("1")).thenReturn(false); + Mockito.when(roomRepository.findAll()).thenReturn(List.of(room)); + + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + boolean result = bookingSystem.cancelBooking("1"); + + Assertions.assertFalse(result); + } + @Test + void cancelBooking_bookingAlreadyStarted_throwsException(){ + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + Mockito.when(timeProvider.getCurrentTime()).thenReturn(start); + Room room = Mockito.mock(Room.class); + Booking booking = Mockito.mock(Booking.class); + Mockito.when(roomRepository.findAll()).thenReturn(List.of(room)); + Mockito.when(room.hasBooking("1")).thenReturn(true); + Mockito.when(room.getBooking("1")).thenReturn(booking); + Mockito.when(booking.getStartTime()).thenReturn(start.plusHours(-1)); + + try { + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + bookingSystem.cancelBooking("1"); + }catch (IllegalStateException e) { + Assertions.assertEquals(e.getMessage(), "Kan inte avboka påbörjad eller avslutad bokning"); + } + + } + @Test + void cancelBooking_success_returnsTrue() { + // Arrange + LocalDateTime start = LocalDateTime.of(2026, 1, 1, 12, 0); + Mockito.when(timeProvider.getCurrentTime()).thenReturn(start); + Room room = Mockito.mock(Room.class); + Booking booking = Mockito.mock(Booking.class); + + Mockito.when(roomRepository.findAll()).thenReturn(List.of(room)); + Mockito.when(room.hasBooking("1")).thenReturn(true); + Mockito.when(room.getBooking("1")).thenReturn(booking); + Mockito.when(booking.getStartTime()).thenReturn(start.plusHours(1)); + + BookingSystem bookingSystem = new BookingSystem(timeProvider, roomRepository, notificationService); + + boolean result = bookingSystem.cancelBooking("1"); + + Assertions.assertTrue(result); + } + + +} \ No newline at end of file