diff --git a/.gitignore b/.gitignore index 3c8b8dd5..7c5067c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,96 +1,98 @@ -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -##### mac specific - -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items +target/ + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +##### mac specific + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items .apdisk \ No newline at end of file diff --git a/.idea/SoftwareEngineeringPractice.iml b/.idea/SoftwareEngineeringPractice.iml new file mode 100644 index 00000000..78b2cc53 --- /dev/null +++ b/.idea/SoftwareEngineeringPractice.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 28c6362f..91aadb77 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -7,7 +7,11 @@ + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml index b26911bd..11e485db 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,6 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index d87af9ac..d87a0fb3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,9 @@ + + - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..785c424e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sbt.xml b/.idea/sbt.xml index 20187435..8c004fbf 100644 --- a/.idea/sbt.xml +++ b/.idea/sbt.xml @@ -1,6 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..9661ac71 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 87c23b2d..55dcf2dc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,25 @@ -# SoftwareEngineeringPractice -## grading - -To Do | correct ----|--- -at least 8 commits| -isEmailValid| -withdraw| -isamountValid| -constructor & withdraw fix| +Class Diagram: https://drive.google.com/file/d/19JT3qFx5QZFDDfXToH9PeJ05eA53T-fP/view?usp=sharing + +Use Case Diagram: https://drive.google.com/file/d/12X02lLneMNfAI1tqyTuFt6AKf051U_tC/view?usp=sharing + +CreateAccount Sequence Diagram : https://drive.google.com/file/d/17_fjRoPPmLSFtNEhx62D5JeDLVHGVAaf/view?usp=sharing + +Withdraw Sequence diagram BankTeller: https://drive.google.com/file/d/1V51DPsffUscqPMyOBybJN9zhZhDqYtIu/view?usp=sharing + +Withdraw Sequence diagram ATM: https://drive.google.com/file/d/1A6ZFq9g-vcnZ75FzZpjcJTqST8WIMkaQ/view?usp=sharing + +Deposit Sequence Diagra BankTeller:https://drive.google.com/file/d/1yJNCy1H_MU2AL990FQnjaZPBFHO4EZJ_/view?usp=sharing + +Deposit Sequence Diagram ATM: https://drive.google.com/file/d/1MtKO5KAOeuZTXJ0wA9uj9zg5O3bRGwEa/view?usp=sharing + +Ideas for Improvement: + +-Use maybe a map for the customer collection. + +-Throw particular exception. + +-Take createAccount and turn it into createCustomer and addAccountToCustomer + +-Admin freeze/Unfreeze + +-Transfer 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/pom.xml b/pom.xml index 416ce09a..4a051d15 100644 --- a/pom.xml +++ b/pom.xml @@ -1,64 +1,64 @@ - - - 4.0.0 - - edu.ithaca.dragon - SoftwareEngineeringPractice - 1.0-SNAPSHOT - - - UTF-8 - 1.10 - - 4.12 - 5.0.0 - ${junit.version}.0 - 5.0.0 - 1.0.0 - - - - - - maven-compiler-plugin - 3.1 - - ${java.version} - ${java.version} - - - - - - - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test - - - - junit - junit - ${junit.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit.vintage.version} - test - - - + + + 4.0.0 + + edu.ithaca.dragon + SoftwareEngineeringPractice + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + + 4.12 + 5.0.0 + ${junit.version}.0 + 5.0.0 + 1.0.0 + + + + + + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + + + + + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + + junit + junit + ${junit.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.junit.vintage + junit-vintage-engine + ${junit.vintage.version} + test + + + \ No newline at end of file diff --git a/src/main/java/edu/ithaca/dragon/bank/ATM.java b/src/main/java/edu/ithaca/dragon/bank/ATM.java new file mode 100644 index 00000000..64cb93e7 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/ATM.java @@ -0,0 +1,56 @@ +package edu.ithaca.dragon.bank; + +public class ATM implements BasicAPI { + private CustomerCollection customers; + + + public ATM(CustomerCollection customersIn){ + customers = customersIn; + } + + + + public boolean confirmCredentials(String acctId, String password) { + return false; + } + + public double checkBalance(String acctId) { + + return customers.getBalance(acctId); + + } + + public void withdraw(String acctId, double amount) throws InsufficientFundsException, IllegalArgumentException { + customers.withdraw(acctId, amount); + } + + public void deposit(String acctId, double amount) { + if (isAmountValid(amount)){ + customers.deposit( acctId, amount); + } + else { + throw new IllegalArgumentException("invalid amount "); + } + } + + public void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws InsufficientFundsException, IllegalArgumentException { + if(amount < 0 || (amount * 100) % 1 != 0) + throw new IllegalArgumentException("invalid input"); + else{ + customers.withdraw(acctIdToWithdrawFrom, amount); + customers.deposit( acctIdToDepositTo, amount);; + } + } + + public String transactionHistory(String acctId) { + return null; + } + + public static boolean isAmountValid(double amountIn){ + if (amountIn < 0) return false; + double scale = Math.pow(10, 9); + amountIn = Math.round(amountIn*scale)/scale; + if(Double.compare(amountIn, Math.round(amountIn*100)/100.0)!= 0) return false; + else return true; + } +} diff --git a/src/main/java/edu/ithaca/dragon/bank/Account.java b/src/main/java/edu/ithaca/dragon/bank/Account.java new file mode 100644 index 00000000..26927564 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/Account.java @@ -0,0 +1,26 @@ +package edu.ithaca.dragon.bank; + + +public abstract class Account { + protected String ID; + protected double balance; + protected boolean frozen; + + public Account(String IDIn, double startingBalance){ + ID = IDIn; + balance = startingBalance; + frozen = false; + } + + public double getBalance(){return balance;} + public String getID(){return ID;} + public boolean getFrozen(){return frozen;} + public void toggleFrozen(){frozen = !frozen;} + + + public abstract void deposit(double amount); + public abstract void withdraw(double amount) throws InsufficientFundsException, IllegalArgumentException; + public abstract void transfer(Account transferTo, double amount) throws InsufficientFundsException; + + +} 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..5adc0f0c --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/AdvancedAPI.java @@ -0,0 +1,13 @@ +package edu.ithaca.dragon.bank; + +//API to be used by Teller systems +public interface AdvancedAPI extends BasicAPI { + + public void createCustomerWithAccount(String actID, String password, double startingBalance) throws IllegalArgumentException; + + public void createCustomer(String acctId, String password) throws IllegalArgumentException; + + public void addAccount(String actID, double startingBalance) throws IllegalArgumentException; + + public void closeCustomer(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..fe897779 100644 --- a/src/main/java/edu/ithaca/dragon/bank/BankAccount.java +++ b/src/main/java/edu/ithaca/dragon/bank/BankAccount.java @@ -1,46 +1,136 @@ -package edu.ithaca.dragon.bank; - -public class BankAccount { - - private String email; - private double balance; - - /** - * @throws IllegalArgumentException if email is invalid - */ - public BankAccount(String email, double startingBalance){ - if (isEmailValid(email)){ - this.email = email; - this.balance = startingBalance; - } - else { - throw new IllegalArgumentException("Email address: " + email + " is invalid, cannot create account"); - } - } - - public double getBalance(){ - return balance; - } - - public String getEmail(){ - return email; - } - - /** - * @post reduces the balance by amount if amount is non-negative and smaller than balance - */ - public void withdraw (double amount) { - balance -= amount; - - } - - - public static boolean isEmailValid(String email){ - if (email.indexOf('@') == -1){ - return false; - } - else { - return true; - } - } -} +package edu.ithaca.dragon.bank; + +import java.util.ArrayList; + +public class BankAccount { + + private String email; + private double balance; + + /** + * @throws IllegalArgumentException if email is invalid + */ + public BankAccount(String email, double startingBalance){ + if (isEmailValid(email)) this.email = email; + else throw new IllegalArgumentException("Email address: " + email + " is invalid, cannot create account"); + if (isAmountValid(startingBalance)) this.balance = startingBalance; + else throw new IllegalArgumentException(Double.toString(startingBalance)+" is an invalid starting Balance"); + } + + public double getBalance(){ + return balance; + } + + public String getEmail(){ + return email; + } + + /** + * @post reduces the balance by amount if amount is non-negative and smaller than balance + if the amount is less than 0 + print out "Amount wanted is less than 0" error + Don't change the original balance + + if the amount is 0 + return the balance as is/do nothing and have the subtraction be 0 + + if the amount is greater than the current balance + print out "Amount wanted is greater than the current balance" error + Don't change the original balance + + if all past if statements failed/was not used + subtract the amount from the current balance regularly + */ + public void withdraw (double amount) throws InsufficientFundsException, IllegalArgumentException{ + if (Double.compare(amount, 0.0)==0) throw new IllegalArgumentException("Cannot withdraw zero dollars"); + if (!isAmountValid(amount)) throw new IllegalArgumentException(Double.toString(amount)+" is not a valid withdraw amount"); + if(amount > balance) throw new InsufficientFundsException("Not enough Money"); + else balance -= amount; + } + + /** + * Returns true if amountIn is positive and has 2 or less decimal places. Returns false otherwise. + * @param amountIn + * @return + */ + public static boolean isAmountValid(double amountIn){ + if (amountIn < 0) return false; + double scale = Math.pow(10, 9); + amountIn = Math.round(amountIn*scale)/scale; + if(Double.compare(amountIn, Math.round(amountIn*100)/100.0)!= 0) return false; + else return true; + } + + /** + * returns true if email is valid and false if not + * @param email + * @return if email is valid + */ + public static boolean isEmailValid(String email){ + ArrayList validChar = validCharsList(); + + + int atId = email.indexOf('@'); //gets the index of the first @ + if(atId== -1) return false; //if no @ invalid email + if(email.lastIndexOf('@')!=atId) return false; // if last @ is not the first @ invalid email + if(atId == 0||atId == email.length()-1) return false; // if the @ is the first or the last char the email is invalid + + int lastPeriod = email.lastIndexOf('.'); + if(lastPeriod==-1)return false;//if there is no period there is no extension + if(lastPeriod validCharsList (){ + ArrayList validChar = new ArrayList(); + for(int x = 0; x < 26; x++){ + validChar.add((char)(x+65)); + validChar.add((char)(x+97)); + } + for(int x = 0; x < 10; x++){ + validChar.add((char)(x+'0')); + } + validChar.add('-'); + validChar.add('_'); + validChar.add('@'); + validChar.add('.'); + return validChar; + } + + /** + * If non zero valid amount add amount ot balance + * @param amount + * @throws IllegalArgumentException + */ + public void deposit(double amount) throws IllegalArgumentException{ + if(Double.compare(amount, 0)==0)throw new IllegalArgumentException("Cannot deposit zero dollars"); + if(!isAmountValid(amount))throw new IllegalArgumentException(Double.toString(amount)+" is not a valid deposit amount"); + else balance+=amount; + } + + /** + * transfers amount from this to transferTo if amount is non zero and valid + * @param amount + * @param transferTo + * @throws IllegalArgumentException + */ + public void transfer(double amount, BankAccount transferTo) throws IllegalArgumentException, InsufficientFundsException { + this.withdraw(amount); + transferTo.deposit(amount); + } +} diff --git a/src/main/java/edu/ithaca/dragon/bank/BankTeller.java b/src/main/java/edu/ithaca/dragon/bank/BankTeller.java new file mode 100644 index 00000000..27a92357 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/BankTeller.java @@ -0,0 +1,80 @@ +package edu.ithaca.dragon.bank; + + +public class BankTeller implements AdvancedAPI { + private CustomerCollection customers; + + public BankTeller(){ customers = new CustomerCollection(); } + + public CustomerCollection getCustomers() { + return customers; + } + + public boolean confirmCredentials(String acctId, String password) { + return false; + } + + public double checkBalance(String acctId) { + return customers.getBalance(acctId); + } + + public void withdraw(String acctId, double amount) throws InsufficientFundsException, IllegalArgumentException { + customers.withdraw(acctId, amount); + + } + + public void deposit(String acctId, double amount) { + if (isAmountValid(amount)){ + customers.deposit( acctId, amount);; + } + else { + throw new IllegalArgumentException("invalid amount "); + + } + + } + + public void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws InsufficientFundsException, IllegalArgumentException{ + if(amount < 0 || (amount * 100) % 1 != 0){ + throw new IllegalArgumentException("invalid input"); + } + else{ + customers.withdraw(acctIdToWithdrawFrom, amount); + customers.deposit( acctIdToDepositTo, amount);; + } + } + + public String transactionHistory(String acctId) { + return null; + } + + public void createCustomer(String acctId, String password) throws IllegalArgumentException { + customers.addCustomer(acctId, password); + } + + public void addAccount(String actID, double startingBalance) throws IllegalArgumentException{ + customers.createAccount(actID, startingBalance); + } + + public void createCustomerWithAccount(String actID, String password, double startingBalance) throws IllegalArgumentException{ + customers.addCustomer(actID, password); + customers.createAccount(actID, startingBalance); + + } + + public void closeCustomer(String acctId) throws IllegalArgumentException { + customers.closeCustomer(acctId); + } + + public int getNumCustomers(){ + return customers.getNumCustomers(); + + } + public static boolean isAmountValid(double amountIn){ + if (amountIn < 0) return false; + double scale = Math.pow(10, 9); + amountIn = Math.round(amountIn*scale)/scale; + if(Double.compare(amountIn, Math.round(amountIn*100)/100.0)!= 0) return false; + else return true; + } +} 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..bd65b941 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/BasicAPI.java @@ -0,0 +1,18 @@ +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..ac5c2f6e --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/CentralBank.java @@ -0,0 +1,63 @@ +package edu.ithaca.dragon.bank; + +import java.util.Collection; + +public class CentralBank implements AdvancedAPI, AdminAPI { + + //----------------- BasicAPI methods -------------------------// + + public boolean confirmCredentials(String acctId, String password) { + return false; + } + + public double checkBalance(String acctId) { + return 0; + } + + public void withdraw(String acctId, double amount) throws InsufficientFundsException { + + } + + public void deposit(String acctId, double amount) { + + } + + public void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws InsufficientFundsException { + + } + + public String transactionHistory(String acctId) { + return null; + } + + + //----------------- AdvancedAPI methods -------------------------// + + public void createCustomerWithAccount(String actID, String password, double startingBalance) throws IllegalArgumentException{} + + public void createCustomer(String acctId, String password) throws IllegalArgumentException{} + + public void addAccount(String actID, double startingBalance) throws IllegalArgumentException{} + + public void closeCustomer(String 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..7d652049 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/CheckingAccount.java @@ -0,0 +1,37 @@ +package edu.ithaca.dragon.bank; + +import java.math.BigDecimal; + +public class CheckingAccount extends Account { + + public CheckingAccount(String ID, double balance){ + super(ID, balance); + } + public void deposit(double amount){ + if (isAmountValid(amount)){ + balance += amount; + } + else { + throw new IllegalArgumentException("invalid amount "); + + } + } + public void withdraw(double amount) throws InsufficientFundsException, IllegalArgumentException{ + if(!CheckingAccount.isAmountValid(amount))throw new IllegalArgumentException("Not a valid Amount"); + if(Double.compare(amount, 0.0)==0)throw new IllegalArgumentException("Cannot Withdraw zero dollars"); + if(Double.compare(this.balance-amount, 0.0)==-1)throw new InsufficientFundsException("Not enough Funds"); + else this.balance -= amount; + + + } + + public void transfer(Account transferTo, double amount) throws InsufficientFundsException{} + + public static boolean isAmountValid(double amountIn){ + if (amountIn < 0) return false; + double scale = Math.pow(10, 9); + amountIn = Math.round(amountIn*scale)/scale; + if(Double.compare(amountIn, Math.round(amountIn*100)/100.0)!= 0) return false; + else return true; + } +} diff --git a/src/main/java/edu/ithaca/dragon/bank/Customer.java b/src/main/java/edu/ithaca/dragon/bank/Customer.java new file mode 100644 index 00000000..2b0e3a67 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/Customer.java @@ -0,0 +1,94 @@ +package edu.ithaca.dragon.bank; + +import java.util.ArrayList; + +public class Customer { + private String id; + private String password; + private Account checking; + + public Customer( String idIn, String passwordIn){ + id = idIn; + password = passwordIn; + checking = null; + } + + public void deposit(double amount){ + checking.deposit(amount); + } + + public void withdraw(double amount)throws IllegalArgumentException, InsufficientFundsException{ + if(checking == null)throw new IllegalArgumentException("Account Not Created"); + checking.withdraw(amount); + } + + public double getBalance(){ + if(checking == null)throw new IllegalArgumentException("No account"); + return checking.getBalance(); + } + + public boolean checkCredentials(String idIn, String passwordIn){ + return false; + } + + public void createAccount(double startingBalance) throws IllegalArgumentException{ + if(checking != null)throw new IllegalArgumentException("Account already Exists"); + if(!CheckingAccount.isAmountValid(startingBalance)) throw new IllegalArgumentException("Invalid Starting balance"); + checking = new CheckingAccount(id, startingBalance); + } + + public String getId() { + return id; + } + + public String getPassword() { + return password; + } + + + public static boolean isEmailValid(String email){ + ArrayList validChar = validCharsList(); + + + int atId = email.indexOf('@'); //gets the index of the first @ + if(atId== -1) return false; //if no @ invalid email + if(email.lastIndexOf('@')!=atId) return false; // if last @ is not the first @ invalid email + if(atId == 0||atId == email.length()-1) return false; // if the @ is the first or the last char the email is invalid + + int lastPeriod = email.lastIndexOf('.'); + if(lastPeriod==-1)return false;//if there is no period there is no extension + if(lastPeriod validCharsList (){ + ArrayList validChar = new ArrayList(); + for(int x = 0; x < 26; x++){ + validChar.add((char)(x+65)); + validChar.add((char)(x+97)); + } + for(int x = 0; x < 10; x++){ + validChar.add((char)(x+'0')); + } + validChar.add('-'); + validChar.add('_'); + validChar.add('@'); + validChar.add('.'); + return validChar; + } +} diff --git a/src/main/java/edu/ithaca/dragon/bank/CustomerCollection.java b/src/main/java/edu/ithaca/dragon/bank/CustomerCollection.java new file mode 100644 index 00000000..b79cec43 --- /dev/null +++ b/src/main/java/edu/ithaca/dragon/bank/CustomerCollection.java @@ -0,0 +1,60 @@ +package edu.ithaca.dragon.bank; + +import java.util.HashMap; + +public class CustomerCollection { + private HashMap customers; + + public CustomerCollection(){ + customers = new HashMap<>(); + } + + public void addCustomer(String idIn, String passwordIn){ + if(customers.get(idIn)!= null)throw new IllegalArgumentException("Customer Already Exists"); + customers.put(idIn, new Customer(idIn, passwordIn)); + } + + public void deposit(String ID, double amount){ + if(customers.get(ID)== null)throw new IllegalArgumentException("Account doesn't exist"); + customers.get(ID).deposit(amount); + } + + public void withdraw(String ID, double amount) throws IllegalArgumentException, InsufficientFundsException { + if(customers.get(ID)== null)throw new IllegalArgumentException("Account doesn't exist"); + customers.get(ID).withdraw(amount); + } + + public double getBalance(String ID){ + if(customers.get(ID)== null)throw new IllegalArgumentException("Account doesn't exist"); + return customers.get(ID).getBalance(); + + } + + public void transfer(String acctIdToWithdrawFrom, String acctIdToDepositTo, double amount) throws InsufficientFundsException, IllegalArgumentException { + if(amount < 0 || (amount * 100) % 1 != 0) + throw new IllegalArgumentException("invalid input"); + else{ + customers.get(acctIdToWithdrawFrom).withdraw(amount); + customers.get(acctIdToDepositTo).deposit(amount);; + } + } + + public boolean checkCredentials(String ID, String password){ + return false; + } + + public void createAccount(String actID, double startingBalance) throws IllegalArgumentException{ + if(customers.get(actID)== null)throw new IllegalArgumentException("Account doesn't exist"); + customers.get(actID).createAccount(startingBalance); + } + + public void closeCustomer(String actID) throws IllegalArgumentException{ + if(customers.get(actID)== null)throw new IllegalArgumentException("Account doesn't exist"); + customers.remove(actID); + } + + public int getNumCustomers(){ + return customers.size(); + } + +} diff --git a/src/main/java/edu/ithaca/dragon/bank/InsufficientFundsException.java b/src/main/java/edu/ithaca/dragon/bank/InsufficientFundsException.java index 8c794be8..a1baf929 100644 --- a/src/main/java/edu/ithaca/dragon/bank/InsufficientFundsException.java +++ b/src/main/java/edu/ithaca/dragon/bank/InsufficientFundsException.java @@ -6,4 +6,4 @@ public InsufficientFundsException(String s){ super(s); } -} \ No newline at end of file +} diff --git a/src/test/java/edu/ithaca/dragon/bank/ATMTest.java b/src/test/java/edu/ithaca/dragon/bank/ATMTest.java new file mode 100644 index 00000000..264d1d66 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/ATMTest.java @@ -0,0 +1,117 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ATMTest { + + @Test + void withdrawTest() throws Exception { + CustomerCollection newCol = new CustomerCollection(); + newCol.addCustomer("a@b.com", "xyz"); + newCol.createAccount("a@b.com", 200); + newCol.addCustomer("b@c.com", "xyz"); + newCol.createAccount("b@c.com", 1000); + newCol.addCustomer("c@d.com", "xyz"); + newCol.createAccount("c@d.com", 2000); + newCol.addCustomer("e@f.com", "xyz"); + newCol.createAccount("e@f.com", 300); + newCol.addCustomer("f@g.com", "xyz"); + newCol.createAccount("f@g.com", 50); + + ATM bankAccount = new ATM(newCol); + + bankAccount.withdraw("a@b.com", 99); + assertEquals(101, bankAccount.checkBalance("a@b.com")); + bankAccount.withdraw("e@f.com", 1); + assertEquals(299, bankAccount.checkBalance("e@f.com")); + bankAccount.withdraw("a@b.com", 100.89); + assertEquals(0.11, bankAccount.checkBalance("a@b.com"), 10); + + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", 0)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", 1.001)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", -14)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", -0.001)); + + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw("a@b.com", 2000)); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw("a@b.com", 201)); + } + @Test + void depositTest() throws Exception { + //Equivalence class: valid amount-positive int + CustomerCollection c1 = new CustomerCollection(); + c1.addCustomer("Mari", "love12"); + c1.createAccount("Mari", 100); + + ATM atm =new ATM(c1); + + atm.deposit("Mari",100); + assertEquals(200, atm.checkBalance("Mari")); + + atm.deposit("Mari",1); + assertEquals(201, atm.checkBalance("Mari")); + + atm.deposit("Mari",5000); + assertEquals(5201, atm.checkBalance("Mari")); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () ->atm.deposit("Mari",-1)); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () -> atm.deposit("Mari",-10)); + + //Equivalence Class-IllegalArgumentException more than 2 decimal places + assertThrows(IllegalArgumentException.class, () -> atm.deposit("Mari",1.908)); + + } + + @Test + void checkBalanceTest() throws Exception { + //Equivalence Class-valid balance + CustomerCollection c1 = new CustomerCollection(); + c1.addCustomer("Mari", "love12"); + c1.createAccount("Mari", 100); + + ATM atm =new ATM(c1); + + assertEquals(100, atm.checkBalance("Mari")); + + //Equivalence Class- 0 starting balance + c1.addCustomer("Ami", "yes101"); + c1.createAccount("Ami", 0); + + assertEquals(0, atm.checkBalance("Ami")); + + //Equivalence Class- balance >1000 + c1.addCustomer("Houry", "101NP"); + c1.createAccount("Houry", 5000); + + assertEquals(5000, atm.checkBalance("Houry")); + } + @Test + void transferTest() throws Exception{ + CustomerCollection newCol = new CustomerCollection(); + newCol.addCustomer("a@b.com", "xyz"); + newCol.createAccount("a@b.com", 100); + newCol.addCustomer("b@c.com", "xyz"); + newCol.createAccount("b@c.com", 600); + + newCol.transfer("a@b.com", "b@c.com", 50); + assertEquals(50, newCol.getBalance("a@b.com")); + assertEquals(650, newCol.getBalance("b@c.com")); + + newCol.addCustomer("c@b.com", "xyz"); + newCol.createAccount("c@b.com", 0); + newCol.addCustomer("z@r.com", "xyz"); + newCol.createAccount("z@r.com", 200); + + assertThrows(InsufficientFundsException.class, ()->newCol.transfer("c@b.com", "z@r.com", 300)); + + assertThrows(IllegalArgumentException.class, ()->newCol.transfer("a@b.com", "b@c.com", -1)); + assertThrows(IllegalArgumentException.class, ()->newCol.transfer("a@b.com", "b@c.com", -500)); + assertThrows(IllegalArgumentException.class, ()->newCol.transfer("a@b.com", "b@c.com", -500.654)); + assertThrows(IllegalArgumentException.class, ()->newCol.transfer("a@b.com", "b@c.com", 0)); + assertThrows(IllegalArgumentException.class, ()->newCol.transfer("a@b.com", "b@c.com", 300.5654)); + } +} diff --git a/src/test/java/edu/ithaca/dragon/bank/AccountTest.java b/src/test/java/edu/ithaca/dragon/bank/AccountTest.java new file mode 100644 index 00000000..a60d1ad0 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/AccountTest.java @@ -0,0 +1,58 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AccountTest { + @Test + void withdrawTest() throws InsufficientFundsException { + + CheckingAccount account1 = new CheckingAccount("a@b.com", 200); + account1.withdraw(100); + + assertEquals(100, account1.getBalance()); + + + //Equivalence Class-InsufficientFundsException + assertThrows(IllegalArgumentException.class, ()-> account1.withdraw(0)); + + assertThrows(InsufficientFundsException.class, () -> account1.withdraw(101)); + + + //Equivalence Class-IllegalArgumentException more than 2 decimal places + assertThrows(IllegalArgumentException.class, () -> account1.withdraw(1045.078)); + //Equivalence Class-IllegalArgumentException more than 2 decimal places + assertThrows(IllegalArgumentException.class, () -> account1.withdraw(1.02839)); + + + //Equivalence Class-Invalid withdraw amount 0 + assertThrows(IllegalArgumentException.class, () -> account1.withdraw(0)); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () -> account1.withdraw(-1)); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () -> account1.withdraw(-10)); + //Equivalence Class-IllegalArgumentException exceeds balance + assertThrows(InsufficientFundsException.class, () -> account1.withdraw(1000)); + + + //Equivalence Class- withdraw $1 + account1.withdraw(1); + assertEquals(99, account1.getBalance()); + + //Equivalence Class- withdraw $.1 + account1.withdraw(.1); + assertEquals(98.9, account1.getBalance()); + + //Equivalence Class- withdraw $.01 + account1.withdraw(.01); + assertEquals(98.89, account1.getBalance()); + + //Equivalence Class No balance + CheckingAccount account2 = new CheckingAccount("a@c.cm", 0); + assertThrows(InsufficientFundsException.class, ()-> account2.withdraw(1)); + assertEquals(0, account2.getBalance()); + } +} diff --git a/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java b/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java index d19ecb02..8371d7ac 100644 --- a/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java +++ b/src/test/java/edu/ithaca/dragon/bank/BankAccountTest.java @@ -1,40 +1,190 @@ -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); - - assertEquals(200, bankAccount.getBalance()); - } - - @Test - void withdrawTest() { - BankAccount bankAccount = new BankAccount("a@b.com", 200); - bankAccount.withdraw(100); - - assertEquals(100, bankAccount.getBalance()); - } - - @Test - void isEmailValidTest(){ - assertTrue(BankAccount.isEmailValid( "a@b.com")); - assertFalse( BankAccount.isEmailValid("")); - } - - @Test - void constructorTest() { - BankAccount bankAccount = new BankAccount("a@b.com", 200); - - assertEquals("a@b.com", bankAccount.getEmail()); - assertEquals(200, bankAccount.getBalance()); - //check for exception thrown correctly - assertThrows(IllegalArgumentException.class, ()-> new BankAccount("", 100)); - } - +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BankAccountTest { + + @Test + void getBalanceTest() { + //Equivalence Class starting positive balance + BankAccount bankAccount = new BankAccount("a@b.com", 200); + assertEquals(200, bankAccount.getBalance()); + bankAccount = new BankAccount("a@b.com", 0); + assertEquals(0, bankAccount.getBalance()); + } + + @Test + void withdrawTest() throws InsufficientFundsException{ + BankAccount bankAccount = new BankAccount("a@b.com", 200); + bankAccount.withdraw(100); + + assertEquals(100, bankAccount.getBalance()); + + //Equivalence Class Has balance + BankAccount bankAccount1 = new BankAccount("a@c.com", 300); + bankAccount1.withdraw(99);//valid withdraw + assertEquals(201, bankAccount1.getBalance()); + bankAccount1.withdraw(1);//valid withdraw edgecase + assertEquals(200, bankAccount1.getBalance()); + bankAccount1.withdraw(0.1); + assertEquals(199.9, bankAccount1.getBalance(),10); + bankAccount1.withdraw(0.01); + assertEquals(199.89, bankAccount1.getBalance(), 10); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.withdraw(201)); + assertEquals(199.89, bankAccount1.getBalance(), 10); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.withdraw(20100)); + assertEquals(199.89, bankAccount1.getBalance(), 10); + bankAccount1.withdraw(199.89);//perfect withdraw edgecase + assertEquals(0, bankAccount1.getBalance(), 10); + + //Equivalence Class No balance + BankAccount ba2 = new BankAccount("a@c.cm", 0); + assertThrows(InsufficientFundsException.class, ()-> ba2.withdraw(1)); + assertEquals(0, ba2.getBalance()); + + BankAccount ba3 = new BankAccount("a@c.cm", 200); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(0)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(1.001)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(-14)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(-0.001)); + + } + + @Test + void isEmailValidTest(){ + assertTrue(BankAccount.isEmailValid( "a@b.com")); + assertFalse( BankAccount.isEmailValid("")); + + //Partitions of ""=invalid partition, address first, domain second, extension third + + //Equivalence class being in first partitions, with boundary value to index[0]->indexOf(@) + //Multiple periods Partition tests + assertFalse(BankAccount.isEmailValid("a..b@male.com")); + assertTrue(BankAccount.isEmailValid("a.f.a@tah.com")); + assertTrue(BankAccount.isEmailValid("a.ffff.a@gasd.asd")); + assertFalse(BankAccount.isEmailValid("a...f@asdf.asd")); + assertFalse(BankAccount.isEmailValid("abc.def@mail..com")); //Only one is allowed in the second half regardless + + //Slash partitionTest + assertFalse(BankAccount.isEmailValid("abc-@mail.com")); + assertTrue(BankAccount.isEmailValid("abc-d@mail.com")); + + //Invalid period Location + assertFalse(BankAccount.isEmailValid(".abc@mail.com")); + assertTrue(BankAccount.isEmailValid("a.a@gasd.com")); + assertTrue(BankAccount.isEmailValid("abc.def@mail.com")); + + //Invalid Character Partitions + assertFalse(BankAccount.isEmailValid("abc#def@mail.com")); + assertFalse(BankAccount.isEmailValid("abc.def@mail#archive.com")); + assertTrue(BankAccount.isEmailValid("abc@mail.com")); + assertTrue(BankAccount.isEmailValid("abc_def@mail.com")); + + //Equivalence class Short or missing extentions + assertFalse(BankAccount.isEmailValid("abc.def@mail.c")); + assertFalse(BankAccount.isEmailValid("bc.def@mail")); + assertFalse(BankAccount.isEmailValid("asd@mail.")); + assertTrue(BankAccount.isEmailValid("asd@asd.cc")); + assertTrue(BankAccount.isEmailValid("asd@asd.ccc")); + + //Equivalence Class different extentions + assertTrue(BankAccount.isEmailValid("abc.def@mail-archive.com")); + assertTrue(BankAccount.isEmailValid("abc.def@mail.org")); + assertTrue(BankAccount.isEmailValid("abc.def@mail.com")); + + //Equivalence Class @ symbols + assertFalse(BankAccount.isEmailValid("as@as@asd.com")); + assertFalse(BankAccount.isEmailValid("ASDF@ADSA.F@ASCOM")); + assertFalse(BankAccount.isEmailValid("asdfasdfsadf.sad")); + assertFalse(BankAccount.isEmailValid("asdfasdfasdf")); + + assertFalse(BankAccount.isEmailValid("asd%@asddff.coc")); + assertFalse(BankAccount.isEmailValid("asd@asddff.coco")); + } + + @Test + void constructorTest() { + BankAccount bankAccount = new BankAccount("a@b.com", 200); + assertEquals("a@b.com", bankAccount.getEmail()); + assertEquals(200, bankAccount.getBalance()); + //check for exception thrown correctly + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("", 100)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@basd.com", 100.001)); + assertThrows(IllegalArgumentException.class, ()-> new BankAccount("a@basd.com", -100)); + } + + @Test + void isAmountValidTest(){ + assertTrue(BankAccount.isAmountValid(10)); + assertTrue(BankAccount.isAmountValid(10.0)); + assertTrue(BankAccount.isAmountValid(10.00)); + assertTrue(BankAccount.isAmountValid(10.000000000)); + assertTrue(BankAccount.isAmountValid(10.1)); + assertTrue(BankAccount.isAmountValid(10.11)); + assertTrue(BankAccount.isAmountValid(0.0000000)); + assertTrue(BankAccount.isAmountValid(0.1)); + assertTrue(BankAccount.isAmountValid(0.01)); + assertTrue(BankAccount.isAmountValid(0.00000000001)); + + assertFalse(BankAccount.isAmountValid(10.001)); + assertFalse(BankAccount.isAmountValid(10.0001)); + assertFalse(BankAccount.isAmountValid(10.00000001)); + assertFalse(BankAccount.isAmountValid(-10)); + assertFalse(BankAccount.isAmountValid(-10.0)); + assertFalse(BankAccount.isAmountValid(-10.00)); + assertFalse(BankAccount.isAmountValid(-10.00000)); + assertFalse(BankAccount.isAmountValid(-10.1)); + assertFalse(BankAccount.isAmountValid(-10.01)); + assertFalse(BankAccount.isAmountValid(-10.001)); + assertFalse(BankAccount.isAmountValid(-0.1)); + assertFalse(BankAccount.isAmountValid(-0.01)); + assertFalse(BankAccount.isAmountValid(-0.001)); + } + + @Test + void depositTest(){ + BankAccount bankAccount = new BankAccount("a@a.cc", 0); + + bankAccount.deposit(100); + assertEquals(100, bankAccount.getBalance(), 10); + bankAccount.deposit(0.1); + assertEquals(100.1, bankAccount.getBalance(), 10); + bankAccount.deposit(0.01); + assertEquals(100.11, bankAccount.getBalance(), 10); + + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(0)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.01)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(1.001)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.deposit(-1.001)); + } + + @Test + void transferTest() throws InsufficientFundsException{ + BankAccount bankAccount = new BankAccount("a@a.cc", 300); + BankAccount bankAccount1 = new BankAccount("A@AA.CC", 0); + + bankAccount.transfer(100, bankAccount1); + assertEquals(200, bankAccount.getBalance(), 10); + assertEquals(100, bankAccount1.getBalance(), 10); + bankAccount.transfer(0.1, bankAccount1); + assertEquals(199.9, bankAccount.getBalance(), 10); + assertEquals(100.1, bankAccount1.getBalance(), 10); + bankAccount.transfer(0.01, bankAccount1); + assertEquals(199.89, bankAccount.getBalance(), 10); + assertEquals(100.11, bankAccount1.getBalance(), 10); + + assertThrows(IllegalArgumentException.class, ()-> bankAccount.transfer(0, bankAccount1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.transfer(-1, bankAccount1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.transfer(-1.01, bankAccount1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.transfer(-1.0001, bankAccount1)); + assertThrows(IllegalArgumentException.class, ()-> bankAccount.transfer(0.001, bankAccount1)); + + assertThrows(InsufficientFundsException.class, ()->bankAccount.transfer(1000, bankAccount1)); + } + + + } \ No newline at end of file diff --git a/src/test/java/edu/ithaca/dragon/bank/BankTellerTest.java b/src/test/java/edu/ithaca/dragon/bank/BankTellerTest.java new file mode 100644 index 00000000..762b80e7 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/BankTellerTest.java @@ -0,0 +1,175 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class BankTellerTest { + + @Test + void withdrawTest() throws Exception { + BankTeller bankAccount = new BankTeller(); + + bankAccount.createCustomerWithAccount("a@b.com", "xyz", 200); + bankAccount.createCustomerWithAccount("b@c.com", "xyz", 500); + bankAccount.createCustomerWithAccount("c@d.com", "xyz", 1000); + bankAccount.createCustomerWithAccount("e@f.com", "xyz", 10); + bankAccount.createCustomerWithAccount("f@g.com", "xyz", 150); + + bankAccount.withdraw("a@b.com", 100); + + assertEquals(100, bankAccount.checkBalance("a@b.com")); + + //Equivalence Class Has balance + bankAccount.withdraw("a@b.com", 99);//valid withdraw + assertEquals(1, bankAccount.checkBalance("a@b.com"),10); + bankAccount.withdraw("b@c.com", 1);//valid withdraw edgecase + assertEquals(499, bankAccount.checkBalance("b@c.com")); + bankAccount.withdraw("c@d.com", 0.1); + assertEquals(999.9, bankAccount.checkBalance("c@d.com"), 10); + bankAccount.withdraw("a@b.com", 0.01); + assertEquals(0.99, bankAccount.checkBalance("a@b.com"), 10); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw("a@b.com", 201)); + assertEquals(0.99, bankAccount.checkBalance("a@b.com"), 10); + assertThrows(InsufficientFundsException.class, () -> bankAccount.withdraw("a@b.com", 20100)); + assertEquals(0.99, bankAccount.checkBalance("a@b.com"), 10); + bankAccount.withdraw("a@b.com", 0.99);//perfect withdraw edgecase + assertEquals(0, bankAccount.checkBalance("a@b.com"), 10); + + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", 0)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", 1.001)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", -14)); + assertThrows(IllegalArgumentException.class, () -> bankAccount.withdraw("a@b.com", -0.001)); + + assertThrows(IllegalArgumentException.class, ()-> bankAccount.withdraw("asdfa", 100)); + } + + @Test + void depositTest() throws Exception { + //Equivalence class: valid amount-positive int + BankTeller bt1 = new BankTeller(); + bt1.createCustomerWithAccount("Mari", "love12", 100); + bt1.deposit("Mari", 100); + assertEquals(200, bt1.checkBalance("Mari")); + + bt1.deposit("Mari", 1); + assertEquals(201, bt1.checkBalance("Mari")); + + bt1.deposit("Mari", 1.01); + assertEquals(202.01, bt1.checkBalance("Mari")); + + bt1.deposit("Mari", 5000); + assertEquals(5202.01, bt1.checkBalance("Mari")); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () -> bt1.deposit("Mari", -1)); + + //Equivalence Class-IllegalArgumentException negative amount + assertThrows(IllegalArgumentException.class, () -> bt1.deposit("Mari", -10)); + + //Equivalence Class-IllegalArgumentException more than 2 decimal places + assertThrows(IllegalArgumentException.class, () -> bt1.deposit("Mari", 1.908)); + } + + @Test + void checkBalanceTest() throws Exception { + //Equivalence class: valid amount-positive int + BankTeller bt1 = new BankTeller(); + bt1.createCustomerWithAccount("Mari", "love12", 100); + + assertEquals(100, bt1.checkBalance("Mari")); + + //Equivalence Class- 0 starting balance + bt1.createCustomerWithAccount("Ami", "yes101", 0); + + assertEquals(0, bt1.checkBalance("Ami")); + + //Equivalence Class- balance >1000 + bt1.createCustomerWithAccount("Houry", "101NP", 5000); + + assertEquals(5000, bt1.checkBalance("Houry")); + } + + @Test + void testCreateCustomerWithAccount() throws IllegalArgumentException { + BankTeller b1 = new BankTeller(); + assertEquals(0, b1.getNumCustomers()); + b1.createCustomerWithAccount("bob", "password", 100); + assertEquals(100, b1.checkBalance("bob")); + assertEquals(1, b1.getNumCustomers()); + b1.createCustomerWithAccount("bb", "password", 100); + assertEquals(100, b1.checkBalance("bb")); + assertEquals(2, b1.getNumCustomers()); + + assertThrows(IllegalArgumentException.class, () -> b1.createCustomerWithAccount("bb", "password", 100)); + assertThrows(IllegalArgumentException.class, () -> b1.createCustomerWithAccount("b", "password", -100)); + assertThrows(IllegalArgumentException.class, () -> b1.createCustomerWithAccount("b", "password", 100.001)); + } + + @Test + void testCreateCustomer() throws IllegalArgumentException{ + BankTeller b1 = new BankTeller(); + assertEquals(0, b1.getNumCustomers()); + b1.createCustomer("bob", "password"); + assertEquals(1, b1.getNumCustomers()); + b1.createCustomer("bb", "password"); + assertEquals(2, b1.getNumCustomers()); + + assertThrows(IllegalArgumentException.class, ()-> b1.createCustomer("bob", "pwasdawaerd")); + } + + @Test + void testAddAccount() throws IllegalArgumentException{ + BankTeller b1 = new BankTeller(); + b1.createCustomer("bob", "password"); + b1.createCustomer("bb", "password"); + b1.createCustomer("b", "pasdfawrod"); + b1.addAccount("bob", 100); + assertEquals(100, b1.checkBalance("bob")); + b1.addAccount("bb", 0); + assertEquals(0, b1.checkBalance("bb")); + b1.addAccount("b", 10000); + assertEquals(10000, b1.checkBalance("b")); + + assertThrows(IllegalArgumentException.class, ()-> b1.addAccount("bob", 100)); + + } + + @Test + void testCloseCustomer() throws IllegalArgumentException { + BankTeller b1 = new BankTeller(); + b1.createCustomerWithAccount("bob", "password", 100); + b1.createCustomerWithAccount("bb", "password", 100); + assertEquals(2, b1.getNumCustomers()); + b1.closeCustomer("bob"); + assertEquals(1, b1.getNumCustomers()); + + assertThrows(IllegalArgumentException.class, () -> b1.closeCustomer("bob")); + } + + @Test + void transferTest() throws Exception{ + BankTeller bankAccount = new BankTeller(); + + bankAccount.createAccount("a@b.com", "xyz", 200); + bankAccount.createAccount("b@c.com", "xyz", 500); + bankAccount.createAccount("c@d.com", "xyz", 1000); + bankAccount.createAccount("e@f.com", "xyz", 10); + bankAccount.createAccount("z@y.com", "xyz", 150); + bankAccount.createAccount("d@j.com", "xyz", 1); + bankAccount.createAccount("a@v.com", "xyz", 0); + + bankAccount.transfer("a@b.com", "b@c.com", 100); + assertEquals(100, bankAccount.checkBalance("a@b.com")); + assertEquals(600, bankAccount.checkBalance("b@c.com")); + + assertThrows(InsufficientFundsException.class, ()->bankAccount.transfer("a@v.com", "e@f.com", 300)); + + assertThrows(IllegalArgumentException.class, ()->bankAccount.transfer("c@d.com", "e@f.com", -1)); + assertThrows(IllegalArgumentException.class, ()->bankAccount.transfer("a@v.com", "d@j.com", -500)); + assertThrows(IllegalArgumentException.class, ()->bankAccount.transfer("a@v.com", "d@j.com", -500.8979)); + assertThrows(IllegalArgumentException.class, ()->bankAccount.transfer("d@j.com", "e@f.com", 938.845)); + assertThrows(IllegalArgumentException.class, ()->bankAccount.transfer("d@j.com", "e@f.com", 0)); + assertThrows(InsufficientFundsException.class, ()->bankAccount.transfer("z@y.com", "c@d.com", 938.84)); + } +} \ No newline at end of file diff --git a/src/test/java/edu/ithaca/dragon/bank/CheckingAccountTest.java b/src/test/java/edu/ithaca/dragon/bank/CheckingAccountTest.java new file mode 100644 index 00000000..ac7f5b38 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/CheckingAccountTest.java @@ -0,0 +1,45 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CheckingAccountTest { + @Test + void withdrawCheckingTest() throws InsufficientFundsException{ + CheckingAccount bankAccount = new CheckingAccount("a@b.com", 200); + bankAccount.withdraw(100); + + assertEquals(100, bankAccount.getBalance()); + + //Equivalence Class Has balance + BankAccount bankAccount1 = new BankAccount("a@c.com", 300); + bankAccount1.withdraw(99);//valid withdraw + assertEquals(201, bankAccount1.getBalance()); + bankAccount1.withdraw(1);//valid withdraw edgecase + assertEquals(200, bankAccount1.getBalance()); + bankAccount1.withdraw(0.1); + assertEquals(199.9, bankAccount1.getBalance(),10); + bankAccount1.withdraw(0.01); + assertEquals(199.89, bankAccount1.getBalance(), 10); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.withdraw(201)); + assertEquals(199.89, bankAccount1.getBalance(), 10); + assertThrows(InsufficientFundsException.class, ()-> bankAccount1.withdraw(20100)); + assertEquals(199.89, bankAccount1.getBalance(), 10); + bankAccount1.withdraw(199.89);//perfect withdraw edgecase + assertEquals(0, bankAccount1.getBalance(), 10); + + //Equivalence Class No balance + CheckingAccount ba2 = new CheckingAccount("a@c.cm", 0); + assertThrows(InsufficientFundsException.class, ()-> ba2.withdraw(1)); + assertEquals(0, ba2.getBalance()); + + CheckingAccount ba3 = new CheckingAccount("a@c.cm", 200); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(0)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(1.001)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(-14)); + assertThrows(IllegalArgumentException.class, ()-> ba3.withdraw(-0.001)); + + } +} + diff --git a/src/test/java/edu/ithaca/dragon/bank/CustomerCollectionTest.java b/src/test/java/edu/ithaca/dragon/bank/CustomerCollectionTest.java new file mode 100644 index 00000000..ec0a4d2d --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/CustomerCollectionTest.java @@ -0,0 +1,58 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class CustomerCollectionTest { + @Test + void addCustomerTest(){ + CustomerCollection c1 = new CustomerCollection(); + assertEquals(0, c1.getNumCustomers()); + c1.addCustomer("bob", "password"); + assertEquals(1, c1.getNumCustomers()); + c1.addCustomer("bb", "password"); + assertEquals(2, c1.getNumCustomers()); + + assertThrows(IllegalArgumentException.class, ()-> c1.addCustomer("bob", "password")); + } + + @Test + void addAccountTest() throws Exception{ + CustomerCollection c1 = new CustomerCollection(); + c1.addCustomer("bob", "password"); + c1.createAccount("bob", 100); + assertEquals(100, c1.getBalance("bob")); + c1.addCustomer("bb", "password"); + assertThrows(IllegalArgumentException.class, ()->c1.createAccount("bb", -100)); + assertThrows(IllegalArgumentException.class, ()->c1.createAccount("bb", 100.001)); + assertThrows(IllegalArgumentException.class, ()->c1.createAccount("bob", 100)); + assertThrows(IllegalArgumentException.class, ()->c1.createAccount("b", 100)); + } + + @Test + void getBalanceTest() throws Exception{ + CustomerCollection c1 = new CustomerCollection(); + c1.addCustomer("bob", "password"); + c1.createAccount("bob", 100); + assertEquals(100, c1.getBalance("bob")); + c1.addCustomer("bb", "password"); + c1.createAccount("bb", 200); + assertEquals(200, c1.getBalance("bb")); + c1.addCustomer("bbb", "password"); + + assertThrows(IllegalArgumentException.class, ()-> c1.getBalance("b")); + assertThrows(IllegalArgumentException.class, ()-> c1.getBalance("bbb")); + } + + @Test + void closeCustomerTest()throws Exception{ + CustomerCollection c1 = new CustomerCollection(); + c1.addCustomer("bob", "password"); + c1.addCustomer("bb", "password"); + assertEquals(2, c1.getNumCustomers()); + c1.closeCustomer("bob"); + assertEquals(1, c1.getNumCustomers()); + assertThrows(IllegalArgumentException.class, ()-> c1.closeCustomer("bbb")); + } +} diff --git a/src/test/java/edu/ithaca/dragon/bank/CustomerTest.java b/src/test/java/edu/ithaca/dragon/bank/CustomerTest.java new file mode 100644 index 00000000..3b50a563 --- /dev/null +++ b/src/test/java/edu/ithaca/dragon/bank/CustomerTest.java @@ -0,0 +1,95 @@ +package edu.ithaca.dragon.bank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class CustomerTest { + + @Test + void isEmailValidTest(){ + assertTrue(Customer.isEmailValid( "a@b.com")); + assertFalse( Customer.isEmailValid("")); + + //Partitions of ""=invalid partition, address first, domain second, extension third + + //Equivalence class being in first partitions, with boundary value to index[0]->indexOf(@) + //Multiple periods Partition tests + assertFalse(Customer.isEmailValid("a..b@male.com")); + assertTrue(Customer.isEmailValid("a.f.a@tah.com")); + assertTrue(Customer.isEmailValid("a.ffff.a@gasd.asd")); + assertFalse(Customer.isEmailValid("a...f@asdf.asd")); + assertFalse(Customer.isEmailValid("abc.def@mail..com")); //Only one is allowed in the second half regardless + + //Slash partitionTest + assertFalse(Customer.isEmailValid("abc-@mail.com")); + assertTrue(Customer.isEmailValid("abc-d@mail.com")); + + //Invalid period Location + assertFalse(Customer.isEmailValid(".abc@mail.com")); + assertTrue(Customer.isEmailValid("a.a@gasd.com")); + assertTrue(Customer.isEmailValid("abc.def@mail.com")); + + //Invalid Character Partitions + assertFalse(Customer.isEmailValid("abc#def@mail.com")); + assertFalse(Customer.isEmailValid("abc.def@mail#archive.com")); + assertTrue(Customer.isEmailValid("abc@mail.com")); + assertTrue(Customer.isEmailValid("abc_def@mail.com")); + + //Equivalence class Short or missing extentions + assertFalse(Customer.isEmailValid("abc.def@mail.c")); + assertFalse(Customer.isEmailValid("bc.def@mail")); + assertFalse(Customer.isEmailValid("asd@mail.")); + assertTrue(Customer.isEmailValid("asd@asd.cc")); + assertTrue(Customer.isEmailValid("asd@asd.ccc")); + + //Equivalence Class different extentions + assertTrue(Customer.isEmailValid("abc.def@mail-archive.com")); + assertTrue(Customer.isEmailValid("abc.def@mail.org")); + assertTrue(Customer.isEmailValid("abc.def@mail.com")); + + //Equivalence Class @ symbols + assertFalse(Customer.isEmailValid("as@as@asd.com")); + assertFalse(Customer.isEmailValid("ASDF@ADSA.F@ASCOM")); + assertFalse(Customer.isEmailValid("asdfasdfsadf.sad")); + assertFalse(Customer.isEmailValid("asdfasdfasdf")); + + assertFalse(Customer.isEmailValid("asd%@asddff.coc")); + assertFalse(Customer.isEmailValid("asd@asddff.coco")); + } + + @Test + void constructorTest(){ + Customer c1 = new Customer("bob", "asdfasdf"); + assertEquals("bob", c1.getId()); + assertEquals("asdfasdf", c1.getPassword()); + } + + @Test + void createAccount() throws Exception{ + Customer c1 = new Customer("bob", "1"); + c1.createAccount(100); + assertEquals(100, c1.getBalance()); + Customer c2 = new Customer("bob", "1"); + c2.createAccount(200); + assertEquals(200, c2.getBalance()); + assertThrows(IllegalArgumentException.class, ()->c2.createAccount(200)); + assertThrows(IllegalArgumentException.class, ()->c2.createAccount(300)); + Customer c3 = new Customer("bob", "1"); + assertThrows(IllegalArgumentException.class, ()-> c3.createAccount(100.001)); + assertThrows(IllegalArgumentException.class, ()-> c3.createAccount(-100)); + } + + @Test + void getBalanceTest() throws Exception{ + Customer c1 = new Customer("bob", "1"); + c1.createAccount(100); + assertEquals(100, c1.getBalance()); + Customer c2 = new Customer("bb", "1"); + c2.createAccount(200); + assertEquals(200, c2.getBalance()); + Customer c3 = new Customer("bbb","password"); + + assertThrows(IllegalArgumentException.class, ()-> c3.getBalance()); + } +}