From c9b2b0fc1c2a938657db6e5071e06ea83beb6210 Mon Sep 17 00:00:00 2001 From: Phuriphat Yuanyee Date: Fri, 5 Jun 2026 04:28:38 +0200 Subject: [PATCH] update for seminar5 uploaded, make the chang as require for another complitering --- source/src/main/controller/Controller.java | 71 ++++++++++++++---- source/src/main/integration/BikeRegistry.java | 13 +++- .../main/integration/CustomerRegistry.java | 34 +++++++++ .../src/main/integration/RegistryCreator.java | 50 +++++++++++++ .../main/integration/RepairOrderRegistry.java | 56 ++++++++++++++ source/src/main/model/ActiveRepair.java | 7 +- source/src/main/model/BikeDTO.java | 22 +++--- source/src/main/model/CustomerDTO.java | 51 +++++++++++++ .../{RepairOrder.java => RepairOrderDTO.java} | 24 ++++-- source/src/main/model/RepairShop.java | 11 ++- source/src/main/startup/Main.java | 8 +- source/src/main/view/View.java | 66 +++++++++++++++-- .../src/test/controller/ControllerTest.java | 60 ++++++++++++--- .../test/integration/BikeRegistryTest.java | 4 +- .../integration/CustomerRegistryTest.java | 41 +++++++++++ .../integration/RepairOrderRegistryTest.java | 73 +++++++++++++++++++ source/src/test/model/ActiveRepairTest.java | 31 +++++--- source/src/test/model/RepairShopTest.java | 40 +++++++--- 18 files changed, 577 insertions(+), 85 deletions(-) create mode 100644 source/src/main/integration/CustomerRegistry.java create mode 100644 source/src/main/integration/RegistryCreator.java create mode 100644 source/src/main/integration/RepairOrderRegistry.java create mode 100644 source/src/main/model/CustomerDTO.java rename source/src/main/model/{RepairOrder.java => RepairOrderDTO.java} (63%) create mode 100644 source/src/test/integration/CustomerRegistryTest.java create mode 100644 source/src/test/integration/RepairOrderRegistryTest.java diff --git a/source/src/main/controller/Controller.java b/source/src/main/controller/Controller.java index bb2509f..b44993c 100644 --- a/source/src/main/controller/Controller.java +++ b/source/src/main/controller/Controller.java @@ -1,13 +1,19 @@ package controller; import integration.BikeRegistry; +import integration.CustomerRegistry; +import integration.RegistryCreator; +import integration.RepairOrderRegistry; import integration.RepairTaskCatalog; import model.Amount; import model.BikeDTO; -import model.RepairOrder; +import model.CustomerDTO; +import model.RepairOrderDTO; import model.RepairShop; import model.TaskDTO; +import java.util.List; + /** * Coordinates use-case execution between the view and the model and integration layers. * All calls from the view pass through this class. @@ -16,19 +22,22 @@ public class Controller { private final RepairShop repairShop; private final BikeRegistry bikeRegistry; private final RepairTaskCatalog taskCatalog; + private final CustomerRegistry customerRegistry; + private final RepairOrderRegistry repairOrderRegistry; /** - * Creates a Controller wired to the given dependencies. + * Creates a Controller wired to the model and to the registries provided by + * the given registry creator. * - * @param repairShop The repair shop facade (model layer). - * @param bikeRegistry The bike registry (integration layer). - * @param taskCatalog The repair task catalog (integration layer). + * @param repairShop The repair shop facade (model layer). + * @param registryCreator The creator that holds all integration-layer registries. */ - public Controller(RepairShop repairShop, BikeRegistry bikeRegistry, - RepairTaskCatalog taskCatalog) { + public Controller(RepairShop repairShop, RegistryCreator registryCreator) { this.repairShop = repairShop; - this.bikeRegistry = bikeRegistry; - this.taskCatalog = taskCatalog; + this.bikeRegistry = registryCreator.getBikeRegistry(); + this.taskCatalog = registryCreator.getRepairTaskCatalog(); + this.customerRegistry = registryCreator.getCustomerRegistry(); + this.repairOrderRegistry = registryCreator.getRepairOrderRegistry(); } /** @@ -78,11 +87,47 @@ public class Controller { } /** - * Ends the current repair session and returns the completed repair order. + * Ends the current repair session, saves the resulting repair order in the + * repair order registry, and returns it. * - * @return The {@link RepairOrder} summarising all repair details. + * @return The {@link RepairOrderDTO} summarising all repair details. */ - public RepairOrder endRepair() { - return repairShop.endRepair(); + public RepairOrderDTO endRepair() { + RepairOrderDTO repairOrder = repairShop.endRepair(); + repairOrderRegistry.saveRepairOrder(repairOrder); + return repairOrder; + } + + /** + * Searches for a previously saved repair order with the given ID. + * + * @param repairOrderID The unique identifier of the repair order to find. + * @return The matching {@link RepairOrderDTO}, or {@code null} if no repair + * order with the given ID has been saved. + */ + public RepairOrderDTO findRepairOrder(String repairOrderID) { + return repairOrderRegistry.findRepairOrderByID(repairOrderID); + } + + /** + * Searches for all saved repair orders belonging to the customer with the + * given ID. + * + * @param customerID The unique identifier of the customer to search for. + * @return A list of the customer's saved repair orders, possibly empty. + */ + public List findRepairOrdersForCustomer(String customerID) { + return repairOrderRegistry.findRepairOrdersByCustomer(customerID); + } + + /** + * Searches for a customer with the given ID. + * + * @param customerID The unique identifier of the customer to find. + * @return The matching {@link CustomerDTO}, or {@code null} if no customer + * with the given ID exists in the registry. + */ + public CustomerDTO findCustomer(String customerID) { + return customerRegistry.findCustomer(customerID); } } diff --git a/source/src/main/integration/BikeRegistry.java b/source/src/main/integration/BikeRegistry.java index 3eb49da..d8d7f37 100644 --- a/source/src/main/integration/BikeRegistry.java +++ b/source/src/main/integration/BikeRegistry.java @@ -1,6 +1,7 @@ package integration; import model.BikeDTO; +import model.CustomerDTO; import java.util.HashMap; import java.util.Map; @@ -13,12 +14,16 @@ public class BikeRegistry { private final Map bikes = new HashMap<>(); /** - * Creates a BikeRegistry pre-loaded with sample bike records. + * Creates a BikeRegistry pre-loaded with sample bike records, each linked to + * the customer who owns it. */ public BikeRegistry() { - bikes.put("BIKE-001", new BikeDTO("BIKE-001", "Alice Svensson")); - bikes.put("BIKE-002", new BikeDTO("BIKE-002", "Bob Lindqvist")); - bikes.put("BIKE-003", new BikeDTO("BIKE-003", "Carl Johansson")); + bikes.put("BIKE-001", new BikeDTO("BIKE-001", + new CustomerDTO("CUST-001", "Alice Svensson", "070-111 11 11"))); + bikes.put("BIKE-002", new BikeDTO("BIKE-002", + new CustomerDTO("CUST-002", "Bob Lindqvist", "070-222 22 22"))); + bikes.put("BIKE-003", new BikeDTO("BIKE-003", + new CustomerDTO("CUST-003", "Carl Johansson", "070-333 33 33"))); } /** diff --git a/source/src/main/integration/CustomerRegistry.java b/source/src/main/integration/CustomerRegistry.java new file mode 100644 index 0000000..f0a2d3f --- /dev/null +++ b/source/src/main/integration/CustomerRegistry.java @@ -0,0 +1,34 @@ +package integration; + +import model.CustomerDTO; + +import java.util.HashMap; +import java.util.Map; + +/** + * Handles retrieval of customer information from persistent storage. + * In this implementation, customers are stored in memory as sample data. + */ +public class CustomerRegistry { + private final Map customers = new HashMap<>(); + + /** + * Creates a CustomerRegistry pre-loaded with sample customer records. + */ + public CustomerRegistry() { + customers.put("CUST-001", new CustomerDTO("CUST-001", "Alice Svensson", "070-111 11 11")); + customers.put("CUST-002", new CustomerDTO("CUST-002", "Bob Lindqvist", "070-222 22 22")); + customers.put("CUST-003", new CustomerDTO("CUST-003", "Carl Johansson", "070-333 33 33")); + } + + /** + * Looks up and returns the customer with the given ID. + * + * @param customerID The unique identifier of the customer to look up. + * @return The {@link CustomerDTO} for the found customer, or {@code null} if no + * customer with the given ID exists in the registry. + */ + public CustomerDTO findCustomer(String customerID) { + return customers.get(customerID); + } +} diff --git a/source/src/main/integration/RegistryCreator.java b/source/src/main/integration/RegistryCreator.java new file mode 100644 index 0000000..7cbb507 --- /dev/null +++ b/source/src/main/integration/RegistryCreator.java @@ -0,0 +1,50 @@ +package integration; + +/** + * Creates and holds the single instance of each registry in the integration + * layer, so that the same registries are shared by everyone that needs them. + * This keeps registry creation in one place and keeps the constructors of the + * classes that use the registries short. + */ +public class RegistryCreator { + private final BikeRegistry bikeRegistry = new BikeRegistry(); + private final RepairTaskCatalog repairTaskCatalog = new RepairTaskCatalog(); + private final CustomerRegistry customerRegistry = new CustomerRegistry(); + private final RepairOrderRegistry repairOrderRegistry = new RepairOrderRegistry(); + + /** + * Returns the registry that stores bikes. + * + * @return The {@link BikeRegistry} instance. + */ + public BikeRegistry getBikeRegistry() { + return bikeRegistry; + } + + /** + * Returns the catalog that stores repair tasks. + * + * @return The {@link RepairTaskCatalog} instance. + */ + public RepairTaskCatalog getRepairTaskCatalog() { + return repairTaskCatalog; + } + + /** + * Returns the registry that stores customers. + * + * @return The {@link CustomerRegistry} instance. + */ + public CustomerRegistry getCustomerRegistry() { + return customerRegistry; + } + + /** + * Returns the registry that stores completed repair orders. + * + * @return The {@link RepairOrderRegistry} instance. + */ + public RepairOrderRegistry getRepairOrderRegistry() { + return repairOrderRegistry; + } +} diff --git a/source/src/main/integration/RepairOrderRegistry.java b/source/src/main/integration/RepairOrderRegistry.java new file mode 100644 index 0000000..6d98cd7 --- /dev/null +++ b/source/src/main/integration/RepairOrderRegistry.java @@ -0,0 +1,56 @@ +package integration; + +import model.RepairOrderDTO; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Stores completed repair orders and provides lookup of saved orders. + * In this implementation the orders are held in memory, simulating the database + * that the integration layer would otherwise be responsible for calling. + */ +public class RepairOrderRegistry { + private final Map repairOrders = new LinkedHashMap<>(); + + /** + * Saves a completed repair order so that it can be retrieved later. An order + * with an ID that is already stored overwrites the previously saved order. + * + * @param repairOrder The completed repair order to save. + */ + public void saveRepairOrder(RepairOrderDTO repairOrder) { + repairOrders.put(repairOrder.getRepairOrderID(), repairOrder); + } + + /** + * Searches for a saved repair order with the given ID. + * + * @param repairOrderID The unique identifier of the repair order to look up. + * @return The matching {@link RepairOrderDTO}, or {@code null} if no repair + * order with the given ID has been saved. + */ + public RepairOrderDTO findRepairOrderByID(String repairOrderID) { + return repairOrders.get(repairOrderID); + } + + /** + * Searches for all saved repair orders belonging to the customer with the + * given ID. + * + * @param customerID The unique identifier of the customer to search for. + * @return A list of the matching repair orders, in the order they were saved. + * The list is empty if the customer has no saved repair orders. + */ + public List findRepairOrdersByCustomer(String customerID) { + List matches = new ArrayList<>(); + for (RepairOrderDTO order : repairOrders.values()) { + if (order.getBike().getCustomer().getCustomerID().equals(customerID)) { + matches.add(order); + } + } + return matches; + } +} diff --git a/source/src/main/model/ActiveRepair.java b/source/src/main/model/ActiveRepair.java index ed3568b..8871e64 100644 --- a/source/src/main/model/ActiveRepair.java +++ b/source/src/main/model/ActiveRepair.java @@ -47,11 +47,12 @@ class ActiveRepair { /** * Ends the repair session and returns a completed repair order. * - * @return The {@link RepairOrder} summarising all repair details. + * @param repairOrderID The unique identifier assigned to this repair order. + * @return The {@link RepairOrderDTO} summarising all repair details. */ - RepairOrder endRepair() { + RepairOrderDTO endRepair(String repairOrderID) { List immutableTasks = Collections.unmodifiableList(new ArrayList<>(tasks)); - return new RepairOrder(bike, immutableTasks, diagnosticReport, total); + return new RepairOrderDTO(repairOrderID, bike, immutableTasks, diagnosticReport, total); } private Amount calculateTotal() { diff --git a/source/src/main/model/BikeDTO.java b/source/src/main/model/BikeDTO.java index d5dcafc..dfba331 100644 --- a/source/src/main/model/BikeDTO.java +++ b/source/src/main/model/BikeDTO.java @@ -2,21 +2,21 @@ package model; /** * Data Transfer Object that carries bike information across layer boundaries. - * Instances are immutable. + * Each bike is associated with the customer who owns it. Instances are immutable. */ public class BikeDTO { private final String bikeID; - private final String ownerName; + private final CustomerDTO customer; /** - * Creates a BikeDTO with the specified bike ID and owner name. + * Creates a BikeDTO with the specified bike ID and owning customer. * - * @param bikeID The unique identifier of the bike. - * @param ownerName The full name of the bike's owner. + * @param bikeID The unique identifier of the bike. + * @param customer The customer who owns the bike. */ - public BikeDTO(String bikeID, String ownerName) { + public BikeDTO(String bikeID, CustomerDTO customer) { this.bikeID = bikeID; - this.ownerName = ownerName; + this.customer = customer; } /** @@ -29,11 +29,11 @@ public class BikeDTO { } /** - * Returns the full name of the bike's owner. + * Returns the customer who owns this bike. * - * @return The owner's name. + * @return The owning {@link CustomerDTO}. */ - public String getOwnerName() { - return ownerName; + public CustomerDTO getCustomer() { + return customer; } } diff --git a/source/src/main/model/CustomerDTO.java b/source/src/main/model/CustomerDTO.java new file mode 100644 index 0000000..85f6765 --- /dev/null +++ b/source/src/main/model/CustomerDTO.java @@ -0,0 +1,51 @@ +package model; + +/** + * Data Transfer Object that carries customer information across layer boundaries. + * Instances are immutable. + */ +public class CustomerDTO { + private final String customerID; + private final String name; + private final String phoneNumber; + + /** + * Creates a CustomerDTO with the specified ID, name and phone number. + * + * @param customerID The unique identifier of the customer. + * @param name The full name of the customer. + * @param phoneNumber The customer's contact phone number. + */ + public CustomerDTO(String customerID, String name, String phoneNumber) { + this.customerID = customerID; + this.name = name; + this.phoneNumber = phoneNumber; + } + + /** + * Returns the customer's unique identifier. + * + * @return The customer ID string. + */ + public String getCustomerID() { + return customerID; + } + + /** + * Returns the full name of the customer. + * + * @return The customer's name. + */ + public String getName() { + return name; + } + + /** + * Returns the customer's contact phone number. + * + * @return The phone number string. + */ + public String getPhoneNumber() { + return phoneNumber; + } +} diff --git a/source/src/main/model/RepairOrder.java b/source/src/main/model/RepairOrderDTO.java similarity index 63% rename from source/src/main/model/RepairOrder.java rename to source/src/main/model/RepairOrderDTO.java index 88d2e06..1c10bcb 100644 --- a/source/src/main/model/RepairOrder.java +++ b/source/src/main/model/RepairOrderDTO.java @@ -3,30 +3,44 @@ package model; import java.util.List; /** - * Represents a completed repair order issued at the end of a repair session. - * Instances are immutable. + * Data Transfer Object that carries the details of a completed repair order + * across layer boundaries, including from the model to the view and into the + * repair order registry. Instances are immutable. */ -public class RepairOrder { +public class RepairOrderDTO { + private final String repairOrderID; private final BikeDTO bike; private final List tasks; private final String diagnosticReport; private final Amount total; /** - * Creates a RepairOrder with all details of the completed repair. + * Creates a RepairOrderDTO with all details of the completed repair. * + * @param repairOrderID The unique identifier of the repair order. * @param bike The bike that was repaired. * @param tasks The list of repair tasks performed. * @param diagnosticReport The mechanic's diagnostic notes. * @param total The total cost of all repair tasks. */ - RepairOrder(BikeDTO bike, List tasks, String diagnosticReport, Amount total) { + public RepairOrderDTO(String repairOrderID, BikeDTO bike, List tasks, + String diagnosticReport, Amount total) { + this.repairOrderID = repairOrderID; this.bike = bike; this.tasks = tasks; this.diagnosticReport = diagnosticReport; this.total = total; } + /** + * Returns the unique identifier of this repair order. + * + * @return The repair order ID string. + */ + public String getRepairOrderID() { + return repairOrderID; + } + /** * Returns the bike information for this repair order. * diff --git a/source/src/main/model/RepairShop.java b/source/src/main/model/RepairShop.java index 5d7cc9d..237517f 100644 --- a/source/src/main/model/RepairShop.java +++ b/source/src/main/model/RepairShop.java @@ -7,6 +7,7 @@ package model; public class RepairShop { private ActiveRepair currentRepair; + private int nextRepairOrderNumber = 1; /** * Creates a new RepairShop ready to accept repair sessions. @@ -50,11 +51,13 @@ public class RepairShop { } /** - * Ends the current repair session and returns the completed repair order. + * Ends the current repair session and returns the completed repair order, + * assigning it a unique repair order identifier. * - * @return The {@link RepairOrder} for the finished repair. + * @return The {@link RepairOrderDTO} for the finished repair. */ - public RepairOrder endRepair() { - return currentRepair.endRepair(); + public RepairOrderDTO endRepair() { + String repairOrderID = "RO-" + nextRepairOrderNumber++; + return currentRepair.endRepair(repairOrderID); } } diff --git a/source/src/main/startup/Main.java b/source/src/main/startup/Main.java index c0872a1..7aab5d0 100644 --- a/source/src/main/startup/Main.java +++ b/source/src/main/startup/Main.java @@ -1,8 +1,7 @@ package startup; import controller.Controller; -import integration.BikeRegistry; -import integration.RepairTaskCatalog; +import integration.RegistryCreator; import model.RepairShop; import view.View; @@ -18,10 +17,9 @@ public class Main { * @param args Command-line arguments (not used). */ public static void main(String[] args) { - BikeRegistry bikeRegistry = new BikeRegistry(); - RepairTaskCatalog taskCatalog = new RepairTaskCatalog(); + RegistryCreator registryCreator = new RegistryCreator(); RepairShop repairShop = new RepairShop(); - Controller controller = new Controller(repairShop, bikeRegistry, taskCatalog); + Controller controller = new Controller(repairShop, registryCreator); View view = new View(controller); view.runFakeExecution(); } diff --git a/source/src/main/view/View.java b/source/src/main/view/View.java index 6adb284..f66083a 100644 --- a/source/src/main/view/View.java +++ b/source/src/main/view/View.java @@ -3,9 +3,12 @@ package view; import controller.Controller; import model.Amount; import model.BikeDTO; -import model.RepairOrder; +import model.CustomerDTO; +import model.RepairOrderDTO; import model.TaskDTO; +import java.util.List; + /** * Placeholder view that simulates mechanic interactions using hard-coded method calls. * Everything returned by the controller is printed to standard output. @@ -23,20 +26,30 @@ public class View { } /** - * Simulates a complete repair session using hard-coded inputs, printing all - * output returned by the controller to standard output. + * Simulates a complete repair session and the two follow-up searches using + * hard-coded inputs, printing all output returned by the controller to + * standard output. */ public void runFakeExecution() { System.out.println("=== Repair Electric Bike System ==="); + + RepairOrderDTO repairOrder = registerNewRepair(); + searchForSavedRepairOrder(repairOrder.getRepairOrderID()); + searchForCustomer("CUST-001"); + } + + private RepairOrderDTO registerNewRepair() { System.out.println(); + System.out.println("--- Use case: register a new repair ---"); controller.startNewRepair(); System.out.println("[Mechanic] Started new repair session."); BikeDTO bike = controller.enterBikeID("BIKE-001"); if (bike != null) { + CustomerDTO customer = bike.getCustomer(); System.out.println("[System] Bike registered: ID=" + bike.getBikeID() - + ", Owner=" + bike.getOwnerName()); + + ", Customer=" + customer.getName() + " (" + customer.getCustomerID() + ")"); } else { System.out.println("[System] Bike not found."); } @@ -57,17 +70,56 @@ public class View { controller.enterDiagnosticReport(diagnosticNotes); System.out.println("[Mechanic] Diagnostic report entered."); - RepairOrder repairOrder = controller.endRepair(); + RepairOrderDTO repairOrder = controller.endRepair(); printRepairOrder(repairOrder); + System.out.println("[System] Repair order " + repairOrder.getRepairOrderID() + + " saved to the repair order registry."); + return repairOrder; } - private void printRepairOrder(RepairOrder repairOrder) { + private void searchForSavedRepairOrder(String repairOrderID) { + System.out.println(); + System.out.println("--- Use case: search for a saved repair order ---"); + System.out.println("[Mechanic] Searching for repair order \"" + repairOrderID + "\"..."); + + RepairOrderDTO found = controller.findRepairOrder(repairOrderID); + if (found != null) { + printRepairOrder(found); + } else { + System.out.println("[System] No repair order found with ID \"" + repairOrderID + "\"."); + } + } + + private void searchForCustomer(String customerID) { + System.out.println(); + System.out.println("--- Use case: search for a customer ---"); + System.out.println("[Mechanic] Searching for customer \"" + customerID + "\"..."); + + CustomerDTO customer = controller.findCustomer(customerID); + if (customer != null) { + System.out.println("[System] Customer found: " + customer.getCustomerID() + + ", " + customer.getName() + ", " + customer.getPhoneNumber()); + } else { + System.out.println("[System] No customer found with ID \"" + customerID + "\"."); + return; + } + + List history = controller.findRepairOrdersForCustomer(customerID); + System.out.println("[System] Repair orders on file for this customer: " + history.size()); + for (RepairOrderDTO order : history) { + System.out.println(" " + order.getRepairOrderID() + + " | total " + order.getTotal()); + } + } + + private void printRepairOrder(RepairOrderDTO repairOrder) { System.out.println(); System.out.println("========================================"); System.out.println(" REPAIR ORDER "); System.out.println("========================================"); + System.out.println("Order ID: " + repairOrder.getRepairOrderID()); System.out.println("Bike ID : " + repairOrder.getBike().getBikeID()); - System.out.println("Owner : " + repairOrder.getBike().getOwnerName()); + System.out.println("Customer: " + repairOrder.getBike().getCustomer().getName()); System.out.println("----------------------------------------"); System.out.println("Repair Tasks:"); for (TaskDTO task : repairOrder.getTasks()) { diff --git a/source/src/test/controller/ControllerTest.java b/source/src/test/controller/ControllerTest.java index eaa3192..31b2e17 100644 --- a/source/src/test/controller/ControllerTest.java +++ b/source/src/test/controller/ControllerTest.java @@ -2,13 +2,15 @@ package controller; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import integration.BikeRegistry; -import integration.RepairTaskCatalog; +import integration.RegistryCreator; import model.Amount; import model.BikeDTO; -import model.RepairOrder; +import model.CustomerDTO; +import model.RepairOrderDTO; import model.RepairShop; +import java.util.List; + import static org.junit.jupiter.api.Assertions.*; class ControllerTest { @@ -17,10 +19,9 @@ class ControllerTest { @BeforeEach void setUp() { - BikeRegistry bikeRegistry = new BikeRegistry(); - RepairTaskCatalog taskCatalog = new RepairTaskCatalog(); + RegistryCreator registryCreator = new RegistryCreator(); RepairShop repairShop = new RepairShop(); - controller = new Controller(repairShop, bikeRegistry, taskCatalog); + controller = new Controller(repairShop, registryCreator); controller.startNewRepair(); } @@ -75,14 +76,14 @@ class ControllerTest { void endRepairReturnsNonNullRepairOrder() { controller.enterBikeID("BIKE-001"); controller.addRepairTask("Battery Check"); - RepairOrder repairOrder = controller.endRepair(); + RepairOrderDTO repairOrder = controller.endRepair(); assertNotNull(repairOrder); } @Test void endRepairReturnsRepairOrderWithCorrectBikeId() { controller.enterBikeID("BIKE-002"); - RepairOrder repairOrder = controller.endRepair(); + RepairOrderDTO repairOrder = controller.endRepair(); assertEquals("BIKE-002", repairOrder.getBike().getBikeID()); } @@ -91,7 +92,7 @@ class ControllerTest { controller.enterBikeID("BIKE-001"); controller.addRepairTask("Battery Check"); controller.addRepairTask("Chain Lubrication"); - RepairOrder repairOrder = controller.endRepair(); + RepairOrderDTO repairOrder = controller.endRepair(); assertEquals(350, repairOrder.getTotal().getValue(), 0.001); } @@ -99,7 +100,46 @@ class ControllerTest { void enterDiagnosticReportIsReflectedInFinalRepairOrder() { controller.enterBikeID("BIKE-003"); controller.enterDiagnosticReport("Chain replaced and tested."); - RepairOrder repairOrder = controller.endRepair(); + RepairOrderDTO repairOrder = controller.endRepair(); assertEquals("Chain replaced and tested.", repairOrder.getDiagnosticReport()); } + + @Test + void endRepairSavesRepairOrderSoItCanBeFoundById() { + controller.enterBikeID("BIKE-001"); + controller.addRepairTask("Battery Check"); + RepairOrderDTO saved = controller.endRepair(); + RepairOrderDTO found = controller.findRepairOrder(saved.getRepairOrderID()); + assertEquals(saved.getRepairOrderID(), found.getRepairOrderID()); + } + + @Test + void findRepairOrderWithUnknownIdReturnsNull() { + assertNull(controller.findRepairOrder("RO-999")); + } + + @Test + void findCustomerWithExistingIdReturnsCorrectName() { + CustomerDTO customer = controller.findCustomer("CUST-001"); + assertEquals("Alice Svensson", customer.getName()); + } + + @Test + void findCustomerWithUnknownIdReturnsNull() { + assertNull(controller.findCustomer("CUST-999")); + } + + @Test + void findRepairOrdersForCustomerReturnsSavedOrderForThatCustomer() { + controller.enterBikeID("BIKE-001"); + controller.endRepair(); + List history = controller.findRepairOrdersForCustomer("CUST-001"); + assertEquals(1, history.size()); + } + + @Test + void findRepairOrdersForCustomerWithNoOrdersReturnsEmptyList() { + List history = controller.findRepairOrdersForCustomer("CUST-002"); + assertTrue(history.isEmpty()); + } } diff --git a/source/src/test/integration/BikeRegistryTest.java b/source/src/test/integration/BikeRegistryTest.java index 8f1828a..0985b0b 100644 --- a/source/src/test/integration/BikeRegistryTest.java +++ b/source/src/test/integration/BikeRegistryTest.java @@ -28,9 +28,9 @@ class BikeRegistryTest { } @Test - void findBikeWithExistingIdReturnsCorrectOwnerName() { + void findBikeWithExistingIdReturnsCorrectCustomerName() { BikeDTO bike = bikeRegistry.findBike("BIKE-002"); - assertEquals("Bob Lindqvist", bike.getOwnerName()); + assertEquals("Bob Lindqvist", bike.getCustomer().getName()); } @Test diff --git a/source/src/test/integration/CustomerRegistryTest.java b/source/src/test/integration/CustomerRegistryTest.java new file mode 100644 index 0000000..96f604c --- /dev/null +++ b/source/src/test/integration/CustomerRegistryTest.java @@ -0,0 +1,41 @@ +package integration; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import model.CustomerDTO; + +import static org.junit.jupiter.api.Assertions.*; + +class CustomerRegistryTest { + + private CustomerRegistry customerRegistry; + + @BeforeEach + void setUp() { + customerRegistry = new CustomerRegistry(); + } + + @Test + void findCustomerWithExistingIdReturnsCustomer() { + CustomerDTO customer = customerRegistry.findCustomer("CUST-001"); + assertNotNull(customer); + } + + @Test + void findCustomerWithExistingIdReturnsCorrectName() { + CustomerDTO customer = customerRegistry.findCustomer("CUST-002"); + assertEquals("Bob Lindqvist", customer.getName()); + } + + @Test + void findCustomerWithNonExistingIdReturnsNull() { + CustomerDTO customer = customerRegistry.findCustomer("CUST-999"); + assertNull(customer); + } + + @Test + void findCustomerWithEmptyStringReturnsNull() { + CustomerDTO customer = customerRegistry.findCustomer(""); + assertNull(customer); + } +} diff --git a/source/src/test/integration/RepairOrderRegistryTest.java b/source/src/test/integration/RepairOrderRegistryTest.java new file mode 100644 index 0000000..77bb140 --- /dev/null +++ b/source/src/test/integration/RepairOrderRegistryTest.java @@ -0,0 +1,73 @@ +package integration; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import model.Amount; +import model.BikeDTO; +import model.CustomerDTO; +import model.RepairOrderDTO; + +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class RepairOrderRegistryTest { + + private RepairOrderRegistry registry; + + @BeforeEach + void setUp() { + registry = new RepairOrderRegistry(); + } + + private RepairOrderDTO order(String repairOrderID, String customerID) { + BikeDTO bike = new BikeDTO("BIKE-X", + new CustomerDTO(customerID, "Sample Customer", "070-000 00 00")); + return new RepairOrderDTO(repairOrderID, bike, Collections.emptyList(), + "report", new Amount(100)); + } + + @Test + void saveThenFindByIdReturnsTheSavedOrder() { + RepairOrderDTO saved = order("RO-1", "CUST-001"); + registry.saveRepairOrder(saved); + RepairOrderDTO found = registry.findRepairOrderByID("RO-1"); + assertEquals("RO-1", found.getRepairOrderID()); + } + + @Test + void findByIdWithUnknownIdReturnsNull() { + registry.saveRepairOrder(order("RO-1", "CUST-001")); + assertNull(registry.findRepairOrderByID("RO-999")); + } + + @Test + void findByIdOnEmptyRegistryReturnsNull() { + assertNull(registry.findRepairOrderByID("RO-1")); + } + + @Test + void saveWithExistingIdOverwritesThePreviousOrder() { + registry.saveRepairOrder(order("RO-1", "CUST-001")); + registry.saveRepairOrder(order("RO-1", "CUST-002")); + RepairOrderDTO found = registry.findRepairOrderByID("RO-1"); + assertEquals("CUST-002", found.getBike().getCustomer().getCustomerID()); + } + + @Test + void findByCustomerReturnsOnlyThatCustomersOrders() { + registry.saveRepairOrder(order("RO-1", "CUST-001")); + registry.saveRepairOrder(order("RO-2", "CUST-002")); + registry.saveRepairOrder(order("RO-3", "CUST-001")); + List result = registry.findRepairOrdersByCustomer("CUST-001"); + assertEquals(2, result.size()); + } + + @Test + void findByCustomerWithNoMatchesReturnsEmptyList() { + registry.saveRepairOrder(order("RO-1", "CUST-001")); + List result = registry.findRepairOrdersByCustomer("CUST-999"); + assertTrue(result.isEmpty()); + } +} diff --git a/source/src/test/model/ActiveRepairTest.java b/source/src/test/model/ActiveRepairTest.java index 87ac653..0090e92 100644 --- a/source/src/test/model/ActiveRepairTest.java +++ b/source/src/test/model/ActiveRepairTest.java @@ -8,10 +8,13 @@ import static org.junit.jupiter.api.Assertions.*; class ActiveRepairTest { private ActiveRepair activeRepair; + private BikeDTO sampleBike; @BeforeEach void setUp() { activeRepair = new ActiveRepair(); + sampleBike = new BikeDTO("BIKE-001", + new CustomerDTO("CUST-001", "Alice Svensson", "070-111 11 11")); } @Test @@ -30,43 +33,49 @@ class ActiveRepairTest { @Test void endRepairWithRegisteredBikeReturnsBikeInRepairOrder() { - BikeDTO bike = new BikeDTO("BIKE-001", "Alice Svensson"); - activeRepair.registerBike(bike); - RepairOrder repairOrder = activeRepair.endRepair(); + activeRepair.registerBike(sampleBike); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-1"); assertEquals("BIKE-001", repairOrder.getBike().getBikeID()); } + @Test + void endRepairStampsTheGivenRepairOrderId() { + activeRepair.registerBike(sampleBike); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-42"); + assertEquals("RO-42", repairOrder.getRepairOrderID()); + } + @Test void endRepairAfterAddingTasksReturnsAllTasksInOrder() { - activeRepair.registerBike(new BikeDTO("BIKE-001", "Alice Svensson")); + activeRepair.registerBike(sampleBike); activeRepair.addTask(new TaskDTO("Brake Pad Replacement", new Amount(350))); activeRepair.addTask(new TaskDTO("Tire Replacement", new Amount(500))); - RepairOrder repairOrder = activeRepair.endRepair(); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-1"); assertEquals(2, repairOrder.getTasks().size()); } @Test void endRepairReturnsCorrectTotalInRepairOrder() { - activeRepair.registerBike(new BikeDTO("BIKE-001", "Alice Svensson")); + activeRepair.registerBike(sampleBike); activeRepair.addTask(new TaskDTO("Brake Pad Replacement", new Amount(350))); activeRepair.addTask(new TaskDTO("Tire Replacement", new Amount(500))); - RepairOrder repairOrder = activeRepair.endRepair(); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-1"); assertEquals(850, repairOrder.getTotal().getValue(), 0.001); } @Test void endRepairWithoutTasksReturnsTotalOfZero() { - activeRepair.registerBike(new BikeDTO("BIKE-001", "Alice Svensson")); - RepairOrder repairOrder = activeRepair.endRepair(); + activeRepair.registerBike(sampleBike); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-1"); assertEquals(0, repairOrder.getTotal().getValue(), 0.001); } @Test void enterDiagnosticReportIsIncludedInRepairOrder() { - activeRepair.registerBike(new BikeDTO("BIKE-001", "Alice Svensson")); + activeRepair.registerBike(sampleBike); String report = "Front tire replaced."; activeRepair.enterDiagnosticReport(report); - RepairOrder repairOrder = activeRepair.endRepair(); + RepairOrderDTO repairOrder = activeRepair.endRepair("RO-1"); assertEquals(report, repairOrder.getDiagnosticReport()); } } diff --git a/source/src/test/model/RepairShopTest.java b/source/src/test/model/RepairShopTest.java index 1e28737..34fa96b 100644 --- a/source/src/test/model/RepairShopTest.java +++ b/source/src/test/model/RepairShopTest.java @@ -15,6 +15,10 @@ class RepairShopTest { repairShop.startRepair(); } + private BikeDTO bike(String bikeID, String customerID, String customerName) { + return new BikeDTO(bikeID, new CustomerDTO(customerID, customerName, "070-000 00 00")); + } + @Test void addTaskAfterStartReturnsTaskCostAsRunningTotal() { TaskDTO task = new TaskDTO("Brake Pad Replacement", new Amount(350)); @@ -31,37 +35,53 @@ class RepairShopTest { @Test void endRepairAfterRegisterBikeAndTasksReturnsRepairOrderWithBike() { - BikeDTO bike = new BikeDTO("BIKE-002", "Bob Lindqvist"); - repairShop.registerBike(bike); + repairShop.registerBike(bike("BIKE-002", "CUST-002", "Bob Lindqvist")); repairShop.addTask(new TaskDTO("Battery Check", new Amount(200))); - RepairOrder repairOrder = repairShop.endRepair(); + RepairOrderDTO repairOrder = repairShop.endRepair(); assertEquals("BIKE-002", repairOrder.getBike().getBikeID()); } @Test void endRepairReturnsRepairOrderWithCorrectTotal() { - repairShop.registerBike(new BikeDTO("BIKE-002", "Bob Lindqvist")); + repairShop.registerBike(bike("BIKE-002", "CUST-002", "Bob Lindqvist")); repairShop.addTask(new TaskDTO("Battery Check", new Amount(200))); repairShop.addTask(new TaskDTO("Chain Lubrication", new Amount(150))); - RepairOrder repairOrder = repairShop.endRepair(); + RepairOrderDTO repairOrder = repairShop.endRepair(); assertEquals(350, repairOrder.getTotal().getValue(), 0.001); } + @Test + void endRepairAssignsANonNullRepairOrderId() { + repairShop.registerBike(bike("BIKE-001", "CUST-001", "Alice Svensson")); + RepairOrderDTO repairOrder = repairShop.endRepair(); + assertNotNull(repairOrder.getRepairOrderID()); + } + + @Test + void twoConsecutiveRepairsGetDifferentRepairOrderIds() { + repairShop.registerBike(bike("BIKE-001", "CUST-001", "Alice Svensson")); + RepairOrderDTO first = repairShop.endRepair(); + repairShop.startRepair(); + repairShop.registerBike(bike("BIKE-002", "CUST-002", "Bob Lindqvist")); + RepairOrderDTO second = repairShop.endRepair(); + assertNotEquals(first.getRepairOrderID(), second.getRepairOrderID()); + } + @Test void startRepairTwiceCreatesNewSessionWithZeroTotal() { - repairShop.registerBike(new BikeDTO("BIKE-001", "Alice Svensson")); + repairShop.registerBike(bike("BIKE-001", "CUST-001", "Alice Svensson")); repairShop.addTask(new TaskDTO("Brake Pad Replacement", new Amount(350))); repairShop.startRepair(); - repairShop.registerBike(new BikeDTO("BIKE-002", "Bob Lindqvist")); - RepairOrder repairOrder = repairShop.endRepair(); + repairShop.registerBike(bike("BIKE-002", "CUST-002", "Bob Lindqvist")); + RepairOrderDTO repairOrder = repairShop.endRepair(); assertEquals(0, repairOrder.getTotal().getValue(), 0.001); } @Test void enterDiagnosticReportIsReflectedInRepairOrder() { - repairShop.registerBike(new BikeDTO("BIKE-003", "Carl Johansson")); + repairShop.registerBike(bike("BIKE-003", "CUST-003", "Carl Johansson")); repairShop.enterDiagnosticReport("Tire replaced successfully."); - RepairOrder repairOrder = repairShop.endRepair(); + RepairOrderDTO repairOrder = repairShop.endRepair(); assertEquals("Tire replaced successfully.", repairOrder.getDiagnosticReport()); } }