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