Skip to content

Commit

Permalink
Merge pull request #327 from MelanieVeigl/master
Browse files Browse the repository at this point in the history
Added tests for DataTypeReader and missing qdt namespace
  • Loading branch information
stephanstapel authored Aug 16, 2024
2 parents a644086 + 7b46860 commit 18a4dcd
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 1 deletion.
120 changes: 120 additions & 0 deletions ZUGFeRD-Test/DataTypeReaderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
using System.Reflection;
using System.Xml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using s2industries.ZUGFeRD;

namespace ZUGFeRD_Test
{
[TestClass]
public class DataTypeReaderTests
{
private readonly Type? _dataTypeReader = typeof(InvoiceDescriptor).Assembly.GetType("s2industries.ZUGFeRD.DataTypeReader");

[TestMethod]
public void ReadFormattedIssueDateTime_ReturnsCorrectDateTime_WhenNodeContainsQdt()
{
// Arrange
var doc = new XmlDocument();
doc.LoadXml("<root xmlns=\"http://www.sample.com/file\" xmlns:qdt=\"http://example.com/1\">" +
"<dateTime>" +
"<qdt:DateTimeString format=\"102\">20230101</qdt:DateTimeString>" +
"</dateTime></root>");
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("qdt", "http://example.com/1");
nsmgr.AddNamespace("def", "http://www.sample.com/file");
var node = doc.SelectSingleNode("//def:dateTime", nsmgr);

// Act
var result = InvokeReadFormattedIssueDateTime(node, ".", nsmgr, null);

// Assert
Assert.AreEqual(new DateTime(2023, 1, 1), result);
}

[TestMethod]
public void ReadFormattedIssueDateTime_ReturnsCorrectDateTime_WhenNodeContainsUdt()
{
// Arrange
var doc = new XmlDocument();
doc.LoadXml("<root xmlns=\"http://www.sample.com/file\" xmlns:udt=\"http://example.com/1\">" +
"<dateTime>" +
"<udt:DateTimeString format=\"102\">20230101</udt:DateTimeString>" +
"</dateTime></root>");
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("udt", "http://example.com/1");
nsmgr.AddNamespace("def", "http://www.sample.com/file");
var node = doc.SelectSingleNode("//def:dateTime", nsmgr);

// Act
var result = InvokeReadFormattedIssueDateTime(node, ".", nsmgr, null);

// Assert
Assert.AreEqual(new DateTime(2023, 1, 1), result);
}


[TestMethod]
public void ReadFormattedIssueDateTime_ReturnsDefaultValue_WhenNodeIsEmpty()
{
// Arrange
var doc = new XmlDocument();
doc.LoadXml("<root><dateTime></dateTime></root>");
var node = doc.SelectSingleNode("//dateTime");
var nsmgr = new XmlNamespaceManager(new NameTable());
DateTime? expected = new DateTime(2023, 1, 1);

// Act
var result = InvokeReadFormattedIssueDateTime(node, ".", nsmgr, expected);

// Assert
Assert.AreEqual(expected, result);
}

[TestMethod]
public void ReadFormattedIssueDateTime_ReturnsDefaultValue_WhenNodeDoesNotContainQdtOrUdt()
{
// Arrange
var doc = new XmlDocument();
doc.LoadXml("<root><dateTime>NoSpecialTag</dateTime></root>");
var node = doc.SelectSingleNode("//dateTime");
var nsmgr = new XmlNamespaceManager(new NameTable());
var defaultValue = new DateTime(2023, 1, 1);

// Act
var result = InvokeReadFormattedIssueDateTime(node, ".", nsmgr, defaultValue);

// Assert
Assert.AreEqual(defaultValue, result);
}


private DateTime? InvokeReadFormattedIssueDateTime(params object?[] methodParams)
{
ArgumentNullException.ThrowIfNull(_dataTypeReader);

var method = _dataTypeReader.GetMethod("ReadFormattedIssueDateTime", BindingFlags.NonPublic | BindingFlags.Static);

ArgumentNullException.ThrowIfNull(method);

return (DateTime?)method.Invoke(null, methodParams);
}
}
}
16 changes: 15 additions & 1 deletion ZUGFeRD-Test/ZUGFeRD22Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NuGet.Frameworks;
using s2industries.ZUGFeRD;


Expand Down Expand Up @@ -2021,5 +2020,20 @@ public void TestSellerContact()

Assert.AreEqual(loadedInvoice.Seller.Description, description);
} // !TestSellerContact()

[TestMethod]
public void ShouldLoadCiiWithoutQdtNamespace()
{
string path = @"..\..\..\..\demodata\xRechnung\xRechnung CII - without qdt.xml";
path = _makeSurePathIsCrossPlatformCompatible(path);

InvoiceDescriptor desc = InvoiceDescriptor.Load(path);

Assert.AreEqual(desc.Profile, Profile.XRechnung);
Assert.AreEqual(desc.Type, InvoiceType.Invoice);
Assert.AreEqual(desc.InvoiceNo, "123456XX");
Assert.AreEqual(desc.TradeLineItems.Count, 2);
Assert.AreEqual(desc.LineTotalAmount, 314.86m);
} // !ShouldLoadCIIWithoutQdtNamespace()
}
}
161 changes: 161 additions & 0 deletions demodata/xRechnung/xRechnung CII - without qdt.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>123456XX</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20160404</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:Content>Es gelten unsere Allgem. Geschäftsbedingungen, die Sie unter […] finden.</ram:Content>
<ram:SubjectCode>ADU</ram:SubjectCode>
</ram:IncludedNote>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>Zeitschrift [...]</ram:LineID>
<ram:IncludedNote>
<ram:Content>Die letzte Lieferung im Rahmen des abgerechneten Abonnements erfolgt in 12/2016 Lieferung erfolgt / erfolgte direkt vom Verlag</ram:Content>
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:SellerAssignedID>246</ram:SellerAssignedID>
<ram:Name>Zeitschrift [...]</ram:Name>
<ram:Description>Zeitschrift Inland</ram:Description>
<ram:DesignatedProductClassification>
<ram:ClassCode listID="IB">0721-880X</ram:ClassCode>
</ram:DesignatedProductClassification>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:BuyerOrderReferencedDocument>
<ram:LineID>6171175.1</ram:LineID>
</ram:BuyerOrderReferencedDocument>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>288.79</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="XPP">1</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:BillingSpecifiedPeriod>
<ram:StartDateTime>
<udt:DateTimeString format="102">20160101</udt:DateTimeString>
</ram:StartDateTime>
<ram:EndDateTime>
<udt:DateTimeString format="102">20161231</udt:DateTimeString>
</ram:EndDateTime>
</ram:BillingSpecifiedPeriod>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>288.79</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>Porto + Versandkosten</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Porto + Versandkosten</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>26.07</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="XPP">1</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>26.07</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:BuyerReference>04011000-12345-34</ram:BuyerReference>
<ram:SellerTradeParty>
<ram:Name>[Seller name]</ram:Name>
<ram:Description>123/456/7890, HRA-Eintrag in […]</ram:Description>
<ram:SpecifiedLegalOrganization>
<ram:ID>[HRA-Eintrag]</ram:ID>
<ram:TradingBusinessName>[Seller trading name]</ram:TradingBusinessName>
</ram:SpecifiedLegalOrganization>
<ram:DefinedTradeContact>
<ram:PersonName>nicht vorhanden</ram:PersonName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49 1234-5678</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>[email protected]</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>12345</ram:PostcodeCode>
<ram:LineOne>[Seller address line 1]</ram:LineOne>
<ram:CityName>[Seller city]</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE 123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>[Buyer identifier]</ram:ID>
<ram:Name>[Buyer name]</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>12345</ram:PostcodeCode>
<ram:LineOne>[Buyer address line 1]</ram:LineOne>
<ram:CityName>[Buyer city]</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery/>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>58</ram:TypeCode>
<ram:PayeePartyCreditorFinancialAccount>
<!-- dies ist eine nicht existerende aber valide IBAN als test dummy -->
<ram:IBANID>DE75512108001245126199</ram:IBANID>
</ram:PayeePartyCreditorFinancialAccount>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>22.04</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>314.86</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>7</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Zahlbar sofort ohne Abzug.</ram:Description>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>314.86</ram:LineTotalAmount>
<ram:TaxBasisTotalAmount>314.86</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">22.04</ram:TaxTotalAmount>
<ram:GrandTotalAmount>336.9</ram:GrandTotalAmount>
<ram:DuePayableAmount>336.9</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

0 comments on commit 18a4dcd

Please sign in to comment.