Skip to content

Commit d181deb

Browse files
author
Yafiaha
committed
Feat : Lesson-17 SavingsAccount & BusinessCheckingAccount
1 parent a3a21bb commit d181deb

File tree

7 files changed

+247
-6
lines changed

7 files changed

+247
-6
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.codedifferently.lesson17.bank;
2+
3+
import java.util.Set;
4+
5+
public class BusinessCheckingAccount extends CheckingAccount {
6+
7+
public BusinessCheckingAccount(
8+
String accountNumber, Set<Customer> owners, double initialBalance) {
9+
super(accountNumber, owners, initialBalance); // Call to Account's constructor
10+
11+
if (owners.stream().noneMatch(Customer::isBusiness)) {
12+
throw new IllegalArgumentException(
13+
"A BusinessCheckingAccount must have at least one business owner.");
14+
}
15+
}
16+
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class Customer {
99

1010
private final UUID id;
1111
private final String name;
12+
private final CustomerType type;
1213
private final Set<CheckingAccount> accounts = new HashSet<>();
1314

1415
/**
@@ -17,9 +18,10 @@ public class Customer {
1718
* @param id The ID of the customer.
1819
* @param name The name of the customer.
1920
*/
20-
public Customer(UUID id, String name) {
21+
public Customer(UUID id, String name, CustomerType type) {
2122
this.id = id;
2223
this.name = name;
24+
this.type = type;
2325
}
2426

2527
/**
@@ -58,6 +60,11 @@ public Set<CheckingAccount> getAccounts() {
5860
return accounts;
5961
}
6062

63+
// make sure if the custumer is using a business account
64+
public boolean isBusiness() {
65+
return type == CustomerType.BUSINESS;
66+
}
67+
6168
@Override
6269
public int hashCode() {
6370
return id.hashCode();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.codedifferently.lesson17.bank;
2+
3+
public enum CustomerType {
4+
INDIVIDUAL,
5+
BUSINESS
6+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.codedifferently.lesson17.bank;
2+
3+
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
4+
import java.util.Set;
5+
6+
// represent a savings account
7+
public class SavingsAccount {
8+
9+
private final Set<Customer> owners;
10+
private final String accountNumber;
11+
private double balance;
12+
private boolean isActive;
13+
14+
// consturcter of saving account
15+
public SavingsAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
16+
this.accountNumber = accountNumber;
17+
this.owners = owners;
18+
this.balance = initialBalance;
19+
isActive = true;
20+
}
21+
22+
// getters & setters
23+
public String getAccountNumber() {
24+
return accountNumber;
25+
}
26+
27+
public Set<Customer> getOwners() {
28+
return owners;
29+
}
30+
31+
public double getBalance() {
32+
return balance;
33+
}
34+
35+
public boolean isClosed() {
36+
return !isActive;
37+
}
38+
39+
/**
40+
* Deposits funds into the account.
41+
*
42+
* @param amount The amount to deposit.
43+
*/
44+
public void deposit(double amount) throws IllegalStateException {
45+
if (isClosed()) {
46+
throw new IllegalStateException("Cannot deposit to a closed account");
47+
}
48+
if (amount <= 0) {
49+
throw new IllegalArgumentException("Deposit amount must be positive");
50+
}
51+
balance += amount;
52+
}
53+
54+
/**
55+
* Withdraws funds from the account.
56+
*
57+
* @param amount
58+
* @throws InsufficientFundsException
59+
*/
60+
public void withdraw(double amount) throws InsufficientFundsException {
61+
if (isClosed()) {
62+
throw new IllegalStateException("Cannot withdraw from a closed account");
63+
}
64+
if (amount <= 0) {
65+
throw new IllegalStateException("Withdrawal amount must be positive");
66+
}
67+
if (balance < amount) {
68+
throw new InsufficientFundsException("Account does not have enough funds for withdrawal");
69+
}
70+
balance -= amount;
71+
}
72+
73+
/** Closes the account. */
74+
public void closeAccount() throws IllegalStateException {
75+
if (balance > 0) {
76+
throw new IllegalStateException("Cannot close account with a positive balance");
77+
}
78+
isActive = false;
79+
}
80+
81+
@Override
82+
public int hashCode() {
83+
return accountNumber.hashCode();
84+
}
85+
86+
@Override
87+
public boolean equals(Object obj) {
88+
if (obj instanceof SavingsAccount other) {
89+
return accountNumber.equals(other.accountNumber);
90+
}
91+
return false;
92+
}
93+
94+
@Override
95+
public String toString() {
96+
return "SavingsAccount{"
97+
+ "accountNumber='"
98+
+ accountNumber
99+
+ '\''
100+
+ ", balance="
101+
+ balance
102+
+ ", isActive="
103+
+ isActive
104+
+ '}';
105+
}
106+
}

lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class BankAtmTest {
2121
@BeforeEach
2222
void setUp() {
2323
classUnderTest = new BankAtm();
24-
customer1 = new Customer(UUID.randomUUID(), "John Doe");
25-
customer2 = new Customer(UUID.randomUUID(), "Jane Smith");
24+
customer1 = new Customer(UUID.randomUUID(), "John Doe", CustomerType.INDIVIDUAL);
25+
customer2 = new Customer(UUID.randomUUID(), "Jane Smith", CustomerType.INDIVIDUAL);
2626
account1 = new CheckingAccount("123456789", Set.of(customer1), 100.0);
2727
account2 = new CheckingAccount("987654321", Set.of(customer1, customer2), 200.0);
2828
customer1.addAccount(account1);
@@ -35,7 +35,7 @@ void setUp() {
3535
@Test
3636
void testAddAccount() {
3737
// Arrange
38-
Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson");
38+
Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson", CustomerType.INDIVIDUAL);
3939
CheckingAccount account3 = new CheckingAccount("555555555", Set.of(customer3), 300.0);
4040
customer3.addAccount(account3);
4141

lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class CheckingAccountTest {
2020
@BeforeEach
2121
void setUp() {
2222
owners = new HashSet<>();
23-
owners.add(new Customer(UUID.randomUUID(), "John Doe"));
24-
owners.add(new Customer(UUID.randomUUID(), "Jane Smith"));
23+
owners.add(new Customer(UUID.randomUUID(), "John Doe", CustomerType.INDIVIDUAL));
24+
owners.add(new Customer(UUID.randomUUID(), "Jane Smith", CustomerType.INDIVIDUAL));
2525
classUnderTest = new CheckingAccount("123456789", owners, 100.0);
2626
}
2727

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.codedifferently.lesson17.bank;
2+
3+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertFalse;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
8+
import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
import java.util.UUID;
12+
import org.junit.jupiter.api.BeforeEach;
13+
import org.junit.jupiter.api.Test;
14+
15+
public class SavingsAccountTest {
16+
17+
private SavingsAccount classUnderTest;
18+
private Set<Customer> owners;
19+
20+
@BeforeEach
21+
void setUp() {
22+
owners = new HashSet<>();
23+
owners.add(new Customer(UUID.randomUUID(), "John Doe", CustomerType.INDIVIDUAL));
24+
owners.add(new Customer(UUID.randomUUID(), "Jane Smith", CustomerType.INDIVIDUAL));
25+
classUnderTest = new SavingsAccount("123456789", owners, 100.0);
26+
}
27+
28+
@Test
29+
void getAccountNumber() {
30+
assertEquals("123456789", classUnderTest.getAccountNumber());
31+
}
32+
33+
@Test
34+
void getOwners() {
35+
assertEquals(owners, classUnderTest.getOwners());
36+
}
37+
38+
@Test
39+
void deposit() {
40+
classUnderTest.deposit(50.0);
41+
assertEquals(150.0, classUnderTest.getBalance());
42+
}
43+
44+
@Test
45+
void deposit_withNegativeAmount() {
46+
assertThatExceptionOfType(IllegalArgumentException.class)
47+
.isThrownBy(() -> classUnderTest.deposit(-50.0));
48+
}
49+
50+
@Test
51+
void withdraw() {
52+
classUnderTest.withdraw(50.0);
53+
assertEquals(50.0, classUnderTest.getBalance());
54+
}
55+
56+
@Test
57+
void withdraw_withNegativeAmount() {
58+
assertThatExceptionOfType(IllegalStateException.class)
59+
.isThrownBy(() -> classUnderTest.withdraw(-50.0))
60+
.withMessage("Withdrawal amount must be positive");
61+
}
62+
63+
@Test
64+
void withdraw_withInsufficientBalance() {
65+
assertThatExceptionOfType(InsufficientFundsException.class)
66+
.isThrownBy(() -> classUnderTest.withdraw(150.0))
67+
.withMessage("Account does not have enough funds for withdrawal");
68+
}
69+
70+
@Test
71+
void getBalance() {
72+
assertEquals(100.0, classUnderTest.getBalance());
73+
}
74+
75+
@Test
76+
void closeAccount_withPositiveBalance() {
77+
assertThatExceptionOfType(IllegalStateException.class)
78+
.isThrownBy(() -> classUnderTest.closeAccount());
79+
}
80+
81+
@Test
82+
void isClosed() {
83+
assertFalse(classUnderTest.isClosed());
84+
classUnderTest.withdraw(100);
85+
classUnderTest.closeAccount();
86+
assertTrue(classUnderTest.isClosed());
87+
}
88+
89+
@Test
90+
void equals() {
91+
SavingsAccount otherAccount = new SavingsAccount("123456789", owners, 200.0);
92+
assertEquals(classUnderTest, otherAccount);
93+
}
94+
95+
@Test
96+
void hashCodeTest() {
97+
SavingsAccount otherAccount = new SavingsAccount("123456789", owners, 200.0);
98+
assertEquals(classUnderTest.hashCode(), otherAccount.hashCode());
99+
}
100+
101+
@Test
102+
void toStringTest() {
103+
String expected = "SavingsAccount{accountNumber='123456789', balance=100.0, isActive=true}";
104+
assertEquals(expected, classUnderTest.toString());
105+
}
106+
}

0 commit comments

Comments
 (0)