From 5aae0bfe774a50af79d9f5ba20c6d0eab352f240 Mon Sep 17 00:00:00 2001 From: dankito Date: Thu, 14 Nov 2024 17:31:12 +0100 Subject: [PATCH] Using now XPath to assert generated invoices --- e-invoicing-domain/build.gradle.kts | 2 + .../invoicing/creation/EInvoiceCreatorTest.kt | 42 +++++++++++++++++-- .../codinux/invoicing/test/XPathAsserter.kt | 34 +++++++++++++++ gradle.properties | 1 + 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/test/XPathAsserter.kt diff --git a/e-invoicing-domain/build.gradle.kts b/e-invoicing-domain/build.gradle.kts index 4b9ee34..02b0a1f 100644 --- a/e-invoicing-domain/build.gradle.kts +++ b/e-invoicing-domain/build.gradle.kts @@ -13,6 +13,7 @@ val mustangVersion: String by project val klfVersion: String by project val assertKVersion: String by project +val xunitVersion: String by project dependencies { implementation("org.mustangproject:library:$mustangVersion") @@ -23,6 +24,7 @@ dependencies { testImplementation(kotlin("test")) implementation("com.willowtreeapps.assertk:assertk:$assertKVersion") + testImplementation("org.xmlunit:xmlunit-core:$xunitVersion") } diff --git a/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/creation/EInvoiceCreatorTest.kt b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/creation/EInvoiceCreatorTest.kt index b1791d1..6edd27d 100644 --- a/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/creation/EInvoiceCreatorTest.kt +++ b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/creation/EInvoiceCreatorTest.kt @@ -1,9 +1,10 @@ package net.codinux.invoicing.creation import assertk.assertThat -import assertk.assertions.contains import assertk.assertions.isNotEmpty import net.codinux.invoicing.test.DataGenerator +import net.codinux.invoicing.test.XPathAsserter +import java.math.BigDecimal import kotlin.test.Test class EInvoiceCreatorTest { @@ -35,8 +36,43 @@ class EInvoiceCreatorTest { private fun assertInvoiceXml(xml: String) { assertThat(xml).isNotEmpty() - assertThat(xml).contains("${DataGenerator.InvoiceNumber}") - assertThat(xml).contains("""${DataGenerator.InvoicingDate.toString().replace("-", "")}""") + val asserter = XPathAsserter(xml) + + asserter.xpathHasValue("//rsm:ExchangedDocument/ram:ID", DataGenerator.InvoiceNumber) + asserter.xpathHasValue("//rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString", DataGenerator.InvoicingDate.toString().replace("-", "")) + + val senderXPath = "//rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerTradeParty" + assertParty(asserter, senderXPath, DataGenerator.SenderName, DataGenerator.SenderStreet, DataGenerator.SenderPostalCode, DataGenerator.SenderCity, DataGenerator.SenderVatId, DataGenerator.SenderEmail) + + val receiverXPath = "//rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:BuyerTradeParty" + assertParty(asserter, receiverXPath, DataGenerator.RecipientName, DataGenerator.RecipientStreet, DataGenerator.RecipientPostalCode, DataGenerator.RecipientCity, DataGenerator.RecipientVatId, DataGenerator.RecipientEmail) + + val lineItemXPath = "//rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem" + assertLineItem(asserter, lineItemXPath, DataGenerator.ItemName, DataGenerator.ItemUnit, DataGenerator.ItemQuantity, DataGenerator.ItemPrice, DataGenerator.ItemVat, DataGenerator.ItemDescription) + } + + private fun assertParty(asserter: XPathAsserter, partyXPath: String, name: String, street: String, postalCode: String, city: String, vatId: String, email: String) { + asserter.xpathHasValue("$partyXPath/ram:Name", name) + + asserter.xpathHasValue("$partyXPath/ram:PostalTradeAddress/ram:LineOne", street) + asserter.xpathHasValue("$partyXPath/ram:PostalTradeAddress/ram:PostcodeCode", postalCode) + asserter.xpathHasValue("$partyXPath/ram:PostalTradeAddress/ram:CityName", city) + + asserter.xpathHasValue("$partyXPath/ram:SpecifiedTaxRegistration/ram:ID", vatId) + + asserter.xpathHasValue("$partyXPath/ram:URIUniversalCommunication/ram:URIID", email) + } + + private fun assertLineItem(asserter: XPathAsserter, partyXPath: String, name: String, unit: String, quantity: BigDecimal, price: BigDecimal, vatPercentage: BigDecimal, description: String?) { + asserter.xpathHasValue("$partyXPath/ram:SpecifiedTradeProduct/ram:Name", name) + + asserter.xpathHasValue("$partyXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode", unit) + asserter.xpathHasValue("$partyXPath/ram:SpecifiedLineTradeDelivery/ram:BilledQuantity", quantity, 4) + + asserter.xpathHasValue("$partyXPath/ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount", price, 2) + asserter.xpathHasValue("$partyXPath/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:RateApplicablePercent", vatPercentage, 2) + +// asserter.xpathHasValue("$partyXPath/ram:URIUniversalCommunication/ram:URIID", description) } } \ No newline at end of file diff --git a/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/test/XPathAsserter.kt b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/test/XPathAsserter.kt new file mode 100644 index 0000000..b60287f --- /dev/null +++ b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/test/XPathAsserter.kt @@ -0,0 +1,34 @@ +package net.codinux.invoicing.test + +import assertk.assertThat +import assertk.assertions.isEqualTo +import net.codinux.log.Platform +import org.xmlunit.builder.Input +import org.xmlunit.xpath.JAXPXPathEngine +import java.math.BigDecimal +import java.math.RoundingMode + +class XPathAsserter( + xml: String +) { + + private val source = Input.fromString(xml).build() + + private val xpathEngine = JAXPXPathEngine().apply { + setNamespaceContext(mapOf( + "rsm" to "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100", + "ram" to "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100", + "udt" to "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" + )) + } + + + fun xpathHasValue(xpath: String, value: String) { + assertThat(xpathEngine.evaluate(xpath, source)).isEqualTo(value) + } + + fun xpathHasValue(xpath: String, value: BigDecimal, countDecimalPlatform: Int = 2) { + xpathHasValue(xpath, value.setScale(countDecimalPlatform, RoundingMode.HALF_UP).toString()) + } + +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 5099174..10e8f72 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,4 @@ mustangVersion=2.14.2 klfVersion=1.6.2 assertKVersion=0.28.1 +xunitVersion=2.10.0 \ No newline at end of file