Skip to content

feat: adds savings account and saving account test with bank account class in Lesson_17 #549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.codedifferently.lesson17.bank;

import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
import java.util.Set;

public interface Account {
String getAccountNumber();

Set<Customer> getOwners();

void deposit(double amount);

void withdraw(double amount) throws InsufficientFundsException;

double getBalance();

void closeAccount();

boolean isClosed();
}
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
import java.util.Set;

/** Represents a checking account. */
public class CheckingAccount {
public class CheckingAccount implements Account {

private final Set<Customer> owners;
private final String accountNumber;
@@ -30,6 +30,7 @@ public CheckingAccount(String accountNumber, Set<Customer> owners, double initia
*
* @return The account number.
*/
@Override
public String getAccountNumber() {
return accountNumber;
}
@@ -39,6 +40,7 @@ public String getAccountNumber() {
*
* @return The owners of the account.
*/
@Override
public Set<Customer> getOwners() {
return owners;
}
@@ -48,6 +50,7 @@ public Set<Customer> getOwners() {
*
* @param amount The amount to deposit.
*/
@Override
public void deposit(double amount) throws IllegalStateException {
if (isClosed()) {
throw new IllegalStateException("Cannot deposit to a closed account");
@@ -64,6 +67,7 @@ public void deposit(double amount) throws IllegalStateException {
* @param amount
* @throws InsufficientFundsException
*/
@Override
public void withdraw(double amount) throws InsufficientFundsException {
if (isClosed()) {
throw new IllegalStateException("Cannot withdraw from a closed account");
@@ -82,11 +86,13 @@ public void withdraw(double amount) throws InsufficientFundsException {
*
* @return The balance of the account.
*/
@Override
public double getBalance() {
return balance;
}

/** Closes the account. */
@Override
public void closeAccount() throws IllegalStateException {
if (balance > 0) {
throw new IllegalStateException("Cannot close account with a positive balance");
@@ -99,6 +105,7 @@ public void closeAccount() throws IllegalStateException {
*
* @return True if the account is closed, otherwise false.
*/
@Override
public boolean isClosed() {
return !isActive;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.codedifferently.lesson17.bank;

import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
import java.util.Set;

public class SavingsAccount implements Account {

private final Set<Customer> owners;
private final String accountNumber;
private double balance;
private boolean isActive;

public SavingsAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
this.accountNumber = accountNumber;
this.owners = owners;
this.balance = initialBalance;
this.isActive = true;
}

@Override
public String getAccountNumber() {
return accountNumber;
}

@Override
public Set<Customer> getOwners() {
return owners;
}

@Override
public void deposit(double amount) {
if (isClosed()) {
throw new IllegalStateException("Cannot deposit to a closed account");
}
if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive");
}
balance += amount;
}

@Override
public void withdraw(double amount) throws InsufficientFundsException {
if (isClosed()) {
throw new IllegalStateException("Cannot withdraw from a closed account");
}
if (amount <= 0) {
throw new IllegalArgumentException("Withdrawal amount must be positive");
}
if (balance < amount) {
throw new InsufficientFundsException("Account does not have enough funds for withdrawal");
}
balance -= amount;
}

@Override
public double getBalance() {
return balance;
}

@Override
public void closeAccount() {
if (balance > 0) {
throw new IllegalStateException("Cannot close account with a positive balance");
}
isActive = false;
}

@Override
public boolean isClosed() {
return !isActive;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
SavingsAccount other = (SavingsAccount) obj;
return accountNumber.equals(other.accountNumber)
&& Double.compare(other.balance, balance) == 0
&& isActive == other.isActive
&& owners.equals(other.owners);
}

@Override
public int hashCode() {
int result = accountNumber.hashCode();
result = 31 * result + Double.hashCode(balance);
result = 31 * result + Boolean.hashCode(isActive);
result = 31 * result + owners.hashCode();
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.codedifferently.lesson17.bank;

import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class SavingsAccountTest {

private SavingsAccount savingsAccount;
private Set<Customer> accountOwners;

@BeforeEach
void setUp() {
accountOwners = new HashSet<>();
accountOwners.add(new Customer(UUID.randomUUID(), "John Doe"));
savingsAccount = new SavingsAccount("987654321", accountOwners, 200.0);
}

@Test
void shouldReturnAccountNumber() {
assertEquals("987654321", savingsAccount.getAccountNumber());
}

@Test
void shouldReturnAccountOwners() {
assertEquals(accountOwners, savingsAccount.getOwners());
}

@Test
void shouldDepositFundsSuccessfully() {
savingsAccount.deposit(100.0);
assertEquals(300.0, savingsAccount.getBalance());
}

@Test
void shouldThrowExceptionForNegativeDeposit() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> savingsAccount.deposit(-20.0));
}

@Test
void shouldWithdrawFundsSuccessfully() {
savingsAccount.withdraw(50.0);
assertEquals(150.0, savingsAccount.getBalance());
}

@Test
void shouldThrowExceptionForNegativeWithdrawalAmount() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> savingsAccount.withdraw(-10.0))
.withMessage("Withdrawal amount must be positive");
}

@Test
void shouldThrowExceptionForInsufficientBalance() {
assertThatExceptionOfType(InsufficientFundsException.class)
.isThrownBy(() -> savingsAccount.withdraw(500.0))
.withMessage("Account does not have enough funds for withdrawal");
}

@Test
void shouldReturnBalance() {
assertEquals(200.0, savingsAccount.getBalance());
}

@Test
void shouldThrowExceptionWhenClosingAccountWithPositiveBalance() {
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> savingsAccount.closeAccount());
}

@Test
void shouldBeClosedAfterWithdrawAndClose() {
savingsAccount.withdraw(200.0);
savingsAccount.closeAccount();
assertTrue(savingsAccount.isClosed());
}

@Test
void shouldCheckEqualityAndHashCode() {
Set<Customer> owners = new HashSet<>();
owners.add(new Customer(UUID.randomUUID(), "John Doe"));

SavingsAccount account1 = new SavingsAccount("987654321", owners, 200.0);
SavingsAccount account2 = new SavingsAccount("987654321", owners, 200.0);

assertEquals(account1, account2);

assertEquals(account1.hashCode(), account2.hashCode());
}
}