package inventory; import inventory.DiscountCalculator.DiscountResult; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; /** * Unit tests for DiscountCalculator class. */ class DiscountCalculatorTest { private Product book; private Product electronics; /** * Set up test data before each test */ @BeforeEach void setUp() { book = ProductFactory.createProduct("B001", "Test Book", "BOOK", 20.0, 10); electronics = ProductFactory.createProduct("E001", "Test Electronics", "ELECTRONICS", 100.0, 10); } /** * Test student discount on books */ @Test void testStudentDiscountOnBooks() { DiscountResult discount = DiscountCalculator.calculateDiscount(book, 1, "STUDENT"); assertNotNull(discount); assertEquals(1 * book.getPrice() * 0.10, discount.getDiscountAmount()); assertEquals("Student discount: 10% off books", discount.getDescription()); } /** * Test student discount on electronics (should not apply) */ @Test void testStudentDiscountOnElectronics() { DiscountResult discount = DiscountCalculator.calculateDiscount(electronics, 1, "STUDENT"); assertNotNull(discount); assertEquals(0, discount.getDiscountAmount()); assertEquals("Student discount only applies to books", discount.getDescription()); } /** * test bulk discount when quantity >= 5 */ @ParameterizedTest(name = "quantity = {arguments}") @ValueSource(ints = {5,10}) void testBulkDiscountValid(int quantity) { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, quantity, "BULK"); assertNotNull(discountBook); assertEquals(quantity * book.getPrice() * 0.15, discountBook.getDiscountAmount()); assertEquals("Bulk discount: 15% off for 5+ items", discountBook.getDescription()); DiscountResult discountElectronics = DiscountCalculator.calculateDiscount(electronics, quantity, "BULK"); assertNotNull(discountElectronics); assertEquals(quantity * electronics.getPrice() * 0.15, discountElectronics.getDiscountAmount()); assertEquals("Bulk discount: 15% off for 5+ items", discountElectronics.getDescription()); } /** * Test bulk discount when quantity < 5 */ @Test void testBulkDiscountInvalid() { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 2, "BULK"); assertNotNull(discountBook); assertEquals(0, discountBook.getDiscountAmount()); assertEquals("Bulk discount requires 5+ items", discountBook.getDescription()); } /** * Test no discount option */ @Test void testNoDiscount() { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 1, "NONE"); assertNotNull(discountBook); assertEquals(0, discountBook.getDiscountAmount()); assertEquals("No discount applied", discountBook.getDescription()); } /** * Test boundary conditions */ @ParameterizedTest(name = "quantity = {0}, discount(%) = {1}") @CsvSource({"1,0", "5,0.15", "100,0.15", "1000,0.15", "10000,0.15"}) void testBoundaryConditions(int quantity, double discountPercentage) { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, quantity, "BULK"); assertNotNull(discountBook); assertEquals(book.getPrice() * quantity * discountPercentage, discountBook.getDiscountAmount()); } /** * Test discount calculation accuracy */ @Test void testDiscountCalculationAccuracy() { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 2, "STUDENT"); assertNotNull(discountBook); assertEquals(4, discountBook.getDiscountAmount()); DiscountResult discountElectronics = DiscountCalculator.calculateDiscount(electronics, 5, "BULK"); assertNotNull(discountElectronics); assertEquals(75, discountElectronics.getDiscountAmount()); } @ParameterizedTest(name = "type = {0}") @ValueSource(strings = {"STUDENT", "student", "STUdent", "stuDent", "sTudenT"}) void testCaseSensitivityOfDiscountTypes(String type) { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 1, type); assertNotNull(discountBook); assertEquals(2, discountBook.getDiscountAmount()); } @ParameterizedTest(name = "type = {0}") @ValueSource(strings = {"", "--", "\n", "09999", "STUDENT1", "BULKSTUDENT"}) void testInvalidDiscountTypes(String type) { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 1, type); assertNotNull(discountBook); assertEquals(0, discountBook.getDiscountAmount()); } @Test void testDiscountZeroQuantity() { DiscountResult discountBook = DiscountCalculator.calculateDiscount(book, 0, "STUDENT"); assertNotNull(discountBook); assertEquals(0, discountBook.getDiscountAmount()); DiscountResult discountElectronics = DiscountCalculator.calculateDiscount(electronics, 0, "BULK"); assertNotNull(discountElectronics); assertEquals(0, discountElectronics.getDiscountAmount()); } }