Wenn im Zeitalter der elektronischen Kommunikation vertraglich relevante Informationen in Form von PDF-Dokumenten ausgetauscht werden, muss irgendwie sichergestellt werden, dass die Daten auch wirklich von demjenigen stammen, von dem sie vorgeben, zu sein. Für diesen Zweck gibt es Zertifikate. Sie bestätigen - unabhängig von PDF-Dokumenten - die Echtheit von Personen- oder Unternehmensdaten. Mit einem Zertifikat kann der Inhalt von Dokumenten unterschrieben (signiert) werden. Dafür bietet PDF ein spezielles Signaturfeld an.
PDFUnit stellt für Signaturen zahlreiche Testmethoden zur Verfügung:
// Simple methods for signatures: .isSigned() .isSignedBy(..) .hasNumberOfSignatures(..) .hasSignatureField(..) .hasSignatureFields() // Detailed tests for one signature: .hasSignatureField(..).withSignature(..).coveringWholeDocument() .hasSignatureField(..).withSignature(..).signedBy(name) .hasSignatureField(..).withSignature(..).signedOn(date) .hasSignatureField(..).withSignature(..).withReason(..) .hasSignatureField(..).withoutSignature(..) // Tests covering all signature fields: .hasSignatureFields().allSigned() .hasSignatureFields().allUnSigned() // Other tests with signatures: .hasField(..).ofType(SIGNATURE) .hasField(..).withProperty().signed()
Ein „signiertes PDF“ darf nicht mit einem „zertifizierten PDF“ verwechselt werden. Ein „zertifiziertes PDF“ garantiert die Einhaltung bestimmter Eigenschaften, die für eine Verarbeitung benötigt werden. Tests für zertifizierte PDF-Dokumente sind im Kapitel 3.38: „Zertifiziertes PDF“ beschrieben.
Der einfachste Test ist, zu prüfen, ob ein Testdokument überhaupt signiert ist:
@Test public void isSigned() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .isSigned() ; }
Wenn es mehrere Unterschriftsfelder gibt, kann auch geprüft werden, ob alle Felder signiert sind:
@Test public void allFieldsSigned() throws Exception { String filename = "documentUnderTest.pdf"; AssertThat.document(filename) .hasSignatureFields() .allSigned() ; }
Die Methode .allUnsigned()
prüft genau das Gegenteil.
Ein spezielles Unterschriftsfeld kann auf folgende Weise validiert werden:
@Test public void hasField_Signed() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; String fieldnameSignedField = "Signature2"; AssertThat.document(filename) .hasField(fieldnameSignedField) .withProperty() .signed() ; }
Weiterhin kann die Existenz von Unterschriftsfeldern geprüft werden:
@Test public void hasSignatureFields() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature of Seller") .hasSignatureField("Signature of Buyer") ; }
Und führt man die Intention der vorhergehende Tests weiter fort, muss die Frage gestellt werden, ob bestimmte Unterschriftsfelder unterschrieben sind. Die Antwort liefert der folgende Test:
@Test public void hasSignatureFieldsWithSignature() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature of Seller").withSignature() .hasSignatureField("Signature of Buyer").withSignature() ; }
Der umgekehrte Fall, dass ein Unterschriftsfeld keine Unterschrift enthält,
kann mit der Funktion .hasSignatureField("name").withoutSignature()
überprüft werden.
Da ein PDF-Dokument mehrere Unterschriften enthalten kann, gibt es auch einen Test, der lediglich die Anzahl der Signaturen überprüft:
@Test public void hasNumberOfSignatures() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasNumberOfSignatures(1) ; }
Es ist manchmal interessant, festzustellen, wann ein PDF-Dokument unterschrieben wurde:
@Test public void hasSignature_WithSigningDate() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; Calendar signingDate = DateHelper.getCalendar("2009-07-16", "yyyy-MM-dd"); AssertThat.document(filename) .hasSignatureField("Signature2") .signedOn(signingDate) ; }
Möglicherweise ist es für Tests nicht so interessant, den Grund einer Unterschrift zu überprüfen. Falls ein solcher Test aber notwendig sein sollte, dann sieht er folgendermaßen aus:
@Test public void hasSignature_WithReason() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature2") .withSignature() .withReason("I am the author of this document") ; }
Vor dem Vergleich werden die Whitespaces normalisiert.
Auch der Name dessen, der ein PDF-Dokument unterschrieben hat, ist für Testzwecke weniger interessant, als für die produktive Verarbeitung von PDF-Dokumenten. Dennoch gibt es dafür eine Testmethode:
@Test public void hasSignature_WithSigningName() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature2") .withSigningName("John B Harris") ; }
Mit dem folgenden Test kann eine erwartete Unterschrift auch unabhängig von einem bestimmten Feld getestet werden:
@Test public void isSignedBy() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .isSignedBy("John B Harris") ; }
Eine Unterschrift kann sich laut PDF Standard auch auf Teile eines Dokumentes beziehen. Deshalb ist es möglich, zu testen, ob eine Unterschrift das komplette Dokument abdeckt:
@Test public void hasSignature_CoveringWholeDocument() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature2") .coveringWholeDocument() ; }
Mehrere Tests, die sich auf ein Unterschriftsfeld beziehen, können verkettet werden:
@Test public void differentAspectsAroundSignature() throws Exception { String filename = "helloWorld_signed.pdf"; Calendar signingDate = DateHelper.getCalendar("2007-10-14", "yyyy-MM-dd"); AssertThat.document(filename) .hasSignatureField("sign_rbl") .signedBy("Raymond Berthou") .signedOn(signingDate) .coveringWholeDocument() ; }
Überlegen Sie sich aber einen besseren Namen für diesen Test!