diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java index 8cbcd3cc0..d1d4f076d 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java @@ -10,7 +10,7 @@ public class BankAtm { private final Map customerById = new HashMap<>(); - private final Map accountByNumber = new HashMap<>(); + final Map accountByNumber = new HashMap<>(); /** * Adds a checking account to the bank. @@ -25,6 +25,14 @@ public void addAccount(CheckingAccount account) { owner -> { customerById.put(owner.getId(), owner); }); + // Check if the account is a BusinessCheckingAccount and ensure it has a business owner + if (account instanceof BusinessCheckingAccount) { + BusinessCheckingAccount businessAccount = (BusinessCheckingAccount) account; + if (!businessAccount.hasBusinessOwner(account.getOwners())) { + throw new IllegalArgumentException( + "BusinessCheckingAccount must have at least one business owner."); + } + } } /** @@ -58,6 +66,9 @@ public void depositFunds(String accountNumber, double amount) { */ public void depositFunds(String accountNumber, Check check) { CheckingAccount account = getAccountOrThrow(accountNumber); + if (account instanceof SavingsAccount) { + throw new UnsupportedOperationException("Cannot deposit checks into a Savings Account."); + } check.depositFunds(account); } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java new file mode 100644 index 000000000..0d31794d9 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java @@ -0,0 +1,23 @@ +package com.codedifferently.lesson17.bank; + +import java.util.Set; + +public final class BusinessCheckingAccount extends CheckingAccount { + public BusinessCheckingAccount( + String accountNumber, double initialBalance, Set owners) { + // Pass the accountNumber, initialBalance, and owners set to the CheckingAccount constructor + super(accountNumber, owners, initialBalance); + if (!hasBusinessOwner(owners)) { + throw new IllegalArgumentException( + "A BusinessCheckingAccount must have at least one business owner."); + } + } + + /** + * @param check The check to deposit. + * @throws UnsupportedOperationException If a check is attempted to be deposited. + */ + boolean hasBusinessOwner(Set owners) { + return owners.stream().anyMatch(owner -> owner instanceof BusinessCustomer); + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCustomer.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCustomer.java new file mode 100644 index 000000000..e7498adc3 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCustomer.java @@ -0,0 +1,10 @@ +package com.codedifferently.lesson17.bank; + +import java.util.UUID; + +public class BusinessCustomer extends Customer { + + public BusinessCustomer(UUID id, String name) { + super(id, name); + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java index 5d8aeb74d..31fe7d317 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java @@ -6,7 +6,7 @@ /** Represents a checking account. */ public class CheckingAccount { - private final Set owners; + private static Set owners; private final String accountNumber; private double balance; private boolean isActive; @@ -20,7 +20,7 @@ public class CheckingAccount { */ public CheckingAccount(String accountNumber, Set owners, double initialBalance) { this.accountNumber = accountNumber; - this.owners = owners; + CheckingAccount.owners = owners; this.balance = initialBalance; isActive = true; } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java new file mode 100644 index 000000000..795dbf511 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -0,0 +1,19 @@ +package com.codedifferently.lesson17.bank; + +import java.util.Set; + +public class SavingsAccount extends CheckingAccount { + + public SavingsAccount(String accountNumber, double initialBalance, Set owners) { + // Pass the accountNumber, initialBalance, and owners set to the CheckingAccount constructor + super(accountNumber, owners, initialBalance); + } + + /** + * @param check The check to deposit. + * @throws UnsupportedOperationException If a check is attempted to be deposited. + */ + public void depositFunds(Check check) { + throw new UnsupportedOperationException("Cannot deposit checks into a Savings Account."); + } +} diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java index fa4a913a2..a8364ed41 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java @@ -2,9 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; +import java.util.HashSet; import java.util.Set; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; @@ -107,4 +111,95 @@ void testWithdrawFunds_AccountNotFound() { .isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0)) .withMessage("Account not found"); } + + @Test + public void testDepositFundsIntoSavingsAccount() { + BankAtm atm = new BankAtm(); + SavingsAccount savingsAccount = new SavingsAccount("12345", 1000.00, Set.of(customer1)); + atm.addAccount(savingsAccount); + + // Valid deposit + atm.depositFunds("12345", 500.00); + assertEquals(1500.00, savingsAccount.getBalance(), 0.01); + } + + @Test + public void testDepositCheckIntoSavingsAccount() { + // Arrange + BankAtm atm = new BankAtm(); + Set owners = new HashSet<>(); + owners.add(new Customer(UUID.randomUUID(), "Customer1")); + SavingsAccount savingsAccount = new SavingsAccount("12345", 1000.00, Set.of(customer1)); + + atm.addAccount(savingsAccount); // Add savings account to ATM + + // Act & Assert: Check that the exception is thrown when attempting to deposit a check into a + // savings account + Check check = new Check("234", 100.00, savingsAccount); // Creating a check to deposit + + // Assert that an UnsupportedOperationException is thrown + UnsupportedOperationException exception = + assertThrows( + UnsupportedOperationException.class, + () -> { + atm.depositFunds("12345", check); // Attempt to deposit check + }); + + // Optionally, you can also assert the message of the exception if you want more specific + // validation + assertEquals("Cannot deposit checks into a Savings Account.", exception.getMessage()); + } + + @Test + public void testAddBusinessCheckingAccountWithBusinessOwner() { + // Arrange + BankAtm atm = new BankAtm(); + + // Create business and personal customers + BusinessCustomer businessCustomer = new BusinessCustomer(UUID.randomUUID(), "Business1"); + Customer personalCustomer = new Customer(UUID.randomUUID(), "Personal1"); + + // Create a set of owners, including a business customer + Set owners = new HashSet<>(); + owners.add(businessCustomer); + owners.add(personalCustomer); + + // Create a BusinessCheckingAccount with the above owners + BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("67890", 1000.00, owners); + + // Act: Add the BusinessCheckingAccount to the ATM + atm.addAccount(businessAccount); + + // Assert: Ensure no exceptions were thrown and the account was added + assertNotNull(atm.accountByNumber.get("67890")); + } + + @Test + public void testAddBusinessCheckingAccountWithoutBusinessOwner() { + // Arrange + BankAtm atm = new BankAtm(); + + // Create only personal customers (no business owner) + Customer personalCustomer1 = new Customer(UUID.randomUUID(), "Personal1"); + Customer personalCustomer2 = new Customer(UUID.randomUUID(), "Personal2"); + + // Create a set of owners with only personal customers + Set owners = new HashSet<>(); + owners.add(personalCustomer1); + owners.add(personalCustomer2); + + // Act & Assert: Try to add a BusinessCheckingAccount and expect an exception + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> { + BusinessCheckingAccount businessAccount = + new BusinessCheckingAccount("67890", 1000.00, owners); + atm.addAccount(businessAccount); + }); + + // Assert: Ensure the correct exception is thrown + assertEquals( + "A BusinessCheckingAccount must have at least one business owner.", exception.getMessage()); + } }