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..39a82d774 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,11 +1,12 @@ 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 { 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..5c812038f 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 @@ -1,8 +1,9 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; import java.util.Set; +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; + /** Represents a checking account. */ public class CheckingAccount { @@ -86,6 +87,10 @@ public double getBalance() { return balance; } + public boolean getStatus() { + return isActive; + } + /** Closes the account. */ public void closeAccount() throws IllegalStateException { if (balance > 0) { diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/MoneyOrder.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/MoneyOrder.java new file mode 100644 index 000000000..20732febb --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/MoneyOrder.java @@ -0,0 +1,110 @@ +package main.java.com.codedifferently.lesson17.bank; + +import com.codedifferently.lesson17.bank.exceptions.MoneyOrderVoidedException; + +/** Represents a moneyorder. */ +public class MoneyOrder { + + private final String moneyOrderNumber; + private final double amount; + private final CheckingAccount account; + private boolean isVoided = false; + + /** + * Creates a new moneyorder. + * + * @param moneyOrderNumber The moneyorder number. + * @param amount The amount of the moneyorder. + * @param account The account the moneyorder is drawn on. + */ + public MoneyOrder(String moneyOrderNumber, double amount, CheckingAccount account) { + if (amount < 0) { + throw new IllegalArgumentException("MoneyOrder amount must be positive"); + } + account.withdraw(amount); + this.moneyOrderNumber = moneyOrderNumber; + this.amount = amount; + this.account = account; + } + + /** + * Gets the moneyorder number. + * + * @return The moneyorder number + */ + public String getMoneyOrderNumber() { + return moneyOrderNumber; + } + + /** + * Gets the amount given for the moneyorder. + * + * @return The amount. + */ + public double getAmount() { + return amount; + } + + /** + * Gets the account from the moneyordering account. + * + * @return The account in this instance. + */ + public CheckingAccount getAccount() { + return account; + } + + /** + * Gets the voided status of the moneyorder. + * + * @return True if the moneyorder is voided, and false otherwise. + */ + public boolean getIsVoided() { + return isVoided; + } + + /** Voids the moneyorder. */ + public void voidMoneyOrder() { + isVoided = true; + } + + /** + * Deposits the moneyorder into an account. + * + * @param toAccount The account to deposit the moneyorder into. + */ + public void depositFunds(CheckingAccount toAccount) { + if (isVoided) { + throw new MoneyOrderVoidedException("MoneyOrder is voided"); + } + account.withdraw(amount); + toAccount.deposit(amount); + voidMoneyOrder(); + } + + @Override + public int hashCode() { + return moneyOrderNumber.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MoneyOrder other) { + return moneyOrderNumber.equals(other.moneyOrderNumber); + } + return false; + } + + @Override + public String toString() { + return "MoneyOrder{" + + "moneyOrderNumber='" + + moneyOrderNumber + + '\'' + + ", amount=" + + amount + + ", account=" + + account.getAccountNumber() + + '}'; + } +} \ 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 new file mode 100644 index 000000000..31d46bf14 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -0,0 +1,71 @@ +package main.java.com.codedifferently.lesson17.bank; + +import java.util.Set; + +import org.assertj.core.api.ThrowableAssertAlternative; + +import com.codedifferently.lesson17.bank.Customer; + +public class SavingsAccount extends CheckingAccount { + public SavingsAccount(String accountNumber, Set owners, double initialBalance) { + super(accountNumber, owners, initialBalance); + } + + public SavingsAccount(String string, Set owners, double d) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + return getAccountNumber().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SavingsAccount other) { + return this.getAccountNumber().equals(other.getAccountNumber()); + } + return false; + } + + @Override + public String toString() { + return "SavingsAccount{" + + "accountNumber='" + + getAccountNumber() + + '\'' + + ", balance=" + + getBalance() + + ", isActive=" + + getStatus() + + '}'; + } + + public Object getAccountNumber() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Object getOwners() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void deposit(double d) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public double getBalance() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void withdraw(double d) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public ThrowableAssertAlternative closeAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean isClosed() { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/MoneyOrderVoidedException.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/MoneyOrderVoidedException.java new file mode 100644 index 000000000..d1ceeb20c --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/MoneyOrderVoidedException.java @@ -0,0 +1,10 @@ +package main.java.com.codedifferently.lesson17.bank.exceptions; + +public class MoneyOrderVoidedException extends RuntimeException { + + public MoneyOrderVoidedException() {} + + public MoneyOrderVoidedException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/MoneyOrderTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/MoneyOrderTest.java new file mode 100644 index 000000000..ed99e78f7 --- /dev/null +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/MoneyOrderTest.java @@ -0,0 +1,79 @@ +package test.java.com.codedifferently.lesson17.bank; + +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.CheckingAccount; + +import main.java.com.codedifferently.lesson17.bank.MoneyOrder; +import main.java.com.codedifferently.lesson17.bank.exceptions.MoneyOrderVoidedException; + +class MoneyOrderTest { + private CheckingAccount account1; + private CheckingAccount account2; + private MoneyOrder classUnderTest; + + @BeforeEach + void setUp() { + account1 = new CheckingAccount("123456789", null, 100.0); + account2 = new CheckingAccount("987654321", null, 200.0); + classUnderTest = new MoneyOrder("123456789", 50.0, account1); + } + + @Test + void testDepositFunds() { + // Act + classUnderTest.depositFunds(account2); + // Assert + assertThat(account1.getBalance()).isEqualTo(0.0); + assertThat(account2.getBalance()).isEqualTo(250.0); + } + + @Test + void testDepositFunds_MoneyOrderVoided() { + // Arrange + classUnderTest.voidMoneyOrder(); + + // Act & Assert + assertThatExceptionOfType(MoneyOrderVoidedException.class) + .isThrownBy(() -> classUnderTest.depositFunds(account2)) + .withMessage("MoneyOrder is voided"); + } + + @Test + void testConstructor_CantCreateMoneyOrderWithNegativeAmount() { + // Act & Assert + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MoneyOrder("123456789", -50.0, account1)) + .withMessage("MoneyOrder amount must be positive"); + } + + @Test + void testHashCode() { + // Arrange + MoneyOrder otherMoneyOrder = new MoneyOrder("123456789", 50.0, account1); + + // Assert + assertThat(classUnderTest.hashCode()).isEqualTo(otherMoneyOrder.hashCode()); + } + + @Test + void testEquals() { + // Arrange + MoneyOrder otherMoneyOrder = new MoneyOrder("123456789", 50.0, account1); + MoneyOrder differentMoneyOrder = new MoneyOrder("987654321", 100.0, account2); + + // Assert + assertThat(classUnderTest.equals(otherMoneyOrder)).isTrue(); + assertThat(classUnderTest.equals(differentMoneyOrder)).isFalse(); + } + + @Test + void testToString() { + // Assert + assertThat(classUnderTest.toString()) + .isEqualTo("MoneyOrder{moneyOrderNumber='123456789', amount=50.0, account=123456789}"); + } +} \ 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 000000000..331bea768 --- /dev/null +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/SavingsAccountTest.java @@ -0,0 +1,112 @@ +package test.java.com.codedifferently.lesson17.bank; + + + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.codedifferently.lesson17.bank.Customer; +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; + +import main.java.com.codedifferently.lesson17.bank.SavingsAccount; + +class SavingsAccountTest { + + private SavingsAccount classUnderTest; + private Set 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 getAccountNumber() { + assertEquals("123456789", classUnderTest.getAccountNumber()); + } + + @Test + void getOwners() { + assertEquals(owners, classUnderTest.getOwners()); + } + + @Test + void deposit() { + classUnderTest.deposit(50.0); + assertEquals(150.0, classUnderTest.getBalance()); + } + + @Test + void deposit_withNegativeAmount() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> classUnderTest.deposit(-50.0)); + } + + @Test + void withdraw() { + classUnderTest.withdraw(50.0); + assertEquals(50.0, classUnderTest.getBalance()); + } + + @Test + void withdraw_withNegativeAmount() { + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> classUnderTest.withdraw(-50.0)) + .withMessage("Withdrawal amount must be positive"); + } + + @Test + void withdraw_withInsufficientBalance() { + assertThatExceptionOfType(InsufficientFundsException.class) + .isThrownBy(() -> classUnderTest.withdraw(150.0)) + .withMessage("Account does not have enough funds for withdrawal"); + } + + @Test + void getBalance() { + assertEquals(100.0, classUnderTest.getBalance()); + } + + @Test + void closeAccount_withPositiveBalance() { + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> classUnderTest.closeAccount()); + } + + @Test + void isClosed() { + assertFalse(classUnderTest.isClosed()); + classUnderTest.withdraw(100); + classUnderTest.closeAccount(); + assertTrue(classUnderTest.isClosed()); + } + + @Test + void equals() { + SavingsAccount otherAccount = new SavingsAccount("123456789", owners, 200.0); + assertEquals(classUnderTest, otherAccount); + } + + @Test + void hashCodeTest() { + SavingsAccount otherAccount = new SavingsAccount("123456789", owners, 200.0); + assertEquals(classUnderTest.hashCode(), otherAccount.hashCode()); + } + + @Test + void toStringTest() { + String expected = "SavingsAccount{accountNumber='123456789', balance=100.0, isActive=true}"; + assertEquals(expected, classUnderTest.toString()); + } +} \ No newline at end of file