From 15d30fe8683aacf6f4563a70324232c93a8d6738 Mon Sep 17 00:00:00 2001 From: wasabrot <28702988+wasabrot@users.noreply.github.com> Date: Sat, 4 May 2024 18:21:28 +0200 Subject: [PATCH] added comments to tests --- Dockerfile | 2 ++ .../cash36/ebics/EbicsApplicationTests.java | 3 +- .../cash36/ebics/EbicsControllerTest.java | 13 +++++++-- .../ebics/EbicsPaymentServiceProdTests.java | 25 ++++++++++++++++- .../ebics/EbicsPaymentServiceTests.java | 19 +++++++++++++ .../ebics/EbicsPaymentStatusServiceTest.java | 9 ++++++ .../ebics/EbicsStatementServiceTest.java | 15 +++++++++- .../cash36/ebics/GeneratePaymentIdTest.java | 8 ++++++ .../cash36/ebics/PaymentStatusTest.java | 17 +++++++++-- .../io/element36/cash36/ebics/TestTool.java | 28 ++++++++++++++++++- tunnel-ports.sh | 1 + 11 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 tunnel-ports.sh diff --git a/Dockerfile b/Dockerfile index fbf7085..4280a5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,8 @@ # sudo docker run -v $HOME/ebics:/root/ebics ebics -cp "ebics-cli.jar:lib/*" org.kopi.ebics.client.EbicsClient --sta -o /root/ebics/out sta.txt FROM gradle:6-jdk11 AS build +# with local java and using sdkman +# sdk use java 11.0.23-tem && sdk use java 11.0.23-tem # build ebics-client jar and server jars; RUN ls -la; mkdir /app; diff --git a/src/test/java/io/element36/cash36/ebics/EbicsApplicationTests.java b/src/test/java/io/element36/cash36/ebics/EbicsApplicationTests.java index bdfe112..7453a9f 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsApplicationTests.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsApplicationTests.java @@ -11,6 +11,7 @@ public class EbicsApplicationTests { @Test public void contextLoads() { - // log.debug("ebics.textproxy:{}",TESTPROXY); + // Simple test if spring context are loading + log.debug("Ebics spring context loaded"); } } diff --git a/src/test/java/io/element36/cash36/ebics/EbicsControllerTest.java b/src/test/java/io/element36/cash36/ebics/EbicsControllerTest.java index 820a1fd..867d0a2 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsControllerTest.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsControllerTest.java @@ -16,28 +16,35 @@ import io.element36.cash36.ebics.dto.StatementDTO; /** + * Test API call getPayments/ on the controler + * * gradle -x checkstyleMain test --tests io.element36.cash36.ebics.EbicsControllerTest.testGetStatusReport */ @RunWith(SpringRunner.class) @SpringBootTest public class EbicsControllerTest { - + + // the service to be tested @Autowired EbicsController controller; @Test public void testGetPayments() throws Exception { + // testing the getPayments() method of a Spring MVC controller named EbicsController + ResponseEntity> payments = controller.getPayments(); assertThat(payments).isNotNull(); assertThat(payments.getBody()).isNotNull(); - + // chedk if payments are found assertThat(payments.getBody().size()).isGreaterThan(0); + for (StatementDTO item : payments.getBody()) { System.out.println("-----------------------"); + // print the statement TestTool.pp(item); } - // test content + // test content TestTool.testProxyStatements(payments.getBody()); } } diff --git a/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceProdTests.java b/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceProdTests.java index af3909d..509fabc 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceProdTests.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceProdTests.java @@ -15,10 +15,18 @@ @RunWith(SpringRunner.class) @SpringBootTest(properties = {"ebics.mode=disabled", "ebics.outputDir=./out"}) @ActiveProfiles("prod") +/** + * This test is meant to run only in PROD configurations, which real bank backends. + */ public class EbicsPaymentServiceProdTests { + // Access to service where we can trigger payments @Autowired EbicsPaymentService ebicsPaymentService; + /** + * Make a test payment through the payment service. + * + */ @Test public void makePayment() throws Exception { // String makePayment(String msgId, String pmtInfId, String sourceIban, String sourceBic, @@ -32,6 +40,7 @@ public void makePayment() throws Exception { // values taken from // https://www.iban.com/structure + // execute a payment and read the response. TxResponse txResponse = ebicsPaymentService.makePayment( "4711", @@ -54,15 +63,24 @@ public void makePayment() throws Exception { false); System.out.println(txResponse); + // now we want to get hands of the actual Ebics PAIN document, which was + // sent by the bank backend, not only the JSON "business object" String fileName=txResponse.getEbicsDocumentPath().trim(); String content=TestTool.readLineByLineJava8(fileName); - //System.out.println("Payment File content:\n:"+content); + + // we replace timestamps to that we can compare the Ebics XML response. + // Everything should be like we defined in MSG; but of course the timestamps + // are different. So we replace them to make a String comparison. + content=TestTool.findAndReplaceTagContent("CreDtTm", "2021-07-16T14:43:03", content); content=TestTool.findAndReplaceTagContent("ReqdExctnDt", "2021-07-16", content); org.assertj.core.api.Assertions.assertThat(content).isEqualTo(TestTool.PAIN1); } @Test + /** + * Trigger a payment and check the PAIN-XML (payment instruction) generated by the payment service. + */ public void simulatePayment() throws Exception { // String makePayment(String msgId, String pmtInfId, String sourceIban, String sourceBic, // BigDecimal amount, @@ -100,6 +118,11 @@ public void simulatePayment() throws Exception { String fileName=txResponse.getEbicsDocumentPath(); String content=TestTool.readLineByLineJava8(fileName); System.out.println("Payment File content:\n:"+content); + + // we replace timestamps to that we can compare the Ebics XML response. + // Everything should be like we defined in MSG; but of course the timestamps + // are different. So we replace them to make a String comparison. + content=TestTool.findAndReplaceTagContent("CreDtTm", "2021-07-16T15:12:31", content); content=TestTool.findAndReplaceTagContent("ReqdExctnDt", "2021-07-16", content); org.assertj.core.api.Assertions.assertThat(content).isEqualTo(TestTool.PAIN2); diff --git a/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceTests.java b/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceTests.java index e2cd29d..a80383e 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceTests.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsPaymentServiceTests.java @@ -15,9 +15,13 @@ @SpringBootTest public class EbicsPaymentServiceTests { + // Service to be tested @Autowired EbicsPaymentService ebicsPaymentService; @Test + /** + * Test the payment call which triggers an OUTGOING payment (incoming done by simulatePayment below) + */ public void makePayment() throws Exception { // String makePayment(String msgId, String pmtInfId, String sourceIban, String sourceBic, // BigDecimal amount, @@ -30,6 +34,8 @@ public void makePayment() throws Exception { // values taken from // https://www.iban.com/structure + + // execute a payment via the configured service, get the response. TxResponse txResponse = ebicsPaymentService.makePayment( "4711", @@ -55,12 +61,20 @@ public void makePayment() throws Exception { String fileName=txResponse.getEbicsDocumentPath().trim(); String content=TestTool.readLineByLineJava8(fileName); //System.out.println("Payment File content:\n:"+content); + + // we replace timestamps to that we can compare the Ebics XML response. + // Everything should be like we defined in MSG; but of course the timestamps + // are different. So we replace them to make a String comparison + content=TestTool.findAndReplaceTagContent("CreDtTm", "2021-07-16T14:43:03", content); content=TestTool.findAndReplaceTagContent("ReqdExctnDt", "2021-07-16", content); org.assertj.core.api.Assertions.assertThat(content).isEqualTo(TestTool.PAIN1); } @Test + /** + * Test the simulate Payment service call, which simulates in INCOMING payment. + */ public void simulatePayment() throws Exception { // String makePayment(String msgId, String pmtInfId, String sourceIban, String sourceBic, // BigDecimal amount, @@ -98,6 +112,11 @@ public void simulatePayment() throws Exception { String fileName=txResponse.getEbicsDocumentPath(); String content=TestTool.readLineByLineJava8(fileName); System.out.println("Payment File content:\n:"+content); + + // we replace timestamps to that we can compare the Ebics XML response. + // Everything should be like we defined in MSG; but of course the timestamps + // are different. So we replace them to make a String comparison + content=TestTool.findAndReplaceTagContent("CreDtTm", "2021-07-16T15:12:31", content); content=TestTool.findAndReplaceTagContent("ReqdExctnDt", "2021-07-16", content); org.assertj.core.api.Assertions.assertThat(content).isEqualTo(TestTool.PAIN2); diff --git a/src/test/java/io/element36/cash36/ebics/EbicsPaymentStatusServiceTest.java b/src/test/java/io/element36/cash36/ebics/EbicsPaymentStatusServiceTest.java index 3ebea80..1ff2b45 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsPaymentStatusServiceTest.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsPaymentStatusServiceTest.java @@ -13,14 +13,23 @@ @RunWith(SpringRunner.class) @SpringBootTest +/** + * Call StatusReport (z01 document) from the banking backend. + */ public class EbicsPaymentStatusServiceTest { + // the service to be tested @Autowired EbicsPaymentStatusService ebicsPaymentStatusService; @Test public void getStatus() { + // Get Status of our payments, and print it. Its informative + // because we do not rely on status messages, but + // for debugging purpuse is might be interesting to + // see the status of each transaction. List transactions = ebicsPaymentStatusService.getStatusReport(); for (PaymentStatusReportDTO tx : transactions) { + // print message id System.out.println("msg-id: " + tx.getMsgId()); } } diff --git a/src/test/java/io/element36/cash36/ebics/EbicsStatementServiceTest.java b/src/test/java/io/element36/cash36/ebics/EbicsStatementServiceTest.java index 42ff5c4..b224b99 100644 --- a/src/test/java/io/element36/cash36/ebics/EbicsStatementServiceTest.java +++ b/src/test/java/io/element36/cash36/ebics/EbicsStatementServiceTest.java @@ -17,19 +17,30 @@ @RunWith(SpringRunner.class) @SpringBootTest +/** + * Reads daily statement of a bank, according to EBICS specification. + * Means that if you call Service once, the backend will mark + * the statements you received. Next time the service is called it + * will only get new data if there are new transactions. + */ public class EbicsStatementServiceTest { + // the service to be tested @Autowired EbicsStatementService ebicsStatementService; @Test public void testReadBankStatement() throws Exception { + // get all non-fetched bank statements, print how many we found List statement = ebicsStatementService.getBankStatement(); pp("no. statements: ", statement.size()); - + assertThat(statement.size()).isBetween(1, 3); boolean reachedIn = false; boolean reachedOut = false; + // go into each statement report for (StatementDTO account : statement) { + // print the information and check if there + // are incoming and outgoing transactions, otherwise fail. pp( "account: ", account.getBalanceCL(), @@ -57,6 +68,8 @@ public void testReadBankStatement() throws Exception { reachedOut = true; } } + + // check for in and outgoing transactions were found assertThat(reachedIn).isTrue(); assertThat(reachedOut).isTrue(); diff --git a/src/test/java/io/element36/cash36/ebics/GeneratePaymentIdTest.java b/src/test/java/io/element36/cash36/ebics/GeneratePaymentIdTest.java index ad54182..18e0d8c 100644 --- a/src/test/java/io/element36/cash36/ebics/GeneratePaymentIdTest.java +++ b/src/test/java/io/element36/cash36/ebics/GeneratePaymentIdTest.java @@ -13,23 +13,31 @@ @RunWith(SpringRunner.class) @SpringBootTest +/** + * We generate Ids on the backend; lets test the algo. + */ public class GeneratePaymentIdTest { + // service to be tested @Autowired GeneratePaymentIds paymentIds; @Test public void testMsgId() throws Exception { + // Create a new message Id; test the null/default behaviour String id = paymentIds.getMsgId(null, null); pp("tx-id" + id); assertThat(id).isNotNull(); + // compliant with Ebics standard assertThat(id.length()).isBetween(10, 250); } @Test public void testPmtInfId() throws Exception { + // generate a payment id. String id = paymentIds.getPmtInfId(null, null); pp("tx-id" + id); assertThat(id).isNotNull(); + // should be OK with ebics standard. assertThat(id.length()).isBetween(1, 250); } } diff --git a/src/test/java/io/element36/cash36/ebics/PaymentStatusTest.java b/src/test/java/io/element36/cash36/ebics/PaymentStatusTest.java index 89ed1b3..be59b1a 100644 --- a/src/test/java/io/element36/cash36/ebics/PaymentStatusTest.java +++ b/src/test/java/io/element36/cash36/ebics/PaymentStatusTest.java @@ -22,18 +22,25 @@ @RunWith(SpringRunner.class) @SpringBootTest(properties = {"ebics.mode=proxy"}) public class PaymentStatusTest { - + // for storing test data private static final String TMP_DIR = System.getProperty("java.io.tmpdir") + "/"; + // the service to be tested @Autowired PaymentStatus paymentStatus; + @Test + /** + * We test the paymeentStatus backend with test data of MSG (PAIN file below). + */ public void testLoad() throws Exception { + // we need to convert the variable to a format which is + // typical for ebics and can be processed by the service + File tempFile = File.createTempFile(TMP_DIR + "test", ".xml"); // Writes a string to the above temporary file - Files.write(tempFile.toPath(), MSG.getBytes(StandardCharsets.UTF_8)); // zip it File zipFile = File.createTempFile(TMP_DIR + "test", ".zip"); @@ -41,17 +48,23 @@ public void testLoad() throws Exception { FileOutputStream fos = new FileOutputStream(zipFile); ZipOutputStream zos = new ZipOutputStream(fos); + // add tempFile to zip zos.putNextEntry(new ZipEntry(tempFile.getName())); + // convert tmepFile to bytes byte[] bytes = Files.readAllBytes(Paths.get(tempFile.getAbsolutePath())); zos.write(bytes, 0, bytes.length); zos.closeEntry(); zos.close(); + // call the paymentStatus with the ZipFile List status = paymentStatus.process(zipFile); assertThat(status.size()).isEqualTo(1); } + // MSG is a message, actually a PAIN file (payment instruction) - which + // is sent to bank backend to trigger a payment. Later this payment (transaction) is + // visible in the bank statement. static final String MSG = "\n" + " \n" diff --git a/src/test/java/io/element36/cash36/ebics/TestTool.java b/src/test/java/io/element36/cash36/ebics/TestTool.java index 1a7e77d..e41c64f 100644 --- a/src/test/java/io/element36/cash36/ebics/TestTool.java +++ b/src/test/java/io/element36/cash36/ebics/TestTool.java @@ -14,8 +14,13 @@ import io.element36.cash36.ebics.dto.StatementDTO; import io.element36.cash36.ebics.dto.TransactionDTO; +/** + * Some test tools and test data to generate payments and test methods to check if the + * content of the payments was captured properly by the backend. + */ public class TestTool { + /** pp is pretty print; converts an object to String, e.g. for logging and testing */ public static String pp(Object... objects) { String result = " "; if (objects == null) { @@ -29,20 +34,32 @@ public static String pp(Object... objects) { } + /** + * Utility function to get a file as a String + */ public static String readLineByLineJava8(String filePath) throws IOException { return new String(Files.readAllBytes(Paths.get(filePath))); } + + /** Tests statements of a bank acount using its DTO. Overall, this method tests various properties of + * the StatementDTO objects, including balance, IBAN, transaction details, and address lines. + * The assertions ensure that the properties match the expected values, helping to verify the + * correctness of the StatementDTO objects. + * */ public static void testProxyStatements(List statements) { // assertThat(statements.size()).isEqualTo(2); // assertThat(statements.size()).isEqualTo(2); StatementDTO statement = statements.get(0); + // do various test on the data, start with header pp(statement); // check from account assertThat(statement.getBalanceCL()).isEqualTo(new BigDecimal("80097.2")); assertThat(statement.getIban()).isEqualTo("CH4308307000289537312"); + + // pick first transaction TransactionDTO tx = statement.getOutgoingTransactions().get(0); assertThat(tx.getCurrency()).isEqualTo("CHF"); assertThat(tx.getAmount()).isEqualTo(new BigDecimal("745.25")); @@ -51,6 +68,7 @@ public static void testProxyStatements(List statements) { // tx.getAddrLine().get(0) // VISECA CARD SERVICES S.A. + // pick second transaction. statement = statements.get(1); assertThat(statement.getBalanceCL()).isEqualTo(new BigDecimal("110")); assertThat(statement.getIban()).isEqualTo("CH2108307000289537320"); // pegging account @@ -60,13 +78,18 @@ public static void testProxyStatements(List statements) { assertThat(tx.getAddrLine().get(0)).isEqualTo("element36 AG \nBahnmatt 25 \n6340 Baar"); } +/** + * Utility function to replace the .innerHTML of a tag + */ public static String findAndReplaceTagContent(String tag, String replaceWith, String inputString) { Pattern p = Pattern.compile("<"+tag+">(.+?)"); Matcher matcher = p.matcher(inputString); return matcher.replaceAll("<"+tag+">"+replaceWith+""); } - +// PAIN file is a payment instruction sent to the bank backend. One is an ingoing, the other an +// outgoing transaction. Both will be sent to the backend for processing. +// We later look if this information is captured in bank statements. public static final String PAIN1="\n" + "\n" + " \n" @@ -132,6 +155,9 @@ public static String findAndReplaceTagContent(String tag, String replaceWith, St + "\n" + ""; + +// PAIN file is a payment instruction sent to the bank backend. We later look if this information +// is captured in bank statements. public static final String PAIN2="\n" + "\n" + " \n" diff --git a/tunnel-ports.sh b/tunnel-ports.sh new file mode 100644 index 0000000..58f4239 --- /dev/null +++ b/tunnel-ports.sh @@ -0,0 +1 @@ +code --remote-forward 8093:localhost:8093 --remote-forward 3000:localhost:3000