6.10. PDF als Mailanhang testen

Ausgangssituation

Ihr Unternehmen stellt seinen Kunden monatliche Abrechnungen per Mail zu.

Problem

Wie kann die PDF-Datei aus diesem Mail validiert werden?

Es gilt zwei Probleme zu lösen. Einerseits muss innerhalb des Tests ein Mail verschickt werden und unmittelbar wieder ausgewertet werden. Und andererseits ist der PDF-Anhang des erhaltenen Mails zu analysieren.

Lösungsansatz

Das erste Problem löst Dumbster, eine Java-API zum Testen von Mail-Anwendungen, und das zweite Problem löst PDFUnit. Der entscheidende Schritt ist, dass der Mail-Anhang als Byte-Array an PDFUnit übergeben wird.

Lösung

/**
 * This test invokes a business system which sends a mail with a PDF attachment.
 * After sending the mail the PDF file is validated using PDFUnit.
 */
@Test
public void verifyPDFReceivedByEmail() throws Exception {
  // Arrange:
  BusinessSystem myBusinessSystem = BusinessSystem.newInstance();
  
  // Act:
  myBusinessSystem.doSomethingImportant();
  myBusinessSystem.sendMailWithPDFAttachment();
  
  // Assert:
  String pdfFileName = myBusinessSystem.getAttachedPDFName();
  byte[] attachmentAsByteArray = ReceiveMailHelper.getInstance(server)
                                                  .getAttachmentFromLastMail(pdfFileName);
  DocumentValidator pdfDocument = AssertThat.document(attachmentAsByteArray);
  pdfDocument.hasNumberOfPages(4);
  pdfDocument.restrictedTo(EVERY_PAGE)
             .hasText()
             .containing("http://pdfunit.com")
  ;
}

Und hier die restlichen Teil des Tests:

/**
 * Validation of a PDF document received by email.
 * This example uses <a href="https://github.com/rjo1970/dumbster.git">dumbster</a>,
 * as a mail testing API.
 * 
 * @author Carsten Siedentop, August 2014
 */
public class MailWithPDFAttachmentTest {

  private SmtpServer server;
  
  @Before
  public void createEmptyMailStoreDirectory() throws Exception {
    ServerOptions options = new ServerOptions();
    options.port = SendMailHelper.SMTP_PORT;
    options.threaded = false;
    server = SmtpServerFactory.startServer(options);
  }

  @After
  public void teardown() {
    server.stop();
  }

  // @Test
  // public void verifyPDFReceivedByEmail()...
  
}

Anstatt dieser einfachen Prüfung hätten auch Rechnungsdaten über ZUGFeRD validiert werden können. Beispielsweise stellt der folgende Test sicher, dass der Wert der IBAN innerhalb der ZUGFeRD-Daten mit dem Wert der IBAN auf der ersten Seite des Dokumentes gleich ist.

...
XMLNode nodeIBAN = new XMLNode("ram:IBANID");
PageRegion regionIBAN = createRegionIBAN();

DocumentValidator pdfDocument = AssertThat.document(pdfStream);
pdfDocument.restrictedTo(FIRST_PAGE)
           .restrictedTo(regionIBAN)
           .hasText()
           .containingZugferdData(nodeIBAN)
;
...