Skip to content

Commit

Permalink
Cover PdfSignatureAppearance and PdfSignature with tests
Browse files Browse the repository at this point in the history
DEVSIX-5736
  • Loading branch information
ars18wrw committed Aug 24, 2021
1 parent e685164 commit c1af706
Show file tree
Hide file tree
Showing 7 changed files with 450 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ public PdfSignatureAppearance setPageRect(Rectangle pageRect) {
/**
* Get Layer 0 of the appearance.
*
* <p>
* The size of the layer is determined by the rectangle set via
* {@link PdfSignatureAppearance#setPageRect(Rectangle)}
*
* @return layer 0
*/
public PdfFormXObject getLayer0() {
Expand All @@ -293,6 +297,10 @@ public PdfFormXObject getLayer0() {
/**
* Get Layer 2 of the appearance.
*
* <p>
* The size of the layer is determined by the rectangle set via
* {@link PdfSignatureAppearance#setPageRect(Rectangle)}
*
* @return layer 2
*/
public PdfFormXObject getLayer2() {
Expand Down Expand Up @@ -666,29 +674,9 @@ protected PdfFormXObject getAppearance() throws IOException {

Rectangle rotatedRect = rotateRectangle(this.rect, document.getPage(page).getRotation());

String text;

if (layer2Text == null) {
StringBuilder buf = new StringBuilder();
buf.append("Digitally signed by ");
String name = null;
CertificateInfo.X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)signCertificate);
if (x500name != null) {
name = x500name.getField("CN");
if (name == null)
name = x500name.getField("E");
}
if (name == null)
name = "";
buf.append(name).append('\n');
buf.append("Date: ").append(SignUtils.dateToString(signDate));
if (reason != null)
buf.append('\n').append(reasonCaption).append(reason);
if (location != null)
buf.append('\n').append(locationCaption).append(location);
text = buf.toString();
} else {
text = layer2Text;
String text = layer2Text;
if (null == text) {
text = generateLayer2Text();
}

if (image != null) {
Expand Down Expand Up @@ -971,6 +959,30 @@ private void applyCopyFittingFontSize(Paragraph paragraph, Rectangle rect, IRend
paragraph.setFontSize(lFontSize);
}

String generateLayer2Text() {
StringBuilder buf = new StringBuilder();
buf.append("Digitally signed by ");
String name = null;
CertificateInfo.X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)signCertificate);
if (x500name != null) {
name = x500name.getField("CN");
if (name == null) {
name = x500name.getField("E");
}
}
if (name == null) {
name = "";
}
buf.append(name).append('\n');
buf.append("Date: ").append(SignUtils.dateToString(signDate));
if (reason != null) {
buf.append('\n').append(reasonCaption).append(reason);
}
if (location != null) {
buf.append('\n').append(locationCaption).append(location);
}
return buf.toString();
}
/**
* Signature rendering modes.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2021 iText Group NV
Authors: iText Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itextpdf.signatures;

import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.signatures.PdfSignatureAppearance.RenderingMode;
import com.itextpdf.test.ExtendedITextTest;
import com.itextpdf.test.annotations.type.UnitTest;
import com.itextpdf.test.signutils.Pkcs12FileHelper;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

/**
* The idea of this test is to check the {@link PdfSignatureAppearance}'s getters.
* For actual result of setters invocations one should check the integration test for this class.
*/
@Category(UnitTest.class)
public class PdfSignatureAppearanceUnitTest extends ExtendedITextTest {
// The source folder points to the integration test, so that the resources are nor duplicated
public static final String SOURCE_FOLDER
= "./src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/";
public static final String DESTINATION_FOLDER
= "./target/test/com/itextpdf/signatures/sign/PdfSignatureAppearanceUnitTest/";
public static final String KEYSTORE_PATH
= "./src/test/resources/com/itextpdf/signatures/sign/PdfSignatureAppearanceTest/test.p12";
public static final char[] PASSWORD = "kspass".toCharArray();

private static Certificate[] chain;

@BeforeClass
public static void before() throws KeyStoreException, IOException, CertificateException,
NoSuchAlgorithmException {
Security.addProvider(new BouncyCastleProvider());
createOrClearDestinationFolder(DESTINATION_FOLDER);
chain = Pkcs12FileHelper.readFirstChain(KEYSTORE_PATH, PASSWORD);
}

@Test
public void reasonCaptionTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

String newReasonCaption = "Hello World";

Assert.assertNull(signatureAppearance.getLayer2Text());

String layer2Text = signatureAppearance.generateLayer2Text();
// There is no text from new reason caption in the default layer 2 text
Assert.assertFalse(layer2Text.contains(newReasonCaption));

signatureAppearance.setReasonCaption(newReasonCaption);
layer2Text = signatureAppearance.generateLayer2Text();
// Now layer 2 text contains text from new reason caption
Assert.assertTrue(layer2Text.contains(newReasonCaption));
}

@Test
public void locationCaptionTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

String newLocationCaption = "Hello World";

Assert.assertNull(signatureAppearance.getLayer2Text());

String layer2Text = signatureAppearance.generateLayer2Text();
// There is no text from new location caption in the default layer 2 text
Assert.assertFalse(layer2Text.contains(newLocationCaption));

signatureAppearance.setLocationCaption(newLocationCaption);
layer2Text = signatureAppearance.generateLayer2Text();
// Now layer 2 text contains text from new location caption
Assert.assertTrue(layer2Text.contains(newLocationCaption));
}

@Test
public void renderingModeSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

RenderingMode defaultMode = signatureAppearance.getRenderingMode();
Assert.assertEquals(RenderingMode.DESCRIPTION, defaultMode);

RenderingMode testRenderingMode = RenderingMode.GRAPHIC_AND_DESCRIPTION;
signatureAppearance.setRenderingMode(testRenderingMode);
Assert.assertEquals(testRenderingMode, signatureAppearance.getRenderingMode());
}

@Test
public void signatureCreatorSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertEquals("", signatureAppearance.getSignatureCreator());

String signatureCreator = "Hello World";
signatureAppearance.setSignatureCreator(signatureCreator);
Assert.assertEquals(signatureCreator, signatureAppearance.getSignatureCreator());
}

@Test
public void contactSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertEquals("", signatureAppearance.getContact());

String contact = "Hello World";
signatureAppearance.setContact(contact);
Assert.assertEquals(contact, signatureAppearance.getContact());
}

@Test
public void certificateSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertNull(signatureAppearance.getCertificate());

Certificate testCertificate = chain[0];
signatureAppearance.setCertificate(testCertificate);
Assert.assertEquals(testCertificate, signatureAppearance.getCertificate());
}

@Test
public void signatureGraphicSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertNull(signatureAppearance.getSignatureGraphic());

ImageData testImageData = ImageDataFactory.create(SOURCE_FOLDER + "itext.png");
signatureAppearance.setSignatureGraphic(testImageData);
Assert.assertEquals(testImageData, signatureAppearance.getSignatureGraphic());
}

@Test
public void imageSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertNull(signatureAppearance.getImage());

ImageData testImageData = ImageDataFactory.create(SOURCE_FOLDER + "itext.png");
signatureAppearance.setImage(testImageData);
Assert.assertEquals(testImageData, signatureAppearance.getImage());
}

@Test
public void imageScalingSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertEquals(0, signatureAppearance.getImageScale(), 0.0001);

float newScale = 1F;
signatureAppearance.setImageScale(newScale);
Assert.assertEquals(newScale, signatureAppearance.getImageScale(), 0.0001);
}

@Test
public void layer2FontSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertNull(signatureAppearance.getLayer2Font());

PdfFont newFont = PdfFontFactory.createFont();
signatureAppearance.setLayer2Font(newFont);
Assert.assertEquals(newFont, signatureAppearance.getLayer2Font());
}

@Test
public void layer2FontSizeSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertEquals(0, signatureAppearance.getLayer2FontSize(), 0.0001);

float newSize = 12F;
signatureAppearance.setLayer2FontSize(newSize);
Assert.assertEquals(newSize, signatureAppearance.getLayer2FontSize(), 0.0001);
}


@Test
public void layer2FontColorSetGetTest() throws IOException {
PdfSignatureAppearance signatureAppearance = getTestSignatureAppearance();

Assert.assertNull(signatureAppearance.getLayer2FontColor());

Color newColor = ColorConstants.RED;
signatureAppearance.setLayer2FontColor(newColor);
Assert.assertEquals(newColor, signatureAppearance.getLayer2FontColor());
}

private static PdfSignatureAppearance getTestSignatureAppearance() throws IOException {
String src = SOURCE_FOLDER + "simpleDocument.pdf";
PdfSigner signer = new PdfSigner(new PdfReader(src), new ByteArrayOutputStream(), new StampingProperties());
return signer.getSignatureAppearance();
}
}
Loading

0 comments on commit c1af706

Please sign in to comment.