A QR code is a 2-dimensional code and can be tested similar to the 1-dimensional bar code. Internally, PDFUnit uses ZXing to parse QR code. Information about ZXing is available on the project's home page: https://github.com/zxing/zxing.
The following methods can be used to validate QR codes inside PDF files:
// Entry to all QR code validations: .hasImage().withQRCode() // Validate text in barcode: ...withQRCode().containing(..) ...withQRCode().containing(.., WhitespaceProcessing) ...withQRCode().endingWith(..) ...withQRCode().equalsTo(..) ...withQRCode().equalsTo(.., WhitespaceProcessing) ...withQRCode().matchingRegex(..) ...withQRCode().startingWith(..) // Validate text in QR code in image region: ...withQRCodeInRegion(imageRegion).containing(..) ...withQRCodeInRegion(imageRegion).containing(.., WhitespaceProcessing) ...withQRCodeInRegion(imageRegion).endingWith(..) ...withQRCodeInRegion(imageRegion).equalsTo(..) ...withQRCodeInRegion(imageRegion).equalsTo(.., WhitespaceProcessing) ...withQRCodeInRegion(imageRegion).matchingRegex(..) ...withQRCodeInRegion(imageRegion).startingWith(..) // Compare with another QR code: ...withQRCode().matchingImage(..)
ZXing detects QR code formats automatically. The following formats can be used in PDFUnit tests:
// 2D codes, supported by PDFUnit/ZXing: AZTEC DATA_MATRIX QR_CODE MAXICODE // Stacked barcode, support by PDFUnit/ZXing: PDF_417 RSS_14 RSS_EXPANDED
The QR code used in the next examples contains text from Herman Melville's novel 'Moby-Dick'.
@Test public void hasQRCodeWithText_MobyDick() throws Exception { String filename = "documentUnderTest.pdf"; int leftX = 10; int upperY = 175; int width = 70; int height = 70; PageRegion pageRegion = new PageRegion(leftX, upperY, width, height); String expectedText = "Some years ago--never mind how long precisely"; AssertThat.document(filename) .restrictedTo(FIRST_PAGE) .restrictedTo(pageRegion) .hasImage() .withQRCode() .containing(expectedText) ; }
When multiple images occupy a defined region, each image must pass the test. Default whitespace processing when searching text in QR code is NORMALIZE, but whitespace processing can be controlled using a method parameter.
PDFUnit's internal QR code parser ZXing supports many, but not all, formats. So PDFUnit provides an external interface to plug in customer specific QR code parsers. This interface is documented separately. You can requesting it by writing an email to info[at]pdfunit.com.
The next example uses an image that contains two QR codes. To let the test focus on only one QR code, an image region has to be defined. The reference point of such a region is the upper-left corner of the image. Note: the unit for image size values is points, the unit for page size values is millimeter.
@Test public void hasQRCodeInRegion_MobyDick() throws Exception { String filename = "documentUnderTest.pdf"; int leftX = 0; int upperY = 0; int width = 209; int height = 297; PageRegion pageRegion = new PageRegion(leftX, upperY, width, height); int imgLeftX = 120; // pixel int imgUpperY = 0; int imgWidth = 140; int imgHeight = 140; ImageRegion imageRegion = new ImageRegion(imgLeftX, imgUpperY, imgWidth, imgHeight); String expectedText = "Some years ago--never mind how long precisely"; AssertThat.document(filename) .restrictedTo(FIRST_PAGE) .restrictedTo(pageRegion) .hasImage() .withQRCodeInRegion(imageRegion) .containing(expectedText) ; }
In the next example, a QR code from a PDF is compared to a QR code image from a file:
@Test public void hasQRCodeMatchingFile_OnAnyPage() throws Exception { String filename = "documentUnderTest.pdf"; int leftX = 10; int upperY = 65; int width = 50; int height = 50; PageRegion pageRegion = new PageRegion(leftX, upperY, width, height); String expectedQrImage = "images/hello.qrgen.png"; AssertThat.document(filename) .restrictedTo(ANY_PAGE) .restrictedTo(pageRegion) .hasImage() .withQRCode() .matchingImage(expectedQrImage) ; }
Important: For the test to work, the type of the external image file (PNG or TIFF, for example) must match the type of the QR code image of the PDF document.