Skip to content

Commit 6db83c3

Browse files
committed
test(PhpNativeHandlerTest): regressions for GRAPHIC_ONLY and SIGNAME centering
Add three regression tests: - testBuildXObjectGraphicOnlyReturnsEmptyStream: n2 stream must be empty for GRAPHIC_ONLY so no text leaks into graphic-only stamps. - testBuildAppearanceForElementSetsSignatureImageInGraphicOnlyMode: user image must be assigned to the full bbox (signatureImageFrame=null). - testBuildXObjectSignameAndDescriptionCentersNameInLeftHalf: signer name X position must be centred (39.60) not left-aligned (2.00). Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 9be5d04 commit 6db83c3

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

tests/php/Unit/Handler/SignEngine/PhpNativeHandlerTest.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,70 @@ public function testBuildXObjectSignameAndDescriptionIncludesNameAndDescriptionB
334334
$this->assertStringContainsString('102.00 ', $xObject->stream);
335335
}
336336

337+
/**
338+
* Regression: GRAPHIC_ONLY mode must not render any text in the n2 xObject layer.
339+
* Before the fix, the method fell through to the description block and wrote text
340+
* into the stamp.
341+
*/
342+
public function testBuildXObjectGraphicOnlyReturnsEmptyStream(): void {
343+
$handler = $this->getHandlerWithMode(SignerElementsService::RENDER_MODE_GRAPHIC_ONLY);
344+
$xObject = $this->callPrivateMethod(
345+
$handler, 'buildXObject', 100, 50, SignerElementsService::RENDER_MODE_GRAPHIC_ONLY,
346+
);
347+
348+
$this->assertSame('', $xObject->stream);
349+
$this->assertSame([], $xObject->resources);
350+
}
351+
352+
/**
353+
* Regression: GRAPHIC_ONLY mode must assign the user's drawn image to the full bbox
354+
* (signatureImageFrame = null). Before the fix only GRAPHIC_AND_DESCRIPTION set
355+
* signatureImagePath, leaving GRAPHIC_ONLY with no image (blank stamp).
356+
*/
357+
public function testBuildAppearanceForElementSetsSignatureImageInGraphicOnlyMode(): void {
358+
$imagePath = realpath(__DIR__ . '/../../../../../img/app-dark.png');
359+
$this->assertNotFalse($imagePath, 'Test image must exist');
360+
361+
$handler = $this->getHandlerWithMode(SignerElementsService::RENDER_MODE_GRAPHIC_ONLY);
362+
$this->signatureBackgroundService->method('isEnabled')->willReturn(false);
363+
364+
$appearance = $this->callPrivateMethod(
365+
$handler,
366+
'buildAppearanceForElement',
367+
10.0, 20.0, 110.0, 70.0, 800.0, 0, 100, 50,
368+
$imagePath,
369+
);
370+
371+
$this->assertInstanceOf(SignatureAppearanceDto::class, $appearance);
372+
// Image must fill the entire stamp bbox (no split)
373+
$this->assertSame($imagePath, $appearance->signatureImagePath);
374+
$this->assertNull($appearance->signatureImageFrame);
375+
}
376+
377+
/**
378+
* Regression: in SIGNAME_AND_DESCRIPTION the signer name must be horizontally
379+
* centred within the left half of the stamp, not pinned to leftPadding (left edge).
380+
*
381+
* Layout math for width=200, height=80, fontSize=20, name="Al":
382+
* leftHalfW = 100.0
383+
* lineWidth = strlen("Al") * (20 * 0.52) = 2 * 10.4 = 20.8
384+
* nameX = max(2.0, (100 - 20.8) / 2) = 39.6 → "39.60"
385+
* nameStartY = (80 + 24) / 2 - 20 = 32.0 → "32.00"
386+
* Old (broken) code always used leftPadding=2.0 → "2.00 32.00 Td"
387+
*/
388+
public function testBuildXObjectSignameAndDescriptionCentersNameInLeftHalf(): void {
389+
$handler = $this->getHandlerWithMode(SignerElementsService::RENDER_MODE_SIGNAME_AND_DESCRIPTION);
390+
$handler->setSignatureParams(['SignerCommonName' => 'Al']);
391+
$xObject = $this->callPrivateMethod(
392+
$handler, 'buildXObject', 200, 80, SignerElementsService::RENDER_MODE_SIGNAME_AND_DESCRIPTION,
393+
);
394+
395+
// Centred position must appear
396+
$this->assertStringContainsString('39.60 32.00 Td', $xObject->stream);
397+
// Old left-aligned position must NOT appear
398+
$this->assertStringNotContainsString('2.00 32.00 Td', $xObject->stream);
399+
}
400+
337401
public function testBuildXObjectSignameAndDescriptionWithEmptyNameOmitsNameBlock(): void {
338402
// When SignerCommonName is absent and certificate has no CN, no name block should appear
339403
$engine = $this->createMock(\OCA\Libresign\Handler\CertificateEngine\IEngineHandler::class);

0 commit comments

Comments
 (0)