Skip to content

Commit c3f6c6b

Browse files
committed
feat: add BusinessCheckingAccount and MoneyOrder classes with unit tests; enhance Check and BankAccount classes
1 parent 13eee25 commit c3f6c6b

File tree

15 files changed

+399
-121
lines changed

15 files changed

+399
-121
lines changed
Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,43 @@
11
package com.codedifferently.lesson17.bank;
22

3+
import java.time.LocalDateTime;
34
import java.util.ArrayList;
45
import java.util.List;
56

67
public class AuditLog {
7-
private List<String> logEntries;
8+
private final List<String> logEntries = new ArrayList<>();
89

9-
public AuditLog() {
10-
logEntries = new ArrayList<>();
11-
}
12-
13-
public void logTransaction(BankAccount account, double amount, String transactionType) {
14-
String entry = String.format("%s transaction: %s | Amount: %.2f | Balance: %.2f",
10+
public void logTransaction(BankAccount account, double amount, String transactionType) {
11+
String entry =
12+
String.format(
13+
"%s transaction: %s | Amount: %.2f | Balance: %.2f",
1514
transactionType, account.getAccountNumber(), amount, account.getBalance());
16-
logEntries.add(entry);
17-
System.out.println(entry); // You can remove this line if you prefer logging to a file or database
18-
}
15+
logEntries.add(entry);
16+
System.out.println(
17+
entry); // You can remove this line if you prefer logging to a file or database
18+
}
1919

20-
public List<String> getLogEntries() {
21-
return logEntries;
20+
public List<String> getLogEntries() {
21+
return logEntries;
22+
}
23+
24+
public void record(String message) {
25+
String timestampedEntry = LocalDateTime.now() + " | " + message;
26+
logEntries.add(timestampedEntry);
27+
System.out.println(timestampedEntry); // Optional: For real-time feedback
28+
}
29+
30+
public void printLog() {
31+
System.out.println("Audit Log:");
32+
for (String entry : logEntries) {
33+
System.out.println(entry);
2234
}
35+
}
36+
37+
/**
38+
* Records an audit log message.
39+
*
40+
* @param message The message to record.
41+
*/
42+
// Removed duplicate method definition for record(String message)
2343
}

lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAccount.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package com.codedifferently.lesson17.bank;
22

3-
import java.util.Set;
4-
53
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
4+
import java.util.Set;
65

76
public class BankAccount {
87
protected String accountNumber;
@@ -11,7 +10,7 @@ public class BankAccount {
1110
protected boolean isActive;
1211
private static final double LARGE_TRANSACTION_THRESHOLD = 5000.0;
1312

14-
public BankAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
13+
public BankAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
1514
this.accountNumber = accountNumber;
1615
this.owners = owners;
1716
this.balance = initialBalance;
@@ -54,9 +53,8 @@ public void deposit(double amount) throws IllegalStateException {
5453
balance += amount;
5554
}
5655

57-
58-
// Withdraws funds from the account.
59-
56+
// Withdraws funds from the account.
57+
6058
public void withdraw(double amount) throws InsufficientFundsException {
6159
if (isClosed()) {
6260
throw new IllegalStateException("Cannot withdraw from a closed account");
@@ -72,6 +70,7 @@ public void withdraw(double amount) throws InsufficientFundsException {
7270
}
7371
balance -= amount;
7472
}
73+
7574
/**
7675
* Checks if the account is active.
7776
*
@@ -130,4 +129,3 @@ public String toString() {
130129
+ '}';
131130
}
132131
}
133-

lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package com.codedifferently.lesson17.bank;
22

33
import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException;
4+
import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException;
45
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
5-
6-
import main.java.com.codedifferently.lesson17.bank.AuditLog;
7-
import main.java.com.codedifferently.lesson17.bank.BankAccount;
8-
import main.java.com.codedifferently.lesson17.bank.MoneyOrder;
9-
106
import java.util.HashMap;
117
import java.util.Map;
128
import java.util.Set;
@@ -59,10 +55,15 @@ public void depositFunds(String accountNumber, double amount) {
5955
* @param accountNumber The account number.
6056
* @param check The check to deposit.
6157
*/
62-
public void depositFunds(String accountNumber, Check check) {
58+
public void depositFunds(String accountNumber, Check check) throws CheckVoidedException {
6359
BankAccount account = getAccountOrThrow(accountNumber);
60+
61+
if (check.getIsVoided()) {
62+
throw new CheckVoidedException("Check is voided");
63+
}
64+
6465
check.depositFunds(account);
65-
auditLog.record("Deposited check of $" + check.getAmount() + " into account " + accountNumber);
66+
auditLog.record("Deposited check of $" + check.getAmount() + " to account " + accountNumber);
6667
}
6768

6869
/**
@@ -76,15 +77,22 @@ public void withdrawFunds(String accountNumber, double amount) {
7677
account.withdraw(amount);
7778
auditLog.record("Withdrew $" + amount + " from account " + accountNumber);
7879
}
79-
/**
80-
* Handles a money order transaction.
81-
* @param moneyOrder The money order to process.
82-
*/
80+
81+
/**
82+
* Handles a money order transaction.
83+
*
84+
* @param moneyOrder The money order to process.
85+
*/
8386
public void handleMoneyOrder(MoneyOrder moneyOrder) throws InsufficientFundsException {
8487
BankAccount account = getAccountOrThrow(moneyOrder.getSourceAccount().getAccountNumber());
8588
moneyOrder.process();
86-
auditLog.record("Processed money order of $" + moneyOrder.getAmount() + " from account " + account.getAccountNumber());
89+
auditLog.record(
90+
"Processed money order of $"
91+
+ moneyOrder.getAmount()
92+
+ " from account "
93+
+ account.getAccountNumber());
8794
}
95+
8896
/**
8997
* Gets an account by its number or throws an exception if not found.
9098
*

lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,16 @@
22

33
import java.util.Set;
44

5-
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
6-
75
public class BusinessCheckingAccount extends BankAccount {
8-
private boolean isBusiness;
9-
10-
public BusinessCheckingAccount(String accountNumber, Set<Customer> owners, double initialBalance, boolean isBusiness) {
11-
super(accountNumber, owners, initialBalance);
12-
this.isBusiness = isBusiness;
13-
}
6+
private final boolean isBusiness;
147

15-
/**
16-
* Business accounts may have special conditions for checks, etc.
17-
*/
18-
@Override
19-
public void withdraw(double amount) throws InsufficientFundsException {
20-
// Business checking accounts can withdraw with more flexibility
21-
if (amount > balance) {
22-
throw new InsufficientFundsException("Insufficient funds in business checking account.");
23-
}
24-
balance -= amount;
25-
}
8+
public BusinessCheckingAccount(
9+
String accountNumber, Set<Customer> owners, double initialBalance, boolean isBusiness) {
10+
super(accountNumber, owners, initialBalance);
11+
this.isBusiness = isBusiness;
12+
}
2613

27-
public boolean isBusiness() {
28-
return isBusiness;
29-
}
30-
}
14+
public boolean isBusiness() {
15+
return isBusiness;
16+
}
17+
}

lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public void depositFunds(BankAccount account) {
4949
if (account instanceof SavingsAccount) {
5050
throw new UnsupportedOperationException("Cannot deposit checks into a savings account");
5151
}
52+
if (account == null) {
53+
throw new IllegalArgumentException("Account cannot be null");
54+
}
5255
account.deposit(amount);
5356
}
5457

@@ -77,4 +80,13 @@ public String toString() {
7780
+ account.getAccountNumber()
7881
+ '}';
7982
}
83+
84+
/**
85+
* Gets the check number.
86+
*
87+
* @return The check number.
88+
*/
89+
public double getAmount() {
90+
return amount;
91+
}
8092
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package com.codedifferently.lesson17.bank;
1+
package com.codedifferently.lesson17.bank;
22

33
import java.util.Set;
44

55
public class CheckingAccount extends BankAccount {
66

7-
public CheckingAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
8-
super(accountNumber, owners, initialBalance);
9-
}
10-
}
7+
public CheckingAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
8+
super(accountNumber, owners, initialBalance);
9+
}
10+
}

lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/MoneyOrder.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@
33
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
44

55
public class MoneyOrder {
6-
private BankAccount sourceAccount;
7-
private double amount;
6+
private final BankAccount sourceAccount;
7+
private final double amount;
88

9-
public MoneyOrder(BankAccount sourceAccount, double amount) {
10-
this.sourceAccount = sourceAccount;
11-
this.amount = amount;
12-
}
9+
public MoneyOrder(BankAccount sourceAccount, double amount) {
10+
this.sourceAccount = sourceAccount;
11+
this.amount = amount;
12+
}
1313

14-
public BankAccount getSourceAccount() {
15-
return sourceAccount;
16-
}
14+
public BankAccount getSourceAccount() {
15+
return sourceAccount;
16+
}
1717

18-
public double getAmount() {
19-
return amount;
20-
}
18+
public double getAmount() {
19+
return amount;
20+
}
2121

22-
public void process() throws InsufficientFundsException {
23-
if (sourceAccount.getBalance() < amount) {
24-
throw new InsufficientFundsException("Insufficient funds for money order.");
25-
}
26-
sourceAccount.withdraw(amount);
22+
public void process() throws InsufficientFundsException {
23+
if (sourceAccount.getBalance() < amount) {
24+
throw new InsufficientFundsException("Insufficient funds for money order.");
2725
}
26+
sourceAccount.withdraw(amount);
27+
}
2828
}
Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
package com.codedifferently.lesson17.bank;
22

3-
import java.util.Set;
4-
53
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
4+
import java.util.Set;
65

76
public class SavingsAccount extends BankAccount {
87

9-
public SavingsAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
10-
super(accountNumber, owners, initialBalance);
11-
}
8+
public SavingsAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
9+
super(accountNumber, owners, initialBalance);
10+
}
1211

13-
/**
14-
* Override withdraw to restrict check withdrawals for savings accounts.
15-
*/
16-
@Override
17-
public void withdraw(double amount) throws InsufficientFundsException {
18-
// Check for withdrawal via check (additional logic can be added here if needed)
19-
if (amount > balance) {
20-
throw new InsufficientFundsException("Insufficient funds in savings account.");
21-
}
22-
balance -= amount;
12+
/** Override withdraw to restrict check withdrawals for savings accounts. */
13+
@Override
14+
public void withdraw(double amount) throws InsufficientFundsException {
15+
// Check for withdrawal via check (additional logic can be added here if needed)
16+
if (amount > balance) {
17+
throw new InsufficientFundsException("Insufficient funds in savings account.");
2318
}
19+
balance -= amount;
20+
}
2421
}
25-
26-
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.codedifferently.lesson17.bank;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.List;
6+
import java.util.Set;
7+
import java.util.UUID;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
class AuditLogTest {
12+
13+
private AuditLog auditLog;
14+
private BankAccount account;
15+
16+
@BeforeEach
17+
void setUp() {
18+
auditLog = new AuditLog();
19+
Customer customer = new Customer(UUID.randomUUID(), "Test User");
20+
account = new CheckingAccount("123456789", Set.of(customer), 100.0);
21+
}
22+
23+
@Test
24+
void testLogTransaction_addsCorrectEntry() {
25+
auditLog.logTransaction(account, 50.0, "Deposit");
26+
27+
List<String> entries = auditLog.getLogEntries();
28+
29+
assertThat(entries).hasSize(1);
30+
assertThat(entries.get(0))
31+
.contains("Deposit transaction: 123456789")
32+
.contains("Amount: 50.00")
33+
.contains("Balance: 100.00");
34+
}
35+
36+
@Test
37+
void testRecord_addsTimestampedEntry() {
38+
auditLog.record("Custom event happened.");
39+
40+
List<String> entries = auditLog.getLogEntries();
41+
42+
assertThat(entries).hasSize(1);
43+
assertThat(entries.get(0)).contains("Custom event happened.");
44+
assertThat(entries.get(0)).contains("|"); // timestamp separator
45+
}
46+
47+
@Test
48+
void testMultipleEntries_loggedInOrder() {
49+
auditLog.logTransaction(account, 25.0, "Withdrawal");
50+
auditLog.record("Manual log entry.");
51+
auditLog.logTransaction(account, 10.0, "Deposit");
52+
53+
List<String> entries = auditLog.getLogEntries();
54+
55+
assertThat(entries).hasSize(3);
56+
assertThat(entries.get(0)).contains("Withdrawal");
57+
assertThat(entries.get(1)).contains("Manual log entry.");
58+
assertThat(entries.get(2)).contains("Deposit");
59+
}
60+
}

0 commit comments

Comments
 (0)