Skip to content

Commit 04f5c0a

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 04f5c0a

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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\FileMapper;
13+
use OCA\Libresign\Db\IdentifyMethod;
14+
use OCA\Libresign\Db\IdentifyMethodMapper;
15+
use OCA\Libresign\Db\SignRequest;
16+
use OCA\Libresign\Db\SignRequestMapper;
17+
use OCA\Libresign\Service\IdentifyMethod\IdentifyService;
18+
use OCA\Libresign\Service\SessionService;
19+
use OCA\Libresign\Tests\Unit\TestCase;
20+
use OCP\AppFramework\Utility\ITimeFactory;
21+
use OCP\EventDispatcher\IEventDispatcher;
22+
use OCP\Files\IRootFolder;
23+
use OCP\IAppConfig;
24+
use OCP\IL10N;
25+
use OCP\IURLGenerator;
26+
use OCP\IUserManager;
27+
use OCP\Security\IHasher;
28+
use PHPUnit\Framework\MockObject\MockObject;
29+
use Psr\Log\LoggerInterface;
30+
31+
final class IdentifyServiceTest extends TestCase {
32+
private IdentifyMethodMapper&MockObject $identifyMethodMapper;
33+
private SessionService&MockObject $sessionService;
34+
private ITimeFactory&MockObject $timeFactory;
35+
private IEventDispatcher&MockObject $eventDispatcher;
36+
private IRootFolder&MockObject $rootFolder;
37+
private IAppConfig&MockObject $appConfig;
38+
private SignRequestMapper&MockObject $signRequestMapper;
39+
private IL10N&MockObject $l10n;
40+
private FileMapper&MockObject $fileMapper;
41+
private IHasher&MockObject $hasher;
42+
private IUserManager&MockObject $userManager;
43+
private IURLGenerator&MockObject $urlGenerator;
44+
private LoggerInterface&MockObject $logger;
45+
private IdentifyService $service;
46+
47+
public function setUp(): void {
48+
parent::setUp();
49+
50+
$this->identifyMethodMapper = $this->createMock(IdentifyMethodMapper::class);
51+
$this->sessionService = $this->createMock(SessionService::class);
52+
$this->timeFactory = $this->createMock(ITimeFactory::class);
53+
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
54+
$this->rootFolder = $this->createMock(IRootFolder::class);
55+
$this->appConfig = $this->createMock(IAppConfig::class);
56+
$this->signRequestMapper = $this->createMock(SignRequestMapper::class);
57+
$this->l10n = $this->createMock(IL10N::class);
58+
$this->fileMapper = $this->createMock(FileMapper::class);
59+
$this->hasher = $this->createMock(IHasher::class);
60+
$this->userManager = $this->createMock(IUserManager::class);
61+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
62+
$this->logger = $this->createMock(LoggerInterface::class);
63+
64+
$this->service = new IdentifyService(
65+
$this->identifyMethodMapper,
66+
$this->sessionService,
67+
$this->timeFactory,
68+
$this->eventDispatcher,
69+
$this->rootFolder,
70+
$this->appConfig,
71+
$this->signRequestMapper,
72+
$this->l10n,
73+
$this->fileMapper,
74+
$this->hasher,
75+
$this->userManager,
76+
$this->urlGenerator,
77+
$this->logger,
78+
);
79+
}
80+
81+
public function testPropagateIdentifiedDateSkipsCurrentRequestAndUpdatesSiblings(): void {
82+
$identifyMethod = new IdentifyMethod();
83+
$identifyMethod->setSignRequestId(1);
84+
$identifyMethod->setIdentifierKey('email');
85+
$identifyMethod->setIdentifierValue('[email protected]');
86+
$identifyMethod->setIdentifiedAtDate('2024-01-01T00:00:00Z');
87+
88+
$parentEnvelopeId = 99;
89+
90+
$currentFile = new File();
91+
$currentFile->setId(10);
92+
$currentFile->setParentFileId($parentEnvelopeId);
93+
94+
$currentSignRequest = new SignRequest();
95+
$currentSignRequest->setId(1);
96+
$currentSignRequest->setFileId($currentFile->getId());
97+
98+
$siblingFile = new File();
99+
$siblingFile->setId(11);
100+
$siblingFile->setParentFileId($parentEnvelopeId);
101+
102+
$siblingSignRequest = new SignRequest();
103+
$siblingSignRequest->setId(2);
104+
$siblingSignRequest->setFileId($siblingFile->getId());
105+
106+
$this->signRequestMapper
107+
->expects($this->once())
108+
->method('getById')
109+
->with($identifyMethod->getSignRequestId())
110+
->willReturn($currentSignRequest);
111+
112+
$this->fileMapper
113+
->expects($this->once())
114+
->method('getById')
115+
->with($currentFile->getId())
116+
->willReturn($currentFile);
117+
118+
$this->signRequestMapper
119+
->expects($this->once())
120+
->method('getByEnvelopeChildrenAndIdentifyMethod')
121+
->with($parentEnvelopeId, $currentSignRequest->getId())
122+
->willReturn([$currentSignRequest, $siblingSignRequest]);
123+
124+
$siblingIdentifyMethod = new IdentifyMethod();
125+
$siblingIdentifyMethod->setSignRequestId($siblingSignRequest->getId());
126+
$siblingIdentifyMethod->setIdentifierKey($identifyMethod->getIdentifierKey());
127+
$siblingIdentifyMethod->setIdentifierValue($identifyMethod->getIdentifierValue());
128+
129+
$this->identifyMethodMapper
130+
->expects($this->exactly(2))
131+
->method('getIdentifyMethodsFromSignRequestId')
132+
->willReturnMap([
133+
[$identifyMethod->getSignRequestId(), []],
134+
[$siblingSignRequest->getId(), [$siblingIdentifyMethod]],
135+
]);
136+
137+
$this->identifyMethodMapper
138+
->expects($this->once())
139+
->method('insertOrUpdate')
140+
->with($identifyMethod);
141+
142+
$this->identifyMethodMapper
143+
->expects($this->once())
144+
->method('update')
145+
->with($this->callback(function (IdentifyMethod $updated) use ($siblingIdentifyMethod, $identifyMethod) {
146+
return $updated->getSignRequestId() === $siblingIdentifyMethod->getSignRequestId()
147+
&& $updated->getIdentifiedAtDate() == $identifyMethod->getIdentifiedAtDate();
148+
}));
149+
150+
$this->service->save($identifyMethod);
151+
}
152+
}

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)