From 4e902413ea404a0de73b205cf07b8ffc7a17a792 Mon Sep 17 00:00:00 2001 From: "ladislav.cienik" Date: Wed, 13 Sep 2023 08:56:17 +0200 Subject: [PATCH] change and implementation of new features --- pom.xml | 12 ++ src/main/java/com/abc/Account.java | 73 --------- src/main/java/com/abc/Bank.java | 50 +++--- src/main/java/com/abc/Customer.java | 75 ++++----- src/main/java/com/abc/DateProvider.java | 18 --- src/main/java/com/abc/Transaction.java | 33 +++- src/main/java/com/abc/TransactionType.java | 21 +++ src/main/java/com/abc/account/Account.java | 107 +++++++++++++ .../java/com/abc/account/CheckingAccount.java | 19 +++ .../com/abc/account/MaxiSavingsAccount.java | 37 +++++ .../java/com/abc/account/SavingsAccount.java | 35 +++++ src/test/java/com/abc/AccountTest.java | 59 +++++++ src/test/java/com/abc/BankTest.java | 146 ++++++++++++++---- src/test/java/com/abc/CustomerTest.java | 101 ++++++++---- src/test/java/com/abc/TransactionTest.java | 16 +- 15 files changed, 579 insertions(+), 223 deletions(-) delete mode 100644 src/main/java/com/abc/Account.java delete mode 100644 src/main/java/com/abc/DateProvider.java create mode 100644 src/main/java/com/abc/TransactionType.java create mode 100644 src/main/java/com/abc/account/Account.java create mode 100644 src/main/java/com/abc/account/CheckingAccount.java create mode 100644 src/main/java/com/abc/account/MaxiSavingsAccount.java create mode 100644 src/main/java/com/abc/account/SavingsAccount.java create mode 100644 src/test/java/com/abc/AccountTest.java diff --git a/pom.xml b/pom.xml index 3994d594..18b548ff 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,8 @@ UTF-8 + 16 + 16 @@ -20,5 +22,15 @@ 4.11 test + + org.apache.logging.log4j + log4j-api + 2.20.0 + + + org.apache.logging.log4j + log4j-core + 2.20.0 + 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 index 5dd535bd..674c27c7 100644 --- a/src/main/java/com/abc/Bank.java +++ b/src/main/java/com/abc/Bank.java @@ -4,43 +4,39 @@ import java.util.List; public class Bank { - private List customers; - - public Bank() { - customers = new ArrayList(); - } + private final List customers = new ArrayList<>(); + /** + * Adds a new Customer to Bank + */ public void addCustomer(Customer customer) { customers.add(customer); } - public String customerSummary() { - String summary = "Customer Summary"; + /** + * prints a report showing the list of customers and how many accounts they have + */ + public String printCustomerSummary() { + StringBuilder summary = new StringBuilder(); + summary.append("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"); + summary.append(System.lineSeparator()) + .append(" - ") + .append(c.getName()).append(" (") + .append(c.getAccounts().size()) + .append(c.getAccounts().size()==1?" account":" accounts") + .append(")"); + return summary.toString(); } - public double totalInterestPaid() { + /** + * prints a report showing the total interest paid by the bank on all accounts + */ + public double calculateTotalInterestsPaid() { double total = 0; - for(Customer c: customers) + 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"; } + return total; } } diff --git a/src/main/java/com/abc/Customer.java b/src/main/java/com/abc/Customer.java index 31571685..5b836753 100644 --- a/src/main/java/com/abc/Customer.java +++ b/src/main/java/com/abc/Customer.java @@ -1,78 +1,81 @@ package com.abc; +import com.abc.account.Account; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.util.ArrayList; import java.util.List; import static java.lang.Math.abs; public class Customer { - private String name; - private List accounts; + + private static final Logger LOG = LogManager.getLogger(Customer.class); + private final String name; + private final List accounts = new ArrayList<>(); public Customer(String name) { this.name = name; - this.accounts = new ArrayList(); } public String getName() { return name; } - public Customer openAccount(Account account) { + public List getAccounts() { + return accounts; + } + + public void openAccount(Account account) { accounts.add(account); - return this; + LOG.debug("New {} account created for customer {}", account.getType(), getName()); } - public int getNumberOfAccounts() { - return accounts.size(); + public void transfer(Account from, Account to, double amount) { + LOG.debug("Transfer of {} triggered", amount); + from.withdraw(amount); + to.deposit(amount); } public double totalInterestEarned() { double total = 0; for (Account a : accounts) - total += a.interestEarned(); + total += a.getInterestsEarned(); return total; } - public String getStatement() { - String statement = null; - statement = "Statement for " + name + "\n"; + public String printStatement() { + StringBuilder statement = new StringBuilder(); + statement.append("Statement for ").append(name).append(System.lineSeparator()); double total = 0.0; for (Account a : accounts) { - statement += "\n" + statementForAccount(a) + "\n"; - total += a.sumTransactions(); + statement.append(System.lineSeparator()).append(getStatementForAccount(a)).append(System.lineSeparator()); + total += a.calculateAccountBalance(); } - statement += "\nTotal In All Accounts " + toDollars(total); - return statement; + statement.append(System.lineSeparator()).append("Total In All Accounts ").append(toDollars(total)); + return statement.toString(); } - 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; - } + private String getStatementForAccount(Account a) { + StringBuilder str = new StringBuilder(); + str.append(a.getType()).append(" Account").append(System.lineSeparator()); //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; + for (Transaction t : a.getTransactions()) { + str.append(" ") + .append(t.getTransactionType().getType()) + .append(" ") + .append(toDollars(t.getAmount())) + .append(System.lineSeparator()); + total += t.getAmount(); } - s += "Total " + toDollars(total); - return s; + str.append("Total ").append(toDollars(total)); + return str.toString(); } - private String toDollars(double d){ + private String toDollars(double d) { return String.format("$%,.2f", abs(d)); } } diff --git a/src/main/java/com/abc/DateProvider.java b/src/main/java/com/abc/DateProvider.java deleted file mode 100644 index 035ee90b..00000000 --- a/src/main/java/com/abc/DateProvider.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.abc; - -import java.util.Calendar; -import java.util.Date; - -public class DateProvider { - private static DateProvider instance = null; - - public static DateProvider getInstance() { - if (instance == null) - instance = new DateProvider(); - return instance; - } - - public Date now() { - return Calendar.getInstance().getTime(); - } -} diff --git a/src/main/java/com/abc/Transaction.java b/src/main/java/com/abc/Transaction.java index c1f7c67e..cea1180e 100644 --- a/src/main/java/com/abc/Transaction.java +++ b/src/main/java/com/abc/Transaction.java @@ -1,16 +1,37 @@ package com.abc; -import java.util.Calendar; -import java.util.Date; +import java.time.LocalDateTime; public class Transaction { - public final double amount; + private final double amount; - private Date transactionDate; + private TransactionType transactionType; - public Transaction(double amount) { + private LocalDateTime transactionDate; + + public Transaction(double amount, TransactionType transactionType, LocalDateTime transactionDate) { this.amount = amount; - this.transactionDate = DateProvider.getInstance().now(); + this.transactionType = transactionType; + this.transactionDate = transactionDate; + } + + public double getAmount() { + return amount; + } + + public TransactionType getTransactionType() { + return transactionType; } + @SuppressWarnings("unused") + public void setTransactionType(TransactionType transactionType) { + this.transactionType = transactionType; + } + public LocalDateTime getTransactionDate() { + return transactionDate; + } + + public void setTransactionDate(LocalDateTime transactionDate) { + this.transactionDate = transactionDate; + } } diff --git a/src/main/java/com/abc/TransactionType.java b/src/main/java/com/abc/TransactionType.java new file mode 100644 index 00000000..ed0283c8 --- /dev/null +++ b/src/main/java/com/abc/TransactionType.java @@ -0,0 +1,21 @@ +package com.abc; + +/** + * Enum class that holds types of transactions + */ +public enum TransactionType { + + WITHDRAWAL("withdrawal"), + DEPOSIT("deposit"); + + private final String type; + + TransactionType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} diff --git a/src/main/java/com/abc/account/Account.java b/src/main/java/com/abc/account/Account.java new file mode 100644 index 00000000..b33f4b79 --- /dev/null +++ b/src/main/java/com/abc/account/Account.java @@ -0,0 +1,107 @@ +package com.abc.account; + +import com.abc.Transaction; +import com.abc.TransactionType; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +public abstract class Account { + + private static final Logger LOG = LogManager.getLogger(Account.class); + + private final List transactions = new ArrayList<>(); + + public abstract String getType(); + + public abstract double getRateByDate(LocalDateTime date); + + public List getTransactions() { + return transactions; + } + + /** + * Deposits money to the account with current timestamp as transaction date + */ + public void deposit(double amount) { + deposit(amount, LocalDateTime.now()); + } + + /** + * Deposits money to the account with specific transaction date + */ + public void deposit(double amount, LocalDateTime transactionDate) { + if (amount <= 0) { + LOG.error("Deposit amount must be bigger than 0."); + throw new IllegalArgumentException("amount must be greater than zero"); + } else { + transactions.add(new Transaction(amount, TransactionType.DEPOSIT, transactionDate)); + LOG.debug("Deposit transaction with amount {} created", amount); + } + } + + /** + * Withdraws money from the account with current timestamp as transaction date + */ + public void withdraw(double amount) { + withdraw(amount, LocalDateTime.now()); + } + + /** + * Withdraws money from the account with specific transaction date + */ + public void withdraw(double amount, LocalDateTime transactionDate) { + if (amount <= 0) { + LOG.error("Withdraw amount must be bigger than 0."); + throw new IllegalArgumentException("amount must be greater than zero"); + } else { + transactions.add(new Transaction(-amount, TransactionType.WITHDRAWAL, transactionDate)); + LOG.debug("Withdraw transaction with amount {} created", amount); + } + } + + /** + * Calculates earned interest of the account based on all transactions. + * The rate is used based on the account instance + */ + public double getInterestsEarned() { + Iterator tIterator = getTransactions().stream().sorted(Comparator.comparing(Transaction::getTransactionDate)).iterator(); + Transaction t = tIterator.next(); + LocalDateTime lastTransactionDate = t.getTransactionDate(); + double balanceWithInterests = t.getAmount(); + + while (tIterator.hasNext()) { + Transaction currentTransaction = tIterator.next(); + long numberOfDays = Duration.between(currentTransaction.getTransactionDate(), lastTransactionDate).toDays(); + balanceWithInterests = calculateAndAddInterestsForPeriod(balanceWithInterests, getRateByDate(currentTransaction.getTransactionDate()), numberOfDays) + currentTransaction.getAmount(); + lastTransactionDate = currentTransaction.getTransactionDate(); + } + balanceWithInterests = calculateAndAddInterestsForPeriod(balanceWithInterests, getRateByDate(LocalDateTime.now()), Duration.between(LocalDateTime.now(),lastTransactionDate).toDays()); + return balanceWithInterests - calculateAccountBalance(); + } + + /** + * Calculates the current balance of the account + * @return current balance + */ + public double calculateAccountBalance() { + double balance = 0; + for (Transaction transaction : transactions) { + balance += transaction.getAmount(); + } + return balance; + } + + /** + * calculates interests earned for period + */ + private double calculateAndAddInterestsForPeriod(double principal, double rate, long numberOfDays) { + return principal*(Math.pow(1 + (rate/ 100 / 365), 365f * (Math.abs(numberOfDays)/365f))); + } +} diff --git a/src/main/java/com/abc/account/CheckingAccount.java b/src/main/java/com/abc/account/CheckingAccount.java new file mode 100644 index 00000000..03cc27ac --- /dev/null +++ b/src/main/java/com/abc/account/CheckingAccount.java @@ -0,0 +1,19 @@ +package com.abc.account; + +import java.time.LocalDateTime; + +public class CheckingAccount extends Account { + + @Override + public String getType() { + return "Checking"; + } + + /** + * Checking account has a flat rate of 0.1 + */ + @Override + public double getRateByDate(LocalDateTime date) { + return 0.1; + } +} diff --git a/src/main/java/com/abc/account/MaxiSavingsAccount.java b/src/main/java/com/abc/account/MaxiSavingsAccount.java new file mode 100644 index 00000000..897cb861 --- /dev/null +++ b/src/main/java/com/abc/account/MaxiSavingsAccount.java @@ -0,0 +1,37 @@ +package com.abc.account; + +import com.abc.TransactionType; + +import java.time.LocalDateTime; + +public class MaxiSavingsAccount extends Account { + private static final int WITHDRAWALS_DAYS = 10; + + @Override + public String getType() { + return "Maxi Savings"; + } + + /** + * Change Maxi-Savings accounts to have an interest rate of 5% assuming no withdrawals in the past 10 days otherwise 0.1% + */ + @Override + public double getRateByDate(LocalDateTime date) { + double rate; + if (checkLastWithdrawalTransaction(date)) { + rate = 5; + } else { + rate = 0.1; + } + return rate; + } + + /** + * Checks whether there was any withdrawal transaction withing last days + */ + private boolean checkLastWithdrawalTransaction(LocalDateTime date) { + return getTransactions().stream().noneMatch(transaction -> transaction.getTransactionType().equals(TransactionType.WITHDRAWAL) + && transaction.getTransactionDate().isAfter(date.minusDays(WITHDRAWALS_DAYS))); + } + +} diff --git a/src/main/java/com/abc/account/SavingsAccount.java b/src/main/java/com/abc/account/SavingsAccount.java new file mode 100644 index 00000000..d5fd961a --- /dev/null +++ b/src/main/java/com/abc/account/SavingsAccount.java @@ -0,0 +1,35 @@ +package com.abc.account; + +import com.abc.Transaction; + +import java.time.LocalDateTime; +import java.util.Set; +import java.util.stream.Collectors; + +public class SavingsAccount extends Account { + + /** + * Savings Accounts have a rate of 0.1% for the first $1,000 then 0.2% + */ + @Override + public double getRateByDate(LocalDateTime date) { + Set relevantTransactions = getTransactions().stream().filter( + transaction -> transaction.getTransactionDate().isBefore(date)).collect(Collectors.toSet()); + double balance = 0; + double rate = 0.1; + for (Transaction t : relevantTransactions) { + balance += t.getAmount(); + if (balance>1000) { + rate = 0.2; + break; + } + } + return rate; + } + + @Override + public String getType() { + return "Savings"; + } + +} diff --git a/src/test/java/com/abc/AccountTest.java b/src/test/java/com/abc/AccountTest.java new file mode 100644 index 00000000..cdd2ae45 --- /dev/null +++ b/src/test/java/com/abc/AccountTest.java @@ -0,0 +1,59 @@ +package com.abc; + +import com.abc.account.Account; +import com.abc.account.CheckingAccount; +import com.abc.account.MaxiSavingsAccount; +import com.abc.account.SavingsAccount; +import org.junit.Test; + +import java.time.LocalDateTime; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class AccountTest { + + @Test + public void test_checkingAccountRate() { + Account a = new CheckingAccount(); + assertEquals(0.1, a.getRateByDate(LocalDateTime.now()),0); + } + + @Test + public void test_savingAccountRateDeposit1000() { + Account a = new SavingsAccount(); + a.deposit(1000); + assertEquals(0.1, a.getRateByDate(LocalDateTime.now()),0); + } + + @Test + public void test_savingAccountRateDeposit1001() { + Account a = new SavingsAccount(); + a.deposit(1001, LocalDateTime.now().minusDays(1)); + assertEquals(0.2, a.getRateByDate(LocalDateTime.now()),0); + } + + @Test + public void test_savingAccountRateNoWithdraw() { + Account a = new MaxiSavingsAccount(); + assertEquals(5, a.getRateByDate(LocalDateTime.now()),0); + } + + @Test + public void test_savingAccountRateWithdrawInCheckedPeriod() { + Account a = new MaxiSavingsAccount(); + a.withdraw(100); + assertEquals(0.1, a.getRateByDate(LocalDateTime.now()),0); + } + + @Test + public void test_savingAccountRateWithdrawNotInCheckedPeriod() { + Account a = new MaxiSavingsAccount(); + a.withdraw(100); + Optional t = a.getTransactions().stream().findAny(); + assertTrue(t.isPresent()); + t.get().setTransactionDate(LocalDateTime.now().minusDays(11)); + assertEquals(5, a.getRateByDate(LocalDateTime.now()),0); + } +} diff --git a/src/test/java/com/abc/BankTest.java b/src/test/java/com/abc/BankTest.java index f8a82896..bf049235 100644 --- a/src/test/java/com/abc/BankTest.java +++ b/src/test/java/com/abc/BankTest.java @@ -1,54 +1,144 @@ package com.abc; +import com.abc.account.CheckingAccount; +import com.abc.account.Account; +import com.abc.account.MaxiSavingsAccount; +import com.abc.account.SavingsAccount; +import org.junit.Before; import org.junit.Test; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.time.LocalDateTime; + import static org.junit.Assert.assertEquals; public class BankTest { - private static final double DOUBLE_DELTA = 1e-15; + private static final DecimalFormat decimalFormatter = new DecimalFormat("0.00"); - @Test - public void customerSummary() { - Bank bank = new Bank(); - Customer john = new Customer("John"); - john.openAccount(new Account(Account.CHECKING)); - bank.addCustomer(john); + private Customer customer; + private Bank bank; - assertEquals("Customer Summary\n - John (1 account)", bank.customerSummary()); + @Before + public void setUp() { + decimalFormatter.setRoundingMode(RoundingMode.UP); + bank = new Bank(); + customer = new Customer("Wayne"); + bank.addCustomer(customer); } @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); + public void test_customerSummaryWithOneAccount() { + customer.openAccount(new CheckingAccount()); + assertEquals("Customer Summary\r\n - John (1 account)", bank.printCustomerSummary()); + } - assertEquals(0.1, bank.totalInterestPaid(), DOUBLE_DELTA); + @Test + public void test_customerSummaryWithMoreAccounts() { + customer.openAccount(new CheckingAccount()); + customer.openAccount(new MaxiSavingsAccount()); + assertEquals("Customer Summary\r\n - John (2 accounts)", bank.printCustomerSummary()); } + /** + * to calculate test result calculator from following site was used + * ... + * with following setup + * principal - 1000 + * interest rate - 0.1% yearly + * years - 1 + * include all days of week - yes + * daily reinvest rate - 100% + * Additional contributions - none + */ @Test - public void savings_account() { - Bank bank = new Bank(); - Account checkingAccount = new Account(Account.SAVINGS); - bank.addCustomer(new Customer("Bill").openAccount(checkingAccount)); + public void test_checkingAccountSingleDeposit() { + Account checkingAccount = new CheckingAccount(); + customer.openAccount(checkingAccount); + checkingAccount.deposit(1000.0, LocalDateTime.now().minusDays(365)); + assertEquals("1.01", decimalFormatter.format(bank.calculateTotalInterestsPaid())); + } - checkingAccount.deposit(1500.0); + /** + * to calculate test result calculator from following site was used + * ... + * with following setup + * principal - 1000 + * interest rate - 0.1% yearly + * years - 1 + * include all days of week - yes + * daily reinvest rate - 100% + * Additional contributions - yes + * One-time additional deposit - 2000 03/16/2023 + * Start date 09/12/2022 + */ + @Test + public void test_checkingAccountTwoDeposits() { + Account checkingAccount = new CheckingAccount(); + customer.openAccount(checkingAccount); + checkingAccount.deposit(2000.0, LocalDateTime.now().minusDays(180)); + checkingAccount.deposit(1000.0, LocalDateTime.now().minusDays(365)); + assertEquals("1.99", decimalFormatter.format(bank.calculateTotalInterestsPaid())); + } - assertEquals(2.0, bank.totalInterestPaid(), DOUBLE_DELTA); + /** + * to calculate test result calculator from following site was used + * ... + * with following setup + * principal - 2000 + * interest rate - 0.2% yearly + * years - 1 + * include all days of week - yes + * daily reinvest rate - 100% + * Additional contributions - none + */ + @Test + public void test_savingAccountSingleDeposit() { + Account saving = new SavingsAccount(); + customer.openAccount(saving); + saving.deposit(2000.0,LocalDateTime.now().minusYears(1)); + assertEquals("4.01", decimalFormatter.format(bank.calculateTotalInterestsPaid())); } @Test - public void maxi_savings_account() { - Bank bank = new Bank(); - Account checkingAccount = new Account(Account.MAXI_SAVINGS); - bank.addCustomer(new Customer("Bill").openAccount(checkingAccount)); + public void test_savingAccountTwoDeposit() { + Account saving = new SavingsAccount(); + customer.openAccount(saving); + saving.deposit(1000,LocalDateTime.now().minusDays(180)); + saving.deposit(1000,LocalDateTime.now().minusDays(365)); + assertEquals("2.49", decimalFormatter.format(bank.calculateTotalInterestsPaid())); + } + /** + * to calculate test result calculator from following site was used + * ... + * with following setup + * principal - 1000 + * interest rate - 5% yearly + * years - 1 + * include all days of week - yes + * daily reinvest rate - 100% + * Additional contributions - none + */ + @Test + public void test_maxiSavingAccount() { + Account saving = new MaxiSavingsAccount(); + customer.openAccount(saving); + saving.deposit(1000,LocalDateTime.now().minusDays(365)); + assertEquals("51.27", decimalFormatter.format(bank.calculateTotalInterestsPaid())); + } - checkingAccount.deposit(3000.0); + @Test + public void test_multipleCustomersWithAccount() { + Account checkingAccount = new CheckingAccount(); + customer.openAccount(checkingAccount); + checkingAccount.deposit(1000.0, LocalDateTime.now().minusDays(365)); - assertEquals(170.0, bank.totalInterestPaid(), DOUBLE_DELTA); + Customer secondCustomer = new Customer("Rooney"); + Account savingsAccount = new SavingsAccount(); + savingsAccount.deposit(2000.0,LocalDateTime.now().minusDays(365)); + secondCustomer.openAccount(savingsAccount); + bank.addCustomer(secondCustomer); + assertEquals("5.01", decimalFormatter.format(bank.calculateTotalInterestsPaid())); } } diff --git a/src/test/java/com/abc/CustomerTest.java b/src/test/java/com/abc/CustomerTest.java index b8df9498..e1b6ba5f 100644 --- a/src/test/java/com/abc/CustomerTest.java +++ b/src/test/java/com/abc/CustomerTest.java @@ -1,57 +1,94 @@ package com.abc; -import org.junit.Ignore; +import com.abc.account.Account; +import com.abc.account.CheckingAccount; +import com.abc.account.MaxiSavingsAccount; +import com.abc.account.SavingsAccount; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class CustomerTest { - @Test //Test customer statement generation - public void testApp(){ + /** + * Tests customer statement + */ + @Test + public void test_customerStatement(){ - Account checkingAccount = new Account(Account.CHECKING); - Account savingsAccount = new Account(Account.SAVINGS); + Account checkingAccount = new CheckingAccount(); + Account savingsAccount = new SavingsAccount(); - Customer henry = new Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount); + Customer henry = new Customer("Henry"); + henry.openAccount(checkingAccount); + henry.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()); + assertEquals("Statement for Henry" + System.lineSeparator() + System.lineSeparator() + + "Checking Account" + System.lineSeparator() + + " deposit $100.00" + System.lineSeparator() + + "Total $100.00" + System.lineSeparator() + System.lineSeparator() + + "Savings Account" + System.lineSeparator() + + " deposit $4,000.00" + System.lineSeparator() + + " withdrawal $200.00" + System.lineSeparator() + + "Total $3,800.00" + System.lineSeparator() + System.lineSeparator() + + "Total In All Accounts $3,900.00", henry.printStatement()); } @Test - public void testOneAccount(){ - Customer oscar = new Customer("Oscar").openAccount(new Account(Account.SAVINGS)); - assertEquals(1, oscar.getNumberOfAccounts()); + public void test_oneAccountInstance(){ + Customer oscar = new Customer("Oscar"); + oscar.openAccount(new SavingsAccount()); + assertEquals(1, oscar.getAccounts().size()); + assertTrue(oscar.getAccounts().stream().anyMatch(account -> account instanceof SavingsAccount)); } @Test - public void testTwoAccount(){ - Customer oscar = new Customer("Oscar") - .openAccount(new Account(Account.SAVINGS)); - oscar.openAccount(new Account(Account.CHECKING)); - assertEquals(2, oscar.getNumberOfAccounts()); + public void test_moreAccountsInstances() { + Customer oscar = new Customer("Oscar"); + oscar.openAccount(new SavingsAccount()); + oscar.openAccount(new CheckingAccount()); + oscar.openAccount(new MaxiSavingsAccount()); + assertEquals(3, oscar.getAccounts().size()); + assertTrue(oscar.getAccounts().stream().anyMatch(account -> account instanceof SavingsAccount)); + assertTrue(oscar.getAccounts().stream().anyMatch(account -> account instanceof CheckingAccount)); + assertTrue(oscar.getAccounts().stream().anyMatch(account -> account instanceof MaxiSavingsAccount)); } - @Ignore - public void testThreeAcounts() { - Customer oscar = new Customer("Oscar") - .openAccount(new Account(Account.SAVINGS)); - oscar.openAccount(new Account(Account.CHECKING)); - assertEquals(3, oscar.getNumberOfAccounts()); + /** + * Test transfer from one account to another + * Customer has 3 accounts, one from which the amount is withdrawn, + * one to which the amount is deposited + * and one account to check that it was not modified by transfer + */ + @Test + public void test_transfer() { + double fromInitialDeposit = 1000; + double toInitialDeposit = 1500; + double neutralInitialDeposit = 50; + double transferAmount = 500; + + Account from = new CheckingAccount(); + from.deposit(fromInitialDeposit); + + Account to = new CheckingAccount(); + to.deposit(toInitialDeposit); + + Account neutralAccount = new CheckingAccount(); + neutralAccount.deposit(neutralInitialDeposit); + + Customer bruce = new Customer("Bruce"); + bruce.openAccount(from); + bruce.openAccount(neutralAccount); + bruce.openAccount(to); + bruce.transfer(from,to,transferAmount); + + assertEquals(fromInitialDeposit - transferAmount, from.calculateAccountBalance(), 0); + assertEquals(toInitialDeposit + transferAmount, to.calculateAccountBalance(), 0); + assertEquals(neutralInitialDeposit, neutralAccount.calculateAccountBalance(), 0); } } diff --git a/src/test/java/com/abc/TransactionTest.java b/src/test/java/com/abc/TransactionTest.java index 28983234..fffc91b6 100644 --- a/src/test/java/com/abc/TransactionTest.java +++ b/src/test/java/com/abc/TransactionTest.java @@ -1,13 +1,23 @@ package com.abc; +import com.abc.account.Account; +import com.abc.account.CheckingAccount; import org.junit.Test; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class TransactionTest { @Test - public void transaction() { - Transaction t = new Transaction(5); - assertTrue(t instanceof Transaction); + public void test_TransactionCreation() { + Account a = new CheckingAccount(); + a.deposit(10); + Optional t = a.getTransactions().stream().findAny(); + assertTrue(t.isPresent()); + assertEquals(1, a.getTransactions().size()); + assertEquals(TransactionType.DEPOSIT.getType(),t.get().getTransactionType().getType()); } + }