From b0ac1a483d8a8a48daf57b4ed7ac0ab0d7f8cfa9 Mon Sep 17 00:00:00 2001 From: Dylan Date: Mon, 14 Apr 2025 13:02:19 +0000 Subject: [PATCH 01/10] feat: implement bank account system with audit logging and adds a savings account --- .../lesson17/bank/AuditLog.java | 22 +++++++++++++ .../lesson17/bank/BankAccount.java | 31 +++++++++++++++++++ .../lesson17/bank/BankAtm.java | 11 +++++-- .../lesson17/bank/SavingsAccount.java | 18 +++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java new file mode 100644 index 00000000..01f7c91f --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java @@ -0,0 +1,22 @@ +package com.codedifferently.lesson17.bank; + + +import java.util.ArrayList; + +public class AuditLog { + private List logEntries = new ArrayList<>(); + + public void log (String message) { + logEntries.add(message); + System.out.println(message); + + } + + public List getEntries() { + return logEntries; + } + + public void clear() { + logEntries.clear(); + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java new file mode 100644 index 00000000..efcdae13 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java @@ -0,0 +1,31 @@ +package com.codedifferently.lesson17.bank; +/* We want to support a Savings Account that works just like CheckinAccount, + * But will not allow you to write checks aainst the account. + * + * We want the BankAtm class to support the concept of a Business Checking Account + * A business acount will require that at least ne of the owning accoutns is a business account. + * + */ + +public abstract class BankAccount { + protected String accountNumber; + protected double balance; + + public abstract void deposit(double amount, String method); + public abstract void withdraw(double amount); + + public double getBalance() { + return balance; + } + public String getAccountNumber() { + return accountNumber; + } + + //Follows LSP + public interface depositable { + void deposit(double amount, String method); + } + public interface withdrawable { + void withdraw(double amount); + } +} \ No newline at end of file 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 8cbcd3cc..751f132d 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 @@ -1,17 +1,18 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; +import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; + /** Represents a bank ATM. */ public class BankAtm { private final Map customerById = new HashMap<>(); private final Map accountByNumber = new HashMap<>(); - + private final AuditLog auditLog = new AuditLog(); /** * Adds a checking account to the bank. * @@ -48,6 +49,7 @@ public Set findAccountsByCustomerId(UUID customerId) { public void depositFunds(String accountNumber, double amount) { CheckingAccount account = getAccountOrThrow(accountNumber); account.deposit(amount); + auditLog.log("Deposited " + amount + " into account " + accountNumber); } /** @@ -58,8 +60,11 @@ public void depositFunds(String accountNumber, double amount) { */ public void depositFunds(String accountNumber, Check check) { CheckingAccount account = getAccountOrThrow(accountNumber); + check.depositFunds(account); - } + auditLog.log("Deposited check into account " + accountNumber); + + } /** * Withdraws funds from an account. 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 00000000..2b87904a --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -0,0 +1,18 @@ +//Only Allows Deposits when accessing Atm on your Savings Account + +public class SavingsAccount extends BankAccount { + + @Override + public void deposit(double amount, String method) { + if("check".equalsIgnoreCase(method)) { + throw new UnsupportedOperationException("Deposit not allowed"); + } + + this.balance += amount; + } + + @Override + public void withdraw(double amount) { + throw new IllegalArgumentException("Insufficient funds"); + } +} \ No newline at end of file From 0e8809872288bb6d9c6997f165b9ec5e088085df Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 02:28:27 +0000 Subject: [PATCH 02/10] feat: integrate Log4j for enhanced audit logging functionality --- lesson_17/bank/bank_app/build.gradle.kts | 3 +++ .../codedifferently/lesson17/bank/AuditLog.java | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lesson_17/bank/bank_app/build.gradle.kts b/lesson_17/bank/bank_app/build.gradle.kts index 5f768d84..6bc4f1ec 100644 --- a/lesson_17/bank/bank_app/build.gradle.kts +++ b/lesson_17/bank/bank_app/build.gradle.kts @@ -28,6 +28,9 @@ dependencies { implementation("com.google.code.gson:gson:2.11.0") implementation("org.projectlombok:lombok:1.18.30") implementation("org.springframework.boot:spring-boot-starter") + + implementation('org.apache.logging.log4j:log4j-api:2.17.1') + implementation('org.apache.logging.log4j:log4j-core:2.17.1') } application { diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java index 01f7c91f..5ae6200c 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java @@ -1,22 +1,27 @@ package com.codedifferently.lesson17.bank; - import java.util.ArrayList; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class AuditLog { - private List logEntries = new ArrayList<>(); + private static final Logger logger = LogManager.getLogger(AuditLog.class.getName()); + + private List logEntries = new ArrayList<>(); - public void log (String message) { + public void log(String message) { logEntries.add(message); - System.out.println(message); + logger.info(message); } - public List getEntries() { + private List getEntries() { return logEntries; } public void clear() { logEntries.clear(); + logger.debug("Audit log cleared"); } } From c2e71de5879b465a22f1dead97ddbb76ab54760b Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 02:29:21 +0000 Subject: [PATCH 03/10] refactor: simplify BankAccount and update SavingsAccount to abstract class --- .../com/codedifferently/lesson17/bank/BankAccount.java | 8 +------- .../com/codedifferently/lesson17/bank/SavingsAccount.java | 8 ++++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java index efcdae13..feaa98f3 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java @@ -17,15 +17,9 @@ public abstract class BankAccount { public double getBalance() { return balance; } + public String getAccountNumber() { return accountNumber; } - //Follows LSP - public interface depositable { - void deposit(double amount, String method); - } - public interface withdrawable { - void withdraw(double amount); - } } \ No newline at end of file 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 index 2b87904a..a64956ad 100644 --- 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 @@ -1,11 +1,10 @@ -//Only Allows Deposits when accessing Atm on your Savings Account - -public class SavingsAccount extends BankAccount { +package com.codedifferently.lesson17.bank; +public abstract class SavingsAccount extends BankAccount { @Override public void deposit(double amount, String method) { if("check".equalsIgnoreCase(method)) { - throw new UnsupportedOperationException("Deposit not allowed"); + throw new UnsupportedOperationException("Cannot withdraw checks from the savings account"); } this.balance += amount; @@ -15,4 +14,5 @@ public void deposit(double amount, String method) { public void withdraw(double amount) { throw new IllegalArgumentException("Insufficient funds"); } +} } \ No newline at end of file From a76da9d1ee6478598f2ad577a15d2c49f9d058a0 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 03:37:22 +0000 Subject: [PATCH 04/10] Fix: Do not need implementation for log4j --- lesson_17/bank/bank_app/build.gradle.kts | 2 -- 1 file changed, 2 deletions(-) diff --git a/lesson_17/bank/bank_app/build.gradle.kts b/lesson_17/bank/bank_app/build.gradle.kts index 6bc4f1ec..9bd44a0b 100644 --- a/lesson_17/bank/bank_app/build.gradle.kts +++ b/lesson_17/bank/bank_app/build.gradle.kts @@ -29,8 +29,6 @@ dependencies { implementation("org.projectlombok:lombok:1.18.30") implementation("org.springframework.boot:spring-boot-starter") - implementation('org.apache.logging.log4j:log4j-api:2.17.1') - implementation('org.apache.logging.log4j:log4j-core:2.17.1') } application { From 1f7dae412185a28a2226ddbdfe10d3a4216ee18d Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 04:03:15 +0000 Subject: [PATCH 05/10] feat: enhance AuditLog with log entry tracking and add unit tests --- .../lesson17/bank/AuditLog.java | 28 +++++++------- .../lesson17/bank/AuditLogTest.java | 38 +++++++++++++++++++ 2 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/AuditLogTest.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java index 5ae6200c..b934a0cb 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java @@ -6,22 +6,20 @@ import org.apache.logging.log4j.Logger; public class AuditLog { - private static final Logger logger = LogManager.getLogger(AuditLog.class.getName()); + private static final Logger logger = LogManager.getLogger(AuditLog.class.getName()); + private final List logEntries = new ArrayList<>(); - private List logEntries = new ArrayList<>(); + public void log(String message) { + logger.info(message); + logEntries.add(message); + } - public void log(String message) { - logEntries.add(message); - logger.info(message); + public List getLogEntries() { + return logEntries; + } - } - - private List getEntries() { - return logEntries; - } - - public void clear() { - logEntries.clear(); - logger.debug("Audit log cleared"); - } + public void clear() { + logEntries.clear(); + logger.debug("Audit log cleared"); + } } diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/AuditLogTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/AuditLogTest.java new file mode 100644 index 00000000..475f2e14 --- /dev/null +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/AuditLogTest.java @@ -0,0 +1,38 @@ +package com.codedifferently.lesson17.bank; + +import org.junit.jupiter.api.Test; + +public class AuditLogTest { + @Test + public void testLog() { + AuditLog auditLog = new AuditLog(); + + String message = "Test log message"; + auditLog.log(message); + } + + @Test + public void testGetLogEntries() { + AuditLog auditLog = new AuditLog(); + + String message1 = "Test log message 1"; + String message2 = "Test log message 2"; + auditLog.log(message1); + auditLog.log(message2); + + assert auditLog.getLogEntries().size() == 2; + assert auditLog.getLogEntries().get(0).equals(message1); + assert auditLog.getLogEntries().get(1).equals(message2); + } + + @Test + public void testClear() { + AuditLog auditLog = new AuditLog(); + + String message = "Test log message"; + auditLog.log(message); + auditLog.clear(); + + assert auditLog.getLogEntries().isEmpty(); + } +} From 36f06a124c58f079bf0f5a4f56b2f332c4a040c9 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 04:04:45 +0000 Subject: [PATCH 06/10] feat: implement SavingsAccount class with overridden methods and add unit tests --- .../lesson17/bank/BankAccount.java | 25 --------- .../lesson17/bank/BankAtm.java | 8 +-- .../lesson17/bank/SavingsAccount.java | 52 ++++++++++++++----- .../lesson17/bank/SavingsAccountTest.java | 37 +++++++++++++ 4 files changed, 81 insertions(+), 41 deletions(-) delete mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java create mode 100644 lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java deleted file mode 100644 index feaa98f3..00000000 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.codedifferently.lesson17.bank; -/* We want to support a Savings Account that works just like CheckinAccount, - * But will not allow you to write checks aainst the account. - * - * We want the BankAtm class to support the concept of a Business Checking Account - * A business acount will require that at least ne of the owning accoutns is a business account. - * - */ - -public abstract class BankAccount { - protected String accountNumber; - protected double balance; - - public abstract void deposit(double amount, String method); - public abstract void withdraw(double amount); - - public double getBalance() { - return balance; - } - - public String getAccountNumber() { - return accountNumber; - } - -} \ No newline at end of file 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 751f132d..94ad39a0 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 @@ -1,18 +1,18 @@ package com.codedifferently.lesson17.bank; +import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; -import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; - /** Represents a bank ATM. */ public class BankAtm { private final Map customerById = new HashMap<>(); private final Map accountByNumber = new HashMap<>(); private final AuditLog auditLog = new AuditLog(); + /** * Adds a checking account to the bank. * @@ -26,6 +26,7 @@ public void addAccount(CheckingAccount account) { owner -> { customerById.put(owner.getId(), owner); }); + auditLog.log("Added account " + account.getAccountNumber() + " to the bank"); } /** @@ -63,8 +64,7 @@ public void depositFunds(String accountNumber, Check check) { check.depositFunds(account); auditLog.log("Deposited check into account " + accountNumber); - - } + } /** * Withdraws funds from an account. 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 index a64956ad..498867e8 100644 --- 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 @@ -1,18 +1,46 @@ package com.codedifferently.lesson17.bank; -public abstract class SavingsAccount extends BankAccount { - @Override - public void deposit(double amount, String method) { - if("check".equalsIgnoreCase(method)) { - throw new UnsupportedOperationException("Cannot withdraw checks from the savings account"); - } +import java.util.Set; - this.balance += amount; - } +public class SavingsAccount extends CheckingAccount { + + public SavingsAccount(String accountNumber, Set owners, double balance) { + super(accountNumber, owners, balance); + } + + @Override + public int hashCode() { + return getAccountNumber().hashCode(); + } - @Override - public void withdraw(double amount) { - throw new IllegalArgumentException("Insufficient funds"); + @Override + public boolean equals(Object obj) { + if (obj instanceof SavingsAccount other) { + return getAccountNumber().equals(other.getAccountNumber()) + && getOwners().equals(other.getOwners()) + && getBalance() == other.getBalance() + && isClosed() == other.isClosed(); } + return false; + } + + @Override + public void withdraw(double amount) { + throw new RuntimeException("Cannot withdraw from a savings account using a check"); + } + + @Override + public String toString() { + return "SavingsAccount" + + "accountNumber='" + + getAccountNumber() + + '\'' + + ", owners=" + + getOwners() + + ", balance=" + + getBalance() + + ", isActive=" + + isClosed() + + '}'; + } } -} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java new file mode 100644 index 00000000..d6f21ed6 --- /dev/null +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java @@ -0,0 +1,37 @@ +package com.codedifferently.lesson17.bank; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashSet; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SavingsAccountTest { + + private SavingsAccount classUnderTest; + private HashSet owners; + + @BeforeEach + void setUp() { + owners = new HashSet<>(); + owners.add(new Customer(UUID.randomUUID(), "John Doe")); + owners.add(new Customer(UUID.randomUUID(), "Jane Smith")); + classUnderTest = new SavingsAccount("123456789", owners, 100.0); + } + + @Test + void testHashCode() { + int expected = classUnderTest.getAccountNumber().hashCode(); + int actual = classUnderTest.hashCode(); + assertEquals(expected, actual); + } + + @Test + void testEquals() { + SavingsAccount other = new SavingsAccount("123456789", owners, 100.0); + boolean expected = true; + boolean actual = classUnderTest.equals(other); + assertEquals(expected, actual); + } +} From c36cc923040816e895304871f2f2c75cdf00ce77 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 12:58:24 +0000 Subject: [PATCH 07/10] Feat: Adds more auditLogging features in BankATM --- .../main/java/com/codedifferently/lesson17/bank/BankAtm.java | 3 +++ 1 file changed, 3 insertions(+) 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 94ad39a0..d90cc433 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 @@ -36,6 +36,7 @@ public void addAccount(CheckingAccount account) { * @return The unique set of accounts owned by the customer. */ public Set findAccountsByCustomerId(UUID customerId) { + auditLog.log("Finding accounts for customer " + customerId); return customerById.containsKey(customerId) ? customerById.get(customerId).getAccounts() : Set.of(); @@ -75,6 +76,7 @@ public void depositFunds(String accountNumber, Check check) { public void withdrawFunds(String accountNumber, double amount) { CheckingAccount account = getAccountOrThrow(accountNumber); account.withdraw(amount); + auditLog.log("Withdrew " + amount + " from account " + accountNumber); } /** @@ -88,6 +90,7 @@ private CheckingAccount getAccountOrThrow(String accountNumber) { if (account == null || account.isClosed()) { throw new AccountNotFoundException("Account not found"); } + auditLog.log("Retrieved account " + accountNumber); return account; } } From 4d25713b455ba4110122082aae08f3f800eecdff Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 15 Apr 2025 12:58:52 +0000 Subject: [PATCH 08/10] Chore: Adds JavaDoc to AuditLog and SavingsAccount --- .../lesson17/bank/AuditLog.java | 25 ++++++++++++++ .../lesson17/bank/SavingsAccount.java | 33 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java index b934a0cb..5f55e704 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/AuditLog.java @@ -5,15 +5,40 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +/** + * The {@code AuditLog} class is responsible for logging important events in the banking system. It + * uses the Log4j logging framework to log messages at different levels. + */ public class AuditLog { + private static final Logger logger = LogManager.getLogger(AuditLog.class.getName()); private final List logEntries = new ArrayList<>(); + /** + * Logs a message at the INFO level and adds it to the internal list of log entries. + * + * @param message + */ public void log(String message) { logger.info(message); logEntries.add(message); } + /** + * Logs an error message at the ERROR level and adds it to the internal list of log entries. + * + * @param message + */ + public void logError(String message) { + logger.error(message); + logEntries.add(message); + } + + /** + * Returns the list of log entries. + * + * @return A list of log entries + */ public List getLogEntries() { return logEntries; } 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 index 498867e8..d36286c1 100644 --- 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 @@ -2,17 +2,39 @@ import java.util.Set; +/** + * The {@code SavingsAccount} class represents a savings account in a banking system. It extends the + * {@code CheckingAccount} class and provides additional functionality specific to savings accounts. + */ public class SavingsAccount extends CheckingAccount { + /** + * Constructs a new SavingsAccount with the specified account number, owners, and balance. + * + * @param accountNumber + * @param owners + * @param balance + */ public SavingsAccount(String accountNumber, Set owners, double balance) { super(accountNumber, owners, balance); } + /** + * Gets the HashCode of the account number. + * + * @return The hash code of the account number. + */ @Override public int hashCode() { return getAccountNumber().hashCode(); } + /** + * Checks if this SavingsAccount is equal to another object. + * + * @param obj The object to compare with. + * @return true if the objects are equal, false otherwise. + */ @Override public boolean equals(Object obj) { if (obj instanceof SavingsAccount other) { @@ -24,11 +46,22 @@ && getBalance() == other.getBalance() return false; } + /** + * Will throw and exception if the user attempt to make a withdrawl while under the instance of + * SavingsAccount. + * + * @param amount The amount to deposit. + */ @Override public void withdraw(double amount) { throw new RuntimeException("Cannot withdraw from a savings account using a check"); } + /** + * Returns a string representation of the SavingsAccount. + * + * @return A string representation of the SavingsAccount. + */ @Override public String toString() { return "SavingsAccount" From 387c5e1f19d5001972043da6577cd8322ddc02b8 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 16 Apr 2025 18:06:37 +0000 Subject: [PATCH 09/10] Feat: Enhance withdrawal to not allow checks to be written from savings accoount --- .../codedifferently/lesson17/bank/BankAtm.java | 3 ++- .../lesson17/bank/CheckingAccount.java | 2 ++ .../lesson17/bank/SavingsAccount.java | 16 ++++++++++++++-- .../lesson17/bank/BankAtmTest.java | 13 +++++++------ .../lesson17/bank/CheckingAccountTest.java | 3 ++- .../lesson17/bank/SavingsAccountTest.java | 15 +++++++++++++++ 6 files changed, 42 insertions(+), 10 deletions(-) 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 d90cc433..92a9f042 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 @@ -73,9 +73,10 @@ public void depositFunds(String accountNumber, Check check) { * @param accountNumber * @param amount */ - public void withdrawFunds(String accountNumber, double amount) { + public void withdrawFunds(String accountNumber, double amount, Check check) { CheckingAccount account = getAccountOrThrow(accountNumber); account.withdraw(amount); + auditLog.log("Withdrew " + amount + " from account " + accountNumber); } 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 5d8aeb74..45cf8675 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 @@ -68,9 +68,11 @@ public void withdraw(double amount) throws InsufficientFundsException { if (isClosed()) { throw new IllegalStateException("Cannot withdraw from a closed account"); } + if (amount <= 0) { throw new IllegalStateException("Withdrawal amount must be positive"); } + if (balance < amount) { throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); } 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 index d36286c1..e8c5bd27 100644 --- 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 @@ -2,6 +2,8 @@ import java.util.Set; +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; + /** * The {@code SavingsAccount} class represents a savings account in a banking system. It extends the * {@code CheckingAccount} class and provides additional functionality specific to savings accounts. @@ -49,12 +51,22 @@ && getBalance() == other.getBalance() /** * Will throw and exception if the user attempt to make a withdrawl while under the instance of * SavingsAccount. + * + * And the makes a second withdrawl that will check if there + * is a check and throw an error if one comes in. * * @param amount The amount to deposit. */ @Override - public void withdraw(double amount) { - throw new RuntimeException("Cannot withdraw from a savings account using a check"); + public void withdraw(double amount) throws InsufficientFundsException { + throw new IllegalStateException("you cannot write a check from the savings account"); + } + + public void withdraw(double amount, Check check) { + if (check != null) { + throw new IllegalStateException("Cannot withdraw from a savings account using a check"); + } + withdraw(amount); // Call the original withdraw method } /** 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 fa4a913a..ab8c97d9 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 @@ -1,14 +1,15 @@ package com.codedifferently.lesson17.bank; +import java.util.Set; +import java.util.UUID; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; -import java.util.Set; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; class BankAtmTest { @@ -92,7 +93,7 @@ void testDepositFunds_DoesntDepositCheckTwice() { @Test void testWithdrawFunds() { // Act - classUnderTest.withdrawFunds(account2.getAccountNumber(), 50.0); + classUnderTest.withdrawFunds(account2.getAccountNumber(), 50.0, null); // Assert assertThat(account2.getBalance()).isEqualTo(150.0); @@ -104,7 +105,7 @@ void testWithdrawFunds_AccountNotFound() { // Act & Assert assertThatExceptionOfType(AccountNotFoundException.class) - .isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0)) + .isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0, null)) .withMessage("Account not found"); } } diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java index f155d8e5..49332a11 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java @@ -48,7 +48,8 @@ void deposit_withNegativeAmount() { } @Test - void withdraw() { + void withdraw() { // Assuming Check has a constructor with id and amount + // Assuming Check has a constructor with id and amount classUnderTest.withdraw(50.0); assertEquals(50.0, classUnderTest.getBalance()); } diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java index d6f21ed6..b1eb801c 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java @@ -1,6 +1,7 @@ package com.codedifferently.lesson17.bank; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.HashSet; import java.util.UUID; @@ -34,4 +35,18 @@ void testEquals() { boolean actual = classUnderTest.equals(other); assertEquals(expected, actual); } + + @Test + void testCheckWithdrawl() { + Check check = new Check("123456789", 1000.0, classUnderTest); + + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> { + classUnderTest.withdraw(1000, check); + }); + + assertEquals("Cannot withdraw from a savings account using a check", exception.getMessage()); + } } From b9c341d52b10c1815500b84fdbae0a7a74aaad02 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 16 Apr 2025 18:09:51 +0000 Subject: [PATCH 10/10] Fix: Allows Checks to pass on github --- .../codedifferently/lesson17/bank/SavingsAccount.java | 9 ++++----- .../com/codedifferently/lesson17/bank/BankAtmTest.java | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) 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 index e8c5bd27..ac1f1152 100644 --- 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 @@ -1,8 +1,7 @@ package com.codedifferently.lesson17.bank; -import java.util.Set; - import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; +import java.util.Set; /** * The {@code SavingsAccount} class represents a savings account in a banking system. It extends the @@ -51,9 +50,9 @@ && getBalance() == other.getBalance() /** * Will throw and exception if the user attempt to make a withdrawl while under the instance of * SavingsAccount. - * - * And the makes a second withdrawl that will check if there - * is a check and throw an error if one comes in. + * + *

And the makes a second withdrawl that will check if there is a check and throw an error if + * one comes in. * * @param amount The amount to deposit. */ 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 ab8c97d9..2fb08ed9 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 @@ -1,15 +1,14 @@ package com.codedifferently.lesson17.bank; -import java.util.Set; -import java.util.UUID; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class BankAtmTest {