From cc1e044d267205c2900c90b3a5490535590a40d8 Mon Sep 17 00:00:00 2001 From: Safak Date: Wed, 4 Dec 2024 16:19:30 +0100 Subject: [PATCH] =?UTF-8?q?fertige=20Tests=20f=C3=BCr=20Payment=20und=20Tr?= =?UTF-8?q?ansfer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kleine Anpassungen im Exception Handling der Konstruktoren --- accountdata/Max.json | 32 +- src/main/java/Main.java | 13 +- src/main/java/bank/Bank.java | 2 +- src/main/java/bank/IncomingTransfer.java | 8 +- src/main/java/bank/OutgoingTransfer.java | 8 +- src/main/java/bank/Payment.java | 23 +- src/main/java/bank/PrivateBank.java | 153 ++++++--- src/main/java/bank/PrivateBankAlt.java | 332 ------------------- src/main/java/bank/Transaction.java | 8 +- src/main/java/bank/Transfer.java | 6 +- src/test/java/PaymentTest.java | 122 +++++++ src/test/java/PrivateBankTest.java | 385 +++++++++++++++++++++++ src/test/java/TransferTest.java | 93 ++++++ 13 files changed, 773 insertions(+), 412 deletions(-) delete mode 100644 src/main/java/bank/PrivateBankAlt.java create mode 100644 src/test/java/PaymentTest.java create mode 100644 src/test/java/PrivateBankTest.java create mode 100644 src/test/java/TransferTest.java diff --git a/accountdata/Max.json b/accountdata/Max.json index bc16387..ed7487f 100644 --- a/accountdata/Max.json +++ b/accountdata/Max.json @@ -2,31 +2,41 @@ { "CLASSNAME": "Payment", "INSTANCE": { - "incomingInterest": 0.025, - "outgoingInterest": 0.05, + "incomingInterest": 0.5, + "outgoingInterest": 0.25, "date": "10.01.1988", - "amount": 1500, + "amount": 1500.0, "description": "Deposit; 1500" } }, { "CLASSNAME": "IncomingTransfer", "INSTANCE": { - "sender": "Account Eva", - "recipient": "Account Adam", + "sender": "Eva", + "recipient": "Max", "date": "01.01.2021", - "amount": 150, - "description": "Incoming Transfer; Eva->Adam; 150" + "amount": 150.0, + "description": "Incoming Transfer; Eva-\u003eMax; 150" } }, { "CLASSNAME": "OutgoingTransfer", "INSTANCE": { - "sender": "Account Adam", - "recipient": "Account Eva", + "sender": "Max", + "recipient": "Eva", "date": "03.01.2021", - "amount": 50, - "description": "Outgoing Transfer; Adam->Eva; 50" + "amount": 50.0, + "description": "Outgoing Transfer; Max-\u003eEva; 50" + } + }, + { + "CLASSNAME": "Payment", + "INSTANCE": { + "incomingInterest": 0.5, + "outgoingInterest": 0.25, + "date": "01.01.24", + "amount": 10.0, + "description": "Verwendungszweck P1" } } ] \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 3cbc1d1..6d99ded 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,6 +1,5 @@ import bank.*; -import bank.exceptions.IOException; -import bank.exceptions.TransactionAttributeException; +import bank.exceptions.*; import java.util.ArrayList; import java.util.Arrays; @@ -251,7 +250,7 @@ public class Main { // ------------------------ MAIN ------------------------ - public static void main(String[] args) throws TransactionAttributeException, IOException, java.io.IOException { + public static void main(String[] args) throws TransactionAttributeException, IOException, java.io.IOException, TransactionAlreadyExistException, AccountAlreadyExistsException, AccountDoesNotExistException { String person1 = "Max Mustermann"; String person2 = "Maria Musterfrau"; String person3 = "Tom Mustermann"; @@ -259,8 +258,9 @@ public class Main { // ------------------------ Transactions ------------------------ - /* + Payment p1 = new Payment("01.01.24", 10, "Verwendungszweck P1"); + /* Payment p2 = new Payment("01.01.24", 10, "Verwendungszweck P2", 0, 0); Payment p3 = new Payment("01.01.24", -10, "Verwendungszweck P3", 0.5, 0); Payment p4 = new Payment("01.01.24", -10, "Verwendungszweck P4", 0, 0.25); @@ -301,13 +301,14 @@ public class Main { System.out.println("\n------------------------ Bank"); PrivateBank bank = new PrivateBank("Sparkasse", 0.5, 0.25,"accountdata"); - PrivateBankAlt bankAlt = new PrivateBankAlt("SparkasseAlt", 0.5, 0.25); PrivateBank bank1 = new PrivateBank("Commerzbank", 0.5, 0.25,"accountdata"); // ------------------------ Bank: Adding Accounts bank.readAccounts(); - + bank.writeAccount("Max"); + bank.addTransaction("Max",p1); + bank.writeAccount("Max"); } diff --git a/src/main/java/bank/Bank.java b/src/main/java/bank/Bank.java index 6aa3867..03366bf 100644 --- a/src/main/java/bank/Bank.java +++ b/src/main/java/bank/Bank.java @@ -29,7 +29,7 @@ public interface Bank { * @throws TransactionAttributeException if the validation check for certain attributes fail */ void createAccount(String account, List transactions) - throws AccountAlreadyExistsException, TransactionAlreadyExistException, TransactionAttributeException; + throws AccountAlreadyExistsException, TransactionAlreadyExistException, TransactionAttributeException, IOException; /** * Adds a transaction to an already existing account. diff --git a/src/main/java/bank/IncomingTransfer.java b/src/main/java/bank/IncomingTransfer.java index 3229701..8c7e2ec 100644 --- a/src/main/java/bank/IncomingTransfer.java +++ b/src/main/java/bank/IncomingTransfer.java @@ -15,7 +15,7 @@ public class IncomingTransfer extends Transfer { * @param newAmount The amount of the transfer. * @param newDescription The description of the transfer. */ - public IncomingTransfer(String newDate, double newAmount, String newDescription) throws TransactionAttributeException { + public IncomingTransfer(String newDate, double newAmount, String newDescription) { super(newDate, newAmount, newDescription); } @@ -30,10 +30,14 @@ public class IncomingTransfer extends Transfer { * @param newSender * @param newRecipient */ - public IncomingTransfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) throws TransactionAttributeException { + public IncomingTransfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) { super(newDate, newAmount, newDescription, newSender, newRecipient); } + public IncomingTransfer(IncomingTransfer transfer) { + this(transfer.getDate(), transfer.getAmount(), transfer.getDescription(), transfer.getSender(), transfer.getRecipient()); + } + @Override public double calculate() { return this.getAmount(); diff --git a/src/main/java/bank/OutgoingTransfer.java b/src/main/java/bank/OutgoingTransfer.java index dd44af3..2f39200 100644 --- a/src/main/java/bank/OutgoingTransfer.java +++ b/src/main/java/bank/OutgoingTransfer.java @@ -18,7 +18,7 @@ public class OutgoingTransfer extends Transfer { * @param newAmount The amount of the transfer. * @param newDescription The description of the transfer. */ - public OutgoingTransfer(String newDate, double newAmount, String newDescription) throws TransactionAttributeException { + public OutgoingTransfer(String newDate, double newAmount, String newDescription) { super(newDate, newAmount, newDescription); } @@ -32,10 +32,14 @@ public class OutgoingTransfer extends Transfer { * @param newSender * @param newRecipient */ - public OutgoingTransfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) throws TransactionAttributeException { + public OutgoingTransfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) { super(newDate, newAmount, newDescription, newSender, newRecipient); } + public OutgoingTransfer(OutgoingTransfer transfer) { + this(transfer.getDate(), transfer.getAmount(), transfer.getDescription(), transfer.getSender(), transfer.getRecipient()); + } + @Override public double calculate() { return this.getAmount() * (-1); diff --git a/src/main/java/bank/Payment.java b/src/main/java/bank/Payment.java index 48c0ec3..d092c05 100644 --- a/src/main/java/bank/Payment.java +++ b/src/main/java/bank/Payment.java @@ -1,12 +1,7 @@ package bank; import bank.exceptions.TransactionAttributeException; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSerializationContext; -import java.lang.reflect.Type; /** * The Payment class represents a payment with a date, amount, description, @@ -70,7 +65,7 @@ public class Payment extends Transaction { * @param newAmount The amount of the payment. * @param newDescription The description of the payment. */ - public Payment(String newDate, double newAmount, String newDescription) throws TransactionAttributeException { + public Payment(String newDate, double newAmount, String newDescription) { super(newDate, newAmount, newDescription); } @@ -84,10 +79,18 @@ public class Payment extends Transaction { * @param newIncomingInterest The incoming interest rate. * @param newOutgoingInterest The outgoing interest rate. */ - public Payment(String newDate, double newAmount, String newDescription, double newIncomingInterest, double newOutgoingInterest) throws TransactionAttributeException { + public Payment(String newDate, double newAmount, String newDescription, double newIncomingInterest, double newOutgoingInterest) { super(newDate, newAmount, newDescription); - this.setIncomingInterest(newIncomingInterest); - this.setOutgoingInterest(newOutgoingInterest); + try { + this.setIncomingInterest(newIncomingInterest); + } catch (TransactionAttributeException e) { + System.out.println(e.getMessage()); + } + try { + this.setOutgoingInterest(newOutgoingInterest); + } catch (TransactionAttributeException e) { + System.out.println(e.getMessage()); + } } /** @@ -95,7 +98,7 @@ public class Payment extends Transaction { * * @param p The Payment object to copy from. */ - public Payment(Payment p) throws TransactionAttributeException { + public Payment(Payment p) { this(p.getDate(), p.getAmount(), p.getDescription(), p.getIncomingInterest(), p.getOutgoingInterest()); } diff --git a/src/main/java/bank/PrivateBank.java b/src/main/java/bank/PrivateBank.java index aa6d1d1..a9bedbb 100644 --- a/src/main/java/bank/PrivateBank.java +++ b/src/main/java/bank/PrivateBank.java @@ -6,10 +6,12 @@ import java.lang.reflect.Type; import java.util.*; import java.nio.file.*; import java.io.File; +import java.io.FileWriter; + import com.google.gson.*; -public class PrivateBank implements Bank, JsonSerializer, JsonDeserializer { +public class PrivateBank implements Bank, JsonSerializer, JsonDeserializer { private String name; private String directoryName; private double incomingInterest; @@ -66,7 +68,8 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser /** * Sets DirectoryName - * @param newDirectoryName DirectoryName + * + * @param newDirectoryName DirectoryName */ public void setDirectoryName(String newDirectoryName) { this.directoryName = newDirectoryName; @@ -74,6 +77,7 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser /** * Returns DirectoryName + * * @return DirectoryName */ public String getDirectoryName() { @@ -159,7 +163,7 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser */ @Override - public void createAccount(String account, List transactions) throws AccountAlreadyExistsException, TransactionAlreadyExistException, TransactionAttributeException { + public void createAccount(String account, List transactions) throws AccountAlreadyExistsException, TransactionAlreadyExistException, TransactionAttributeException, IOException { createAccount(account); for (Transaction transaction : transactions) { if (this.accountsToTransactions.get(account).contains(transaction)) @@ -167,6 +171,8 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser else if (checkTransactionAttributes(account, transaction)) this.accountsToTransactions.get(account).add(transaction); } + // Wenn man aus nicht JSON Quellen Konten erzeugen würde + // writeAccount(account); } /** @@ -179,22 +185,23 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser * @throws TransactionAttributeException if the validation check for certain attributes fail */ @Override - public void addTransaction(String account, Transaction transaction) throws TransactionAlreadyExistException, AccountDoesNotExistException, TransactionAttributeException, IOException { + public void addTransaction(String account, Transaction transaction) throws TransactionAlreadyExistException, AccountDoesNotExistException, TransactionAttributeException { // 1. check if Account exists if (this.containsAccount(account)) { // 2. check if Transaction exists if (this.containsTransaction(account, transaction)) throw new TransactionAlreadyExistException(); - else if (checkTransactionAttributes(account, transaction)){ + else if (checkTransactionAttributes(account, transaction)) { this.accountsToTransactions.get(account).add(transaction); // 3. rewrite account because of change - writeAccount(account); + try { + writeAccount(account); + } catch (IOException e) { + System.out.println(e.getMessage()); + } } - - - } else { + } else throw new AccountDoesNotExistException(); - } } /** @@ -254,13 +261,11 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser this.accountsToTransactions.get(account).remove(transaction); // 3. rewrite account because of change writeAccount(account); - } - else + } else throw new TransactionDoesNotExistException(); - } else { + } else throw new AccountDoesNotExistException(); - } } /** @@ -296,12 +301,9 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser double balance = 0; List transactions = accountsToTransactions.get(account); - for (Transaction transaction : transactions) { - /* - * basierend auf den Transaktions Typen, wird die entsprechende calculate() aufgerufen - */ + for (Transaction transaction : transactions) + // basierend auf den Transaktions Typen, wird die entsprechende calculate() aufgerufen balance += transaction.calculate(); - } return balance; } @@ -354,9 +356,10 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser /** * Import Accounts from existing JSON Files - * @throws IOException if an error occurs while deserializing + * + * @throws IOException if an error occurs while deserializing */ - public void readAccounts() throws IOException, java.io.IOException { + public void readAccounts() throws IOException, java.io.IOException, AccountAlreadyExistsException, TransactionAlreadyExistException, AccountDoesNotExistException, TransactionAttributeException { /* 1. JSONs einlesen 2. for each Transaction @@ -364,53 +367,64 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser 2. Objekte in einer Liste zusammenführen 3. Konto mit einer Liste von Transaktionen erzeugen */ + List transactions = new ArrayList<>(); - List transactionList; File directory = new File(directoryName); - File[] files = {}; - int fileCount = 0; + File[] files = directory.listFiles(); - if (directory.exists() && directory.isDirectory()) { - files = directory.listFiles(); - if (files != null) - // Zähle nur die Dateien, nicht die Unterverzeichnisse - for (File file : files) if (file.isFile()) fileCount++; - } - - if(files.length > 0){ + if (files != null) { // jedes file ist ein Konto for (File file : files) { + String accountName = file.getName().substring(0, file.getName().lastIndexOf(".")); + String jsonContent = Files.readString(Paths.get(directoryName + "/" + file.getName())); JsonElement accountData = JsonParser.parseString(jsonContent); - for(JsonElement account: accountData.getAsJsonArray()) { + for (JsonElement account : accountData.getAsJsonArray()) { JsonObject accountObject = account.getAsJsonObject(); - - String transactionType = accountObject.get("CLASSNAME").getAsString(); - JsonElement transactionInstance = accountObject.get("INSTANCE").getAsJsonObject(); - - // Fallunterscheidung je nach Typ - deserialize() + Transaction t = deserialize(accountObject, null, null); + transactions.add(t); } + + createAccount(accountName, transactions); } } } /** * Export Account to JSON - * @param account Account to be exportet - * @throws IOException if an error occurs while serializing + * + * @param account Account to be exportet + * @throws IOException if an error occurs while serializing */ - public void writeAccount(String account) throws IOException{ + public void writeAccount(String account) throws IOException { /* 1. alle Transactionen des Kontos abholen 2. basierend auf Transactionstyp serialisieren 3. zusammenpacken und speichern */ + JsonArray accountData = new JsonArray(); + List transactions = this.accountsToTransactions.get(account); + + for (Transaction transaction : transactions) + accountData.add(serialize(transaction, null, null)); + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String filename = directoryName + "/" + account + ".json"; + + // try-with-resources + try (FileWriter fileWriter = new FileWriter(filename)) { + gson.toJson(accountData, fileWriter); + } catch (Exception e) { + System.out.println(e); + } + } /** + * Transform JSON into Transaction + * * @param jsonElement * @param type * @param jsonDeserializationContext @@ -419,10 +433,30 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser */ @Override public Transaction deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + String transactionType = jsonElement.getAsJsonObject().get("CLASSNAME").getAsString(); + JsonObject transactionInstance = jsonElement.getAsJsonObject().get("INSTANCE").getAsJsonObject(); + + String date = transactionInstance.get("date").getAsString(); + double amount = transactionInstance.get("amount").getAsDouble(); + String description = transactionInstance.get("description").getAsString(); + + switch (transactionType) { + case "IncomingTransfer": + return new IncomingTransfer(date, amount, description, transactionInstance.get("sender").getAsString(), transactionInstance.get("recipient").getAsString()); + + case "OutgoingTransfer": + return new OutgoingTransfer(date, amount, description, transactionInstance.get("sender").getAsString(), transactionInstance.get("recipient").getAsString()); + + case "Payment": + return new Payment(date, amount, description, transactionInstance.get("incomingInterest").getAsDouble(), transactionInstance.get("outgoingInterest").getAsDouble()); + + } return null; } /** + * Transform Transaction into JSON + * * @param transaction * @param type * @param jsonSerializationContext @@ -430,6 +464,39 @@ public class PrivateBank implements Bank, JsonSerializer, JsonDeser */ @Override public JsonElement serialize(Transaction transaction, Type type, JsonSerializationContext jsonSerializationContext) { - return null; + JsonObject rootObject = new JsonObject(); + + if (transaction instanceof IncomingTransfer) + rootObject.addProperty("CLASSNAME", "IncomingTransfer"); + + else if (transaction instanceof OutgoingTransfer) + rootObject.addProperty("CLASSNAME", "OutgoingTransfer"); + + else if (transaction instanceof Payment) + rootObject.addProperty("CLASSNAME", "Payment"); + + + JsonObject jsonObject = new JsonObject(); + + // Typspezifische Props + if (transaction instanceof IncomingTransfer) { + jsonObject.addProperty("sender", ((IncomingTransfer) transaction).getSender()); + jsonObject.addProperty("recipient", ((IncomingTransfer) transaction).getRecipient()); + } else if (transaction instanceof OutgoingTransfer) { + jsonObject.addProperty("sender", ((OutgoingTransfer) transaction).getSender()); + jsonObject.addProperty("recipient", ((OutgoingTransfer) transaction).getRecipient()); + } else if (transaction instanceof Payment) { + jsonObject.addProperty("incomingInterest", ((Payment) transaction).getIncomingInterest()); + jsonObject.addProperty("outgoingInterest", ((Payment) transaction).getOutgoingInterest()); + } + + // generische Props + jsonObject.addProperty("date", transaction.getDate()); + jsonObject.addProperty("amount", transaction.getAmount()); + jsonObject.addProperty("description", transaction.getDescription()); + + rootObject.add("INSTANCE", jsonObject); + + return rootObject; } } diff --git a/src/main/java/bank/PrivateBankAlt.java b/src/main/java/bank/PrivateBankAlt.java deleted file mode 100644 index 647d6b0..0000000 --- a/src/main/java/bank/PrivateBankAlt.java +++ /dev/null @@ -1,332 +0,0 @@ -package bank; - -import bank.exceptions.*; - -import java.util.*; - -public class PrivateBankAlt implements Bank { - private String name; - private double incomingInterest; - private double outgoingInterest; - protected Map> accountsToTransactions = new HashMap<>(); - - /** - * @return Name of the Bank - */ - public String getName() { - return name; - } - - /** - * Sets the Name of the Bank - * - * @param newName Name - */ - public void setName(String newName) { - this.name = newName; - } - - /** - * @return IncomingInterest - */ - public double getIncomingInterest() { - return incomingInterest; - } - - /** - * Sets the IncomingInterest - * - * @param newIncomingInterest IncomingInterest - */ - public void setIncomingInterest(double newIncomingInterest) { - this.incomingInterest = newIncomingInterest; - } - - /** - * @return OutgoingInterest - */ - public double getOutgoingInterest() { - return outgoingInterest; - } - - /** - * Sets OutgoingInterest - * - * @param newOutgoingInterest OutgoingInterest - */ - public void setOutgoingInterest(double newOutgoingInterest) { - this.outgoingInterest = newOutgoingInterest; - } - - /** - * Default Constructor - * - * @param name Name - * @param incomingInterest incoming Interest - * @param outgoingInterest outgoing Interest - */ - public PrivateBankAlt(String name, double incomingInterest, double outgoingInterest) { - this.setName(name); - this.setIncomingInterest(incomingInterest); - this.setOutgoingInterest(outgoingInterest); - } - - /** - * Copy Constructor - * - * @param privateBank Bank to copy from - */ - public PrivateBankAlt(PrivateBank privateBank) { - this.setName(privateBank.getName()); - this.setIncomingInterest(privateBank.getIncomingInterest()); - this.setOutgoingInterest(privateBank.getOutgoingInterest()); - this.accountsToTransactions = privateBank.accountsToTransactions; - } - - @Override - public String toString() { - return ("\n--------------Bank-------------" + - "\n Name: " + this.getName() + - "\nIncomingInt: " + this.getIncomingInterest() + - "\nOutgoingInt: " + this.getOutgoingInterest() + - "\n-------------------------------\n" - ); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PrivateBank) { - PrivateBank privateBank = (PrivateBank) obj; - return this.getName().equals(privateBank.getName()) && - this.getIncomingInterest() == privateBank.getIncomingInterest() && - this.getOutgoingInterest() == privateBank.getOutgoingInterest() && - // Compares the values in the maps and not if the objects are the same - this.accountsToTransactions.equals(privateBank.accountsToTransactions); - } - return false; - } - - /** - * Adds an account to the bank. - * - * @param account the account to be added - * @throws AccountAlreadyExistsException if the account already exists - */ - @Override - public void createAccount(String account) throws AccountAlreadyExistsException { - if (this.accountsToTransactions.containsKey(account)) { - throw new AccountAlreadyExistsException(); - } else { - List transactions = new ArrayList<>(); - this.accountsToTransactions.put(account, transactions); - } - - } - - /** - * Adds an account (with specified transactions) to the bank. - * Important: duplicate transactions must not be added to the account! - * - * @param account the account to be added - * @param transactions a list of already existing transactions which should be added to the newly created account - * @throws AccountAlreadyExistsException if the account already exists - * @throws TransactionAlreadyExistException if the transaction already exists - * @throws TransactionAttributeException if the validation check for certain attributes fail - */ - - @Override - public void createAccount(String account, List transactions) throws AccountAlreadyExistsException, TransactionAlreadyExistException, TransactionAttributeException { - createAccount(account); - for (Transaction transaction : transactions) { - if (this.accountsToTransactions.get(account).contains(transaction)) - throw new TransactionAlreadyExistException(); - else if (checkTransactionAttributes(account, transaction)) - this.accountsToTransactions.get(account).add(transaction); - } - } - - /** - * Adds a transaction to an already existing account. - * - * @param account the account to which the transaction is added - * @param transaction the transaction which should be added to the specified account - * @throws TransactionAlreadyExistException if the transaction already exists - * @throws AccountDoesNotExistException if the specified account does not exist - * @throws TransactionAttributeException if the validation check for certain attributes fail - */ - @Override - public void addTransaction(String account, Transaction transaction) throws TransactionAlreadyExistException, AccountDoesNotExistException, TransactionAttributeException { - // 1. check if Account exists - if (this.containsAccount(account)) { - // 2. check if Transaction exists - if (this.containsTransaction(account, transaction)) - throw new TransactionAlreadyExistException(); - else if (checkTransactionAttributes(account, transaction)) - this.accountsToTransactions.get(account).add(transaction); - - } else { - throw new AccountDoesNotExistException(); - } - } - - /** - * Checking transaction to be added, if they contain all necessary and correct Attributes - * - * @param account account holder name - * @param transaction transaction - * @throws TransactionAttributeException if the validation check for certain attributes fail - */ - private boolean checkTransactionAttributes(String account, Transaction transaction) throws TransactionAttributeException { - // 1 Overwriting interest values if it is a payment - if (transaction instanceof Payment) { - ((Payment) transaction).setIncomingInterest(this.getIncomingInterest()); - ((Payment) transaction).setOutgoingInterest(this.getOutgoingInterest()); - return true; - } - - // 2 setting as incoming transfer - else if (transaction instanceof IncomingTransfer) { - if (((IncomingTransfer) transaction).getSender().equals("") || ((IncomingTransfer) transaction).getRecipient().equals("")) - throw new TransactionAttributeException("Transfer without sender or recipient"); - - else if (((IncomingTransfer) transaction).getRecipient().equals(account)) - return true; - else - throw new TransactionAttributeException("Transfer recipient is not account holder"); - } - - // 3 setting as outgoing transfer - else if (transaction instanceof OutgoingTransfer) { - if (((OutgoingTransfer) transaction).getSender().equals("") || ((OutgoingTransfer) transaction).getRecipient().equals("")) - throw new TransactionAttributeException("Transfer without sender or recipient"); - - else if (((OutgoingTransfer) transaction).getSender().equals(account)) - return true; - else - throw new TransactionAttributeException("Transfer sender is not account holder "); - } - return false; - } - - /** - * Removes a transaction from an account. If the transaction does not exist, an exception is - * thrown. - * - * @param account the account from which the transaction is removed - * @param transaction the transaction which is removed from the specified account - * @throws AccountDoesNotExistException if the specified account does not exist - * @throws TransactionDoesNotExistException if the transaction cannot be found - */ - @Override - public void removeTransaction(String account, Transaction transaction) throws AccountDoesNotExistException, TransactionDoesNotExistException { - // 1. check if Account exists - if (this.containsAccount(account)) { - // 2. check if Transaction exists - if (this.containsTransaction(account, transaction)) - this.accountsToTransactions.get(account).remove(transaction); - else - throw new TransactionDoesNotExistException(); - - } else { - throw new AccountDoesNotExistException(); - } - } - - /** - * Checks whether the specified transaction for a given account exists. - * - * @param account the account from which the transaction is checked - * @param transaction the transaction to search/look for - */ - @Override - public boolean containsTransaction(String account, Transaction transaction) { - return this.accountsToTransactions.containsKey(account) && - this.accountsToTransactions.get(account).contains(transaction); - } - - /** - * Checks whether the specified account exists. - * - * @param account account name - * @return exitens - */ - public boolean containsAccount(String account) { - return this.accountsToTransactions.containsKey(account); - } - - /** - * Calculates and returns the current account balance. - * - * @param account the selected account - * @return the current account balance - */ - @Override - public double getAccountBalance(String account) { - double balance = 0; - List transactions = accountsToTransactions.get(account); - - if (!transactions.isEmpty()) { - for (Transaction transaction : transactions) { - // adding or subtracting the amount based on type - - if (transaction instanceof IncomingTransfer) { - balance += transaction.getAmount(); - } else if (transaction instanceof OutgoingTransfer) { - balance -= transaction.getAmount(); - } else if (transaction instanceof Payment) { - balance += transaction.calculate(); - } - } - } - - return balance; - } - - - - /** - * Returns a list of transactions for an account. - * - * @param account the selected account - * @return the list of all transactions for the specified account - */ - @Override - public List getTransactions(String account) { - if (this.accountsToTransactions.containsKey(account)) - return this.accountsToTransactions.get(account); - else - return new ArrayList<>(); - } - - /** - * Returns a sorted list (-> calculated amounts) of transactions for a specific account. Sorts the list either in ascending or descending order - * (or empty). - * - * @param account the selected account - * @param asc selects if the transaction list is sorted in ascending or descending order - * @return the sorted list of all transactions for the specified account - */ - @Override - public List getTransactionsSorted(String account, boolean asc) { - List transactions = this.accountsToTransactions.get(account); - transactions.sort(Comparator.comparingDouble(Transaction::calculate)); - return transactions; - } - - /** - * Returns a list of either positive or negative transactions (-> calculated amounts). - * - * @param account the selected account - * @param positive selects if positive or negative transactions are listed - * @return the list of all transactions by type - */ - @Override - public List getTransactionsByType(String account, boolean positive) { - List transactions = this.accountsToTransactions.get(account); - if (positive) - transactions.removeIf(transaction -> transaction.calculate() >= 0); - else - transactions.removeIf(transaction -> transaction.calculate() < 0); - return transactions; - } -} diff --git a/src/main/java/bank/Transaction.java b/src/main/java/bank/Transaction.java index f46a3c1..c727688 100644 --- a/src/main/java/bank/Transaction.java +++ b/src/main/java/bank/Transaction.java @@ -72,8 +72,12 @@ public abstract class Transaction implements CalculateBill{ * @param newAmount The amount of the transfer. * @param newDescription The description of the transfer. */ - public Transaction(String newDate, double newAmount, String newDescription) throws TransactionAttributeException { - this.setAmount(newAmount); + public Transaction(String newDate, double newAmount, String newDescription) { + try { + this.setAmount(newAmount); + } catch (TransactionAttributeException e) { + System.out.println(e.getMessage()); + } this.setDescription(newDescription); this.setDate(newDate); } diff --git a/src/main/java/bank/Transfer.java b/src/main/java/bank/Transfer.java index 901951e..dc94a1b 100644 --- a/src/main/java/bank/Transfer.java +++ b/src/main/java/bank/Transfer.java @@ -76,7 +76,7 @@ public class Transfer extends Transaction { * @param newAmount The amount of the transfer. * @param newDescription The description of the transfer. */ - public Transfer(String newDate, double newAmount, String newDescription) throws TransactionAttributeException { + public Transfer(String newDate, double newAmount, String newDescription) { super(newDate, newAmount, newDescription); } @@ -95,7 +95,7 @@ public class Transfer extends Transaction { * @param newSender The sender of the transfer. * @param newRecipient The recipient of the transfer. */ - public Transfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) throws TransactionAttributeException { + public Transfer(String newDate, double newAmount, String newDescription, String newSender, String newRecipient) { super(newDate, newAmount, newDescription); this.setSender(newSender); this.setRecipient(newRecipient); @@ -106,7 +106,7 @@ public class Transfer extends Transaction { * * @param t The Transfer object to copy from. */ - public Transfer(Transfer t) throws TransactionAttributeException { + public Transfer(Transfer t) { this(t.getDate(), t.getAmount(), t.getDescription(), t.getSender(), t.getRecipient()); } diff --git a/src/test/java/PaymentTest.java b/src/test/java/PaymentTest.java new file mode 100644 index 0000000..0198734 --- /dev/null +++ b/src/test/java/PaymentTest.java @@ -0,0 +1,122 @@ +import bank.Payment; + +import bank.exceptions.TransactionAttributeException; +import org.junit.jupiter.api.*; + +import static org.junit.jupiter.api.Assertions.*; + + +public class PaymentTest { + + static Payment payment1; + static Payment payment2; + static Payment copyPayment; + + @BeforeAll + public static void init() { + System.out.println("Set up for Payment objects"); + + payment1 = new Payment( + "12.03.2008", + 321, + "Payment 01" + ); + + payment2 = new Payment( + "23.09.1897", + -2500, + "Payment 02", + 0.8, + 0.5 + ); + + copyPayment = new Payment(payment2); + + } + + + @Test + public void threeAttributesConstructorTest() { + assertEquals( + "12.03.2008", + payment1.getDate() + ); + assertEquals( + "Payment 01", + payment1.getDescription() + ); + assertEquals( + 321, + payment1.getAmount() + ); + } + + @Test + public void allAttributesConstructorTest() { + assertEquals( + "23.09.1897", + payment2.getDate() + ); + assertEquals( + "Payment 02", + payment2.getDescription() + ); + assertEquals(-2500, + payment2.getAmount() + ); + assertEquals( + 0.8, payment2.getIncomingInterest() + ); + assertEquals( + 0.5, payment2.getOutgoingInterest() + ); + } + + @Test + public void copyConstructorTest() { + assertEquals(payment2.getDate(), copyPayment.getDate()); + assertEquals(payment2.getDescription(), copyPayment.getDescription()); + assertEquals(payment2.getAmount(), copyPayment.getAmount()); + assertEquals(payment2.getIncomingInterest(), copyPayment.getIncomingInterest()); + assertEquals(payment2.getOutgoingInterest(), copyPayment.getOutgoingInterest()); + } + + + @Test + public void calculateIncomingInterestTest() { + double expected = payment1.getAmount() - payment1.getIncomingInterest() * payment1.getAmount(); + assertTrue(payment1.getAmount() >= 0); + assertEquals(expected, payment1.calculate()); + } + + @Test + public void calculateOutgoingInterestTest() { + double expected = payment2.getAmount() + payment2.getOutgoingInterest() * payment2.getAmount(); + assertTrue(payment2.getAmount() < 0); + assertEquals(expected, payment2.calculate()); + } + + @Test + public void equalsTrueTest() { + assertEquals(payment2, copyPayment); + } + + @Test + public void equalsFalseTest() { + assertNotEquals(payment1, payment2); + } + + @Test + public void toStringTester() { + String string = + "\n------------Payment------------\n" + + " Date: 12.03.2008\n" + + "Description: Payment 01\n" + + " Amount: 321.0\n" + + "IncomingInt: 0.0\n" + + "OutgoingInt: 0.0\n" + + "-------------------------------\n"; + assertEquals(string, payment1.toString()); + } + +} diff --git a/src/test/java/PrivateBankTest.java b/src/test/java/PrivateBankTest.java new file mode 100644 index 0000000..e8dc804 --- /dev/null +++ b/src/test/java/PrivateBankTest.java @@ -0,0 +1,385 @@ +import bank.*; +import bank.exceptions.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Test methods for PrivateBank") +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) + +public class PrivateBankTest { + + static PrivateBank privateBank; + static PrivateBank copyPrivateBank; + + @DisplayName("Set up a PrivateBank") + @BeforeAll + public static void init() throws AccountAlreadyExistsException, IOException, TransactionAlreadyExistException, + AccountDoesNotExistException, TransactionAttributeException { + + final File folder = new File("data/junit5"); + if (folder.exists()) { + final File[] listOfFiles = folder.listFiles(); + assert listOfFiles != null; + for (File file : listOfFiles) + file.delete(); + Files.deleteIfExists(Path.of("data/junit5")); + } + + privateBank = new PrivateBank( + "JUnit 5", + 0, + 0, + "data/test" + ); + + privateBank.createAccount("Hagen"); + privateBank.createAccount("Tim"); + privateBank.addTransaction( + "Hagen", + new Payment( + "19.01.2011", + -789, + "Payment", + 0.9, + 0.25 + ) + ); + privateBank.addTransaction( + "Tim", + new IncomingTransfer( + "03.03.2000", + 80, + "IncomingTransfer from Adam to Tim; 80", + "Adam", + "Tim" + ) + ); + copyPrivateBank = new PrivateBank(privateBank); + + } + + @DisplayName("Testing constructor") + @Test + @Order(0) + public void constructorTest() { + assertAll("PrivateBank", + () -> assertEquals("JUnit 5", privateBank.getName()), + () -> assertEquals("junit5", privateBank.getDirectoryName()), + () -> assertEquals(0, privateBank.getIncomingInterest()), + () -> assertEquals(0.12, privateBank.getOutgoingInterest())); + } + + @DisplayName("Testing copy constructor") + @Test + @Order(1) + public void copyConstructorTest() { + assertAll("CopyPrivateBank", + () -> assertEquals(privateBank.getName(), copyPrivateBank.getName()), + () -> assertEquals(privateBank.getDirectoryName(), copyPrivateBank.getDirectoryName()), + () -> assertEquals(privateBank.getIncomingInterest(), copyPrivateBank.getIncomingInterest()), + () -> assertEquals(privateBank.getOutgoingInterest(), copyPrivateBank.getOutgoingInterest())); + } + + @DisplayName("Create a duplicate account") + @ParameterizedTest + @Order(2) + @ValueSource(strings = {"Hagen", "Tim"}) + public void createDuplicateAccountTest(String account) { + Exception e = assertThrows(AccountAlreadyExistsException.class, + () -> privateBank.createAccount(account)); + System.out.println(e.getMessage()); + } + + @DisplayName("Create a valid account") + @ParameterizedTest + @Order(3) + @ValueSource(strings = {"Dinesh", "Bob", "Narsha"}) + public void createValidAccountTest(String account) { + assertDoesNotThrow( + () -> privateBank.createAccount(account) + ); + } + + @DisplayName("Create a valid account with a transactions list") + @ParameterizedTest + @Order(4) + @ValueSource(strings = {"Klaus", "Harsh", "Rastla"}) + public void createValidAccountWithTransactionsListTest(String account) { + assertDoesNotThrow( + () -> privateBank.createAccount( + account, + List.of( + new Payment( + "23.09.1897", + -2500, + "Payment 02", + 0.8, + 0.5 + ), + new OutgoingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + account, + "Hagen" + ) + ) + ) + ); + } + + @DisplayName("Create a duplicate account with a transactions list") + @ParameterizedTest + @Order(5) + @ValueSource(strings = {"Hagen", "Klaus", "Tim", "Bob", "Dinesh", "Narsha", "Harsh", "Rastla"}) + public void createInvalidAccountWithTransactionsListTest(String account) { + Exception e = assertThrows(AccountAlreadyExistsException.class, + () -> privateBank.createAccount( + account, + List.of( + new Payment( + "23.09.1897", + -2500, + "Payment 02", + 0.8, + 0.5 + ) + ) + ) + ); + System.out.println(e.getMessage()); + } + + @DisplayName("Add a valid transaction to a valid account") + @ParameterizedTest + @Order(6) + @ValueSource(strings = {"Hagen", "Bob", "Narsha", "Dinesh", "Klaus"}) + public void addValidTransactionValidAccountTest(String account) { + assertDoesNotThrow( + () -> privateBank.addTransaction( + account, + new IncomingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + "Tom", + account + ) + ) + ); + } + + @DisplayName("Add a duplicate transaction to a valid account") + @ParameterizedTest + @Order(7) + @ValueSource(strings = {"Klaus", "Harsh", "Rastla"}) + public void addDuplicateTransactionTest(String account) { + Exception e = assertThrows(TransactionAlreadyExistException.class, + () -> privateBank.addTransaction( + account, + new Payment( + "23.09.1897", + -2500, + "Payment 02", + 0.8, + 0.5 + ) + ) + ); + System.out.println(e.getMessage()); + } + + @DisplayName("Add a valid transaction to an invalid account") + @ParameterizedTest + @Order(8) + @ValueSource(strings = {"Gina", "Bona", "Yang"}) + public void addTransactionInvalidAccountTest(String account) { + Exception e = assertThrows(AccountDoesNotExistException.class, + () -> privateBank.addTransaction( + account, + new Payment( + "19.01.2011", + -789, + "Payment", + 0.9, + 0.25 + ) + ) + ); + System.out.println(e.getMessage()); + } + + @DisplayName("Remove a valid transaction") + @ParameterizedTest + @Order(9) + @ValueSource(strings = {"Harsh", "Rastla", "Klaus"}) + public void removeValidTransactionTest(String account) { + assertDoesNotThrow( + () -> privateBank.removeTransaction( + account, + new Payment( + "23.09.1897", + -2500, + "Payment 02", + 0.8, + 0.5 + ) + ) + ); + } + + @DisplayName("Remove an invalid transaction") + @ParameterizedTest + @Order(10) + @ValueSource(strings = {"Harsh", "Rastla", "Klaus"}) + public void removeInvalidTransactionTest(String account) { + Exception e = assertThrows( + TransactionDoesNotExistException.class, + () -> privateBank.removeTransaction( + account, + new Payment( + "19.01.2011", + -789, + "Payment", + 0.9, + 0.25 + ) + ) + ); + System.out.println(e.getMessage()); + } + + @DisplayName("Contains a transaction is true") + @ParameterizedTest + @Order(11) + @ValueSource(strings = {"Harsh", "Rastla", "Klaus"}) + public void containsTransactionTrueTest(String account) { + assertTrue( + privateBank.containsTransaction( + account, + new OutgoingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + account, + "Hagen" + ) + ) + ); + System.out.println("containsTransactionTrueTest in <" + account + "> is correct."); + } + + @DisplayName("Contains a transaction is false") + @ParameterizedTest + @Order(12) + @ValueSource(strings = {"Hagen", "Bob", "Narsha", "Dinesh", "Tim"}) + public void containsTransactionFalseTest(String account) { + assertFalse( + privateBank.containsTransaction( + account, + new OutgoingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + account, + "Hagen" + ) + ) + ); + System.out.println("containsTransactionFalseTest in <" + account + "> is correct."); + } + + @DisplayName("Get account balance") + @ParameterizedTest + @Order(14) + @CsvSource({"Klaus, 0", "Tim, 80", "Hagen, 1006.32"}) + public void getAccountBalanceTest(String account, double balance) { + System.out.println( + "Expected <" + balance + "> in account <" + account + ">" + ); + assertEquals( + balance, + privateBank.getAccountBalance(account) + ); + } + + @DisplayName("Get transactions list") + @Test + @Order(15) + public void getTransactionTest() { + List transactionList = List.of( + new Payment( + "19.01.2011", + -789, + "Payment", + 0, + 0.12), + new IncomingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + "Tom", + "Hagen" + ) + ); + assertEquals( + transactionList, + privateBank.getTransactions("Hagen") + ); + System.out.println("getTransactionTest in is correct."); + } + + @DisplayName("Get transactions list by type") + @Test + @Order(16) + public void getTransactionsByTypeTest() { + List transactionList = List.of( + new OutgoingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hagen", + "Klaus", + "Hagen" + ) + ); + assertEquals( + transactionList, + privateBank.getTransactionsByType( + "Klaus", + false + ) + ); + System.out.println("getTransactionByTypeTest in is correct."); + } + + @Test + @Order(17) + @DisplayName("Get sorted transactions list") + public void getTransactionsSortedTest() { + assertEquals( + List.of( + new IncomingTransfer( + "03.03.2000", + 80, + "IncomingTransfer from Adam to Tim; 80", + "Adam", + "Tim" + ) + ), + privateBank.getTransactionsSorted( + "Tim", + true + ) + ); + } +} diff --git a/src/test/java/TransferTest.java b/src/test/java/TransferTest.java new file mode 100644 index 0000000..9942819 --- /dev/null +++ b/src/test/java/TransferTest.java @@ -0,0 +1,93 @@ +import bank.IncomingTransfer; +import bank.OutgoingTransfer; + +import bank.Transfer; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + + +public class TransferTest { + + static IncomingTransfer incomingTransfer; + static OutgoingTransfer outgoingTransfer; + static Transfer copyTransfer; + + @BeforeAll + public static void init() { + incomingTransfer = new IncomingTransfer( + "03.03.2000", + 80, + "IncomingTransfer from Max to Maria; 80"); + outgoingTransfer = new OutgoingTransfer( + "30.07.2020", + 1890, + "OutgoingTransfer to Hans", + "Maria", + "Hans"); + copyTransfer = new OutgoingTransfer(outgoingTransfer); + } + + + @Test + public void threeAttributesConstructorTest() { + assertEquals("03.03.2000", incomingTransfer.getDate()); + assertEquals("IncomingTransfer from Max to Maria; 80", incomingTransfer.getDescription()); + assertEquals(80, incomingTransfer.getAmount()); + + } + + @Test + public void allAttributesConstructorTest() { + assertEquals("30.07.2020", outgoingTransfer.getDate()); + assertEquals("OutgoingTransfer to Hans", outgoingTransfer.getDescription()); + assertEquals(1890, outgoingTransfer.getAmount()); + assertEquals("Maria", outgoingTransfer.getSender()); + assertEquals("Hans", outgoingTransfer.getRecipient()); + } + + @Test + public void copyConstructorTester() { + assertEquals(outgoingTransfer.getAmount(), copyTransfer.getAmount()); + assertEquals(outgoingTransfer.getDate(), copyTransfer.getDate()); + assertEquals(outgoingTransfer.getRecipient(), copyTransfer.getRecipient()); + assertEquals(outgoingTransfer.getAmount(), copyTransfer.getAmount()); + assertEquals(outgoingTransfer.getSender(), copyTransfer.getSender()); + assertEquals(outgoingTransfer.getDescription(), copyTransfer.getDescription()); + } + + @Test + public void calculateIncomingTransferTest() { + assertInstanceOf(IncomingTransfer.class, incomingTransfer); + assertEquals(incomingTransfer.getAmount(), incomingTransfer.calculate()); + } + + @Test + public void calculateOutgoingTransferTest() { + assertInstanceOf(OutgoingTransfer.class, outgoingTransfer); + assertEquals(-outgoingTransfer.getAmount(), outgoingTransfer.calculate()); + } + + @Test + public void equalsTrueTest() { + assertEquals(outgoingTransfer, copyTransfer); + } + + @Test + public void equalsFalseTest() { + assertNotEquals(incomingTransfer, outgoingTransfer); + } + + @Test + public void toStringTester() { + // String string = outgoingTransfer.toString(); + String string = "\n" + + "------------Transfer-----------\n" + + " Date: 30.07.2020\n" + + "Description: OutgoingTransfer to Hans\n" + + " Amount: -1890.0\n" + + " Sender: Maria\n" + + " Recipient: Hans\n" + + "-------------------------------\n"; + assertEquals(string, outgoingTransfer.toString()); + } +}