Skip to content

Commit 83ed341

Browse files
committed
test: cover envelope child flows
Add unit coverage for envelope child signing selection and identify propagation when identify data is applied to sibling requests. Signed-off-by: Vitor Mattos <[email protected]>
1 parent 1795d93 commit 83ed341

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
6+
* SPDX-License-Identifier: AGPL-3.0-or-later
7+
*/
8+
9+
namespace OCA\Libresign\Tests\Unit\Service\IdentifyMethod;
10+
11+
use OCA\Libresign\Db\File;
12+
use OCA\Libresign\Db\IdentifyMethod;
13+
use OCA\Libresign\Db\IdentifyMethodMapper;
14+
use OCA\Libresign\Db\SignRequest;
15+
use OCA\Libresign\Db\SignRequestMapper;
16+
use OCA\Libresign\Service\IdentifyMethod\IdentifyService;
17+
use OCA\Libresign\Service\SessionService;
18+
use OCA\Libresign\Tests\Unit\TestCase;
19+
use OCP\AppFramework\Utility\ITimeFactory;
20+
use OCP\EventDispatcher\IEventDispatcher;
21+
use OCP\Files\IRootFolder;
22+
use OCP\IAppConfig;
23+
use OCP\IL10N;
24+
use OCP\IURLGenerator;
25+
use OCP\IUserManager;
26+
use OCP\Security\IHasher;
27+
use Psr\Log\LoggerInterface;
28+
29+
final class IdentifyServiceTest extends TestCase {
30+
private IdentifyMethodMapper $identifyMethodMapper;
31+
private SessionService $sessionService;
32+
private ITimeFactory $timeFactory;
33+
private IEventDispatcher $eventDispatcher;
34+
private IRootFolder $rootFolder;
35+
private IAppConfig $appConfig;
36+
private SignRequestMapper $signRequestMapper;
37+
private IL10N $l10n;
38+
private FileMapperStub $fileMapper;
39+
private IHasher $hasher;
40+
private IUserManager $userManager;
41+
private IURLGenerator $urlGenerator;
42+
private LoggerInterface $logger;
43+
private IdentifyService $service;
44+
45+
public function setUp(): void {
46+
parent::setUp();
47+
48+
$this->identifyMethodMapper = $this->createMock(IdentifyMethodMapper::class);
49+
$this->sessionService = $this->createMock(SessionService::class);
50+
$this->timeFactory = $this->createMock(ITimeFactory::class);
51+
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
52+
$this->rootFolder = $this->createMock(IRootFolder::class);
53+
$this->appConfig = $this->createMock(IAppConfig::class);
54+
$this->signRequestMapper = $this->createMock(SignRequestMapper::class);
55+
$this->l10n = $this->createMock(IL10N::class);
56+
$this->fileMapper = new FileMapperStub();
57+
$this->hasher = $this->createMock(IHasher::class);
58+
$this->userManager = $this->createMock(IUserManager::class);
59+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
60+
$this->logger = $this->createMock(LoggerInterface::class);
61+
62+
$this->service = new IdentifyService(
63+
$this->identifyMethodMapper,
64+
$this->sessionService,
65+
$this->timeFactory,
66+
$this->eventDispatcher,
67+
$this->rootFolder,
68+
$this->appConfig,
69+
$this->signRequestMapper,
70+
$this->l10n,
71+
$this->fileMapper,
72+
$this->hasher,
73+
$this->userManager,
74+
$this->urlGenerator,
75+
$this->logger,
76+
);
77+
}
78+
79+
public function testPropagateIdentifiedDateSkipsCurrentRequestAndUpdatesSiblings(): void {
80+
$identifyMethod = new IdentifyMethod();
81+
$identifyMethod->setSignRequestId(1);
82+
$identifyMethod->setIdentifierKey('email');
83+
$identifyMethod->setIdentifierValue('[email protected]');
84+
$identifyMethod->setIdentifiedAtDate('2024-01-01T00:00:00Z');
85+
86+
$parentEnvelopeId = 99;
87+
88+
$currentFile = new File();
89+
$currentFile->setId(10);
90+
$currentFile->setParentFileId($parentEnvelopeId);
91+
92+
$currentSignRequest = new SignRequest();
93+
$currentSignRequest->setId(1);
94+
$currentSignRequest->setFileId($currentFile->getId());
95+
96+
$siblingFile = new File();
97+
siblingFile->setId(11);
98+
siblingFile->setParentFileId($parentEnvelopeId);
99+
100+
$siblingSignRequest = new SignRequest();
101+
$siblingSignRequest->setId(2);
102+
$siblingSignRequest->setFileId($siblingFile->getId());
103+
104+
$this->signRequestMapper
105+
->method('getById')
106+
->with($identifyMethod->getSignRequestId())
107+
->willReturn($currentSignRequest);
108+
109+
$this->fileMapper->setFile($currentFile);
110+
111+
$this->signRequestMapper
112+
->method('getByEnvelopeChildrenAndIdentifyMethod')
113+
->with($parentEnvelopeId, $currentSignRequest->getId())
114+
->willReturn([$currentSignRequest, $siblingSignRequest]);
115+
116+
$siblingIdentifyMethod = new IdentifyMethod();
117+
$siblingIdentifyMethod->setSignRequestId($siblingSignRequest->getId());
118+
$siblingIdentifyMethod->setIdentifierKey($identifyMethod->getIdentifierKey());
119+
$siblingIdentifyMethod->setIdentifierValue($identifyMethod->getIdentifierValue());
120+
121+
$this->identifyMethodMapper
122+
->expects($this->exactly(2))
123+
->method('getIdentifyMethodsFromSignRequestId')
124+
->willReturnMap([
125+
[$identifyMethod->getSignRequestId(), []],
126+
[$siblingSignRequest->getId(), [$siblingIdentifyMethod]],
127+
]);
128+
129+
$this->identifyMethodMapper
130+
->expects($this->once())
131+
->method('insertOrUpdate')
132+
->with($identifyMethod);
133+
134+
$this->identifyMethodMapper
135+
->expects($this->once())
136+
->method('update')
137+
->with($this->callback(function (IdentifyMethod $updated) use ($siblingIdentifyMethod, $identifyMethod) {
138+
return $updated->getSignRequestId() === $siblingIdentifyMethod->getSignRequestId()
139+
&& $updated->getIdentifiedAtDate() == $identifyMethod->getIdentifiedAtDate();
140+
}));
141+
142+
$this->service->save($identifyMethod);
143+
}
144+
}
145+
146+
/**
147+
* Lightweight mapper stub to inject predefined files without hitting the database.
148+
*/
149+
final class FileMapperStub extends \OCA\Libresign\Db\FileMapper {
150+
private ?File $file = null;
151+
152+
public function __construct() {
153+
parent::__construct(\OCP\Server::get(\OCP\IDBConnection::class), \OCP\Server::get(IL10N::class));
154+
}
155+
156+
public function setFile(File $file): void {
157+
$this->file = $file;
158+
}
159+
160+
public function getById(int $id): File {
161+
if ($this->file && $this->file->getId() === $id) {
162+
return $this->file;
163+
}
164+
165+
return parent::getById($id);
166+
}
167+
}

tests/php/Unit/Service/SignFileServiceTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,52 @@ public static function providerGetOrGeneratePfxContent(): array {
625625
];
626626
}
627627

628+
public function testGetSignRequestsToSignWhenFileHasParentEnvelope(): void {
629+
$service = $this->getService();
630+
631+
$envelopeId = 99;
632+
$childFile = new File();
633+
$childFile->setId(10);
634+
$childFile->setParentFileId($envelopeId);
635+
636+
$siblingFile = new File();
637+
$siblingFile->setId(11);
638+
$siblingFile->setParentFileId($envelopeId);
639+
640+
$signRequest = new SignRequest();
641+
$signRequest->setId(200);
642+
$signRequest->setFileId($childFile->getId());
643+
644+
$siblingSignRequest = new SignRequest();
645+
$siblingSignRequest->setId(201);
646+
$siblingSignRequest->setFileId($siblingFile->getId());
647+
648+
$this->fileMapper
649+
->expects($this->once())
650+
->method('getChildrenFiles')
651+
->with($envelopeId)
652+
->willReturn([$childFile, $siblingFile]);
653+
654+
$this->signRequestMapper
655+
->expects($this->once())
656+
->method('getByEnvelopeChildrenAndIdentifyMethod')
657+
->with($envelopeId, $signRequest->getId())
658+
->willReturn([$signRequest, $siblingSignRequest]);
659+
660+
$result = self::invokePrivate(
661+
$service
662+
->setLibreSignFile($childFile)
663+
->setSignRequest($signRequest),
664+
'getSignRequestsToSign'
665+
);
666+
667+
$this->assertCount(2, $result);
668+
$this->assertSame($childFile, $result[0]['file']);
669+
$this->assertSame($signRequest, $result[0]['signRequest']);
670+
$this->assertSame($siblingFile, $result[1]['file']);
671+
$this->assertSame($siblingSignRequest, $result[1]['signRequest']);
672+
}
673+
628674
#[DataProvider('providerStoreUserMetadata')]
629675
public function testStoreUserMetadata(bool $collectMetadata, ?array $previous, array $new, ?array $expected): void {
630676
$signRequest = new \OCA\Libresign\Db\SignRequest();

0 commit comments

Comments
 (0)