diff --git a/pom.xml b/pom.xml index 3994d594..9447b760 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,8 @@ UTF-8 + 20 + 20 @@ -20,5 +22,22 @@ 4.11 test + + org.slf4j + slf4j-api + 2.0.9 + + + org.assertj + assertj-core + 3.24.2 + test + + + org.mockito + mockito-core + 5.5.0 + test + diff --git a/src/main/java/com/abc/Account.java b/src/main/java/com/abc/Account.java deleted file mode 100644 index 099691e0..00000000 --- a/src/main/java/com/abc/Account.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.abc; - -import java.util.ArrayList; -import java.util.List; - -public class Account { - - public static final int CHECKING = 0; - public static final int SAVINGS = 1; - public static final int MAXI_SAVINGS = 2; - - private final int accountType; - public List transactions; - - public Account(int accountType) { - this.accountType = accountType; - this.transactions = new ArrayList(); - } - - public void deposit(double amount) { - if (amount <= 0) { - throw new IllegalArgumentException("amount must be greater than zero"); - } else { - transactions.add(new Transaction(amount)); - } - } - -public void withdraw(double amount) { - if (amount <= 0) { - throw new IllegalArgumentException("amount must be greater than zero"); - } else { - transactions.add(new Transaction(-amount)); - } -} - - public double interestEarned() { - double amount = sumTransactions(); - switch(accountType){ - case SAVINGS: - if (amount <= 1000) - return amount * 0.001; - else - return 1 + (amount-1000) * 0.002; -// case SUPER_SAVINGS: -// if (amount <= 4000) -// return 20; - case MAXI_SAVINGS: - if (amount <= 1000) - return amount * 0.02; - if (amount <= 2000) - return 20 + (amount-1000) * 0.05; - return 70 + (amount-2000) * 0.1; - default: - return amount * 0.001; - } - } - - public double sumTransactions() { - return checkIfTransactionsExist(true); - } - - private double checkIfTransactionsExist(boolean checkAll) { - double amount = 0.0; - for (Transaction t: transactions) - amount += t.amount; - return amount; - } - - public int getAccountType() { - return accountType; - } - -} diff --git a/src/main/java/com/abc/Bank.java b/src/main/java/com/abc/Bank.java deleted file mode 100644 index 5dd535bd..00000000 --- a/src/main/java/com/abc/Bank.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.abc; - -import java.util.ArrayList; -import java.util.List; - -public class Bank { - private List customers; - - public Bank() { - customers = new ArrayList(); - } - - public void addCustomer(Customer customer) { - customers.add(customer); - } - - public String customerSummary() { - String summary = "Customer Summary"; - for (Customer c : customers) - summary += "\n - " + c.getName() + " (" + format(c.getNumberOfAccounts(), "account") + ")"; - return summary; - } - - //Make sure correct plural of word is created based on the number passed in: - //If number passed in is 1 just return the word otherwise add an 's' at the end - private String format(int number, String word) { - return number + " " + (number == 1 ? word : word + "s"); - } - - public double totalInterestPaid() { - double total = 0; - for(Customer c: customers) - total += c.totalInterestEarned(); - return total; - } - - public String getFirstCustomer() { - try { - customers = null; - return customers.get(0).getName(); - } catch (Exception e){ - e.printStackTrace(); - return "Error"; - } - } -} diff --git a/src/main/java/com/abc/Customer.java b/src/main/java/com/abc/Customer.java deleted file mode 100644 index 31571685..00000000 --- a/src/main/java/com/abc/Customer.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.abc; - -import java.util.ArrayList; -import java.util.List; - -import static java.lang.Math.abs; - -public class Customer { - private String name; - private List accounts; - - public Customer(String name) { - this.name = name; - this.accounts = new ArrayList(); - } - - public String getName() { - return name; - } - - public Customer openAccount(Account account) { - accounts.add(account); - return this; - } - - public int getNumberOfAccounts() { - return accounts.size(); - } - - public double totalInterestEarned() { - double total = 0; - for (Account a : accounts) - total += a.interestEarned(); - return total; - } - - public String getStatement() { - String statement = null; - statement = "Statement for " + name + "\n"; - double total = 0.0; - for (Account a : accounts) { - statement += "\n" + statementForAccount(a) + "\n"; - total += a.sumTransactions(); - } - statement += "\nTotal In All Accounts " + toDollars(total); - return statement; - } - - private String statementForAccount(Account a) { - String s = ""; - - //Translate to pretty account type - switch(a.getAccountType()){ - case Account.CHECKING: - s += "Checking Account\n"; - break; - case Account.SAVINGS: - s += "Savings Account\n"; - break; - case Account.MAXI_SAVINGS: - s += "Maxi Savings Account\n"; - break; - } - - //Now total up all the transactions - double total = 0.0; - for (Transaction t : a.transactions) { - s += " " + (t.amount < 0 ? "withdrawal" : "deposit") + " " + toDollars(t.amount) + "\n"; - total += t.amount; - } - s += "Total " + toDollars(total); - return s; - } - - private String toDollars(double d){ - return String.format("$%,.2f", abs(d)); - } -} diff --git a/src/main/java/com/abc/Transaction.java b/src/main/java/com/abc/Transaction.java deleted file mode 100644 index c1f7c67e..00000000 --- a/src/main/java/com/abc/Transaction.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.abc; - -import java.util.Calendar; -import java.util.Date; - -public class Transaction { - public final double amount; - - private Date transactionDate; - - public Transaction(double amount) { - this.amount = amount; - this.transactionDate = DateProvider.getInstance().now(); - } - -} diff --git a/src/main/java/com/mybank/Accounts/Account.java b/src/main/java/com/mybank/Accounts/Account.java new file mode 100644 index 00000000..f0dbb8b8 --- /dev/null +++ b/src/main/java/com/mybank/Accounts/Account.java @@ -0,0 +1,49 @@ +package com.mybank.Accounts; + +import com.mybank.Transaction; +import com.mybank.Utlities.AccountType; +import com.mybank.Utlities.TransactionType; + +import java.util.ArrayList; +import java.util.List; + +public abstract class Account { + private final AccountType accountType; + public List transactions; + + public Account(AccountType accountType) { + this.accountType = accountType; + this.transactions = new ArrayList<>(); + } + + public abstract double interestEarned(); + + public void deposit(double amount) { + if (amount <= 0) { + throw new IllegalArgumentException("amount must be greater than zero"); + } else { + transactions.add(new Transaction(amount, TransactionType.DEPOSIT)); + } + } + + public void withdraw(double amount) { + if (amount <= 0) { + throw new IllegalArgumentException("amount must be greater than zero"); + } else if (amount > sumTransactions()) { + throw new IllegalArgumentException("Amount exceeds Account balance"); + } else { + transactions.add(new Transaction(-amount, TransactionType.WITHDRAWAL)); + } + } + + public double sumTransactions() { + double amount = 0.0; + for (Transaction transaction : transactions) + amount += transaction.amount; + return amount; + } + + public AccountType getAccountType() { + return accountType; + } +} diff --git a/src/main/java/com/mybank/Accounts/CheckingAccount.java b/src/main/java/com/mybank/Accounts/CheckingAccount.java new file mode 100644 index 00000000..1077dd04 --- /dev/null +++ b/src/main/java/com/mybank/Accounts/CheckingAccount.java @@ -0,0 +1,15 @@ +package com.mybank.Accounts; + +import com.mybank.Utlities.AccountType; + +public class CheckingAccount extends Account { + public CheckingAccount() { + super(AccountType.CHECKING); + } + + @Override + public double interestEarned() { + double amount = sumTransactions(); + return amount * 0.001; + } +} diff --git a/src/main/java/com/mybank/Accounts/MaxiSavingsAccount.java b/src/main/java/com/mybank/Accounts/MaxiSavingsAccount.java new file mode 100644 index 00000000..88d1858c --- /dev/null +++ b/src/main/java/com/mybank/Accounts/MaxiSavingsAccount.java @@ -0,0 +1,25 @@ +package com.mybank.Accounts; + +import com.mybank.Transaction; +import com.mybank.Utlities.AccountType; +import com.mybank.Utlities.DateProvider; +import com.mybank.Utlities.TransactionType; + +public class MaxiSavingsAccount extends Account { + public MaxiSavingsAccount() { + super(AccountType.MAXI_SAVINGS); + } + + @Override + public double interestEarned() { + double amount = sumTransactions(); + for (Transaction transaction : transactions) { + if (transaction.getTransactionDate().isAfter(DateProvider.getInstance().tenDays()) + && transaction.getTransactionType().equals(TransactionType.WITHDRAWAL)) { + return amount * 0.001; + } + } + return amount * 0.05; + } + +} diff --git a/src/main/java/com/mybank/Accounts/SavingsAccount.java b/src/main/java/com/mybank/Accounts/SavingsAccount.java new file mode 100644 index 00000000..45e1e3cc --- /dev/null +++ b/src/main/java/com/mybank/Accounts/SavingsAccount.java @@ -0,0 +1,19 @@ +package com.mybank.Accounts; + +import com.mybank.Utlities.AccountType; + +public class SavingsAccount extends Account { + public SavingsAccount() { + super(AccountType.SAVINGS); + } + + @Override + public double interestEarned() { + double amount = sumTransactions(); + if (amount <= 1000) + return amount * 0.001; + else + return (amount - 1000) * 0.002; + } + +} diff --git a/src/main/java/com/mybank/Bank.java b/src/main/java/com/mybank/Bank.java new file mode 100644 index 00000000..252efccf --- /dev/null +++ b/src/main/java/com/mybank/Bank.java @@ -0,0 +1,57 @@ +package com.mybank; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class Bank { + private final List customers; + private List customerNames; + private static final Logger logger = LoggerFactory.getLogger(Bank.class); + + public Bank() { + customers = new ArrayList<>(); + } + + public void addCustomer(Customer customer) { + try { + customers.add(customer); + } catch (Exception e) { + logger.error("Error whilst adding customer", e); + } + } + + public String customerSummary() { + StringBuilder summary = new StringBuilder("Customer Summary"); + for (Customer c : customers) + summary.append("\n - ") + .append(c.getName()) + .append(" (").append(format(c.getNumberOfAccounts(), "account")) + .append(")"); + return summary.toString(); + } + + private String format(int number, String word) { + return number + " " + (number == 1 ? word : word + "s"); + } + + public double totalInterestPaid() { + double total = 0; + for (Customer c : customers) + total += c.totalInterestEarned(); + return total; + } + + public List getCustomers() { + try { + for (Customer customer : customers) { + customerNames.add(customer.getName()); + } + return customerNames; + } catch (Exception e) { + throw new RuntimeException("Error whilst getting customer", e); + } + } +} diff --git a/src/main/java/com/mybank/Customer.java b/src/main/java/com/mybank/Customer.java new file mode 100644 index 00000000..28516e40 --- /dev/null +++ b/src/main/java/com/mybank/Customer.java @@ -0,0 +1,94 @@ +package com.mybank; + +import com.mybank.Accounts.Account; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +import static java.lang.Math.abs; + +public class Customer { + private static final Logger logger = LoggerFactory.getLogger(Customer.class); + private final String name; + private final List accounts; + + public Customer(String name) { + this.name = name; + this.accounts = new ArrayList<>(); + } + + public String getName() { + return name; + } + + public Customer openAccount(Account account) { + try { + accounts.add(account); + } catch (Exception e) { + logger.error("Error whilst opening account", e); + } + return this; + } + + public int getNumberOfAccounts() { + return accounts.size(); + } + + public double totalInterestEarned() { + double total = 0.0; + for (Account account : accounts) + total += account.interestEarned(); + return total; + } + + public String getStatement() { + StringBuilder statement = new StringBuilder("Statement for ").append(name).append("\n"); + double total = 0.0; + for (Account account : accounts) { + statement.append("\n") + .append(statementForAccount(account)) + .append("\n"); + total += account.sumTransactions(); + } + statement.append("\nTotal In All Accounts ").append(toDollars(total)); + return statement.toString(); + } + + private String statementForAccount(Account account) { + StringBuilder stringBuilder = new StringBuilder(); + + switch (account.getAccountType()) { + case CHECKING -> stringBuilder.append("Checking Account\n"); + case SAVINGS -> stringBuilder.append("Savings Account\n"); + case MAXI_SAVINGS -> stringBuilder.append("Maxi Savings Account\n"); + } + + double total = 0.0; + for (Transaction transaction : account.transactions) { + stringBuilder.append(" ") + .append(transaction.amount < 0 ? "withdrawal" : "deposit") + .append(" ").append(toDollars(transaction.amount)) + .append("\n"); + total += transaction.amount; + } + stringBuilder.append("Total ") + .append(toDollars(total)); + return stringBuilder.toString(); + } + + private String toDollars(double total) { + return String.format("$%,.2f", abs(total)); + } + + public void transferBetweenAccounts(Account from, Account to, double amount) { + if (amount > from.sumTransactions()) { + throw new IllegalArgumentException("Amount exceeds account balance."); + } else { + from.withdraw(amount); + to.deposit(amount); + logger.info(String.format("%f has been deposited from %s to %s", amount, from, to)); + } + } +} diff --git a/src/main/java/com/mybank/Transaction.java b/src/main/java/com/mybank/Transaction.java new file mode 100644 index 00000000..ba93fdd9 --- /dev/null +++ b/src/main/java/com/mybank/Transaction.java @@ -0,0 +1,26 @@ +package com.mybank; + +import com.mybank.Utlities.DateProvider; +import com.mybank.Utlities.TransactionType; + +import java.time.LocalDate; + +public class Transaction { + public double amount; + private final LocalDate transactionDate; + private final TransactionType transactionType; + + public Transaction(double amount, TransactionType transactionType ) { + this.amount = amount; + this.transactionDate = DateProvider.getInstance().now(); + this.transactionType = transactionType; + } + + public LocalDate getTransactionDate() { + return transactionDate; + } + + public TransactionType getTransactionType() { + return transactionType; + } +} diff --git a/src/main/java/com/mybank/Utlities/AccountType.java b/src/main/java/com/mybank/Utlities/AccountType.java new file mode 100644 index 00000000..0f7600bc --- /dev/null +++ b/src/main/java/com/mybank/Utlities/AccountType.java @@ -0,0 +1,7 @@ +package com.mybank.Utlities; + +public enum AccountType { + CHECKING, + SAVINGS, + MAXI_SAVINGS +} diff --git a/src/main/java/com/abc/DateProvider.java b/src/main/java/com/mybank/Utlities/DateProvider.java similarity index 55% rename from src/main/java/com/abc/DateProvider.java rename to src/main/java/com/mybank/Utlities/DateProvider.java index 035ee90b..8e86ca66 100644 --- a/src/main/java/com/abc/DateProvider.java +++ b/src/main/java/com/mybank/Utlities/DateProvider.java @@ -1,7 +1,6 @@ -package com.abc; +package com.mybank.Utlities; -import java.util.Calendar; -import java.util.Date; +import java.time.LocalDate; public class DateProvider { private static DateProvider instance = null; @@ -12,7 +11,11 @@ public static DateProvider getInstance() { return instance; } - public Date now() { - return Calendar.getInstance().getTime(); + public LocalDate now() { + return LocalDate.now(); + } + + public LocalDate tenDays() { + return now().minusDays(10); } } diff --git a/src/main/java/com/mybank/Utlities/TransactionType.java b/src/main/java/com/mybank/Utlities/TransactionType.java new file mode 100644 index 00000000..77dc89b8 --- /dev/null +++ b/src/main/java/com/mybank/Utlities/TransactionType.java @@ -0,0 +1,6 @@ +package com.mybank.Utlities; + +public enum TransactionType { + WITHDRAWAL, + DEPOSIT +} diff --git a/src/test/java/com/abc/BankTest.java b/src/test/java/com/abc/BankTest.java deleted file mode 100644 index f8a82896..00000000 --- a/src/test/java/com/abc/BankTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.abc; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class BankTest { - private static final double DOUBLE_DELTA = 1e-15; - - @Test - public void customerSummary() { - Bank bank = new Bank(); - Customer john = new Customer("John"); - john.openAccount(new Account(Account.CHECKING)); - bank.addCustomer(john); - - assertEquals("Customer Summary\n - John (1 account)", bank.customerSummary()); - } - - @Test - public void checkingAccount() { - Bank bank = new Bank(); - Account checkingAccount = new Account(Account.CHECKING); - Customer bill = new Customer("Bill").openAccount(checkingAccount); - bank.addCustomer(bill); - - checkingAccount.deposit(100.0); - - assertEquals(0.1, bank.totalInterestPaid(), DOUBLE_DELTA); - } - - @Test - public void savings_account() { - Bank bank = new Bank(); - Account checkingAccount = new Account(Account.SAVINGS); - bank.addCustomer(new Customer("Bill").openAccount(checkingAccount)); - - checkingAccount.deposit(1500.0); - - assertEquals(2.0, bank.totalInterestPaid(), DOUBLE_DELTA); - } - - @Test - public void maxi_savings_account() { - Bank bank = new Bank(); - Account checkingAccount = new Account(Account.MAXI_SAVINGS); - bank.addCustomer(new Customer("Bill").openAccount(checkingAccount)); - - checkingAccount.deposit(3000.0); - - assertEquals(170.0, bank.totalInterestPaid(), DOUBLE_DELTA); - } - -} diff --git a/src/test/java/com/abc/CustomerTest.java b/src/test/java/com/abc/CustomerTest.java deleted file mode 100644 index b8df9498..00000000 --- a/src/test/java/com/abc/CustomerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.abc; - -import org.junit.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class CustomerTest { - - @Test //Test customer statement generation - public void testApp(){ - - Account checkingAccount = new Account(Account.CHECKING); - Account savingsAccount = new Account(Account.SAVINGS); - - Customer henry = new Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount); - - checkingAccount.deposit(100.0); - savingsAccount.deposit(4000.0); - savingsAccount.withdraw(200.0); - - assertEquals("Statement for Henry\n" + - "\n" + - "Checking Account\n" + - " deposit $100.00\n" + - "Total $100.00\n" + - "\n" + - "Savings Account\n" + - " deposit $4,000.00\n" + - " withdrawal $200.00\n" + - "Total $3,800.00\n" + - "\n" + - "Total In All Accounts $3,900.00", henry.getStatement()); - } - - @Test - public void testOneAccount(){ - Customer oscar = new Customer("Oscar").openAccount(new Account(Account.SAVINGS)); - assertEquals(1, oscar.getNumberOfAccounts()); - } - - @Test - public void testTwoAccount(){ - Customer oscar = new Customer("Oscar") - .openAccount(new Account(Account.SAVINGS)); - oscar.openAccount(new Account(Account.CHECKING)); - assertEquals(2, oscar.getNumberOfAccounts()); - } - - @Ignore - public void testThreeAcounts() { - Customer oscar = new Customer("Oscar") - .openAccount(new Account(Account.SAVINGS)); - oscar.openAccount(new Account(Account.CHECKING)); - assertEquals(3, oscar.getNumberOfAccounts()); - } -} diff --git a/src/test/java/com/abc/TransactionTest.java b/src/test/java/com/abc/TransactionTest.java deleted file mode 100644 index 28983234..00000000 --- a/src/test/java/com/abc/TransactionTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.abc; - -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class TransactionTest { - @Test - public void transaction() { - Transaction t = new Transaction(5); - assertTrue(t instanceof Transaction); - } -} diff --git a/src/test/java/com/mybank/Accounts/AccountTest.java b/src/test/java/com/mybank/Accounts/AccountTest.java new file mode 100644 index 00000000..192417d4 --- /dev/null +++ b/src/test/java/com/mybank/Accounts/AccountTest.java @@ -0,0 +1,174 @@ +package com.mybank.Accounts; + + +import com.mybank.Bank; +import com.mybank.Customer; +import com.mybank.Transaction; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AccountTest { + private Bank bank; + private Account checkingAccount; + private Account savingAccount; + private Account maxiSaving; + private Exception exception; + + @Test + public void testDepositIntoChecking() { + givenBank(); + givenCheckingAccountIsCreated(); + givenCustomerOpensAccount(checkingAccount); + + whenMoneyIsDepositedIntoChecking(); + + thenMoneyIsDeposited(checkingAccount, 7000.0); + + } + + @Test + public void testDepositIntoSaving() { + givenBank(); + givenSavingAccountIsCreated(); + givenCustomerOpensAccount(savingAccount); + + whenMoneyIsDepositedIntoSaving(); + + thenMoneyIsDeposited(savingAccount, 300.0); + } + + @Test + public void testDepositIntoMaxiSaving() { + givenBank(); + givenMaxiSavingAccountIsCreated(); + givenCustomerOpensAccount(maxiSaving); + + whenMoneyIsDepositedIntoMaxiSaving(); + + thenMoneyIsDeposited(maxiSaving, 90.0); + } + + @Test + public void testSuccessfulWithdrawalFromChecking() { + givenBank(); + givenCheckingAccountIsCreated(); + givenCustomerOpensAccount(checkingAccount); + + whenMoneyIsDepositedIntoChecking(); + whenMoneyIsWithdrawnFromChecking(200); + + thenTotalBalanceIsCorrect(checkingAccount, 6800.0); + } + + @Test + public void testSuccessfulWithdrawalFromSavings() { + givenBank(); + givenSavingAccountIsCreated(); + givenCustomerOpensAccount(savingAccount); + + whenMoneyIsDepositedIntoSaving(); + whenMoneyIsWithdrawnFromSaving(); + + thenTotalBalanceIsCorrect(savingAccount, 250.0); + } + + @Test + public void testSuccessfulWithdrawalFromMaxiSavings() { + givenBank(); + givenMaxiSavingAccountIsCreated(); + givenCustomerOpensAccount(maxiSaving); + + whenMoneyIsDepositedIntoMaxiSaving(); + whenMoneyIsWithdrawnFromMaxiSaving(); + + thenTotalBalanceIsCorrect(maxiSaving, 0.0); + } + + @Test + public void testUnsuccessfulWithdrawalFromChecking() { + givenBank(); + givenCheckingAccountIsCreated(); + givenCustomerOpensAccount(checkingAccount); + + whenMoneyIsDepositedIntoChecking(); + whenMoneyIsWithdrawnFromChecking(8000.0); + + thenErrorIsLogged(checkingAccount); + } + + //TODO: UnsuccessfulWithdrawalFromSavings + //TODO: UnsuccessfulWithdrawalFromMaxiSavings + //TODO: Move interestCalculationTestsToAccountTest + //TODO: test other methods to ensure complete code coverage + + + private void givenCustomerOpensAccount(Account checkingAccount) { + Customer customer = new Customer("Sandra"); + bank.addCustomer(customer); + customer.openAccount(checkingAccount); + } + + private void givenCheckingAccountIsCreated() { + checkingAccount = new CheckingAccount(); + } + + private void givenSavingAccountIsCreated() { + savingAccount = new SavingsAccount(); + } + + private void givenMaxiSavingAccountIsCreated() { + maxiSaving = new MaxiSavingsAccount(); + } + + private void givenBank() { + bank = new Bank(); + } + + private void whenMoneyIsDepositedIntoChecking() { + checkingAccount.deposit(7000.0); + } + + private void whenMoneyIsDepositedIntoSaving() { + savingAccount.deposit(300.0); + } + + private void whenMoneyIsDepositedIntoMaxiSaving() { + maxiSaving.deposit(90.0); + } + + private void whenMoneyIsWithdrawnFromChecking(double amount) { + try { + checkingAccount.withdraw(amount); + } catch (Exception e) { + exception = e; + } + } + + private void whenMoneyIsWithdrawnFromSaving() { + savingAccount.withdraw(50); + } + + private void whenMoneyIsWithdrawnFromMaxiSaving() { + maxiSaving.withdraw(90); + } + + private void thenMoneyIsDeposited(Account accountType, double expectedAmount) { + assertThat(accountType.transactions).size().isEqualTo(1); + + for (Transaction transaction : accountType.transactions) { + double amount = transaction.amount; + assertThat(amount).isEqualTo(expectedAmount); + } + } + + private void thenTotalBalanceIsCorrect(Account accountType, double expectedAmount) { + assertThat(accountType.transactions).size().isEqualTo(2); + assertThat(accountType.sumTransactions()).isEqualTo(expectedAmount); + } + + private void thenErrorIsLogged(Account accountType) { + assertThat(accountType.transactions).size().isEqualTo(1); + assertThat(exception).isNotNull().isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file diff --git a/src/test/java/com/mybank/BankTest.java b/src/test/java/com/mybank/BankTest.java new file mode 100644 index 00000000..dc329d3b --- /dev/null +++ b/src/test/java/com/mybank/BankTest.java @@ -0,0 +1,160 @@ +package com.mybank; + +import com.mybank.Accounts.Account; +import com.mybank.Accounts.CheckingAccount; +import com.mybank.Accounts.MaxiSavingsAccount; +import com.mybank.Accounts.SavingsAccount; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; + +public class BankTest { + private static final double DOUBLE_DELTA = 1e-15; + private Bank bank; + private Customer john; + private Account checkingAccount; + private Account savingsAccount; + private Account maxiSaving; + private Exception exception; + + @Test + public void successfulCustomerSummary() { + givenBank(); + + whenCustomerOpensAccount(); + + thenCustomerIsSuccessfullyAdded(); + thenNoExceptionsAreThrown(); + } + + @Test + public void unsuccessfulCustomerSummary() { + givenBank(); + + whenCustomerUnableToOpenAccount(); + + thenExceptionsAreThrown(); + } + + @Test + public void checkingAccount() { + givenBank(); + givenCheckingAccountIsCreated(); + givenCustomerOpensAccount(checkingAccount); + + whenMoneyIsDepositedIntoChecking(); + + thenCorrectAmountOfInterest(0.1); + } + + + @Test + public void savings_account() { + givenBank(); + givenSavingAccountIsCreated(); + givenCustomerOpensAccount(savingsAccount); + + whenMoneyIsDepositedIntoSaving(); + + thenCorrectAmountOfInterest(1.0); + } + + + @Test + public void maxi_savings_accountNoWithdrawalBefore10Days() { + givenBank(); + givenMaxiSavingAccountIsCreated(); + givenCustomerOpensAccount(maxiSaving); + + whenMoneyIsDepositedIntoMaxiSaving(); + + thenCorrectAmountOfInterest(300.0); + } + + private void whenMoneyIsDepositedIntoMaxiSaving() { + maxiSaving.deposit(6000.0); + } + + @Test + public void maxi_savings_accountWithdrawalWithin10Days() { + givenBank(); + givenMaxiSavingAccountIsCreated(); + givenCustomerOpensAccount(maxiSaving); + + whenMoneyIsDepositedIntoMaxiSavingWithWithdrawal(); + + thenCorrectAmountOfInterest(2.80); + } + + //TODO: Test case for getting first customer + + private void givenBank() { + bank = new Bank(); + } + + private void givenCheckingAccountIsCreated() { + checkingAccount = new CheckingAccount(); + } + + private void givenMaxiSavingAccountIsCreated() { + maxiSaving = new MaxiSavingsAccount(); + } + + private void givenSavingAccountIsCreated() { + savingsAccount = new SavingsAccount(); + } + + private void givenCustomerOpensAccount(Account accountType) { + bank.addCustomer(new Customer("Bill").openAccount(accountType)); + } + + private void whenCustomerOpensAccount() { + try { + john = new Customer("John").openAccount(new CheckingAccount()); + bank.addCustomer(john); + } catch (Exception e) { + exception = e; + // do nothing further + } + } + + private void whenCustomerUnableToOpenAccount() { + try { + Customer john = null; + john.openAccount(new CheckingAccount()); + bank.addCustomer(john); + } catch (Exception e) { + exception = e; + // do nothing as we don't want test classes to throw exceptions + } + } + + private void whenMoneyIsDepositedIntoChecking() { + checkingAccount.deposit(100.0); + } + + private void whenMoneyIsDepositedIntoSaving() { + savingsAccount.deposit(1500.0); + } + private void whenMoneyIsDepositedIntoMaxiSavingWithWithdrawal() { + maxiSaving.deposit(3000.0); + maxiSaving.withdraw(200.0); + } + + private void thenNoExceptionsAreThrown() { + assertThat(exception).isNull(); + } + + private void thenExceptionsAreThrown() { + assertThat(exception).isNotNull(); + } + + private void thenCustomerIsSuccessfullyAdded() { + assertEquals("Customer Summary\n - John (1 account)", bank.customerSummary()); + } + + private void thenCorrectAmountOfInterest(Double interest) { + assertEquals(interest, bank.totalInterestPaid(), DOUBLE_DELTA); + } +} diff --git a/src/test/java/com/mybank/CustomerTest.java b/src/test/java/com/mybank/CustomerTest.java new file mode 100644 index 00000000..72e23cdf --- /dev/null +++ b/src/test/java/com/mybank/CustomerTest.java @@ -0,0 +1,163 @@ +package com.mybank; + +import com.mybank.Accounts.Account; +import com.mybank.Accounts.CheckingAccount; +import com.mybank.Accounts.MaxiSavingsAccount; +import com.mybank.Accounts.SavingsAccount; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; + +public class CustomerTest { + + private Account checkingAccount; + private Account savingsAccount; + private Account maxiSaving; + private Customer henry; + private Customer oscar; + private Customer layla; + + private Exception exception; + + @Test //Test customer statement generation + public void testApp() { + givenBankAccounts(); + givenAccountOpening(); + + whenTransactionsArePerformed(); + + thenStatementsAreProduced(); + } + + @Test + public void testOneAccount() { + whenOneAccountOpened(); + + thenCheckNoOfAccounts(1); + } + + @Test + public void testTwoAccount() { + whenTwoAccountsOpened(); + + thenCheckNoOfAccounts(2); + + } + + @Test + public void testThreeAccounts() { + whenThreeAccountsOpened(); + + thenCheckNoOfAccounts(3); + } + + @Test + public void testAccountTransferringFromCheckingToSaving() { + givenBankAccountsForCustomer(); + whenThreeAccountsOpenedForCustomer(); + givenDeposit(); + + whenTransferringBetweenCheckingToSaving(100.0); + + thenAmountIsSuccessfullyTransferred(); + + } + + @Test + public void testAccountTransferNotEnoughBalance() { + givenBankAccountsForCustomer(); + whenThreeAccountsOpenedForCustomer(); + givenDeposit(); + + whenTransferringBetweenCheckingToSaving(500.0); + + thenExceptionIsThrown(); + } + + private void givenDeposit() { + checkingAccount.deposit(100.0); + } + + private void givenAccountOpening() { + henry = new Customer("Henry") + .openAccount(checkingAccount) + .openAccount(savingsAccount); + } + + private void givenBankAccounts() { + checkingAccount = new CheckingAccount(); + savingsAccount = new SavingsAccount(); + } + + private void givenBankAccountsForCustomer() { + checkingAccount = new CheckingAccount(); + savingsAccount = new SavingsAccount(); + maxiSaving = new MaxiSavingsAccount(); + } + + private void whenTransferringBetweenCheckingToSaving(Double amount) { + try { + layla.transferBetweenAccounts(checkingAccount, savingsAccount, amount); + } catch (Exception e) { + exception = e; + } + } + + private void whenThreeAccountsOpenedForCustomer() { + layla = new Customer("Layla") + .openAccount(savingsAccount) + .openAccount(checkingAccount) + .openAccount(maxiSaving); + } + + private void whenTransactionsArePerformed() { + checkingAccount.deposit(100.0); + savingsAccount.deposit(4000.0); + savingsAccount.withdraw(200.0); + } + + private void whenOneAccountOpened() { + oscar = new Customer("Oscar").openAccount(new SavingsAccount()); + } + + private void whenTwoAccountsOpened() { + oscar = new Customer("Oscar") + .openAccount(new SavingsAccount()) + .openAccount(new CheckingAccount()); + } + + private void whenThreeAccountsOpened() { + oscar = new Customer("Oscar") + .openAccount(new SavingsAccount()) + .openAccount(new CheckingAccount()) + .openAccount(new MaxiSavingsAccount()); + } + + private void thenStatementsAreProduced() { + assertEquals("Statement for Henry\n" + + "\n" + + "Checking Account\n" + + " deposit $100.00\n" + + "Total $100.00\n" + + "\n" + + "Savings Account\n" + + " deposit $4,000.00\n" + + " withdrawal $200.00\n" + + "Total $3,800.00\n" + + "\n" + + "Total In All Accounts $3,900.00", henry.getStatement()); + } + + private void thenCheckNoOfAccounts(int noOfAccounts) { + assertEquals(noOfAccounts, oscar.getNumberOfAccounts()); + } + + private void thenExceptionIsThrown() { + assertThat(exception).isNotNull().isInstanceOf(IllegalArgumentException.class); + } + + private void thenAmountIsSuccessfullyTransferred() { + assertThat(savingsAccount.sumTransactions()).isEqualTo(100.0); + } +} diff --git a/src/test/java/com/mybank/TransactionTest.java b/src/test/java/com/mybank/TransactionTest.java new file mode 100644 index 00000000..ece2699f --- /dev/null +++ b/src/test/java/com/mybank/TransactionTest.java @@ -0,0 +1,26 @@ +package com.mybank; + +import com.mybank.Utlities.TransactionType; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class TransactionTest { + private Transaction transaction; + + @Test + public void transaction() { + givenTransaction(); + + thenIsInstanceOfTransaction(); + } + + private void givenTransaction() { + transaction = new Transaction(5.0, TransactionType.DEPOSIT); + } + + private void thenIsInstanceOfTransaction() { + assertNotNull(transaction); + } +}