If contractual information is sent as a PDF document, you must check that the data really was sent by the person they claim to be. Certificates allow this. A certificate confirms the authenticity of personal or corporate data. It confirms your signature when you “sign” the content of a document in a special formular field.
PDFUnit provides these test methods for signatures:
// 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()
A “signed” PDF must not be confused with a “certified” PDF. A “certified” PDF guarantees the compliance with certain properties which are needed to process a document in further workflow steps. Tests for certified PDF documents are described in chapter 3.6: “Certified PDF”.
The simplest test is to check whether a document is actually signed:
@Test public void isSigned() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .isSigned() ; }
Multiple signature fields can be verified together:
@Test public void allFieldsSigned() throws Exception { String filename = "documentUnderTest.pdf"; AssertThat.document(filename) .hasSignatureFields() .allSigned() ; }
The method .allUnsigned()
validates the absence of all
signatures in all fields.
PDFUnit can check, whether a particular signature field contains a signature:
@Test public void hasField_Signed() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; String fieldnameSignedField = "Signature2"; AssertThat.document(filename) .hasField(fieldnameSignedField) .withProperty() .signed() ; }
The next example shows how to check whether there are any specific signature fields:
@Test public void hasSignatureFields() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature of Seller") .hasSignatureField("Signature of Buyer") ; }
The previous example can be extended to check whether specific signature fields are signed:
@Test public void hasSignatureFieldsWithSignature() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature of Seller").withSignature() .hasSignatureField("Signature of Buyer").withSignature() ; }
The function .hasSignatureField("name").withoutSignature()
checks
that a signature field is unsigned.
Because a document may contain multiple signatures, a test exists to check the number of the signatures:
@Test public void hasNumberOfSignatures() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasNumberOfSignatures(1) ; }
Sometimes, you need to know when a PDF document was signed:
@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) ; }
Maybe, it's not interesting enough to validate the signature-reason. But if it turns out to be, it can be checked:
@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") ; }
Whitespaces will be normalized before string comparison.
The name of the person who signed a PDF document can be checked as well, even if such a test is more interesting for validation in a productive work flow than in a testing scenario.
@Test public void hasSignature_WithSigningName() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature2") .withSigningName("John B Harris") ; }
The following test checks that a document is signed by the expected person. This test is unrelated to a signature field.
@Test public void isSignedBy() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .isSignedBy("John B Harris") ; }
The PDF standard allows a signature to cover only a part of a document. Thus, one may need to test whether a signature covers the complete document:
@Test public void hasSignature_CoveringWholeDocument() throws Exception { String filename = "sampleSignedPDFDocument.pdf"; AssertThat.document(filename) .hasSignatureField("Signature2") .coveringWholeDocument() ; }
Of course, test methods can be chained when they are related to one signature field:
@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() ; }
But think of a better name for this test. It would be better to split it into several tests with specific names.