From 459c8e5ce2de8b619121d6e358b7d54dd3e271c1 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 09:15:04 +0100 Subject: [PATCH 01/18] Updates pom.xml with newer versions --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 543c1aa50..dfea121e7 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.7 test org.mockito mockito-junit-jupiter - 5.15.2 + 5.21.0 test @@ -37,17 +37,17 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.1 org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + 3.5.4 org.apache.maven.plugins maven-failsafe-plugin - 3.5.2 + 3.5.4 @@ -60,7 +60,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.14 true From ff5af729276bc5f4e3e0b85f33f803e73ad702b4 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 11:06:42 +0100 Subject: [PATCH 02/18] Creates Test whenMakingCorrectBookingBookRoomReturnTrue. And test green --- .../java/com/example/BookingSystemTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/test/java/com/example/BookingSystemTest.java diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java new file mode 100644 index 000000000..5f277bb56 --- /dev/null +++ b/src/test/java/com/example/BookingSystemTest.java @@ -0,0 +1,55 @@ +package com.example; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.LocalDateTime; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class BookingSystemTest { + +@Mock + NotificationService notificationService; +@Mock + RoomRepository roomRepository; +@Mock + TimeProvider timeProvider; +@InjectMocks + BookingSystem bookingSystem; +//Metoder som finns i BookingSystem. + //boolean bookRoom, 4 if-satser + //List getAvailableRooms, 2 if-satser + //boolean cancelBooking, 3 if-satser + + +@Test + void whenMakingCorrectBookingBookRoomReturnTrue(){ + + String roomId = "5"; + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); + + when(timeProvider.getCurrentTime()).thenReturn(now); + + Room room = new Room(roomId,"Room Five"); + + when(roomRepository.findById(roomId)).thenReturn(Optional.of(room)); + + boolean result = bookingSystem.bookRoom(roomId,startTime,endTime); + + assertThat(result).isTrue(); + + Mockito.verify(roomRepository).save(room); + +} + +} From b5790463a7483beae03b142f6903157601edafcf Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 12:02:50 +0100 Subject: [PATCH 03/18] Creates and completes test: shouldThrowExceptionForInvalidInput --- .../java/com/example/BookingSystemTest.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 5f277bb56..0fcfdff11 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -2,6 +2,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; @@ -11,6 +13,7 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -25,7 +28,7 @@ public class BookingSystemTest { @InjectMocks BookingSystem bookingSystem; //Metoder som finns i BookingSystem. - //boolean bookRoom, 4 if-satser + //boolean bookRoom, 4 if-satser + tomt rum //List getAvailableRooms, 2 if-satser //boolean cancelBooking, 3 if-satser @@ -51,5 +54,22 @@ void whenMakingCorrectBookingBookRoomReturnTrue(){ Mockito.verify(roomRepository).save(room); } - +@ParameterizedTest + @CsvSource({ + ", 2026-02-02T10:00, 2026-02-02T12:00, 'Bokning kräver giltiga start- och sluttider samt rum-id'", // roomId is null + "5, , 2026-02-02T12:00, 'Bokning kräver giltiga start- och sluttider samt rum-id'", // startTime is null + "5, 2026-02-02T10:00, , 'Bokning kräver giltiga start- och sluttider samt rum-id'", // endTime is null + "5, 2025-02-02T10:00, 2026-02-02T12:00, 'Kan inte boka tid i dåtid'", // startTime is in the past + "5, 2026-02-02T10:00, 2026-01-02T12:00, 'Sluttid måste vara efter starttid'" // endTime is before starTime + }) + void shouldThrowExceptionForInvalidInput(String roomId, LocalDateTime startTime, LocalDateTime endTime, String expectedMessage){ + + if (roomId !=null && startTime != null && endTime != null) { + LocalDateTime testNow = LocalDateTime.of(2026, 01, 01, 00, 00); + when(timeProvider.getCurrentTime()).thenReturn(testNow); + } + assertThatThrownBy(()->bookingSystem.bookRoom(roomId,startTime,endTime)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(expectedMessage); +} } From 8f1c12fde7765267e054c26c92d8cf7ea48a4722 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 12:03:55 +0100 Subject: [PATCH 04/18] Creates and completes test: shouldThrowExceptionForInvalidInput --- src/test/java/com/example/BookingSystemTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 0fcfdff11..7d978f43c 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -65,7 +65,7 @@ void whenMakingCorrectBookingBookRoomReturnTrue(){ void shouldThrowExceptionForInvalidInput(String roomId, LocalDateTime startTime, LocalDateTime endTime, String expectedMessage){ if (roomId !=null && startTime != null && endTime != null) { - LocalDateTime testNow = LocalDateTime.of(2026, 01, 01, 00, 00); + LocalDateTime testNow = LocalDateTime.of(2026, 1, 1, 0, 0); when(timeProvider.getCurrentTime()).thenReturn(testNow); } assertThatThrownBy(()->bookingSystem.bookRoom(roomId,startTime,endTime)) From 019e72624f1c2336392119c9170cd6f2c8bd7d11 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 13:32:23 +0100 Subject: [PATCH 05/18] Creates test: whenRoomDoesNotExistBookRoomReturnException. And passed tests --- .../java/com/example/BookingSystemTest.java | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 7d978f43c..b1cd29b44 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -14,18 +14,19 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class BookingSystemTest { -@Mock + @Mock NotificationService notificationService; -@Mock + @Mock RoomRepository roomRepository; -@Mock + @Mock TimeProvider timeProvider; -@InjectMocks + @InjectMocks BookingSystem bookingSystem; //Metoder som finns i BookingSystem. //boolean bookRoom, 4 if-satser + tomt rum @@ -33,28 +34,29 @@ public class BookingSystemTest { //boolean cancelBooking, 3 if-satser -@Test - void whenMakingCorrectBookingBookRoomReturnTrue(){ + @Test + void whenMakingCorrectBookingBookRoomReturnTrue() { - String roomId = "5"; - LocalDateTime now = LocalDateTime.now(); - LocalDateTime startTime = now.plusDays(1); - LocalDateTime endTime = startTime.plusDays(3); + String roomId = "5"; + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); - when(timeProvider.getCurrentTime()).thenReturn(now); + when(timeProvider.getCurrentTime()).thenReturn(now); - Room room = new Room(roomId,"Room Five"); + Room room = new Room(roomId, "Room Five"); - when(roomRepository.findById(roomId)).thenReturn(Optional.of(room)); + when(roomRepository.findById(roomId)).thenReturn(Optional.of(room)); - boolean result = bookingSystem.bookRoom(roomId,startTime,endTime); + boolean result = bookingSystem.bookRoom(roomId, startTime, endTime); - assertThat(result).isTrue(); + assertThat(result).isTrue(); - Mockito.verify(roomRepository).save(room); + Mockito.verify(roomRepository).save(room); -} -@ParameterizedTest + } + + @ParameterizedTest @CsvSource({ ", 2026-02-02T10:00, 2026-02-02T12:00, 'Bokning kräver giltiga start- och sluttider samt rum-id'", // roomId is null "5, , 2026-02-02T12:00, 'Bokning kräver giltiga start- och sluttider samt rum-id'", // startTime is null @@ -62,14 +64,31 @@ void whenMakingCorrectBookingBookRoomReturnTrue(){ "5, 2025-02-02T10:00, 2026-02-02T12:00, 'Kan inte boka tid i dåtid'", // startTime is in the past "5, 2026-02-02T10:00, 2026-01-02T12:00, 'Sluttid måste vara efter starttid'" // endTime is before starTime }) - void shouldThrowExceptionForInvalidInput(String roomId, LocalDateTime startTime, LocalDateTime endTime, String expectedMessage){ + void shouldThrowExceptionForInvalidInputInBookRoom(String roomId, LocalDateTime startTime, LocalDateTime endTime, String expectedMessage) { + if (roomId != null && startTime != null && endTime != null) { + LocalDateTime testNow = LocalDateTime.of(2026, 1, 1, 0, 0); + when(timeProvider.getCurrentTime()).thenReturn(testNow); + } + assertThatThrownBy(() -> bookingSystem.bookRoom(roomId, startTime, endTime)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(expectedMessage); + } + + @Test + void whenRoomDoesNotExistBookRoomReturnException() { + String roomId = "5"; + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); - if (roomId !=null && startTime != null && endTime != null) { - LocalDateTime testNow = LocalDateTime.of(2026, 1, 1, 0, 0); - when(timeProvider.getCurrentTime()).thenReturn(testNow); + when(timeProvider.getCurrentTime()).thenReturn(now); + + when(roomRepository.findById(roomId)).thenReturn(Optional.empty()); + + assertThatThrownBy(()-> bookingSystem.bookRoom(roomId, startTime, endTime)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Rummet existerar inte"); } - assertThatThrownBy(()->bookingSystem.bookRoom(roomId,startTime,endTime)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(expectedMessage); -} + + } From 70a280afee273d853aba8b217e16c6cf71366360 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 14:23:04 +0100 Subject: [PATCH 06/18] Creates two tests for method bookRoom, for occupiedRoom and failed notification, both passes --- .../java/com/example/BookingSystemTest.java | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index b1cd29b44..b3bad5e11 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -14,8 +14,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class BookingSystemTest { @@ -38,7 +38,7 @@ public class BookingSystemTest { void whenMakingCorrectBookingBookRoomReturnTrue() { String roomId = "5"; - LocalDateTime now = LocalDateTime.now(); + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); LocalDateTime startTime = now.plusDays(1); LocalDateTime endTime = startTime.plusDays(3); @@ -90,5 +90,48 @@ void whenRoomDoesNotExistBookRoomReturnException() { .hasMessage("Rummet existerar inte"); } + @Test + void whenARoomIsOccupiedBookRoomReturnFalse() throws NotificationException { + + String roomId = "5"; + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); + + when(timeProvider.getCurrentTime()).thenReturn(now); + + Room room = new Room(roomId, "Room Five"); + Booking existingBooking = new Booking("existing-id", roomId, startTime, endTime); + room.addBooking(existingBooking); + + when(roomRepository.findById(roomId)).thenReturn(Optional.of(room)); + + boolean result = bookingSystem.bookRoom(roomId, startTime, endTime); + + assertThat(result).isFalse(); + + verify(roomRepository, never()).save(any()); + } + + @Test + void shouldReturnTrueEvenWhenNotificationFails() throws NotificationException { + String roomId = "5"; + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); + + when(timeProvider.getCurrentTime()).thenReturn(now); + Room room = new Room(roomId, "Room Five"); + when(roomRepository.findById(roomId)).thenReturn(Optional.of(room)); + + doThrow(NotificationException.class) + .when(notificationService).sendBookingConfirmation(any()); + + boolean result = bookingSystem.bookRoom(roomId, startTime, endTime); + assertThat(result).isTrue(); + + verify(roomRepository).save(room); + Mockito.verify(notificationService).sendBookingConfirmation(any()); + } } From 7e840a992c89922898a7c0a56433ca15080fca3b Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 19:13:30 +0100 Subject: [PATCH 07/18] Creates test invalid input for method getAvailableRooms --- src/test/java/com/example/BookingSystemTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index b3bad5e11..8565841ac 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -134,4 +134,19 @@ void shouldReturnTrueEvenWhenNotificationFails() throws NotificationException { verify(roomRepository).save(room); Mockito.verify(notificationService).sendBookingConfirmation(any()); } + + @ParameterizedTest + @CsvSource({ + "2026-02-02T10:00, ,'Måste ange både start- och sluttid'", + " , 2026-02-02T10:00,'Måste ange både start- och sluttid'", + "2026-02-02T10:00,2026-01-05T10:00,'Sluttid måste vara efter starttid'" + }) + void shouldThrowExceptionForInvalidInputInGetAvailableRooms(LocalDateTime startTime, LocalDateTime endTime, String expectedMessage) { + + assertThatThrownBy(() -> bookingSystem.getAvailableRooms(startTime, endTime)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(expectedMessage); + } + + } From aa8d3f501e7170ce965a55f07551c7d96d5ce6bf Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Mon, 2 Feb 2026 19:44:54 +0100 Subject: [PATCH 08/18] Creates test for getAvailableRooms, and pass --- .../java/com/example/BookingSystemTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 8565841ac..6dd6ede7b 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -10,6 +10,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @@ -148,5 +149,27 @@ void shouldThrowExceptionForInvalidInputInGetAvailableRooms(LocalDateTime startT .hasMessage(expectedMessage); } + @Test + void whenGivenOccupiedAndAvailableRoomGetAvailableRoomsShouldReturnAvailableRooms() + throws NotificationException { + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); + + Room roomA = new Room("5", "Room Five"); + Room roomB = new Room("6", "Room Six"); + Room roomC = new Room("7", "Room Seven"); + Booking booking = new Booking("b1","6", startTime, endTime); + roomB.addBooking(booking); + + when(roomRepository.findAll()).thenReturn(List.of(roomA, roomB, roomC)); + + List result = bookingSystem.getAvailableRooms(startTime, endTime); + + assertThat(result) + .hasSize(2) + .containsExactly(roomA, roomC) + .doesNotContain(roomB); + } } From e3b265f47af9337960f8b6eccf2b7f3236538f78 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Tue, 3 Feb 2026 18:22:14 +0100 Subject: [PATCH 09/18] Write 4 tests for method cancelBooking and pass. --- .../java/com/example/BookingSystemTest.java | 88 +++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 6dd6ede7b..7e9098157 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -19,7 +19,7 @@ import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) -public class BookingSystemTest { +class BookingSystemTest { @Mock NotificationService notificationService; @@ -92,7 +92,7 @@ void whenRoomDoesNotExistBookRoomReturnException() { } @Test - void whenARoomIsOccupiedBookRoomReturnFalse() throws NotificationException { + void whenARoomIsOccupiedBookRoomReturnFalse() { String roomId = "5"; LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); @@ -150,8 +150,7 @@ void shouldThrowExceptionForInvalidInputInGetAvailableRooms(LocalDateTime startT } @Test - void whenGivenOccupiedAndAvailableRoomGetAvailableRoomsShouldReturnAvailableRooms() - throws NotificationException { + void whenGivenOccupiedAndAvailableRoomGetAvailableRoomsShouldReturnAvailableRooms() { LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); LocalDateTime startTime = now.plusDays(1); LocalDateTime endTime = startTime.plusDays(3); @@ -170,6 +169,85 @@ void whenGivenOccupiedAndAvailableRoomGetAvailableRoomsShouldReturnAvailableRoom .hasSize(2) .containsExactly(roomA, roomC) .doesNotContain(roomB); - } + // cancel booking + // make sure that roomWithBooking returns false if .isEmpty() + // om endTime innan StartTime + // Lyckad cancelering + + @Test + void whenNullBookingIdCancelBookingShouldReturnException(){ + + String bookingId = null; + + assertThatThrownBy(() -> bookingSystem.cancelBooking(bookingId)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Boknings-id kan inte vara null"); + } + + @Test + void whenCancelingAnExistingBookingCancelBookingShouldReturnTrue() throws NotificationException { + String roomId = "5"; + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 0, 0); + LocalDateTime startTime = now.plusDays(1); + LocalDateTime endTime = startTime.plusDays(3); + + when(timeProvider.getCurrentTime()).thenReturn(now); + Room room = new Room(roomId, "Room Five"); + Room room2 = new Room("6", "Room Six"); + + when(roomRepository.findAll()).thenReturn(List.of(room, room2)); + + Booking fakeBooking = new Booking("fakeBookingId", roomId, startTime, endTime); + Booking fakeBooking2 = new Booking("fakeBookingId2", "6", startTime, endTime); + room.addBooking(fakeBooking); + room2.addBooking(fakeBooking2); + + assertThat(bookingSystem.cancelBooking(fakeBooking.getId())).isTrue(); + assertThat(room.hasBooking("fakeBookingId")).isFalse(); + + verify(roomRepository).save(room); + verify(notificationService).sendCancellationConfirmation(fakeBooking); + + } + + @Test + void cancelBookingShouldReturnFalseWhenBookingNotFound(){ + + Room room = new Room("5", "Room Five"); + Room room2 = new Room("6", "Room Six"); + + String bookingId = "fakeBookingId"; + + when(roomRepository.findAll()).thenReturn(List.of(room, room2)); + + boolean result = bookingSystem.cancelBooking(bookingId); + + assertThat(result).isFalse(); + + verify(roomRepository, never()).save(any()); + } + + @Test + void cancelBookingShouldThrowExceptionWhenBookinghasAlreadyStarted() { + String bookingId = "past-booking"; + LocalDateTime now = LocalDateTime.of(2026, 1, 1, 10, 0); + LocalDateTime startTime = now.minusHours(1); + LocalDateTime endTime = startTime.plusHours(3); + + when(timeProvider.getCurrentTime()).thenReturn(now); + + Room room = new Room("5", "Room Five"); + Booking pastBooking = new Booking(bookingId,"5", startTime, endTime); + room.addBooking(pastBooking); + + when(roomRepository.findAll()).thenReturn(List.of(room)); + + assertThatThrownBy(() -> bookingSystem.cancelBooking(bookingId)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Kan inte avboka påbörjad eller avslutad bokning"); + + assertThat(room.hasBooking(bookingId)).isTrue(); + + } } From c94af23e484d329130b33a35a40b9ea3fae466c7 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 10:57:30 +0100 Subject: [PATCH 10/18] First test written, first red then make needed class, get test green. Then refactor and add class Item. --- src/main/java/com/example/shop/Item.java | 19 +++++++++++++++++++ .../java/com/example/shop/ShoppingCart.java | 17 +++++++++++++++++ .../com/example/shop/ShoppingcartTest.java | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/main/java/com/example/shop/Item.java create mode 100644 src/main/java/com/example/shop/ShoppingCart.java create mode 100644 src/test/java/com/example/shop/ShoppingcartTest.java diff --git a/src/main/java/com/example/shop/Item.java b/src/main/java/com/example/shop/Item.java new file mode 100644 index 000000000..f50635cb8 --- /dev/null +++ b/src/main/java/com/example/shop/Item.java @@ -0,0 +1,19 @@ +package com.example.shop; + +import java.math.BigDecimal; + +public class Item { + + private final String name; + private final BigDecimal price; + private int quantity; + private BigDecimal discountPercentage; + public Item(String name, BigDecimal price, int quantity) { + this.name = name; + this.price = price; + this.quantity = quantity; + this.discountPercentage = BigDecimal.ZERO; + } + + +} diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java new file mode 100644 index 000000000..8d8d6b2ba --- /dev/null +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -0,0 +1,17 @@ +package com.example.shop; + +import java.util.ArrayList; +import java.util.List; + +public class ShoppingCart { + private final List items = new ArrayList<>(); + + + public void addItem(Item item) { + items.add(item); + } + + public List getItems() { + return items; + } +} diff --git a/src/test/java/com/example/shop/ShoppingcartTest.java b/src/test/java/com/example/shop/ShoppingcartTest.java new file mode 100644 index 000000000..b3cd35cc6 --- /dev/null +++ b/src/test/java/com/example/shop/ShoppingcartTest.java @@ -0,0 +1,18 @@ +package com.example.shop; + +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ShoppingcartTest { + + @Test + void ShouldReturnSizeOneWhenOneItemIsAdded(){ + ShoppingCart cart = new ShoppingCart(); + Item item = new Item("Football", new BigDecimal("150.0"),1); + cart.addItem(item); + assertEquals(1, cart.getItems().size()); + } +} From 0517be7adc1abdaa06f47d2b750ff2fdeedcb640 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 12:08:08 +0100 Subject: [PATCH 11/18] Test with totalPrice. Made new method in ShoppingCart and getters in Item-class. green test, and refactoring --- src/main/java/com/example/shop/Item.java | 14 ++++++++++++++ src/main/java/com/example/shop/ShoppingCart.java | 10 ++++++++++ .../java/com/example/shop/ShoppingcartTest.java | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/main/java/com/example/shop/Item.java b/src/main/java/com/example/shop/Item.java index f50635cb8..dc8b7265a 100644 --- a/src/main/java/com/example/shop/Item.java +++ b/src/main/java/com/example/shop/Item.java @@ -15,5 +15,19 @@ public Item(String name, BigDecimal price, int quantity) { this.discountPercentage = BigDecimal.ZERO; } + public String getName() { + return name; + } + + public BigDecimal getPrice() { + return price; + } + public int getQuantity() { + return quantity; + } + + public BigDecimal getDiscountPercentage() { + return discountPercentage; + } } diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java index 8d8d6b2ba..628ab321b 100644 --- a/src/main/java/com/example/shop/ShoppingCart.java +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -1,5 +1,6 @@ package com.example.shop; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -14,4 +15,13 @@ public void addItem(Item item) { public List getItems() { return items; } + + public BigDecimal getTotalPrice() { + BigDecimal totalPrice = BigDecimal.ZERO; + for(Item item : items) { + totalPrice = totalPrice.add(item.getPrice()); + } + + return totalPrice; + } } diff --git a/src/test/java/com/example/shop/ShoppingcartTest.java b/src/test/java/com/example/shop/ShoppingcartTest.java index b3cd35cc6..b5f0aca8c 100644 --- a/src/test/java/com/example/shop/ShoppingcartTest.java +++ b/src/test/java/com/example/shop/ShoppingcartTest.java @@ -15,4 +15,14 @@ void ShouldReturnSizeOneWhenOneItemIsAdded(){ cart.addItem(item); assertEquals(1, cart.getItems().size()); } + + @Test + void ShouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ + ShoppingCart cart = new ShoppingCart(); + cart.addItem(new Item("Football", new BigDecimal("150.0"),1)); + cart.addItem(new Item("Socks", new BigDecimal("50.0"),1)); + + assertEquals(new BigDecimal("200.0"), cart.getTotalPrice()); + } + } From fc7426f6525ffbd267c612302b57dfe889502497 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 12:22:14 +0100 Subject: [PATCH 12/18] Test with remove item from the ShoppingCart list. --- .../java/com/example/shop/ShoppingCart.java | 4 ++++ .../com/example/shop/ShoppingcartTest.java | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java index 628ab321b..dc9d3c3d3 100644 --- a/src/main/java/com/example/shop/ShoppingCart.java +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -24,4 +24,8 @@ public BigDecimal getTotalPrice() { return totalPrice; } + + public void removeItem(Item item) { + items.remove(item); + } } diff --git a/src/test/java/com/example/shop/ShoppingcartTest.java b/src/test/java/com/example/shop/ShoppingcartTest.java index b5f0aca8c..a6a0fe4c7 100644 --- a/src/test/java/com/example/shop/ShoppingcartTest.java +++ b/src/test/java/com/example/shop/ShoppingcartTest.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; class ShoppingcartTest { @@ -25,4 +26,23 @@ void ShouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ assertEquals(new BigDecimal("200.0"), cart.getTotalPrice()); } + @Test + void ShouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ + ShoppingCart cart = new ShoppingCart(); + Item football = new Item("Football", new BigDecimal("150.0"),1); + Item socks = new Item("Socks", new BigDecimal("50.0"),1); + + cart.addItem(football); + cart.addItem(socks); + + cart.removeItem(football); + + assertAll( + ()-> assertEquals(1, cart.getItems().size(),"Number of items is incorrect"), + ()-> assertEquals(0, new BigDecimal("50.0") + .compareTo(cart.getTotalPrice()),"Total price is incorrect") + ); + + } + } From 305d38eed40d42813a9eda97751e58258269031a Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 13:34:40 +0100 Subject: [PATCH 13/18] Remove comments in BookingSystemTest --- src/test/java/com/example/BookingSystemTest.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/example/BookingSystemTest.java b/src/test/java/com/example/BookingSystemTest.java index 7e9098157..ebea7b560 100644 --- a/src/test/java/com/example/BookingSystemTest.java +++ b/src/test/java/com/example/BookingSystemTest.java @@ -29,10 +29,7 @@ class BookingSystemTest { TimeProvider timeProvider; @InjectMocks BookingSystem bookingSystem; -//Metoder som finns i BookingSystem. - //boolean bookRoom, 4 if-satser + tomt rum - //List getAvailableRooms, 2 if-satser - //boolean cancelBooking, 3 if-satser + @Test @@ -170,10 +167,7 @@ void whenGivenOccupiedAndAvailableRoomGetAvailableRoomsShouldReturnAvailableRoom .containsExactly(roomA, roomC) .doesNotContain(roomB); } - // cancel booking - // make sure that roomWithBooking returns false if .isEmpty() - // om endTime innan StartTime - // Lyckad cancelering + @Test void whenNullBookingIdCancelBookingShouldReturnException(){ From 9d37aae61e9fd56ae392db4539e8dbfafc3951fb Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 14:18:49 +0100 Subject: [PATCH 14/18] Test and method, dealing with quantity increasing --- src/main/java/com/example/shop/Item.java | 16 ++++++++++++++ .../java/com/example/shop/ShoppingCart.java | 14 ++++++++---- ...ingcartTest.java => ShoppingCartTest.java} | 22 +++++++++++++++---- 3 files changed, 44 insertions(+), 8 deletions(-) rename src/test/java/com/example/shop/{ShoppingcartTest.java => ShoppingCartTest.java} (63%) diff --git a/src/main/java/com/example/shop/Item.java b/src/main/java/com/example/shop/Item.java index dc8b7265a..1ffc832cc 100644 --- a/src/main/java/com/example/shop/Item.java +++ b/src/main/java/com/example/shop/Item.java @@ -1,6 +1,7 @@ package com.example.shop; import java.math.BigDecimal; +import java.util.Objects; public class Item { @@ -30,4 +31,19 @@ public int getQuantity() { public BigDecimal getDiscountPercentage() { return discountPercentage; } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Item item)) return false; + return quantity == item.quantity && Objects.equals(name, item.name) && Objects.equals(price, item.price) && Objects.equals(discountPercentage, item.discountPercentage); + } + + @Override + public int hashCode() { + return Objects.hash(name, price, quantity, discountPercentage); + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } } diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java index dc9d3c3d3..2bc1c5e23 100644 --- a/src/main/java/com/example/shop/ShoppingCart.java +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -8,8 +8,14 @@ public class ShoppingCart { private final List items = new ArrayList<>(); - public void addItem(Item item) { - items.add(item); + public void addItem(Item newItem) { + items.stream() + .filter(item -> item.getName().equals(newItem.getName())) + .findFirst() + .ifPresentOrElse( + existing -> existing.setQuantity(existing.getQuantity() + newItem.getQuantity()), + () -> items.add(newItem) + ); } public List getItems() { @@ -19,9 +25,9 @@ public List getItems() { public BigDecimal getTotalPrice() { BigDecimal totalPrice = BigDecimal.ZERO; for(Item item : items) { - totalPrice = totalPrice.add(item.getPrice()); + BigDecimal itemTotal = item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())); + totalPrice = totalPrice.add(itemTotal); } - return totalPrice; } diff --git a/src/test/java/com/example/shop/ShoppingcartTest.java b/src/test/java/com/example/shop/ShoppingCartTest.java similarity index 63% rename from src/test/java/com/example/shop/ShoppingcartTest.java rename to src/test/java/com/example/shop/ShoppingCartTest.java index a6a0fe4c7..bd120fc5c 100644 --- a/src/test/java/com/example/shop/ShoppingcartTest.java +++ b/src/test/java/com/example/shop/ShoppingCartTest.java @@ -7,10 +7,10 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; -class ShoppingcartTest { +class ShoppingCartTest { @Test - void ShouldReturnSizeOneWhenOneItemIsAdded(){ + void shouldReturnSizeOneWhenOneItemIsAdded(){ ShoppingCart cart = new ShoppingCart(); Item item = new Item("Football", new BigDecimal("150.0"),1); cart.addItem(item); @@ -18,7 +18,7 @@ void ShouldReturnSizeOneWhenOneItemIsAdded(){ } @Test - void ShouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ + void shouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ ShoppingCart cart = new ShoppingCart(); cart.addItem(new Item("Football", new BigDecimal("150.0"),1)); cart.addItem(new Item("Socks", new BigDecimal("50.0"),1)); @@ -27,7 +27,7 @@ void ShouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ } @Test - void ShouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ + void shouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ ShoppingCart cart = new ShoppingCart(); Item football = new Item("Football", new BigDecimal("150.0"),1); Item socks = new Item("Socks", new BigDecimal("50.0"),1); @@ -45,4 +45,18 @@ void ShouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ } + @Test + void shouldIncreaseQuantityWhenAddingSameItem(){ + ShoppingCart cart = new ShoppingCart(); + Item football = new Item("Football", new BigDecimal("150.0"),1); + + cart.addItem(football); + cart.addItem(football); + + assertEquals(1, cart.getItems().size(), "Should not add new row of the same item"); + assertEquals(2, football.getQuantity(),"Quantity should be two"); + assertEquals(0, new BigDecimal("300.0").compareTo(cart.getTotalPrice()), "Price should reflect total quantity"); + + } + } From f5e35c47753734241c04d1ad3b788000a50b90b7 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 16:52:48 +0100 Subject: [PATCH 15/18] Write test for discounts, with changes to methods in shoppingcart and add interface DiscountService --- .../com/example/shop/DiscountService.java | 7 +++++++ .../java/com/example/shop/ShoppingCart.java | 14 +++++++++++++- .../com/example/shop/ShoppingCartTest.java | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/shop/DiscountService.java diff --git a/src/main/java/com/example/shop/DiscountService.java b/src/main/java/com/example/shop/DiscountService.java new file mode 100644 index 000000000..04733e75d --- /dev/null +++ b/src/main/java/com/example/shop/DiscountService.java @@ -0,0 +1,7 @@ +package com.example.shop; + +import java.math.BigDecimal; + +public interface DiscountService { + BigDecimal getDiscountMultiplier(String itemName); +} diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java index 2bc1c5e23..debd73fb4 100644 --- a/src/main/java/com/example/shop/ShoppingCart.java +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -6,7 +6,14 @@ public class ShoppingCart { private final List items = new ArrayList<>(); + private final DiscountService discountService; + ShoppingCart(DiscountService discountService) { + this.discountService = discountService; + } + ShoppingCart() { + this.discountService = itemName -> BigDecimal.ONE; + } public void addItem(Item newItem) { items.stream() @@ -25,7 +32,12 @@ public List getItems() { public BigDecimal getTotalPrice() { BigDecimal totalPrice = BigDecimal.ZERO; for(Item item : items) { - BigDecimal itemTotal = item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())); + BigDecimal multiplier = discountService.getDiscountMultiplier(item.getName()); + + BigDecimal itemTotal = item.getPrice() + .multiply(BigDecimal.valueOf(item.getQuantity())) + .multiply(multiplier); + totalPrice = totalPrice.add(itemTotal); } return totalPrice; diff --git a/src/test/java/com/example/shop/ShoppingCartTest.java b/src/test/java/com/example/shop/ShoppingCartTest.java index bd120fc5c..ea68ef0f3 100644 --- a/src/test/java/com/example/shop/ShoppingCartTest.java +++ b/src/test/java/com/example/shop/ShoppingCartTest.java @@ -1,14 +1,22 @@ package com.example.shop; 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.math.BigDecimal; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +@ExtendWith(MockitoExtension.class) class ShoppingCartTest { + @Mock + DiscountService discountService; + @Test void shouldReturnSizeOneWhenOneItemIsAdded(){ ShoppingCart cart = new ShoppingCart(); @@ -59,4 +67,15 @@ void shouldIncreaseQuantityWhenAddingSameItem(){ } + @Test + void shouldApplyDiscountToPrice(){ + DiscountService discountServiceMock = Mockito.mock(DiscountService.class); + + Mockito.when(discountServiceMock.getDiscountMultiplier("Handball")).thenReturn(new BigDecimal("0.9")); + + ShoppingCart cart = new ShoppingCart(discountServiceMock); + cart.addItem(new Item("Handball", new BigDecimal("100.0"),1)); + + assertEquals(0, new BigDecimal("90").compareTo(cart.getTotalPrice())); + } } From ac894cfec3b855526047d637a362f380290f3941 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 16:57:22 +0100 Subject: [PATCH 16/18] rearrange som written code --- src/main/java/com/example/shop/Item.java | 6 +--- .../com/example/shop/ShoppingCartTest.java | 32 +++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/example/shop/Item.java b/src/main/java/com/example/shop/Item.java index 1ffc832cc..1d16a81e4 100644 --- a/src/main/java/com/example/shop/Item.java +++ b/src/main/java/com/example/shop/Item.java @@ -8,7 +8,7 @@ public class Item { private final String name; private final BigDecimal price; private int quantity; - private BigDecimal discountPercentage; + private final BigDecimal discountPercentage; public Item(String name, BigDecimal price, int quantity) { this.name = name; this.price = price; @@ -28,10 +28,6 @@ public int getQuantity() { return quantity; } - public BigDecimal getDiscountPercentage() { - return discountPercentage; - } - @Override public boolean equals(Object o) { if (!(o instanceof Item item)) return false; diff --git a/src/test/java/com/example/shop/ShoppingCartTest.java b/src/test/java/com/example/shop/ShoppingCartTest.java index ea68ef0f3..962aa51e2 100644 --- a/src/test/java/com/example/shop/ShoppingCartTest.java +++ b/src/test/java/com/example/shop/ShoppingCartTest.java @@ -18,27 +18,27 @@ class ShoppingCartTest { DiscountService discountService; @Test - void shouldReturnSizeOneWhenOneItemIsAdded(){ + void shouldReturnSizeOneWhenOneItemIsAdded() { ShoppingCart cart = new ShoppingCart(); - Item item = new Item("Football", new BigDecimal("150.0"),1); + Item item = new Item("Football", new BigDecimal("150.0"), 1); cart.addItem(item); assertEquals(1, cart.getItems().size()); } @Test - void shouldCalculateTotalPriceForMultipleItemsOfOneQuantity(){ + void shouldCalculateTotalPriceForMultipleItemsOfOneQuantity() { ShoppingCart cart = new ShoppingCart(); - cart.addItem(new Item("Football", new BigDecimal("150.0"),1)); - cart.addItem(new Item("Socks", new BigDecimal("50.0"),1)); + cart.addItem(new Item("Football", new BigDecimal("150.0"), 1)); + cart.addItem(new Item("Socks", new BigDecimal("50.0"), 1)); assertEquals(new BigDecimal("200.0"), cart.getTotalPrice()); } @Test - void shouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ + void shouldRemoveItemAndUpdateTotalWhenItemIsRemoved() { ShoppingCart cart = new ShoppingCart(); - Item football = new Item("Football", new BigDecimal("150.0"),1); - Item socks = new Item("Socks", new BigDecimal("50.0"),1); + Item football = new Item("Football", new BigDecimal("150.0"), 1); + Item socks = new Item("Socks", new BigDecimal("50.0"), 1); cart.addItem(football); cart.addItem(socks); @@ -46,35 +46,35 @@ void shouldRemoveItemAndUpdateTotalWhenItemIsRemoved(){ cart.removeItem(football); assertAll( - ()-> assertEquals(1, cart.getItems().size(),"Number of items is incorrect"), - ()-> assertEquals(0, new BigDecimal("50.0") - .compareTo(cart.getTotalPrice()),"Total price is incorrect") + () -> assertEquals(1, cart.getItems().size(), "Number of items is incorrect"), + () -> assertEquals(0, new BigDecimal("50.0") + .compareTo(cart.getTotalPrice()), "Total price is incorrect") ); } @Test - void shouldIncreaseQuantityWhenAddingSameItem(){ + void shouldIncreaseQuantityWhenAddingSameItem() { ShoppingCart cart = new ShoppingCart(); - Item football = new Item("Football", new BigDecimal("150.0"),1); + Item football = new Item("Football", new BigDecimal("150.0"), 1); cart.addItem(football); cart.addItem(football); assertEquals(1, cart.getItems().size(), "Should not add new row of the same item"); - assertEquals(2, football.getQuantity(),"Quantity should be two"); + assertEquals(2, football.getQuantity(), "Quantity should be two"); assertEquals(0, new BigDecimal("300.0").compareTo(cart.getTotalPrice()), "Price should reflect total quantity"); } @Test - void shouldApplyDiscountToPrice(){ + void shouldApplyDiscountToPrice() { DiscountService discountServiceMock = Mockito.mock(DiscountService.class); Mockito.when(discountServiceMock.getDiscountMultiplier("Handball")).thenReturn(new BigDecimal("0.9")); ShoppingCart cart = new ShoppingCart(discountServiceMock); - cart.addItem(new Item("Handball", new BigDecimal("100.0"),1)); + cart.addItem(new Item("Handball", new BigDecimal("100.0"), 1)); assertEquals(0, new BigDecimal("90").compareTo(cart.getTotalPrice())); } From 4c94f96c5cc89bf594c324b2ad30b5217f1a7472 Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 17:35:20 +0100 Subject: [PATCH 17/18] small changes and test to check for zero price when cart is empty --- src/main/java/com/example/shop/ShoppingCart.java | 4 +++- src/test/java/com/example/shop/ShoppingCartTest.java | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/shop/ShoppingCart.java b/src/main/java/com/example/shop/ShoppingCart.java index debd73fb4..98bffa244 100644 --- a/src/main/java/com/example/shop/ShoppingCart.java +++ b/src/main/java/com/example/shop/ShoppingCart.java @@ -33,7 +33,9 @@ public BigDecimal getTotalPrice() { BigDecimal totalPrice = BigDecimal.ZERO; for(Item item : items) { BigDecimal multiplier = discountService.getDiscountMultiplier(item.getName()); - + if (multiplier == null) { + multiplier = BigDecimal.ONE; + } BigDecimal itemTotal = item.getPrice() .multiply(BigDecimal.valueOf(item.getQuantity())) .multiply(multiplier); diff --git a/src/test/java/com/example/shop/ShoppingCartTest.java b/src/test/java/com/example/shop/ShoppingCartTest.java index 962aa51e2..0bc7a2173 100644 --- a/src/test/java/com/example/shop/ShoppingCartTest.java +++ b/src/test/java/com/example/shop/ShoppingCartTest.java @@ -62,7 +62,7 @@ void shouldIncreaseQuantityWhenAddingSameItem() { cart.addItem(football); assertEquals(1, cart.getItems().size(), "Should not add new row of the same item"); - assertEquals(2, football.getQuantity(), "Quantity should be two"); + assertEquals(2, cart.getItems().getFirst().getQuantity(), "Quantity should be two"); assertEquals(0, new BigDecimal("300.0").compareTo(cart.getTotalPrice()), "Price should reflect total quantity"); } @@ -76,6 +76,12 @@ void shouldApplyDiscountToPrice() { ShoppingCart cart = new ShoppingCart(discountServiceMock); cart.addItem(new Item("Handball", new BigDecimal("100.0"), 1)); - assertEquals(0, new BigDecimal("90").compareTo(cart.getTotalPrice())); + assertEquals(0, new BigDecimal("90").compareTo(cart.getTotalPrice()), "Discount wasn't applied correctly"); + } + + @Test + void shouldReturnZeroPriceWhenCartIsEmpty() { + ShoppingCart cart = new ShoppingCart(); + assertEquals(0, BigDecimal.ZERO.compareTo(cart.getTotalPrice())); } } From 314a244121b294a22b9a2c61e1822d3ce80b9abb Mon Sep 17 00:00:00 2001 From: Fredrik Mohlen Date: Fri, 6 Feb 2026 17:38:15 +0100 Subject: [PATCH 18/18] Two more zero-checks --- .../com/example/shop/ShoppingCartTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/com/example/shop/ShoppingCartTest.java b/src/test/java/com/example/shop/ShoppingCartTest.java index 0bc7a2173..3368e92e5 100644 --- a/src/test/java/com/example/shop/ShoppingCartTest.java +++ b/src/test/java/com/example/shop/ShoppingCartTest.java @@ -84,4 +84,24 @@ void shouldReturnZeroPriceWhenCartIsEmpty() { ShoppingCart cart = new ShoppingCart(); assertEquals(0, BigDecimal.ZERO.compareTo(cart.getTotalPrice())); } + + @Test + void shouldReturnZeroPriceWhenOnlyItemIsRemoved() { + ShoppingCart cart = new ShoppingCart(); + Item ball = new Item("Ball", new BigDecimal("100.0"), 1); + cart.addItem(ball); + cart.removeItem(ball); + + assertEquals(0, cart.getItems().size()); + assertEquals(0, BigDecimal.ZERO.compareTo(cart.getTotalPrice())); + } + @Test + void shouldHandleNullDiscountByUsingOriginalPrice() { + DiscountService discountServiceMock = Mockito.mock(DiscountService.class); + + ShoppingCart cart = new ShoppingCart(discountServiceMock); + cart.addItem(new Item("Socks", new BigDecimal("50.0"), 1)); + + assertEquals(0, new BigDecimal("50.0").compareTo(cart.getTotalPrice())); + } }