diff --git a/.gitignore b/.gitignore index b99dc45..c1960de 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ target/ .project .classpath .settings +data/* +*.DS_Store \ No newline at end of file diff --git a/ATMUML.uml b/ATMUML.uml new file mode 100644 index 0000000..6f165a8 --- /dev/null +++ b/ATMUML.uml @@ -0,0 +1,180 @@ + + + JAVA + + + Account + Savings + User + Storeable + Checking + Console + Transaction + ATM + Main + DB + Investment + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Main + + + Fields + Methods + + All + private + + diff --git a/README.md b/README.md index 92d73b7..f73f764 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # project-2-ATM Week 2 project: ATM Simulator +## Notes for Use +- The DB class defines database objects and a number of attendant methods to delete, search, modify, and add rows in the database +- Information is stored in csv files in the /data folder. An example data set is included and will be run when you run `main()`. Any changes to accounts, users, or additional transactions will be saved there. These files are in the `.gitignore`, so any changes you make locally wouldn't overwrite them +- There's one path test that has a hardcoded path from dev, which wasn't a great choice, but the user's `pwd` is used in the actual method, so the file paths will be fine when you test +- One example user, for convenience of entry during testing, has card number 1 and password 1234 +- There are also a couple of test database files (`test.db` and `testbad.csv` which are used in certain tests. Other tests create and destory temporary database files +- Every time a user logs in, interest is earned on savings accounts and investments get returns, based on random chance and risk tolerance defined when creating the account + + ## ATM Requirements Every feature must have corresponding unit tests diff --git a/data/accounts.csv b/data/accounts.csv new file mode 100644 index 0000000..99d7add --- /dev/null +++ b/data/accounts.csv @@ -0,0 +1,3 @@ +"350","275","1320.0","Checking","" +"33","275","5560.36","Savings","0.06" +"2","275","53250.23","Investment","0.06" diff --git a/data/test.csv b/data/test.csv new file mode 100644 index 0000000..3d9f95c --- /dev/null +++ b/data/test.csv @@ -0,0 +1,4 @@ +"Item 1","Item 2","Item 3","Item 4" +"Item 1b","Item 2b","Item 3b","Item 4b" +"Item 1c","Item 2c","Item 3c","Item 4c" +"Item 1d","Item 2d","Item 3d","Item 4d" \ No newline at end of file diff --git a/data/testBad.csv b/data/testBad.csv new file mode 100644 index 0000000..4fb0122 --- /dev/null +++ b/data/testBad.csv @@ -0,0 +1,4 @@ +"Item 1","Item 2","Item 3","Item 4" +"Item 1b","Item 2b","Item 3b","Item 4b" +"Item 1c","Item 2c","Item 3c" +"Item 1d","Item 2d","Item 3d","Item 4d" \ No newline at end of file diff --git a/data/testaccountDB.csv b/data/testaccountDB.csv new file mode 100644 index 0000000..e69de29 diff --git a/data/testtransactionDB.csv b/data/testtransactionDB.csv new file mode 100644 index 0000000..e69de29 diff --git a/data/testuserDB.csv b/data/testuserDB.csv new file mode 100644 index 0000000..e69de29 diff --git a/data/transactions.csv b/data/transactions.csv new file mode 100644 index 0000000..831d694 --- /dev/null +++ b/data/transactions.csv @@ -0,0 +1,11 @@ +"credit","350","1200.00","Tue Oct 29 13:19:54 EDT 2019","Opened account" +"credit","33","5670.30","Tue Oct 29 13:20:08 EDT 2019","Opened account" +"credit","2","45607.30","Tue Oct 29 13:20:21 EDT 2019","Opened account" +"credit","33","3.40","Tue Oct 29 13:20:27 EDT 2019","Interest earned" +"credit","2","2788.62","Tue Oct 29 13:20:27 EDT 2019","Investment returns" +"debit","33","-120.00","Tue Oct 29 13:23:18 EDT 2019","ATM Transfer" +"credit","350","120.00","Tue Oct 29 13:23:18 EDT 2019","ATM Transfer" +"credit","33","3.33","Tue Oct 29 13:24:46 EDT 2019","Interest earned" +"credit","2","3303.34","Tue Oct 29 13:24:46 EDT 2019","Investment returns" +"credit","33","3.33","Tue Oct 29 13:27:00 EDT 2019","Interest earned" +"credit","2","1550.97","Tue Oct 29 13:27:00 EDT 2019","Investment returns" diff --git a/data/users.csv b/data/users.csv new file mode 100644 index 0000000..deae835 --- /dev/null +++ b/data/users.csv @@ -0,0 +1,4 @@ +"719","john","jimmy","90486264","blorp" +"606","jones","jim","84170304","jimmy" +"275","peasy","easy","1","1234" +"827","davis","john","16690334","12345" diff --git a/pom.xml b/pom.xml index 9901415..5ad041c 100644 --- a/pom.xml +++ b/pom.xml @@ -8,5 +8,32 @@ project-2-atm 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + + + + + pl.pragmatists + JUnitParams + 1.1.1 + test + + + com.opencsv + opencsv + 4.5 + + \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..566bda1 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000..cce1d29 Binary files /dev/null and b/src/main/.DS_Store differ diff --git a/src/main/java/ATM.java b/src/main/java/ATM.java new file mode 100644 index 0000000..433cd81 --- /dev/null +++ b/src/main/java/ATM.java @@ -0,0 +1,566 @@ +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +public class ATM { + + private User currentUser; + + private DB userDB; // 0: ID 1: Last Name 2: First Name 3: cardNum 4: PW + private DB transactionDB; // 0: credit/debit 1: accountID 2: amount (signed) 3: timeStamp 4: description + private DB accountDB; // 0: accountID 1: ownerID 2: balance 3: type 4: risk/interest/null (type-dependent) + + public ATM(String userDBName, String accountDBName, String transactionDBName) { + this.currentUser = null; + try { + this.userDB = new DB(userDBName, 5); + this.transactionDB = new DB(transactionDBName, 5); + this.accountDB = new DB(accountDBName, 5); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public User getCurrentUser() { + return this.currentUser; + } + public DB getUserDB() { + return this.userDB; + } + public DB getTransactionDB() { + return this.transactionDB; + } + public DB getAccountDB() { + return this.accountDB; + } + public void setCurrentUser(User currentUser) { + this.currentUser = currentUser; + } + + + // load database info from disk + public void loadDBs() { +// // find accounts, create instances +// ArrayList accountsInfo = getAccountInfoByUser(this.currentUser); +// ArrayList accounts = new ArrayList<>(); +// for (String[] acctInfo : accountsInfo) { +// accounts.add(new Account(...)); +// } +// // + } + + + public void authenticate() { + //Read User's card + Console.println("Card Number:"); + int cardNum = Console.getInteger(); + + // find user in DB + String[] userInfo = this.getUserInfoByCardNum(cardNum); + if (userInfo == null){ + this.authenticate(); + } + // check PW + String password = Console.getInput("Enter Password: "); + if(password.equals(userInfo[4])) { + // 0: ID 1: Last Name 2: First Name 3: cardNum 4: PW + currentUser = new User(userInfo[2], userInfo[1], userInfo[4], Integer.parseInt(userInfo[0]), Integer.parseInt(userInfo[3])); + } else { + this.authenticate(); + } + } + + // add new user - called by getUser() + public User newUser() { + + String firstName = Console.getInput("Enter Your First Name: "); + String lastName = Console.getInput("Enter Your Last Name: "); + String password = Console.getInput("Choose Your Password: "); + + Integer cardNumber = User.genCardNum(); + Console.println("Your Card Number: " + cardNumber + "\n"); + + Integer userID = (int) (Math.random() * 1000); + + + User newUser = new User(firstName, lastName, password, userID, cardNumber); + currentUser = newUser; + this.saveUserToDB(currentUser); + + return newUser; + } + + // log in user - don't return until you do + public void getUser() { + String header = "Welcome to ZipCode National Bank"; + String input = Console.getInput(header, new String[] {"Insert Card", "Open an Account"}); + + switch (input) { + case "1": + this.authenticate(); + if (this.currentUser == null) { + return; + } + break; + case "2": + this.newUser(); + break; + } + } + + // deal with the user's choices + public void userMenu() { + String header = "ZCNB Main Menu"; + + ArrayList choices = new ArrayList<>(); + choices.add("Transaction History"); + choices.add("Add Account"); + + String nextAcctChoice; + ArrayList usrAccts = getAccountsForUser(currentUser); + for (int i = 0; i < usrAccts.size(); i++) { + nextAcctChoice = String.format("%s #%d ($%,.2f)", usrAccts.get(i).getClass().getName(), usrAccts.get(i).getAcctNum(), usrAccts.get(i).getBalance()); + choices.add(nextAcctChoice); + } + + choices.add("Log Out"); + + String input = Console.getInput(header, choices.toArray(new String[choices.size()])); + + if (input.equals(Integer.toString(choices.size()))) { + serviceLoop(); //not ... great, but it'll do for now + } else if (input.equals("1")) { + Console.outputTransactionsWithHeader("Transaction History", getTransactionsForUser(this.currentUser)); + } else if (input.equals("2")) { + Double deposit = Console.getCurrency("Initial deposit amount for this account: "); + addAccount(usrAccts, deposit); + } else { + accountMenu(usrAccts.get(Integer.parseInt(input) - 3)); + } + + userMenu(); + } + + public void addAccount(ArrayList usrAccounts, Double deposit) { + String header = "Choose Account Type:"; + String input = Console.getInput(header, new String[] {"Checking", "Savings", "Investment", "Back to Main Menu" }); + Account newAccount; + Transaction transaction; + + + switch (input) { + case "1": + newAccount = new Checking(deposit, this.currentUser.getUserID(), (int)(Math.random()*1000)); + this.saveAccountToDB(newAccount); + usrAccounts.add(newAccount); + + transaction = new Transaction(deposit, new Date(), newAccount.getAcctNum(), "Opened account", true); + saveTransactionToDB(transaction); + break; + case "2": + Double interestRate = .01 * (1 + Math.floor(deposit/1000)); + Console.println(String.format("Your interest rate: %.2f", interestRate)+"%%"); + newAccount = new Savings(deposit, this.currentUser.getUserID(), (int)(Math.random()*1000), interestRate); + this.saveAccountToDB(newAccount); + usrAccounts.add(newAccount); + + transaction = new Transaction(deposit, new Date(), newAccount.getAcctNum(), "Opened account", true); + saveTransactionToDB(transaction); + break; + case "3": + Console.print("On a scale of 1-10, enter your risk tolerance "); + int riskInput = Console.getInteger(10); + Double risk = riskInput * .01; + newAccount = new Investment(deposit, this.currentUser.getUserID(), (int)(Math.random()*1000), risk); + this.saveAccountToDB(newAccount); + usrAccounts.add(newAccount); + + transaction = new Transaction(deposit, new Date(), newAccount.getAcctNum(), "Opened account", true); + saveTransactionToDB(transaction); + break; + case "4": + break; + } + + + } + + public void accountMenu(Account account) { + String header = account.getClass().getName() + " Account #" + account.getAcctNum().toString() + " Balance: $" + String.format("%,.2f", account.getBalance()); + if (account instanceof Savings) { + header += " Interest Rate: " + String.format("%.2f", ((Savings) account).getInterestRate())+"%%"; + } else if (account instanceof Investment) { + header += " Risk: " + String.format("%d", Math.round(100*((Investment) account).getRisk()))+"/10"; + } + String input = Console.getInput(header, new String[] {"View Transaction History", "Deposit", "Withdrawal", "Close Account", "Transfer", "Back to Main Menu" }); + + Double deposit; + Transaction transaction; + switch (input) { + case "1": + Console.outputTransactionsWithHeader("Transaction History", getTransactionsForAccount(account)); + break; + case "2": + deposit = Console.getCurrency("Deposit amount: "); + account.deposit(deposit); + saveAccountToDB(account); + transaction = new Transaction(deposit, new Date(), account.getAcctNum(), "ATM deposit", true); + saveTransactionToDB(transaction); + break; + case "3": + deposit = Console.getCurrency("Withdrawal amount: "); + if (deposit <= account.getBalance()) { + account.deposit(-1 * deposit); + saveAccountToDB(account); + transaction = new Transaction(deposit, new Date(), account.getAcctNum(), "ATM withdrawal", false); + saveTransactionToDB(transaction); + } else { + Console.println("Insufficient funds"); + Console.getInput("\nPress Enter"); + } + break; + case "4": + + if (account.getBalance() == 0) { + + deleteAccountFromDB(account); + transaction = new Transaction(0.0, new Date(), account.getAcctNum(), "Account Closed", false); + saveTransactionToDB(transaction); + } else { + Console.println("Account still contains funds. Withdraw or transfer all funds before closing."); + Console.getInput("\nPress Enter"); + } + break; + case "5": + + Console.println("Number of Account to transfer to"); + int ActToTransferTo = Console.getInteger(); + String[] actInfo = getAccountInfoByID(ActToTransferTo); + // 0: accountID 1: ownerID 2: balance 3: type 4: risk/interest/null (type-dependent) + Account act = getAccountByInfo(actInfo); + deposit = Console.getCurrency("Transfer amount"); + + if(deposit < account.getBalance()) { + account.deposit(-1 * deposit); + act.deposit(deposit); + + saveAccountToDB(account); + transaction = new Transaction(-1 * deposit, new Date(), account.getAcctNum(), "ATM Transfer", false); + saveTransactionToDB(transaction); + + saveAccountToDB(act); + transaction = new Transaction(deposit, new Date(), act.getAcctNum(), "ATM Transfer", true); + saveTransactionToDB(transaction); + } else { + Console.println("Insufficient funds in account"); + } + + break; + case "6": + break; + } + } + + + public void serviceLoop() { + // authenticate a user (or die trying) + // only returns null if the magic secret exit code is called + + getUser(); + applyInterest(); + applyReturns(); + + loadDBs(); + + userMenu(); + + logOut(); + + serviceLoop(); + } + + public void applyInterest() { + ArrayList userAccounts = getAccountsForUser(this.currentUser); + for (Account account : userAccounts) { + if (account instanceof Savings) { + calcInterest(account); + } + } + } + + public void calcInterest(Account account) { + Double interest = ((Savings) account).getInterestRate() * account.getBalance()/100; + account.deposit(interest); + saveAccountToDB(account); + Transaction transaction = new Transaction(Double.parseDouble(String.format("%.2f",interest)), new Date(), account.getAcctNum(), "Interest earned", true); + saveTransactionToDB(transaction); + } + + public void applyReturns() { + ArrayList userAccounts = getAccountsForUser(this.currentUser); + for (Account account : userAccounts) { + if (account instanceof Investment) { + calcReturns(account); + } + } + } + + public void calcReturns(Account account) { + Double multiplier = ((Investment) account).getRisk() * (2 * Math.random() - .8); + Double earnings = Math.round((multiplier * account.getBalance()*100d))/100d; + account.deposit(earnings); + saveAccountToDB(account); + Boolean isCredit = (earnings > 0); + Transaction transaction = new Transaction(Double.parseDouble(String.format("%.2f",earnings)), new Date(), account.getAcctNum(), "Investment returns", isCredit); + saveTransactionToDB(transaction); + } + + + // log out user + public void logOut() { + saveDBs(); + this.currentUser = null; + } + + // save DBs to disk + public void saveDBs() { +// // write the pending transaction queue +// for (Transaction transaction : this.currentUser.pendingTransactions) { +// transactionDB.addRow(transaction.toStringArray()); +// } +// // write the accounts +// int row; +// for (Account account : this.currentUser.accounts) { +// // find account row, replace it +// row = +// this.accountDB.replaceRow(accountDB.findPartialRow(), account.toString()); +// +// } + } + +// public void showTransactions(Transaction[] transactions) { +// String[][] rows = new String[5][transactions.length]; +// for (int i = 0; i < transactions.length; i++) { +// rows[i] = transactions[i].toStringArray(); +// } +// Console.outputTransactionsWithHeader("Transaction History", rows); +// } + + + /* /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + * DB interaction methods for the ATM + * + * We should create a storage class or generic methods in the DB class or something in the interface, but... + */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public int getUserCount() { + return this.userDB.length(); + } + + //find accounts by owner id (to then be used by constructor) + public int[] getAccountRowsByUser (User user) { + int [] recordRowNums; + recordRowNums = this.accountDB.findPartialRowMultiple(new String[] {user.getUserID().toString()}, new int[] {1}); + + return recordRowNums; + } + + // get string representation of one account + public String[] getAccountInfoByRow (int rowNum) { + return this.accountDB.readRow(rowNum); + } + + // account instance from info (pre-existing account) + public Account getAccountByInfo (String[] info) { + if (info[3].equals("Checking")) { + return new Checking(Double.parseDouble(info[2]), Integer.parseInt(info[1]), Integer.parseInt(info[0])); + } else if (info[3].equals("Savings")) { + return new Savings(Double.parseDouble(info[2]), Integer.parseInt(info[1]), Integer.parseInt(info[0]), Double.parseDouble(info[4])); + } else if (info[3].equals("Investment")) { + return new Investment(Double.parseDouble(info[2]), Integer.parseInt(info[1]), Integer.parseInt(info[0]), Double.parseDouble(info[4])); + } + return null; + } + + // AL of accounts for a user + public ArrayList getAccountsForUser(User user) { + int[] rows = getAccountRowsByUser(user); + ArrayList accounts = new ArrayList<>(); + for (int row : rows) { + accounts.add(getAccountByInfo(getAccountInfoByRow(row))); + } + return accounts; + } + + public int getMaxUserNumber() { + ArrayList userInfo = new ArrayList<>(); + userInfo = this.userDB.readAllRows(); + int maxID = 0; + for (String[] user : userInfo) { + if (Integer.parseInt(user[0]) > maxID) { + maxID = Integer.parseInt(user[0]); + } + } + return maxID; + } + + public int getMaxAccountNumber() { + ArrayList accountInfo = new ArrayList<>(); + accountInfo = this.accountDB.readAllRows(); + int maxID = 0; + for (String[] account : accountInfo) { + if (Integer.parseInt(account[0]) > maxID) { + maxID = Integer.parseInt(account[0]); + } + } + return maxID; + } + + //find user row by id + public Integer getUserRowByID (Integer ID) { + return this.userDB.findPartialRow(new String[]{ID.toString()}, new int[]{0}); + } + + //find user info by id (helper for constructor) + public String [] getUserInfoByID (Integer ID) { + int rowNumOfUser = this.userDB.findPartialRow(new String[] {ID.toString()}, new int[] {0}); + return this.userDB.readRow(rowNumOfUser); + } + + //find user info by card number (helper for constructor) + public String [] getUserInfoByCardNum (Integer cardNum) { + int rowNumOfUser = this.userDB.findPartialRow(new String[] {cardNum.toString()}, new int[] {3}); + return this.userDB.readRow(rowNumOfUser); + } + + //find account row by id + public Integer getAccountRowByID (Integer ID) { + return this.accountDB.findPartialRow(new String[]{ID.toString()}, new int[]{0}); + } + + //find account info by id (helper for constructor) + public String [] getAccountInfoByID (Integer ID) { + int rowNumOfAccount = this.accountDB.findPartialRow(new String[] {ID.toString()}, new int[] {0}); + return this.accountDB.readRow(rowNumOfAccount); + } + + public void saveUserToDB(User user) { + String[] stringRepOfUser = user.toStringArray(); + int userID = user.getUserID(); + int rowNum = getUserRowByID(userID); + if (rowNum == -1) { // user isn't in DB yet + this.userDB.addRow(stringRepOfUser); + } else { // update a found row + this.userDB.replaceRow(rowNum, stringRepOfUser); + } + } + + public void saveAccountToDB(Account account) { + String[] stringRepOfAccount = account.toStringArray(); + int accountNum = account.getAcctNum(); + int rowNum = getAccountRowByID(accountNum); + if (rowNum == -1) { // account isn't in DB yet + this.accountDB.addRow(stringRepOfAccount); + } else { // update a found row + this.accountDB.replaceRow(rowNum, stringRepOfAccount); + } + } + + public void deleteAccountFromDB(Account account) { + String[] stringRepOfAccount = account.toStringArray(); + int accountNum = account.getAcctNum(); + int rowNum = getAccountRowByID(accountNum); + if (rowNum == -1) { // account isn't in DB yet + this.accountDB.addRow(stringRepOfAccount); + return; + } else { // update a found row + this.accountDB.deleteRow(rowNum); + } + } + + public int[] getTransactionRowsByUser (User user) { + int[] accountRows = getAccountRowsByUser(user); + ArrayList accountNums = new ArrayList<>(); + for (int row : accountRows) { + accountNums.add(Integer.parseInt(getAccountInfoByRow(row)[0])); + } + + ArrayList rows = new ArrayList<>(); +// int [] recordRowNums = null; +// for (int accountNum : accountNums) { +// recordRowNums = this.transactionDB.findPartialRowMultiple(new String[]{Integer.toString(accountNum)}, new int[]{1}); +// +// } + ArrayList transData = transactionDB.readAllRows(); + + for (int i = 0; i < transData.size(); i++) { + for (int acctNum : accountNums) { + if ((int) Integer.parseInt(transData.get(i)[1]) == acctNum) { + rows.add(i); + } + } + } + + int[] results = new int[rows.size()]; + for (int i = 0; i < rows.size(); i++) { + results[i] = rows.get(i); + } + + return results; + } + + public int[] getTransactionRowsByAccount (Account account) { + return this.transactionDB.findPartialRowMultiple(new String[]{Integer.toString(account.getAcctNum())}, new int[]{1}); + } + + // get string array representation of one transaction + public String[] getTransactionInfoByRow (int rowNum) { + return this.transactionDB.readRow(rowNum); + } + + public ArrayList getTransactionsForUser(User user) { + return getTransactionsForRows(getTransactionRowsByUser(user)); + } + + public ArrayList getTransactionsForAccount(Account account) { + return getTransactionsForRows(getTransactionRowsByAccount(account)); + } + + public ArrayList getTransactionsForRows(int[] rows) { + ArrayList transactions = new ArrayList<>(); + String[] info = new String[5]; + for (int row : rows) { + info = getTransactionInfoByRow(row); + try { + transactions.add(new Transaction( + Double.parseDouble(info[2]), + new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").parse(info[3]), + Integer.parseInt(info[1]), + info[4], + info[0].equals("credit"))); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + return transactions; + } + + + + public void savePendingTransactionsToDB(ArrayList pendingTransactions) { + for (Transaction transaction : pendingTransactions) { + this.transactionDB.addRow(transaction.toStringArray()); + } + } + + public void saveTransactionToDB(Transaction transaction) { + this.transactionDB.addRow(transaction.toStringArray()); + } + + /* /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + * End DB interaction methods for the ATM + */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} diff --git a/src/main/java/Account.java b/src/main/java/Account.java new file mode 100644 index 0000000..96747eb --- /dev/null +++ b/src/main/java/Account.java @@ -0,0 +1,41 @@ +abstract public class Account implements Storeable { + public Double balance; + public Integer ownerID; + public Integer acctNum; + + public Account(Double balance, Integer ownerID, Integer acctNum) { + this.balance = balance; + this.ownerID = ownerID; + this.acctNum = acctNum; + } + + public Double getBalance(){ + return balance; + } + + public Integer getOwnerID() { + return this.ownerID; + } + + public Integer getAcctNum() { + return this.acctNum; + } + + public void deposit(Double amount){ + this.balance += amount; + String bal = String.format("%.2f",this.balance); + this.balance = Double.parseDouble(bal); + } + + public void withdraw(Double amount){ + if (this.balance > amount) { + this.balance -= amount; + } + } + + + public Boolean equals(Account account) { + return DB.serialize(this.toStringArray()).equals(DB.serialize(account.toStringArray())); + } +} + diff --git a/src/main/java/Checking.java b/src/main/java/Checking.java new file mode 100644 index 0000000..4f26eaf --- /dev/null +++ b/src/main/java/Checking.java @@ -0,0 +1,7 @@ +public class Checking extends Account { + + public Checking(Double balance, Integer ownerID, Integer acctNum){ + super(balance, ownerID, acctNum); + } + +} diff --git a/src/main/java/Console.java b/src/main/java/Console.java new file mode 100644 index 0000000..ac56185 --- /dev/null +++ b/src/main/java/Console.java @@ -0,0 +1,189 @@ +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.Scanner; + +/** + * Created by leon on 2/9/18. + */ +public class Console { + + public static void clearScreen() { + for (int i = 0; i <100; i++) { + Console.println(" "); + } + } + + public static void print(String output, Object... args) { + System.out.printf(output, args); + } + + public static void println(String output, Object... args) { + print(output + "\n", args); + } + + public static String getInput() { + Console.print("> "); + Scanner scanner = new Scanner(System.in); + + String input = scanner.nextLine().toLowerCase(); //get input from user + + return input; + } + + public static String getInput(String prompt) { + Console.print(prompt); + Scanner scanner = new Scanner(System.in); + + String input = scanner.nextLine().toLowerCase(); //get input from user + + return input; + } + + + public static String getInput(String[] options) { + + Console.clearScreen(); + + int numOptions = options.length; + int numRows = (numOptions+1) >> 1; // this is how the cool kids divide by two + String output = ""; + + String[] rows = new String[numRows]; + + for (int i = 0; i < numRows; i++){ + rows[i] = String.format("%d | %-30s", 2*i+1, options[2*i]); + if (2*i + 1 < numRows) { + rows[i] += String.format("%30s | %d", options[2*i + 1], 2*(i+1)); + } + rows[i] += "\n"; + } + + for (int i = 0; i < numRows; i++) { + output += rows[i]; + } + + println(output); + + return Integer.toString(Console.getInteger(numOptions)); + + } + + public static String getInput(String header, String[] options) { + + Console.clearScreen(); + + int numOptions = options.length; + int numRows = (numOptions+1) >> 1; // this is how the cool kids divide by two + String output = StringUtils.center(header,86) + "\n\n"; + + String[] rows = new String[numRows]; + + for (int i = 0; i < numRows; i++){ + rows[i] = String.format("%d | %-40s", 2*i+1, options[2*i]); + if (2*i + 1 < numOptions) { + rows[i] += String.format("%40s | %d", options[2*i + 1], 2*(i+1)); + } + rows[i] += "\n"; + } + + for (int i = 0; i < numRows; i++) { + output += rows[i]; + } + + println(output); + + return Integer.toString(Console.getInteger(numOptions)); + + } + + public static void outputTransactionsWithHeader(String header, ArrayList transactions) { + + Console.clearScreen(); + + String output = StringUtils.center(header,86) + "\n\n"; + String[] row; + for (Transaction transaction : transactions) { + row = transaction.toStringArray(); + output += (String.format("%-8s", row[0]) + + String.format("%-10s", row[1]) + + String.format("%-10s", row[2]) + + String.format("%-20s", row[3]) + + String.format(" %s", row[4]) + + "\n"); + } + + println(output); + getInput("\nPress Enter"); + } + + static Boolean integerCheck(String input) { + return input.matches("^\\d+$"); + } + + static Boolean currencyCheck(String input) { + return input.matches("^[0-9]{1,3}(?:,?[0-9]{3})*(?:\\.[0-9]{2})?$"); + } + + public static Double getCurrency() { + String input = getInput("$"); + while (true) { + if (currencyCheck(input)) break; + else { + println("Enter a number"); + input = getInput("$"); + } + } + return Double.valueOf(input); + } + + public static Double getCurrency(String prompt) { + Console.print(prompt); + String input = getInput("$"); + while (true) { + if (currencyCheck(input)) break; + else { + println("Enter a valid number"); + Console.print(prompt); + input = getInput("$"); + } + } + return Double.valueOf(input); + } + + public static Integer getInteger() { + String input = getInput(); + while (true) { + if (integerCheck(input)) break; + else { + println("Enter a number"); + input = getInput(); + } + } + return Integer.valueOf(input); + } + + public static Integer getInteger(int max) { + String input = getInput(); + while (true) { + if (integerCheck(input)) { + if (Integer.parseInt(input) >= 1 && Integer.parseInt(input) <= max) { + break; + } else { + println("Enter a number between 1 and " + Integer.toString(max)); + input = getInput(); + } + } + else { + println("Enter a number"); + input = getInput(); + } + } + return Integer.valueOf(input); + } + +} diff --git a/src/main/java/DB.java b/src/main/java/DB.java new file mode 100644 index 0000000..853aac7 --- /dev/null +++ b/src/main/java/DB.java @@ -0,0 +1,466 @@ +import com.opencsv.CSVReader; +import com.opencsv.CSVWriter; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class DB { + + private String fileName; + private String path; + private Integer rowLength; + private Boolean deleted; + + /** + * DB object constructor + * + * Creates a DB object - connects to an existing file or creates an empty file + * + * @param fileName String: desired csv filename (with extension) + * @param rowLength Integer: the length of each row in the DB; if it conflicts with data in an existing file, will be overridden + * @throws IOException + */ + public DB(String fileName, Integer rowLength) throws IOException { + this.fileName = fileName; + this.path = fileNameToPath(this.fileName, System.getProperty("user.dir")); + this.rowLength = rowLength; + this.deleted = false; + + try { // look for an existing file with that name + Reader reader = Files.newBufferedReader(Paths.get(this.path)); + CSVReader csvReader = new CSVReader(reader); + + // get all records at once, use that rowLength to override given one, if nec. + List records = csvReader.readAll(); + if (records.size() > 0) { + this.rowLength = records.get(0).length; + } + + } + catch(NoSuchFileException e) { // make a new file, if one doesn't exist in place + File file = new File(this.path); + FileWriter outputfile = new FileWriter(file); + + // create CSVWriter object filewriter object as parameter + CSVWriter writer = new CSVWriter(outputfile); + + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * isDeleted + * + * Returns true if the DB file has been deleted - called in many methods to prevent trying to access deleted file + * + * @return Boolean: deleted status + */ + public Boolean isDeleted() { + return deleted; + } + + /** + * getFileName + * + * Returns the file name of the DB (not the full path) + * + * @return String fileName + */ + public String getFileName() { + if (!this.deleted) { + return this.fileName; + } else { + return null; + } + } + + /** + * pathToFileName (static) + * + * removes last / and everything before from a string, to get the filename + * + * @param Path String: the path to some file + * @return String: fileName + */ + public static String pathToFileName (String Path) { + String[] splitter = Path.split("/"); + return splitter[splitter.length - 1]; + } + + /** + * fileNameToPath (static) + * + * given a file name, append the path to the data folder + * + * @param FN String: the file name + * @param PWD String: present working directory String + * @return + */ + public static String fileNameToPath (String FN, String PWD) { + return PWD + "/data/" + FN; + } + + /** + * length + * + * Determine the length of this DB + * + * @return Integer: length + */ + public Integer length() { + if (!this.deleted) { + return readAllRows().size(); + } else { + return null; + } + } + + /** + * getRowLength + * + * Return the length of rows in this DB + * + * @return Integer: rowLength + */ + public Integer getRowLength() { + if (!this.deleted) { + return this.rowLength; + } else { + return null; + } + } + + /** + * checkIntegrity + * + * Return true if the DB has rows all of the same length, which is the rowLength property + * + * @return Boolean + */ + public Boolean checkIntegrity() { + if (!this.deleted) { + ArrayList records = readAllRows(); + + for (String[] row : records) { + if (row.length != this.rowLength) { + return false; + } + } + return true; + } else { + return false; + } + } + + /** + * addRow + * + * Input a String[] that is a new row to add; if it is the proper length, it is added to the DB + * + * @param row String[]: the row to be input + */ + public void addRow(String[] row) { + if (!this.deleted) { + try { + File file = new File(this.path); + FileWriter outputfile = new FileWriter(file, true); + + // create CSVWriter object filewriter object as parameter + CSVWriter writer = new CSVWriter(outputfile); + if (row.length == this.rowLength) { // only write if this row is the correct length + writer.writeNext(row); + } + + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * replaceRow + * + * Replaces a row (identified by index) with an input String[]; must be correct size array + * + * @param rowNum int: which row to replace + * @param replacement String[]: the row with which to replace it + */ + public void replaceRow(int rowNum, String[] replacement) { + ArrayList records = null; + if (!this.deleted && rowNum < length() && replacement.length == this.rowLength) { + records = readAllRows(); + records.set(rowNum, replacement); + } + clear(); + for (String[] row : records) { + addRow(row); + } + } + + /** + * deleteRow + * + * Delete an existing row, by index + * + * @param rowNum int: the row index to be deleted + */ + public void deleteRow(int rowNum) { + ArrayList records = null; + if (!this.deleted && rowNum < length()) { + records = readAllRows(); + records.remove(rowNum); + } + clear(); + for (String[] row : records) { + addRow(row); + } + } + + /** + * readRow (by index) + * + * Return the ith row + * + * @param rowNum int: the row number + * @return String[] row: the desired row + */ + public String[] readRow(int rowNum) { + ArrayList records = null; + if (!this.deleted && rowNum < length() && rowNum >= 0) { + records = readAllRows(); + return records.get(rowNum); + } else if (rowNum == -1) { + return null; + } + return new String[this.rowLength]; + } + + /** + * findWholeRow (by row) + * + * Returns the index of an entire row which is input + * + * @param row String[]: the row to find + * @return int rowNum: the index of that row + */ + public int findWholeRow (String[] row) { + if (!this.deleted) { + String[] expected; + for (int i = 0; i < this.length(); i++) { + if (this.serialize(row).equals(this.serialize(i))) { + return i; + } + } + return -1; + } else { + return -1; + } + } + + /** + * findPartialRow + * + * Find a row's index, given a set of field values and numbers + * + * @param fragment String[]: an array of field values to find within a row + * @param fields int[]: the field positions that correspond with those values + * @return int rowNum: the index of the row + */ + public int findPartialRow (String[] fragment, int[] fields) { + if (!this.deleted) { + String signature = serialize(fragment); + for (int i = 0; i < this.length(); i++) { + if (signature.equals(this.partialSerialize(i,fields))) { + return i; + } + } + return -1; + } else { + return -1; + } + } + + /** + * findPartialRowMultiple + * + * Find a set of row indices, given a set of field values and numbers to match. + * Matches first result, if multiple are present + * + * @param fragment String[]: an array of field values to find within a row + * @param fields int[]: the field positions that correspond with those values + * @return int[] rowNums: the indices of the rows + */ + public int[] findPartialRowMultiple (String[] fragment, int[] fields) { + if (!this.deleted) { + String signature = serialize(fragment); + ArrayList matchedRows = new ArrayList(); + for (int i = 0; i < this.length(); i++) { + if (signature.equals(this.partialSerialize(i,fields))) { + matchedRows.add(i); + } + } + + if (matchedRows.size() > 0) { + int[] result = new int[matchedRows.size()]; + for (int i = 0; i < matchedRows.size(); i++ ) { + result[i] = matchedRows.get(i); + } + return result; + } else { + return new int[0]; + } + } else { + return null; + } + } + + /** + * serialize (object) + * + * Take any row, by index, and return a string representation + * + * @param rowNum int: the row to serialize + * @return String: serial representation + */ + public String serialize(int rowNum) { + if (!this.deleted) { + return DB.serialize(this.readRow(rowNum)); + } else { + return null; + } + } + + /** + * partialSerialize (object) + * + * Turn part of a row into a string representation + * + * @param rowNum int: the row to serialize + * @param fields int[]: which fields from the row to serialize + * @return String: serialized representation of those fields + */ + public String partialSerialize(int rowNum, int[] fields) { + if (!this.deleted) { + return DB.partialSerialize(this.readRow(rowNum),fields); + } else { + return null; + } + } + + /** + * serialize (static) + * + * Take any String [] and return a string representation + * + * @param row String[]: the 'row' to serialize + * @return String: serial representation + */ + public static String serialize(String[] row) { + return String.join("/", row); + } + + /** + * partialSerialize (static) + * + * Turn part of a String[] into a string representation + * + * @param fragment String[]: an array of field values to serialize + * @param fields int[]: the field positions that correspond with those values + * @return String: serialized representation of those fields + */ + public static String partialSerialize(String[] fragment, int[] fields) { + String[] partialArray = new String[fields.length]; + for (int i = 0; i < fields.length; i++) { + partialArray[i] = fragment[fields[i]]; + } + return String.join("/", partialArray); + } + + /** + * readAllRows + * + * Return an ArrayList of all of the rows in the DB + * + * @return ArrayList of String[] arrays: the data + */ + public ArrayList readAllRows() { + if (!this.deleted) { + try { // look for an existing file with that name + Reader reader = Files.newBufferedReader(Paths.get(this.path)); + CSVReader csvReader = new CSVReader(reader); + + // get all records at once + List records = csvReader.readAll(); + // loop through records + return new ArrayList(records); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } else { + return null; + } + + } + + /** + * printDB + * + * For debugging: print out the whole DB + * + */ + public void printDB() { + if (!this.deleted) { + for (String[] row : readAllRows()) { + System.out.println(serialize(row)); + } + } + } + + /** + * clear + * + * Method to clear the DB + * + */ + public void clear() { + if (!this.deleted) { + try { + File file = new File(this.path); + FileWriter outputfile = new FileWriter(file); + + // create CSVWriter object filewriter object as parameter + CSVWriter writer = new CSVWriter(outputfile); + + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * delete + * + * Method to delete the DB file + * + */ + public void delete() { + + File file = new File(this.path); + file.delete(); + this.deleted = true; + + } + + +} diff --git a/src/main/java/Investment.java b/src/main/java/Investment.java new file mode 100644 index 0000000..f1bb543 --- /dev/null +++ b/src/main/java/Investment.java @@ -0,0 +1,24 @@ +import java.util.Random; + +public class Investment extends Account implements Storeable { + + + + Double risk; + + public Investment(Double balance, Integer ownerID, Integer acctNum, Double risk) { + super(balance, ownerID, acctNum); + this.risk = risk; + + } + public Double getRisk() { + return risk; + } + + public void setRisk(Double risk) { + this.risk = risk; + } + + + +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 05e41a9..fb46af8 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,9 +1,10 @@ -/** - * Created by iyasuwatts on 10/17/17. - */ +import java.io.IOException; + public class Main { - public static void main(String[] args){ - + public static void main(String[] args) { + ATM atm = new ATM("users.csv", "accounts.csv", "transactions.csv"); + + atm.serviceLoop(); } } diff --git a/src/main/java/Savings.java b/src/main/java/Savings.java new file mode 100644 index 0000000..d242ec5 --- /dev/null +++ b/src/main/java/Savings.java @@ -0,0 +1,15 @@ +public class Savings extends Account{ + + public Double interestRate; + + public Savings(Double balance, Integer ownerID, Integer acctNum, Double interestRate) { + super(balance, ownerID, acctNum); + this.interestRate = interestRate; + } + + public Double getInterestRate() { + return this.interestRate; + } + + +} diff --git a/src/main/java/Storeable.java b/src/main/java/Storeable.java new file mode 100644 index 0000000..40a48e3 --- /dev/null +++ b/src/main/java/Storeable.java @@ -0,0 +1,34 @@ +public interface Storeable { + + default String[] toStringArray() { + if (this instanceof Account) { + + String acctType; + String typeSpecificProperty; + if (this instanceof Investment) { + acctType = "Investment"; + typeSpecificProperty = ((Investment) this).risk.toString(); + } else if (this instanceof Savings) { + acctType = "Savings"; + typeSpecificProperty = ((Savings) this).interestRate.toString(); + } else { + acctType = "Checking"; + typeSpecificProperty = ""; + } + + String[] result = new String[] { + ((Account) this).acctNum.toString(), + ((Account) this).ownerID.toString(), + ((Account) this).balance.toString(), + acctType, + typeSpecificProperty + }; + + return result; + + } else { + return null; + } + } + +} diff --git a/src/main/java/Transaction.java b/src/main/java/Transaction.java new file mode 100644 index 0000000..1675c5f --- /dev/null +++ b/src/main/java/Transaction.java @@ -0,0 +1,42 @@ +import java.util.Date; + +public class Transaction implements Storeable { + + private Double amount; + private Date timeStamp; + private Integer accountID; + private String description; + private Boolean isCredit; + // 0: credit/debit 1: accountID 2: amount (signed) 3: timeStamp 4: description + public Transaction(Double amount, Date timeStamp, Integer accountID, String description, Boolean isCredit) { + this.amount = amount; + this.timeStamp = timeStamp; + this.accountID = accountID; + this.description = description; + this.isCredit = isCredit; + } + + public String print() { + return amount + " " + description + timeStamp; + } + + + @Override + public String[] toStringArray() { + String type; + if (isCredit) { + type = "credit"; + } else { + type = "debit"; + } + + String[] result = new String[] { + type, + this.accountID.toString(), + String.format("%.2f",this.amount), + this.timeStamp.toString(), + this.description + }; + return result; + } +} diff --git a/src/main/java/User.java b/src/main/java/User.java new file mode 100644 index 0000000..6955094 --- /dev/null +++ b/src/main/java/User.java @@ -0,0 +1,63 @@ +import java.util.ArrayList; + +public class User implements Storeable { + + private String firstName; + private String lastName; + private String password; + private Integer userID; + private Integer cardNumber; + private ArrayList pendingTransactions; + + public User(String firstName, String lastName, String password, Integer userID, Integer cardNumber) { + this.firstName = firstName; + this.lastName = lastName; + this.password = password; + this.userID = userID; + this.cardNumber = cardNumber; + } + + public static Integer genCardNum() { + String numString = ""; + for (int i = 0; i < 8; i++) { + Integer num; + if(i == 0 || i == 7) { + num = (int)(Math.random() * 9 + 1); + } else { + num = (int)(Math.random() * 10); + } + numString += num.toString(); + } + return Integer.parseInt(numString); + } + + public ArrayList getUserHistory() { + + return pendingTransactions; + } + + public String getPassword() { + return password; + } + + public Integer getUserID() { + return userID; + } + + public ArrayList getPendingTransactions() { + return pendingTransactions; + } + + @Override + public String[] toStringArray() { + String[] result = new String[] { + this.userID.toString(), + this.lastName, + this.firstName, + this.cardNumber.toString(), + this.password + }; + return result; + } + +} diff --git a/src/test/java/ATMTest.java b/src/test/java/ATMTest.java new file mode 100644 index 0000000..95efc72 --- /dev/null +++ b/src/test/java/ATMTest.java @@ -0,0 +1,582 @@ +import junitparams.JUnitParamsRunner; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Arrays; + +@RunWith(JUnitParamsRunner.class) +public class ATMTest { + + private ATM atm; + + @Before + public void setUp() throws Exception { + atm = new ATM ("testuserDB.csv", "testaccountDB.csv", "testtransactionDB.csv"); + } + + @After + public void tearDown() throws Exception { + atm.getUserDB().clear(); + atm.getAccountDB().clear(); + atm.getTransactionDB().clear(); + } + + @Test + public void getUserDB() { + + DB foundDB = atm.getUserDB(); + String fileName = foundDB.getFileName(); + Assert.assertEquals("testuserDB.csv",fileName); + } + + @Test + public void getTransactionDB() { + + DB foundDB = atm.getTransactionDB(); + String fileName = foundDB.getFileName(); + Assert.assertEquals("testtransactionDB.csv",fileName); + } + + @Test + public void getAccountDB() { + + DB foundDB = atm.getAccountDB(); + String fileName = foundDB.getFileName(); + Assert.assertEquals("testaccountDB.csv",fileName); + } + + @Test + public void getUserCount() { + + DB userDB = atm.getUserDB(); + userDB.clear(); + Assert.assertEquals((int) 0, (int) userDB.length()); + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + userDB.addRow(user1.toStringArray()); + Assert.assertEquals((int) 1, (int) userDB.length()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + userDB.addRow(user2.toStringArray()); + Assert.assertEquals((int) 2, (int) userDB.length()); + } + + @Test + public void setCurrentUser() { + + User foundUser = atm.getCurrentUser(); + Assert.assertEquals(foundUser, null); + + User user = new User("Jim","Brown","goolybib", 12, 12343); + atm.setCurrentUser(user); + + foundUser = atm.getCurrentUser(); + Assert.assertEquals(foundUser, user); + } + + @Test + public void authenticate() { + } + + @Test + public void getUserInfoByID() { + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + userDB.addRow(user1.toStringArray()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + userDB.addRow(user2.toStringArray()); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 32, 313); + userDB.addRow(user3.toStringArray()); + + String[] actual = atm.getUserInfoByID(122); + String[] expected = user2.toStringArray(); + + Assert.assertEquals(actual,expected); + } + + @Test + public void getMaxUserNumberTest() { + DB userDB = atm.getUserDB(); + userDB.clear(); + + int actual = atm.getMaxUserNumber(); + int expected = 0; + + Assert.assertEquals(actual,expected); + + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + atm.saveUserToDB(user1); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + atm.saveUserToDB(user2); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 32, 313); + atm.saveUserToDB(user3); + + actual = atm.getMaxUserNumber(); + expected = 122; + + Assert.assertEquals(actual,expected); + + User user4 = new User("Jane","Himne","gasdsdool321ybib", 29, 313); + atm.saveUserToDB(user4); + + actual = atm.getMaxUserNumber(); + expected = 122; + + Assert.assertEquals(actual,expected); + + User user5 = new User("Jane","Himne","gasdsdool321ybib", 199, 313); + atm.saveUserToDB(user5); + + actual = atm.getMaxUserNumber(); + expected = 199; + + Assert.assertEquals(actual,expected); + } + + @Test + public void getMaxAccountNumberTest() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + int actual = atm.getMaxAccountNumber(); + int expected = 0; + + Assert.assertEquals(actual,expected); + + Account account1 = new Checking(1532.34,23,2123); + atm.saveAccountToDB(account1); + + actual = atm.getMaxAccountNumber(); + expected = 2123; + + Assert.assertEquals(actual,expected); + + Account account2 = new Savings(120.43,12,33, 0.01); + atm.saveAccountToDB(account2); + + actual = atm.getMaxAccountNumber(); + expected = 2123; + + Assert.assertEquals(actual,expected); + + Account account3 = new Investment(234023.23,42,48, 0.06); + atm.saveAccountToDB(account3); + Account account4 = new Checking(1532.34,42,5423); + atm.saveAccountToDB(account4); + Account account5 = new Savings(120.43,98,333223, 0.01); + atm.saveAccountToDB(account5); + Account account6 = new Investment(234023.23,42,9948, 0.06); + atm.saveAccountToDB(account6); + Account account7 = new Checking(1532.34,23,515); + atm.saveAccountToDB(account7); + Account account8 = new Savings(120.43,12,749, 0.01); + atm.saveAccountToDB(account8); + Account account9 = new Investment(234023.23,42,904, 0.06); + atm.saveAccountToDB(account9); + + actual = atm.getMaxAccountNumber(); + expected = 333223; + + Assert.assertEquals(actual,expected); + } + + @Test + public void getUserInfoByCardNumTest() { + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + userDB.addRow(user1.toStringArray()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + userDB.addRow(user2.toStringArray()); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 32, 313); + userDB.addRow(user3.toStringArray()); + + String[] actual = atm.getUserInfoByCardNum(1234313); + String[] expected = user2.toStringArray(); + + Assert.assertEquals(actual,expected); + + actual = atm.getUserInfoByCardNum(313); + expected = user3.toStringArray(); + + Assert.assertEquals(actual,expected); + } + + @Test + public void getUserRowByID() { + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + userDB.addRow(user1.toStringArray()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + userDB.addRow(user2.toStringArray()); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 32, 313); + userDB.addRow(user3.toStringArray()); + + int actual = atm.getUserRowByID(122); + int expected = 1; + + Assert.assertEquals(actual,expected); + + actual = atm.getUserRowByID(12); + expected = 0; + + Assert.assertEquals(actual,expected); + + actual = atm.getUserRowByID(32); + expected = 2; + + Assert.assertEquals(actual,expected); + + actual = atm.getUserRowByID(323232); + expected = -1; + + Assert.assertEquals(actual,expected); + } + + @Test + public void getAccountInfoByID() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + Account account1 = new Checking(1532.34,23,1232123); + accountDB.addRow(account1.toStringArray()); + Account account2 = new Savings(120.43,12,333223, 0.01); + accountDB.addRow(account2.toStringArray()); + Account account3 = new Investment(234023.23,42,9948, 0.06); + accountDB.addRow(account3.toStringArray()); + + String[] actual = atm.getAccountInfoByID(333223); + String[] expected = account2.toStringArray(); + + Assert.assertEquals(actual,expected); + } + + @Test + public void getAccountRowByID() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + Account account1 = new Checking(1532.34,23,1232123); + accountDB.addRow(account1.toStringArray()); + Account account2 = new Savings(120.43,12,333223, 0.01); + accountDB.addRow(account2.toStringArray()); + Account account3 = new Investment(234023.23,42,9948, 0.06); + accountDB.addRow(account3.toStringArray()); + + int actual = atm.getAccountRowByID(333223); + int expected = 1; + + Assert.assertEquals(expected, actual); + + actual = atm.getAccountRowByID(1232123); + expected = 0; + + Assert.assertEquals(expected, actual); + + actual = atm.getAccountRowByID(9948); + expected = 2; + + Assert.assertEquals(expected, actual); + + actual = atm.getAccountRowByID(99323248); + expected = -1; + + Assert.assertEquals(expected, actual); + } + + @Test + public void getAccountIDsByUserTest() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 98, 12343); + userDB.addRow(user1.toStringArray()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 42, 1234313); + userDB.addRow(user2.toStringArray()); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 33, 313); + userDB.addRow(user3.toStringArray()); + + + Account account1 = new Checking(1532.34,23,1232123); + accountDB.addRow(account1.toStringArray()); + Account account2 = new Savings(120.43,12,33, 0.01); + accountDB.addRow(account2.toStringArray()); + Account account3 = new Investment(234023.23,42,48, 0.06); + accountDB.addRow(account3.toStringArray()); + Account account4 = new Checking(1532.34,42,5423); + accountDB.addRow(account4.toStringArray()); + Account account5 = new Savings(120.43,98,333223, 0.01); + accountDB.addRow(account5.toStringArray()); + Account account6 = new Investment(234023.23,42,9948, 0.06); + accountDB.addRow(account6.toStringArray()); + Account account7 = new Checking(1532.34,23,515); + accountDB.addRow(account7.toStringArray()); + Account account8 = new Savings(120.43,12,749, 0.01); + accountDB.addRow(account8.toStringArray()); + Account account9 = new Investment(234023.23,42,904, 0.06); + accountDB.addRow(account9.toStringArray()); + + int[] rows = atm.getAccountRowsByUser(user1); + String [] accountInfo; + int[] accts = {333223}; + for (int i = 0; i < rows.length; i++) { + accountInfo = atm.getAccountInfoByRow(rows[i]); + Assert.assertEquals("user1", (int)user1.getUserID(), (int) Integer.parseInt(accountInfo[1])); + Assert.assertEquals("user1", (int)accts[i], (int) Integer.parseInt(accountInfo[0])); + } + + int[] rows2 = atm.getAccountRowsByUser(user2); + String [] accountInfo2; + int[] accts2 = {48,5423,9948,904}; + for (int i = 0; i < rows2.length; i++) { + accountInfo2 = atm.getAccountInfoByRow(rows2[i]); + Assert.assertEquals("user2", (int)user2.getUserID(), (int) Integer.parseInt(accountInfo2[1])); + Assert.assertEquals("user2", (int)accts2[i], (int) Integer.parseInt(accountInfo2[0])); + } + + int[] rows3 = atm.getAccountRowsByUser(user3); + String [] accountInfo3; + int[] accts3 = {}; + for (int i = 0; i < rows3.length; i++) { + accountInfo3 = atm.getAccountInfoByRow(rows3[i]); + Assert.assertEquals("user3", (int)user3.getUserID(), (int) Integer.parseInt(accountInfo3[1])); + Assert.assertEquals("user3", (int)accts3[i], (int) Integer.parseInt(accountInfo3[0])); + } + } + + @Test + public void getAccountByInfoTest() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + Account account1 = new Checking(1532.34,23,1232123); + accountDB.addRow(account1.toStringArray()); + Account account2 = new Savings(120.43,12,33, 0.01); + accountDB.addRow(account2.toStringArray()); + Account account3 = new Investment(234023.23,42,48, 0.06); + accountDB.addRow(account3.toStringArray()); + Account account4 = new Checking(1532.34,42,5423); + accountDB.addRow(account4.toStringArray()); + Account account5 = new Savings(120.43,98,333223, 0.01); + accountDB.addRow(account5.toStringArray()); + + Assert.assertTrue("acct1", account1.equals(atm.getAccountByInfo(account1.toStringArray()))); + Assert.assertTrue("acct2", account2.equals(atm.getAccountByInfo(account2.toStringArray()))); + Assert.assertTrue("acct5", account5.equals(atm.getAccountByInfo(account5.toStringArray()))); + Assert.assertEquals(null, atm.getAccountByInfo(new String[] {"","","","",""})); + + } + + @Test + public void getAccountsForUserTest() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 98, 12343); + userDB.addRow(user1.toStringArray()); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 42, 1234313); + userDB.addRow(user2.toStringArray()); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 33, 313); + userDB.addRow(user3.toStringArray()); + + + Account account1 = new Checking(1532.34,23,1232123); + accountDB.addRow(account1.toStringArray()); + Account account2 = new Savings(120.43,12,33, 0.01); + accountDB.addRow(account2.toStringArray()); + Account account3 = new Investment(234023.23,42,48, 0.06); + accountDB.addRow(account3.toStringArray()); + Account account4 = new Checking(1532.34,42,5423); + accountDB.addRow(account4.toStringArray()); + Account account5 = new Savings(120.43,98,333223, 0.01); + accountDB.addRow(account5.toStringArray()); + Account account6 = new Investment(234023.23,42,9948, 0.06); + accountDB.addRow(account6.toStringArray()); + Account account7 = new Checking(1532.34,23,515); + accountDB.addRow(account7.toStringArray()); + Account account8 = new Savings(120.43,12,749, 0.01); + accountDB.addRow(account8.toStringArray()); + Account account9 = new Investment(234023.23,42,904, 0.06); + accountDB.addRow(account9.toStringArray()); + + ArrayList actual = atm.getAccountsForUser(user1); + + Assert.assertEquals("user1", (int) 1, (int) actual.size()); + Assert.assertTrue("user1.1", Arrays.equals(account5.toStringArray(),actual.get(0).toStringArray())); + + actual = atm.getAccountsForUser(user2); + + Assert.assertEquals("user2", (int) 4, (int) actual.size()); + Assert.assertTrue("user2.1", Arrays.equals(account6.toStringArray(),actual.get(2).toStringArray())); + Assert.assertTrue("user2.3", Arrays.equals(account3.toStringArray(),actual.get(0).toStringArray())); + } + + @Test + public void saveUserToDBTest() { + DB userDB = atm.getUserDB(); + userDB.clear(); + + User user1 = new User("Jim","Brown","goolybib", 12, 12343); + atm.saveUserToDB(user1); + User user2 = new User("Ji123m","Bro23wn","gool321ybib", 122, 1234313); + atm.saveUserToDB(user2); + User user3 = new User("Jane","Himne","gasdsdool321ybib", 32, 313); + atm.saveUserToDB(user3); + + String[] actual = atm.getUserInfoByID(122); + String[] expected = user2.toStringArray(); + + Assert.assertEquals(actual,expected); + + actual = atm.getUserInfoByID(12); + expected = user1.toStringArray(); + + Assert.assertEquals(actual,expected); + + int actual2 = userDB.length(); + int expected2 = 3; + + Assert.assertEquals(actual,expected); + + User user4 = new User("Ji123m","Bro23wn","gool321ysdasdbib", 12, 1234313); + atm.saveUserToDB(user4); + + actual2 = userDB.length(); + expected2 = 3; + + Assert.assertEquals(actual,expected); + + actual = atm.getUserInfoByID(12); + expected = user4.toStringArray(); + + Assert.assertEquals(actual,expected); + + expected = user1.toStringArray(); + + Assert.assertNotEquals(actual,expected); + } + + @Test + public void savePendingTransactionsTest() { + DB transactionDB = atm.getTransactionDB(); + transactionDB.clear(); + Assert.assertEquals((int)0, (int)transactionDB.length()); + + Transaction trans1 = new Transaction(123.42, new Date(2014, 1, 6, 11,23, 40 ),23,"Opened account", true); + Transaction trans2 = new Transaction(-23.57, new Date(2015, 2, 7, 10,23, 3 ),12,"Withdrawal", false); + ArrayList pendingTransactions = new ArrayList(); + pendingTransactions.add(trans1); + pendingTransactions.add(trans2); + + atm.savePendingTransactionsToDB(pendingTransactions); + + Assert.assertEquals((int)2, (int)transactionDB.length()); + + transactionDB.clear(); + Assert.assertEquals((int)0, (int)transactionDB.length()); + + } + + @Test + public void saveAccountToDBTest() { + DB accountDB = atm.getAccountDB(); + accountDB.clear(); + + Account account1 = new Checking(1532.34,23,1232123); + atm.saveAccountToDB(account1); + Account account2 = new Savings(120.43,12,749, 0.01); + atm.saveAccountToDB(account2); + Account account3 = new Investment(234023.23,42,48, 0.06); + atm.saveAccountToDB(account3); + Account account4 = new Checking(1532.34,42,5423); + atm.saveAccountToDB(account4); + + + String[] actual = atm.getAccountInfoByID(48); + String[] expected = account3.toStringArray(); + + Assert.assertEquals(actual,expected); + + actual = atm.getAccountInfoByID(1232123); + expected = account1.toStringArray(); + + Assert.assertEquals(actual,expected); + + int actual2 = accountDB.length(); + int expected2 = 4; + + Assert.assertEquals(actual,expected); + + Account account10 = new Savings(9990.43,12,749, 0.01); + atm.saveAccountToDB(account10); + + actual2 = accountDB.length(); + expected2 = 4; + + Assert.assertEquals(actual,expected); + + actual = atm.getAccountInfoByID(749); + expected = account10.toStringArray(); + + Assert.assertEquals(actual,expected); + + } + +// @Test +// public void transactionHistoryShowTest() { +// DB transactionDB = new DB("transactions.csv"); +// +// +// atm.showTransactions(); +// } + + // convenience methods for dev environment to clear the DBs - only called from the IDE manually +// @Test +// public void clearUserDB() { +// DB userDB = null; +// try { +// userDB = new DB("users.csv", 5); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// userDB.clear(); +// } +// +// @Test +// public void clearAccountDB() { +// DB accountDB = null; +// try { +// accountDB = new DB("accounts.csv", 5); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// accountDB.clear(); +// } +// +// @Test +// public void clearTransactionDB() { +// DB transactionDB = null; +// try { +// transactionDB = new DB("transactions.csv", 5); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// transactionDB.clear(); +// } + +} \ No newline at end of file diff --git a/src/test/java/AccountTest.java b/src/test/java/AccountTest.java new file mode 100644 index 0000000..de2c872 --- /dev/null +++ b/src/test/java/AccountTest.java @@ -0,0 +1,92 @@ +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class AccountTest { + + @Test + public void getBalance() { + // Given + Account account = new Checking(0.0, 3,3); + Double expected = 0.0; + + + // Then + Double actual = account.getBalance(); + assertEquals(expected, actual); + } + + @Test + public void deposit_test() { + // Given + Account account = new Checking(0.0, 3,3); + Double expected = 40.0; + + //When + account.deposit(40.0); + + // Then + Double actual = account.getBalance(); + assertEquals(expected, actual); + + } + + @Test + public void withdraw_test() { + // Given + Account account = new Checking(80.0, 3,3); + Double expected = 40.0; + + //When + account.withdraw(40.0); + + // Then + Double actual = account.getBalance(); + assertEquals(expected, actual); + } + + + @Test + public void getAcctHist() { + } + + @Test + public void getOwnerID() { + // Given + Account account = new Checking(0.0, 3,3); + Integer expected = 3; + + + // Then + Integer actual = account.getOwnerID(); + assertEquals(expected, actual); + } + + @Test + public void getAcctNum() { + // Given + Account account = new Checking(0.0, 3,3); + Integer expected = 3; + + + // Then + Integer actual = account.getAcctNum(); + assertEquals(expected, actual); + + } + + + @Test + public void setRisk() { + // Given + Investment account = new Investment(80000.0, 3,3, 0.09); + Double expected = 0.9; + + account.setRisk(0.9); + + // Then + Double actual = account.getRisk(); + assertEquals(expected, actual); + } +} diff --git a/src/test/java/ConsoleTest.java b/src/test/java/ConsoleTest.java new file mode 100644 index 0000000..aa82a13 --- /dev/null +++ b/src/test/java/ConsoleTest.java @@ -0,0 +1,50 @@ +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Date; + +import static org.junit.Assert.*; +@RunWith(JUnitParamsRunner.class) +public class ConsoleTest { + + @Test + public void print() { + } + + @Test + public void println() { + } + + @Test + public void menuOptionsTest() { + String[] options = new String[] {"Live", "Die", "Repeat"}; + String header = "Account Creation Menu"; + options = new String[] {"Live", "Die", "Repeat", "Bump", "Set", "Spike", "Towel"}; + //Console.getInput(options); + //Console.getInput(header, options); + } + + @Test + public void getInput() { + } + + @Test + public void getCurrency() { + } + + @Test + @Parameters({"1,true","2.3,false","-3,false","0,true","203,true","sad1,false","1223.231,false","3.33,true","2.3412,false"}) + public void currencyCheckTest(String input, Boolean valid) { + Assert.assertTrue(valid == Console.currencyCheck(input)); + } + + @Test + @Parameters({"1,true","2.3,false","-3,false","0,true","203,true","sad1,false","1223.231,false","3.33,false","2.3412,false"}) + public void integerCheckTest(String input, Boolean valid) { + Assert.assertTrue(valid == Console.integerCheck(input)); + } + +} diff --git a/src/test/java/DBTest.java b/src/test/java/DBTest.java new file mode 100644 index 0000000..36e12d9 --- /dev/null +++ b/src/test/java/DBTest.java @@ -0,0 +1,572 @@ +import junitparams.JUnitParamsRunner; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Random; + +@RunWith(JUnitParamsRunner.class) +public class DBTest { + + @Test + public void constructorTest() { + + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + + String expected = fileName; + Assert.assertEquals(db1.getFileName(), expected); + db1.delete(); + } + + @Test + public void constructorBadRowLengthTest() { + + String fileName = "test.csv"; + DB testDB = null; + try { + testDB = new DB(fileName, 7); + } catch (IOException e) { + e.printStackTrace(); + } + + Integer actual = testDB.getRowLength(); + Assert.assertTrue(4 == actual); + } + + @Test + public void DBFileNameTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB testDB = null; + try { + testDB = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + + String actual = testDB.getFileName(); + Assert.assertEquals(testDB.getFileName(), fileName); + testDB.delete(); + } + + @Test + public void pathToFileNameTest() { + String input = "/Users/josh/Desktop/Projects/CR-MacroLabs-OOP-ATM/data/610393892.csv"; + String expected = "610393892.csv"; + Assert.assertEquals(expected, DB.pathToFileName(input)); + } + + @Test + public void fileNametoPathTest() { + String input = "610393892.csv"; + String expected = "/Users/josh/Desktop/Projects/CR-MacroLabs-OOP-ATM/data/610393892.csv"; + Assert.assertEquals(expected, DB.fileNameToPath(input, System.getProperty("user.dir"))); + } + + @Test + public void tempStuff() { +// String fileName = "test.csv"; +// DB testDB = null; +// try { +// testDB = new DB(fileName, 4); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// +// testDB.addRow(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); +// testDB.addRow(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); +// testDB.addRow(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); +// testDB.addRow(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + } + + @Test + public void readTestDBTest() { + String fileName = "test.csv"; + + ArrayList expected = new ArrayList<>(); + expected.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + expected.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + expected.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + expected.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + DB testDB = null; + try { + testDB = new DB(fileName, 4); + + ArrayList records = testDB.readAllRows(); + + for (int i = 0; i < 4; i++) { + Assert.assertEquals(expected.get(i), records.get(i)); + } + + + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void printDBTest() { + String fileName = "test.csv"; + DB testDB = null; + try { + testDB = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + testDB.printDB(); + } + + @Test + public void clearDBTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + + db1.addRow(new String[]{"Sticky", "Icky", "Wicky", "Quicky"}); + db1.clear(); + + ArrayList records = db1.readAllRows(); + + Assert.assertEquals(0,records.size()); + db1.delete(); + } + + @Test + public void addRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + ArrayList records; + for (int i = 0; i < 4; i++) { + db1.addRow(data.get(i)); + Assert.assertTrue(i + 1 == db1.length()); + + records = db1.readAllRows(); + + for (int j = 0; j <= i; j++) { + //System.out.println(String.format("Rows: %d Testing row: %d", i, j)); + Assert.assertEquals(records.get(i), data.get(i)); + } + } + db1.delete(); + } + + @Test + public void getRowLengthTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + Integer rowL = random.nextInt(10); + try { + db1 = new DB(fileName, rowL); + } catch (IOException e) { + e.printStackTrace(); + } + + String[] row = new String[rowL]; + db1.addRow(row); + Assert.assertTrue(1 == db1.length()); + + Assert.assertTrue(rowL == db1.getRowLength()); + db1.delete(); + } + + @Test + public void getFileNameTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + Integer rowL = random.nextInt(10); + try { + db1 = new DB(fileName, rowL); + } catch (IOException e) { + e.printStackTrace(); + } + + Assert.assertTrue(fileName == db1.getFileName()); + db1.delete(); + } + + @Test + public void deleteFileTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + Integer rowL = random.nextInt(10); + try { + db1 = new DB(fileName, rowL); + } catch (IOException e) { + e.printStackTrace(); + } + + Assert.assertTrue(false == db1.isDeleted()); + db1.delete(); + Assert.assertTrue(true == db1.isDeleted()); + } + + @Test + public void integrityGoodTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + ArrayList records; + for (int i = 0; i < 4; i++) { + db1.addRow(data.get(i)); + } + + Assert.assertEquals(true, db1.checkIntegrity()); + db1.delete(); + } + + @Test + public void integrityBadRowAddTest() { // check to make sure it won't add an improper length of row + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + ArrayList records; + for (int i = 0; i < 4; i++) { + db1.addRow(data.get(i)); + } + + Assert.assertTrue(3 == db1.readAllRows().size()); + Assert.assertEquals(true, db1.checkIntegrity()); + db1.delete(); + } + + @Test + public void integrityBadTest() { // check to make sure it won't add an improper length of row + + String fileName = "testBad.csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + + Assert.assertEquals(false, db1.checkIntegrity()); + } + + @Test + public void replaceRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + + for (int i = 0; i < 4; i++) { + db1.addRow(data.get(i)); + } + + String[] replacementRow = new String[] {"Changed Item 1c", "Changed Item 2c", "Changed Item 3c", "Changed Item 4c"}; + + db1.replaceRow(2, replacementRow); + + ArrayList records = db1.readAllRows(); + + for (int i = 0; i < 4; i++) { + if (i == 2) { + Assert.assertEquals(replacementRow, records.get(i)); + } else { + Assert.assertEquals(data.get(i), records.get(i)); + } + } + db1.delete(); + } + + @Test + public void deleteRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + db1.deleteRow(2); + + ArrayList records = db1.readAllRows(); + + for (int i = 0; i < 4; i++) { + if (i >= 2) { + Assert.assertEquals(data.get(i+1), records.get(i)); + } else { + Assert.assertEquals(data.get(i), records.get(i)); + } + } + db1.delete(); + } + + @Test + public void readRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + for (int i = 0; i < 4; i++) { + Assert.assertEquals(data.get(i), db1.readRow(i)); + } + db1.delete(); + } + + @Test + public void serializeTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + for (int i = 0; i < 4; i++) { + Assert.assertEquals(String.join("/",data.get(i)), db1.serialize(i)); + } + db1.delete(); + } + + @Test + public void staticSerializeTest() { + String[] row = new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}; + Assert.assertEquals(String.join("/",row), DB.serialize(row)); + } + + @Test + public void partialSerializeTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + Assert.assertEquals("Item 1d/Item 2d/Item 4d", db1.partialSerialize(3,new int[] {0,1,3})); + Assert.assertEquals("Item 3e", db1.partialSerialize(4,new int[] {2})); + Assert.assertEquals("Item 2e/Item 3e", db1.partialSerialize(4,new int[] {1,2})); + + db1.delete(); + } + + @Test + public void partialStaticSerializeTest() { + String[] row = new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}; + int[] fields = {1,3}; + Assert.assertEquals("Item 2b/Item 4b", DB.partialSerialize(row, fields)); + } + + @Test + public void findWholeRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + for (int i = 0; i < data.size(); i++) { + Assert.assertEquals(i, db1.findWholeRow(data.get(i))); + } + db1.delete(); + } + + @Test + public void findPartialRowTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item 2", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1d", "Item 2d", "Item 3d", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + Assert.assertEquals(3, db1.findPartialRow(new String[] {"Item 1d", "Item 2d", "Item 4d"}, new int[] {0,1,3})); + Assert.assertEquals(1, db1.findPartialRow(new String[] {"Item 3b"}, new int[] {2})); + Assert.assertEquals(-1, db1.findPartialRow(new String[] {"Item 3sdsdasdasdb"}, new int[] {2})); + Assert.assertEquals(4, db1.findPartialRow(new String[] {"Item 1e", "Item 2e", "Item 3e", "Item 4e"}, new int[] {0,1,2,3})); + + db1.delete(); + } + + @Test + public void findPartialRowMultipleTest() { + Random random = new Random(); + String fileName = Integer.toString(Math.abs(random.nextInt())) + ".csv"; + + DB db1 = null; + try { + db1 = new DB(fileName, 4); + } catch (IOException e) { + e.printStackTrace(); + } + ArrayList data = new ArrayList<>(); + data.add(new String[] {"Item 1", "Item", "Item 3", "Item 4"}); + data.add(new String[] {"Item 1b", "Item 2b", "Item 3b", "Item 4b"}); + data.add(new String[] {"Item 1c", "Item 2c", "Item 3c", "Item 4c"}); + data.add(new String[] {"Item 1b", "Item", "Item 3b", "Item 4d"}); + data.add(new String[] {"Item 1e", "Item", "Item 3e", "Item 4e"}); + + for (int i = 0; i < data.size(); i++) { + db1.addRow(data.get(i)); + } + + Assert.assertEquals(1, db1.findPartialRowMultiple(new String[] {"Item 1b", "Item 3b"}, new int[] {0,2})[0]); + Assert.assertEquals(3, db1.findPartialRowMultiple(new String[] {"Item 1b", "Item 3b"}, new int[] {0,2})[1]); + + Assert.assertEquals(0, db1.findPartialRowMultiple(new String[] {"Item"}, new int[] {1})[0]); + Assert.assertEquals(3, db1.findPartialRowMultiple(new String[] {"Item"}, new int[] {1})[1]); + Assert.assertEquals(4, db1.findPartialRowMultiple(new String[] {"Item"}, new int[] {1})[2]); + + Assert.assertEquals((int)0, (int)db1.findPartialRowMultiple(new String[] {"Iteasdm"}, new int[] {1}).length); + + db1.delete(); + } +} \ No newline at end of file diff --git a/src/test/java/StoreableTest.java b/src/test/java/StoreableTest.java new file mode 100644 index 0000000..03d8f90 --- /dev/null +++ b/src/test/java/StoreableTest.java @@ -0,0 +1,75 @@ +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class StoreableTest { + + @Test + public void toStringArrayUser() { + User user = new User("Jim","Brown","goolybib", 12, 12343); + + String[] actual = user.toStringArray(); + String[] expected = new String[] { + "12", + "Brown", + "Jim", + "12343", + "goolybib" + }; + + Assert.assertEquals(actual, expected); + } + + @Test + public void toStringArrayAccountChecking() { + Account account = new Checking(12.23, 23, 3432); + + String[] actual = account.toStringArray(); + String[] expected = new String[] { + "3432", + "23", + "12.23", + "Checking", + "" + }; + + Assert.assertEquals(actual, expected); + } + + @Test + public void toStringArrayAccountSavings() { + Account account = new Savings(12.23, 23, 3432, 0.05); + + String[] actual = account.toStringArray(); + String[] expected = new String[] { + "3432", + "23", + "12.23", + "Savings", + "0.05" + }; + + Assert.assertEquals(actual, expected); + } + + @Test + public void toStringArrayAccountInvestment() { + Account account = new Investment(12.23, 23, 3432, 0.2); + + String[] actual = account.toStringArray(); + String[] expected = new String[] { + "3432", + "23", + "12.23", + "Investment", + "0.2" + }; + + Assert.assertEquals(actual, expected); + } + + @Test + public void saveToDB() { + } +} \ No newline at end of file diff --git a/src/test/java/TransactionTest.java b/src/test/java/TransactionTest.java new file mode 100644 index 0000000..1b749ea --- /dev/null +++ b/src/test/java/TransactionTest.java @@ -0,0 +1,16 @@ +import org.junit.After; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class TransactionTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + +} \ No newline at end of file diff --git a/src/test/java/UserTest.java b/src/test/java/UserTest.java new file mode 100644 index 0000000..eb3fc2b --- /dev/null +++ b/src/test/java/UserTest.java @@ -0,0 +1,30 @@ +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class UserTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void genCardNumTest() { + + System.out.println("Testing Card Number Gen"); + + for (int i = 0; i < 10; i++) { + Integer cardNum = User.genCardNum(); + + System.out.println(cardNum); + Assert.assertEquals(8, cardNum.toString().length()); + } + } +} \ No newline at end of file