diff --git a/.gitignore b/.gitignore index 3c8b8dd5..1b3916ee 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,15 @@ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff +target/ +.idea/ .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf +.idea/misc.xml +.idea/SoftwareEngineeringPractice.iml # Generated files .idea/**/contentModel.xml @@ -93,4 +97,6 @@ Icon .AppleDesktop Network Trash Folder Temporary Items -.apdisk \ No newline at end of file +.apdisk + +SoftwareEngineeringPracticeBank.iml \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 28c6362f..00000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index b26911bd..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index d87af9ac..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/sbt.xml b/.idea/sbt.xml deleted file mode 100644 index 20187435..00000000 --- a/.idea/sbt.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/SoftwareEngineeringPractice.iml b/SoftwareEngineeringPractice.iml index 78b2cc53..53139ab2 100644 --- a/SoftwareEngineeringPractice.iml +++ b/SoftwareEngineeringPractice.iml @@ -1,2 +1,26 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/edu/ithaca/dragon/bank/AdminAPI.java b/src/main/java/edu/ithaca/dragon/bank/AdminAPI.java new file mode 100644 index 00000000..b11e2b4e --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/AdminAPI.java @@ -0,0 +1,15 @@ +package edu.ithaca.dragon.bank; + +import java.util.Collection; + +public interface AdminAPI { + + public double calcTotalAssets(); + + public Collection findAcctIdsWithSuspiciousActivity(); + + public void freezeAccount(String acctId); + + public void unfreezeAcct(String acctId); + +} diff --git a/src/main/java/edu/ithaca/dragon/bank/AdvancedAPI.java b/src/main/java/edu/ithaca/dragon/bank/AdvancedAPI.java new file mode 100644 index 00000000..da47d756 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/AdvancedAPI.java @@ -0,0 +1,10 @@ +package edu.ithaca.dragon.bank; + +//API to be used by Teller systems +public interface AdvancedAPI extends BasicAPI { + + + public void createAccount(String acctId, String email, String password, double startingBalance); + + public void closeAccount(String acctId); +} diff --git a/src/main/java/edu/ithaca/dragon/bank/BankAccount.java b/src/main/java/edu/ithaca/dragon/bank/BankAccount.java index e340e0ea..7c2a19dc 100644 --- a/src/main/java/edu/ithaca/dragon/bank/BankAccount.java +++ b/src/main/java/edu/ithaca/dragon/bank/BankAccount.java @@ -1,17 +1,34 @@ package edu.ithaca.dragon.bank; +import java.util.regex.Pattern; + public class BankAccount { private String email; private double balance; + private String password; + private String acctId; + + + + public BankAccount(String email, double startingBalance) { + this("", email, "", startingBalance); + } /** * @throws IllegalArgumentException if email is invalid */ - public BankAccount(String email, double startingBalance){ + public BankAccount(String acctId, String email, String password, double startingBalance){ if (isEmailValid(email)){ - this.email = email; - this.balance = startingBalance; + if(isAmountValid(startingBalance)){ + this.acctId = acctId; + this.email = email; + this.balance = startingBalance; + this.password = password; + } + else{ + throw new IllegalArgumentException("starting Balance of " + startingBalance + "is an invalid amount to add"); + } } else { throw new IllegalArgumentException("Email address: " + email + " is invalid, cannot create account"); @@ -28,19 +45,67 @@ public String getEmail(){ /** * @post reduces the balance by amount if amount is non-negative and smaller than balance + * throws InsufficientFundsException if the amount is larger than the balance + * If balance is negative or has more than 2 decimal places, throws IllegalArgumentException */ - public void withdraw (double amount) { - balance -= amount; + public void withdraw (double amount) throws InsufficientFundsException, IllegalArgumentException { + if(!isAmountValid(amount)){ + throw new IllegalArgumentException("Amount must have 2 decimal places and must be positive "); + } + if (balance >= amount && amount >= 0) { + balance -= amount; + } + else{ + throw new InsufficientFundsException("Amount requested is more than in your account by " + (amount - balance)); + } } - - public static boolean isEmailValid(String email){ - if (email.indexOf('@') == -1){ - return false; + /** + * @post adds to the balance by amount if amount is non-negative and has 2 or less decimal places + * @throws IllegalArgumentException if amount is negative or has more than 2 decimal places + */ + public void deposit(double amount) throws IllegalArgumentException{ + if(!isAmountValid(amount)){ + throw new IllegalArgumentException("Amount must have 2 or less decimal places and must be positive"); } - else { - return true; + balance += amount; + } + + /** + * @post transfers funds from one bank account to the one passed in, as long as amount is non-negative and has 2 or less decimal places + * @throws IllegalArgumentException if amount is negative or has more than 2 decimal places, or if bankAccount to transfer to is the current one + * @throws InsufficientFundsException if amount is larger than current bank account balance + */ + public void transfer(double amount, BankAccount toTransfer) throws InsufficientFundsException, IllegalArgumentException{ + if(!isAmountValid(amount) || toTransfer == this){ + throw new IllegalArgumentException("Amount must be positive, have 2 decimals or less, and transfer to a new bank account"); + } + this.withdraw(amount); + toTransfer.deposit(amount); + } + + /** + * @post checks to see if a double is a valid input to be withdrawn + * Returns false if double has more than 2 decimal places, or is negative + */ + public static boolean isAmountValid(double amount){ + double positiveRoundOff = Math.abs(Math.round(amount * 100.0) / 100.0); + if(amount != positiveRoundOff){ + + String doubleCheck = Double.toString(Math.abs(amount)); + int integerPlaces = doubleCheck.indexOf('.'); + int decimalPlaces = doubleCheck.length() - integerPlaces - 1; + return (decimalPlaces <= 2 || doubleCheck.indexOf('E') != -1) && !(amount < 0); } + return true; + } + + public static boolean isEmailValid(String email){ + return email.matches("(\\w)+((_|\\.|-)+\\w+)*@(\\w)+((-)?\\w+)*\\.\\w{2,}$"); + } + + public String getPassword() { + return password; } } diff --git a/src/main/java/edu/ithaca/dragon/bank/BasicAPI.java b/src/main/java/edu/ithaca/dragon/bank/BasicAPI.java new file mode 100644 index 00000000..bde440c0 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/BasicAPI.java @@ -0,0 +1,20 @@ +package edu.ithaca.dragon.bank; + +//API to be used by ATMs +public interface BasicAPI { + + boolean confirmCredentials(String acctId, String password); + + double checkBalance(String acctId); + + void withdraw(String acctId, double amount) throws InsufficientFundsException; + + void deposit(String acctId, double amount); + + void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws InsufficientFundsException; + + String transactionHistory(String acctId); + + + +} diff --git a/src/main/java/edu/ithaca/dragon/bank/CentralBank.java b/src/main/java/edu/ithaca/dragon/bank/CentralBank.java new file mode 100644 index 00000000..9798908d --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/CentralBank.java @@ -0,0 +1,119 @@ +package edu.ithaca.dragon.bank; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class CentralBank implements AdvancedAPI, AdminAPI { + + //----------------- BasicAPI methods -------------------------// + + + public MapaccountMap = new HashMap<>(); + + + + + + public boolean confirmCredentials(String acctId, String password){ + + if(accountMap.containsKey(acctId)){ + return accountMap.get(acctId).getPassword().equals(password); + } + + + + return false; + } + + + public double checkBalance(String acctId) throws IllegalArgumentException { + if(!accountMap.containsKey(acctId)){ + throw new IllegalArgumentException("Account does not exist with name: " + acctId); + } + return accountMap.get(acctId).getBalance(); + } + + public void withdraw(String acctId, double amount) throws InsufficientFundsException, IllegalArgumentException { + if(!accountMap.containsKey(acctId)){ + throw new IllegalArgumentException("Account does not exist with name: " + acctId); + } + + accountMap.get(acctId).withdraw(amount); + } + + + public void deposit(String acctId, double amount) throws IllegalArgumentException { + if(!accountMap.containsKey(acctId)){ + throw new IllegalArgumentException("Account does not exist with ID" + acctId); + } + + accountMap.get(acctId).deposit(amount); + + + } + + public void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws IllegalArgumentException, InsufficientFundsException { + if(!accountMap.containsKey(acctIdToWithdrawFrom) || !accountMap.containsKey(acctIdToDepositTo) || acctIdToWithdrawFrom.equals(acctIdToDepositTo)){ + throw new IllegalArgumentException("Account does not exist with IDs given"); + + } + + if(accountMap.get(acctIdToWithdrawFrom).getBalance() < amount){ + throw new InsufficientFundsException("Account does not have enough money"); + } + + + accountMap.get(acctIdToWithdrawFrom).withdraw(amount); + accountMap.get(acctIdToDepositTo).deposit(amount); + + + + } + + public String transactionHistory(String acctId) { + return null; + } + + + //----------------- AdvancedAPI methods -------------------------// + + + public void createAccount(String acctId, String email, String password, double startingBalance) { + BankAccount account = new BankAccount(acctId, email, password, startingBalance); + accountMap.put(acctId, account); + + } + + + + + public void closeAccount(String acctId) { + accountMap.remove(acctId); + + + + + + } + + + //------------------ AdminAPI methods -------------------------// + + public double calcTotalAssets() { + return 0; + } + + public Collection findAcctIdsWithSuspiciousActivity() { + return null; + } + + public void freezeAccount(String acctId) { + + } + + public void unfreezeAcct(String acctId) { + + } + +} diff --git a/src/main/java/edu/ithaca/dragon/bank/CheckingAccount.java b/src/main/java/edu/ithaca/dragon/bank/CheckingAccount.java new file mode 100644 index 00000000..8c494bb0 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/CheckingAccount.java @@ -0,0 +1,10 @@ +package edu.ithaca.dragon.bank; + +public class CheckingAccount extends BankAccount { + /** + * @throws IllegalArgumentException if email is invalid + */ + public CheckingAccount(String email, double startingBalance) { + super(email, startingBalance); + } +} diff --git a/src/main/java/edu/ithaca/dragon/bank/SavingsAccount.java b/src/main/java/edu/ithaca/dragon/bank/SavingsAccount.java new file mode 100644 index 00000000..a2c39017 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/SavingsAccount.java @@ -0,0 +1,44 @@ +package edu.ithaca.dragon.bank; + +public class SavingsAccount extends BankAccount { + private double interest; + private double withdrawLimit; + /** + + * @throws IllegalArgumentException if email is invalid + */ + public SavingsAccount(String email, double startingBalance, double interest, double withdrawLimit) throws IllegalArgumentException { + super(email, startingBalance); + if(interest < 0 || withdrawLimit <= 0){ + throw new IllegalArgumentException("Interest must be at least 0% and you must be able to withdraw from the account"); + } + this.interest = interest / 100; + this.withdrawLimit = withdrawLimit; + } + + /** + * Compounds interest of the day and adds it to balance + */ + public void compoundInterest(){ + double compounded = interest * this.getBalance(); + this.deposit(compounded); + } + + /** + * @post reduces the balance by amount if amount is non-negative and smaller than balance + * throws InsufficientFundsException if the amount is larger than the balance + * If balance is negative or has more than 2 decimal places, throws IllegalArgumentException + * If amount to withdraw is more than withdraw limit, it throws an InsufficientFundsException + */ + @Override + public void withdraw (double amount) throws InsufficientFundsException, IllegalArgumentException { + + if(withdrawLimit - amount < 0) + { + throw new IllegalArgumentException("Cannot withdraw more than the daily limit"); + } + + super.withdraw(amount); + withdrawLimit -= amount; + } +} diff --git a/src/test/java/edu/ithaca/dragon/bank/AdminAPITest.java b/src/test/java/edu/ithaca/dragon/bank/AdminAPITest.java new file mode 100644 index 00000000..87769bfc --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/AdminAPITest.java @@ -0,0 +1,13 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class AdminAPITest { + + + + + + +} diff --git a/src/test/java/edu/ithaca/dragon/bank/AdvancedAPITest.java b/src/test/java/edu/ithaca/dragon/bank/AdvancedAPITest.java new file mode 100644 index 00000000..2fdbb24f --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/AdvancedAPITest.java @@ -0,0 +1,43 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class AdvancedAPITest { + + @Test + void createAccountTest(){ + CentralBank bankAccount = new CentralBank(); + bankAccount.createAccount("1245", "a1@hello.com", "testpassword", 500); + assertNull( bankAccount.accountMap.get("12466")); + assertEquals(500, bankAccount.accountMap.get("1245").getBalance()); + assertEquals("a1@hello.com", bankAccount.accountMap.get("1245").getEmail()); + assertEquals("testpassword", bankAccount.accountMap.get("1245").getPassword()); + + CentralBank bankAccount2 = new CentralBank(); + bankAccount2.createAccount("BH8525", "atest3@gmail.com", "funny", 1000); + assertNull(bankAccount2.accountMap.get("BH85425")); + assertEquals(1000, bankAccount2.accountMap.get("BH8525").getBalance()); + assertEquals("atest3@gmail.com", bankAccount2.accountMap.get("BH8525").getEmail()); + assertEquals("funny", bankAccount2.accountMap.get("BH8525").getPassword()); + + } + + + @Test + void closeAccountTest() { + CentralBank bankAccount = new CentralBank(); + bankAccount.createAccount("1245", "a1@hello.com", "testpassword", 500); + assertEquals("a1@hello.com", bankAccount.accountMap.get("1245").getEmail()); + bankAccount.closeAccount("1245"); + assertNull(bankAccount.accountMap.get("1245")); + + CentralBank bankAccount2 = new CentralBank(); + bankAccount2.createAccount("BH8525", "atest3@gmail.com", "funny", 1000); + assertEquals("atest3@gmail.com", bankAccount2.accountMap.get("BH8525").getEmail()); + bankAccount2.closeAccount("BH8525"); + assertNull(bankAccount2.accountMap.get("BH8525")); + + } + +} diff --git a/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java b/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java index d19ecb02..86cd25d8 100644 --- a/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java +++ b/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java @@ -1,30 +1,111 @@ package edu.ithaca.dragon.bank; import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.*; class BankAccountTest { + @Test - void getBalanceTest() { - BankAccount bankAccount = new BankAccount("a@b.com", 200); + void getBalanceTest() throws InsufficientFundsException, IllegalArgumentException { + //classes - fresh account, after withdrawal, after unsuccessful withdrawal + BankAccount bankAccount = new BankAccount("a@b.com", 1000); - assertEquals(200, bankAccount.getBalance()); + //fresh account + assertEquals(1000, bankAccount.getBalance()); //equivalence class starting balance and not border cas + //after withdrawal + bankAccount.withdraw(100); + assertEquals(900, bankAccount.getBalance()); //equivalence class of less than and not border case + bankAccount.withdraw(500); + assertEquals(400, bankAccount.getBalance()); //equivalence class of more than and not border case + bankAccount.withdraw(400); + assertEquals(0, bankAccount.getBalance()); //equivalence class of zero and border case + + //after unsuccessful withdrawal + BankAccount unsuccessful = new BankAccount("a@b.com",1000); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(1100)); //equivalence class of greater than and border case + assertEquals(1000, unsuccessful.getBalance()); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(2000)); //equivalence class of middle value and not border case + assertEquals(1000, unsuccessful.getBalance()); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(Integer.MAX_VALUE)); //equivalence class of Max Value and border case + assertEquals(1000, unsuccessful.getBalance()); } @Test - void withdrawTest() { - BankAccount bankAccount = new BankAccount("a@b.com", 200); + void withdrawTest() throws InsufficientFundsException, IllegalArgumentException{ + //classes - sufficient funds, insufficient funds, negative funds + BankAccount bankAccount = new BankAccount("a@b.com", 1000); + //sufficient funds + bankAccount.withdraw(0); + assertEquals(1000, bankAccount.getBalance()); bankAccount.withdraw(100); + assertEquals(900, bankAccount.getBalance()); //equivalence class of less than and not border case + bankAccount.withdraw(500); + assertEquals(400, bankAccount.getBalance()); //equivalence class of more than and not border case + bankAccount.withdraw(400); + assertEquals(0, bankAccount.getBalance()); //equivalence class of zero and border case + //insufficient funds + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(300)); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(max)); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw(1)); + //negative numbers + BankAccount negative = new BankAccount("a@b.com", 1000); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(-100)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(-500)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and not border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(min)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + //numbers with more than 2 decimals + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(300.001)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(1000.04940)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and not border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(50.1029384958674950)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + //negative numbers with more than 2 decimals + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(-100.001)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(-100.10239485)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and not border case + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw(-100.1029384758493815)); + assertEquals(1000, negative.getBalance()); //equivalence class of negative balance and border case + + + - assertEquals(100, bankAccount.getBalance()); } @Test void isEmailValidTest(){ - assertTrue(BankAccount.isEmailValid( "a@b.com")); - assertFalse( BankAccount.isEmailValid("")); + //one @ symbol class + assertTrue(BankAccount.isEmailValid( "a.b.c@b.com")); //equivalence class of one @ and not border case + assertFalse(BankAccount.isEmailValid("abc@def@mail.com")); //equivalence class of multiple @ and border case + assertFalse(BankAccount.isEmailValid("abc@d@ef@mail.com")); //equivalence class of multiple @ and border case + assertFalse(BankAccount.isEmailValid("abc@d@ef@ma@il.com")); //equivalence class of multiple @ and border case + assertFalse( BankAccount.isEmailValid("")); //equivalence class of one no @ and border case + //valid special characters in prefix + assertFalse(BankAccount.isEmailValid("abc-@mail.com")); //equivalence class of one valid special characters and not border case + assertFalse(BankAccount.isEmailValid("abc..@mail.com")); //equivalence class of two valid special characters and not border case + assertFalse(BankAccount.isEmailValid(".abc@mail.com")); //equivalence class of valid special characters and not border case + //invalid characters in prefix + assertFalse(BankAccount.isEmailValid("abc#def@mail.com")); //equivalence class of one invalid characters and border case + assertFalse(BankAccount.isEmailValid("abc#de!f@mail.com")); //equivalence class of two invalid characters and border case + assertTrue(BankAccount.isEmailValid("abc.def@mail.com")); //equivalence class of one invalid characters and not border case + //invalid suffix characters + assertFalse(BankAccount.isEmailValid("abc.def@mail#archive.com")); //equivalence class of invalid suffix characters and border case + assertFalse(BankAccount.isEmailValid("abc.def@mail!ar%chive.com")); //equivalence class of invalid suffix characters and border case + assertFalse(BankAccount.isEmailValid("abc.def@mail!ar%chi.ve.com")); //equivalence class of invalid suffix characters and border case + assertFalse(BankAccount.isEmailValid("abc.def@mail--archive.com")); //equivalence class of invalid suffix characters and border case + assertFalse(BankAccount.isEmailValid("abc.def@mail-arc!h.ive.com")); //equivalence class of invalid suffix characters and border case + //valid domain + assertFalse(BankAccount.isEmailValid("abc.def@mail.c")); //equivalence class of invalid domain and not border case + assertFalse(BankAccount.isEmailValid("abc.def@mail")); //equivalence class of no domain and border case + assertFalse(BankAccount.isEmailValid("abc.def@mail..com")); //equivalence class of two . in domain and border case + assertTrue(BankAccount.isEmailValid("abc.def@mail.cc")); //equivalence class of invalid domain and not border case + } @Test @@ -33,8 +114,228 @@ void constructorTest() { assertEquals("a@b.com", bankAccount.getEmail()); assertEquals(200, bankAccount.getBalance()); - //check for exception thrown correctly + //check for exception thrown correctly for email assertThrows(IllegalArgumentException.class, ()-> new BankAccount("", 100)); + //checks if it throws an argument for negative numbers + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -1)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -150)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -10000000)); + //checks if it throws an argument for numbers with more than 2 decimal places + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", 100.001)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", 150.01020495)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -123.1029384758495837)); + //checks if it throws an argument for numbers that are negative and have more than 2 decimal places + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -1.001)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -120.123453)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@b.com", -100.102938456744854)); } + @Test + void isAmountValidTest(){ + //valid number, no decimals + assertTrue(BankAccount.isAmountValid(0)); + assertTrue(BankAccount.isAmountValid(1)); + assertTrue(BankAccount.isAmountValid(500)); + assertTrue(BankAccount.isAmountValid(678)); + assertTrue(BankAccount.isAmountValid(Integer.MAX_VALUE)); + //valid number, 1 decimal + assertTrue(BankAccount.isAmountValid(500.0)); + assertTrue(BankAccount.isAmountValid(500.1)); + assertTrue(BankAccount.isAmountValid(500.5)); + assertTrue(BankAccount.isAmountValid(500.9)); + //valid number, 2 decimals + assertTrue(BankAccount.isAmountValid(500.00)); + assertTrue(BankAccount.isAmountValid(500.01)); + assertTrue(BankAccount.isAmountValid(500.10)); + assertTrue(BankAccount.isAmountValid(500.62)); + assertTrue(BankAccount.isAmountValid(500.99)); + //invalid number, more than 2 decimals + assertTrue(BankAccount.isAmountValid(500.00000000)); + assertFalse(BankAccount.isAmountValid(500.001)); + assertFalse(BankAccount.isAmountValid(500.597)); + assertFalse(BankAccount.isAmountValid(500.56690930452)); + assertFalse(BankAccount.isAmountValid(500.999)); + assertFalse(BankAccount.isAmountValid(500.2048675849586746)); + //invalid number, negative with 0 decimals + assertFalse(BankAccount.isAmountValid(-1)); + assertFalse(BankAccount.isAmountValid(-100)); + assertFalse(BankAccount.isAmountValid(Integer.MIN_VALUE)); + //invalid number, negative with 1 decimal + assertFalse(BankAccount.isAmountValid(-1.0)); + assertFalse(BankAccount.isAmountValid(-100.7)); + assertFalse(BankAccount.isAmountValid(-999999.9)); + //invalid number, negative with 2 decimals + assertFalse(BankAccount.isAmountValid(-1.00)); + assertFalse(BankAccount.isAmountValid(-100.59)); + assertFalse(BankAccount.isAmountValid(-999999999999.99)); + //invalid number, negative with more than 2 decimals + assertFalse(BankAccount.isAmountValid(-100.001)); + assertFalse(BankAccount.isAmountValid(-100.5689)); + assertFalse(BankAccount.isAmountValid(-100.5784939576859)); + assertFalse(BankAccount.isAmountValid(-999.9999999999999999)); + + } + + @Test + void depositTest(){ + BankAccount bankAccount = new BankAccount("a@b.com", 1000); + //deposit valid integer + bankAccount.deposit(1); + assertEquals(1001, bankAccount.getBalance()); + bankAccount.deposit(100); + assertEquals(1101, bankAccount.getBalance()); + bankAccount.deposit(10000); + assertEquals(11101, bankAccount.getBalance()); + //deposit valid double with < 1 decimal + bankAccount.deposit(1.1); + assertEquals(11102.1, bankAccount.getBalance()); + bankAccount.deposit(10.5); + assertEquals(11112.6, bankAccount.getBalance()); + bankAccount.deposit(10.9); + assertEquals(11123.5, bankAccount.getBalance()); + //deposit valid with 2 decimals + bankAccount.deposit(1.00); + assertEquals(11124.50, bankAccount.getBalance()); + bankAccount.deposit(1.11); + assertEquals(11125.61, bankAccount.getBalance()); + bankAccount.deposit(1.57); + assertEquals(11127.18, bankAccount.getBalance()); + bankAccount.deposit(1.99); + assertEquals(11129.17, bankAccount.getBalance()); + //invalid number, negative + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-500)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(Integer.MIN_VALUE)); + assertEquals(11129.17, bankAccount.getBalance()); + //invalid number, negative, one decimal + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.1)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.5)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.9)); + assertEquals(11129.17, bankAccount.getBalance()); + //invalid number, negative, 2 decimals + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.00)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.57)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.99)); + assertEquals(11129.17, bankAccount.getBalance()); + //invalid number, more than 2 decimals + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(1.001)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.585976)); + assertEquals(11129.17, bankAccount.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(50.102938475960794)); + assertEquals(11129.17, bankAccount.getBalance()); + + + } + + @Test + void transferTest() throws InsufficientFundsException,IllegalArgumentException{ + BankAccount bankAccount1 = new BankAccount("a@b.com", 1000); + BankAccount bankAccount2 = new BankAccount("b@a.com", 0); + //checking initial balances + assertEquals(1000, bankAccount1.getBalance()); + assertEquals(0, bankAccount2.getBalance()); + //transfer from 1 to 2, integers, valid amount + bankAccount1.transfer(1, bankAccount2); + assertEquals(999, bankAccount1.getBalance()); + assertEquals(1, bankAccount2.getBalance()); + bankAccount1.transfer(99, bankAccount2); + assertEquals(900, bankAccount1.getBalance()); + assertEquals(100, bankAccount2.getBalance()); + bankAccount1.transfer(900, bankAccount2); + assertEquals(0, bankAccount1.getBalance()); + assertEquals(1000, bankAccount2.getBalance()); + //transfer from 2 to 1, 1 decimal, valid amount + bankAccount2.transfer(0.1, bankAccount1); + assertEquals(0.1, bankAccount1.getBalance()); + assertEquals(999.9, bankAccount2.getBalance()); + bankAccount2.transfer(99.5, bankAccount1); + assertEquals(99.6, bankAccount1.getBalance()); + assertEquals(900.4, bankAccount2.getBalance()); + //transfer from 2 to 1, 2 decimals, valid amount + bankAccount2.transfer(50.41, bankAccount1); + assertEquals(150.01, bankAccount1.getBalance()); + assertEquals(849.99, bankAccount2.getBalance()); + bankAccount2.transfer(50.11, bankAccount1); + assertEquals(200.12, bankAccount1.getBalance()); + assertEquals(799.88, bankAccount2.getBalance()); + bankAccount2.transfer(50.99, bankAccount1); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + //invalid transfer, same bank + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(50, bankAccount1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount2.transfer(50, bankAccount2)); + //invalid transfer, negative numbers + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(-1, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(-50.8, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(-500.99, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + //invalid transfer, 3 or more decimals + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(50.001, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(50.9484930, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + assertThrows(IllegalArgumentException.class, ()-> bankAccount1.transfer(-50.102938495869503, bankAccount2)); + assertEquals(251.11, bankAccount1.getBalance()); + assertEquals(748.89, bankAccount2.getBalance()); + //invalid transfer, insufficient funds + bankAccount1.transfer(251.11, bankAccount2); + + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.transfer(1, bankAccount2)); + assertEquals(0, bankAccount1.getBalance()); + assertEquals(1000, bankAccount2.getBalance()); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.transfer(246, bankAccount2)); + assertEquals(0, bankAccount1.getBalance()); + assertEquals(1000, bankAccount2.getBalance()); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.transfer(Integer.MAX_VALUE, bankAccount2)); + assertEquals(0, bankAccount1.getBalance()); + assertEquals(1000, bankAccount2.getBalance()); + + } + + @Test + void SavingsAccountTest() throws IllegalArgumentException, InsufficientFundsException{ + //constructor test + SavingsAccount savingsAccount = new SavingsAccount("a@b.com", 1000, 5, 500); + + //invalid interest + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, -0.1, 500)); + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, -50.6, 500)); + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, -150.6, 500)); + + //invalid maxWithdraw + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, 5.0, 0)); + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, 5.0, -1)); + assertThrows(IllegalArgumentException.class, ()-> new SavingsAccount("a@b.com", 1000, 5.0, -500.495)); + + //Compound interest + savingsAccount.compoundInterest(); + assertEquals(1050, savingsAccount.getBalance()); + savingsAccount.compoundInterest(); + assertEquals(1102.5, savingsAccount.getBalance()); + + //Overridden Withdraw + savingsAccount.withdraw(102.5); + assertEquals(1000, savingsAccount.getBalance()); + + assertThrows(IllegalArgumentException.class, () -> savingsAccount.withdraw(501)); + assertThrows(IllegalArgumentException.class, () -> savingsAccount.withdraw(750.59)); + assertThrows(IllegalArgumentException.class, () -> savingsAccount.withdraw(1000.75)); + } + + + } \ No newline at end of file diff --git a/src/test/java/edu/ithaca/dragon/bank/BasicAPITest.java b/src/test/java/edu/ithaca/dragon/bank/BasicAPITest.java new file mode 100644 index 00000000..18192ec7 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/BasicAPITest.java @@ -0,0 +1,149 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class BasicAPITest { + + @Test + void confirmCredentialsTest(){ + + CentralBank bankAccount = new CentralBank(); + CentralBank bankAccount2 = new CentralBank(); + bankAccount.createAccount("11212", "a@b.com", "testingPassword", 500); + bankAccount2.createAccount("11BFWGG", "tester@gmail.com", "singleLetter", 1000); + + assertFalse(bankAccount.confirmCredentials("11212", "test")); + assertFalse( bankAccount.confirmCredentials("112", "testingPassword")); + assertTrue( bankAccount.confirmCredentials("11212", "testingPassword")); + + assertFalse(bankAccount2.confirmCredentials("11bfwgg", "singleLetter")); + assertFalse(bankAccount2.confirmCredentials("11bfwgg", "SingleLetter")); + assertTrue(bankAccount2.confirmCredentials("11BFWGG", "singleLetter")); + + } + + @Test + void checkBalanceTest() throws IllegalArgumentException, InsufficientFundsException{ + CentralBank bank = new CentralBank(); + bank.createAccount("test123", "a@b.com", "testpass", 1000); + assertEquals(1000, bank.checkBalance("test123")); + //different account names + bank.withdraw("test123", 1); + assertEquals(999, bank.checkBalance("test123")); + bank.withdraw("test123", 250.47); + assertEquals(748.53, bank.checkBalance("test123")); + bank.withdraw("test123", 748.53); + assertEquals(0, bank.checkBalance("test123")); + + bank.createAccount("test456", "b@a.com", "testpass", 3290.57); + assertEquals(3290.57, bank.checkBalance("test456")); + + bank.createAccount("test789", "b@a.com", "testpass", 999999999.99); + assertEquals(999999999.99, bank.checkBalance("test789")); + + + + } + + @Test + void withdrawTest() throws IllegalArgumentException, InsufficientFundsException{ + CentralBank bank = new CentralBank(); + bank.createAccount("test123", "a@b.com", "testpass", 1000); + assertEquals(1000, bank.checkBalance("test123")); + //legal withdraws + bank.withdraw("test123", 1); + assertEquals(999, bank.checkBalance("test123")); + bank.withdraw("test123", 250.47); + assertEquals(748.53, bank.checkBalance("test123")); + bank.withdraw("test123", 748.53); + assertEquals(0, bank.checkBalance("test123")); + //illegal withdraws + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", -1)); + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", -500.89)); + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", -1000000.45)); + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", -1.96646)); + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", -1.9648690548065809546)); + assertThrows(IllegalArgumentException.class, ()->bank.withdraw("test123", 50.3940685)); + + + + } + + @Test + void depositTest() throws IllegalArgumentException{ + CentralBank bank = new CentralBank(); + bank.createAccount("test123", "a@b.com", "testpass", 1000); + bank.deposit("test123", 100); + assertEquals(1100, bank.checkBalance("test123")); + bank.deposit("test123", 1000); + assertEquals(2100, bank.checkBalance("test123")); + bank.deposit("test123", .19); + assertEquals(2100.19, bank.checkBalance("test123")); + + //account not found deposits + assertThrows(IllegalArgumentException.class, ()-> bank.deposit("test13", 50)); + assertThrows(IllegalArgumentException.class, ()-> bank.deposit("tes3", 100)); + //illegal deposits + assertThrows(IllegalArgumentException.class, ()-> bank.deposit("test123", 50.53894329)); + assertThrows(IllegalArgumentException.class, ()-> bank.deposit("test123", .3894329)); + //check balance remains the same + assertEquals(2100.19, bank.checkBalance("test123")); + + } + + @Test + void transferTest() throws InsufficientFundsException, IllegalArgumentException { + CentralBank bank = new CentralBank(); + bank.createAccount("test1", "a@b.com", "testpass", 10000); + bank.createAccount("test2", "b@c.com", "testpass", 500); + + assertEquals(10000, bank.checkBalance("test1")); + bank.transfer("test1", "test2", 500); + //check legal transfers both ways + assertEquals(9500,bank.checkBalance("test1")); + assertEquals(1000,bank.checkBalance("test2")); + bank.transfer("test1", "test2", 1500); + assertEquals(8000, bank.checkBalance("test1")); + assertEquals(2500,bank.checkBalance("test2")); + bank.transfer("test2", "test1", 150.02); + assertEquals(8150.02, bank.checkBalance("test1")); + assertEquals(2349.98,bank.checkBalance("test2")); + + //check for illegal transfers + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test1", "test2", .5424506)); + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test2", "test1", .506)); + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test2", "test1", -.506)); + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test1", "test2", 100.64345)); + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test1", "test1", 10)); //transfer to same account + assertThrows(IllegalArgumentException.class, ()-> bank.transfer("test2", "test2", 1093)); //transfer to same account + + + //check for insufficient funds + assertThrows(InsufficientFundsException.class, ()-> bank.transfer("test1", "test2", 10000)); + assertThrows(InsufficientFundsException.class, ()-> bank.transfer("test2", "test1", 2349.99)); + assertThrows(InsufficientFundsException.class, ()-> bank.transfer("test1", "test2", 8150.03)); + assertThrows(InsufficientFundsException.class, ()-> bank.transfer("test2", "test1", 8150.03)); + + + + + + + + + + + + + + + } + + + + + + + +}