Skip to content

Commit db3151a

Browse files
committed
test: add unit tests for file-related services\n\nIntroduce initial unit tests for newly extracted File services and format helpers.
Signed-off-by: Vitor Mattos <[email protected]>
1 parent daaecc2 commit db3151a

13 files changed

Lines changed: 2288 additions & 0 deletions
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\Libresign\Tests\Unit\Service\File;
11+
12+
use OCA\Libresign\AppInfo\Application;
13+
use OCA\Libresign\Exception\LibresignException;
14+
use OCA\Libresign\Handler\SignEngine\Pkcs12Handler;
15+
use OCA\Libresign\Service\File\AccountSettingsProvider;
16+
use OCP\Accounts\IAccount;
17+
use OCP\Accounts\IAccountManager;
18+
use OCP\Accounts\IAccountProperty;
19+
use OCP\IAppConfig;
20+
use OCP\IGroupManager;
21+
use OCP\IUser;
22+
use PHPUnit\Framework\MockObject\MockObject;
23+
24+
final class AccountSettingsProviderTest extends \OCA\Libresign\Tests\Unit\TestCase {
25+
private IAccountManager|MockObject $accountManager;
26+
private IAppConfig|MockObject $appConfig;
27+
private IGroupManager|MockObject $groupManager;
28+
private Pkcs12Handler|MockObject $pkcs12Handler;
29+
30+
public function setUp(): void {
31+
parent::setUp();
32+
$this->accountManager = $this->createMock(IAccountManager::class);
33+
$this->appConfig = $this->createMock(IAppConfig::class);
34+
$this->groupManager = $this->createMock(IGroupManager::class);
35+
$this->pkcs12Handler = $this->createMock(Pkcs12Handler::class);
36+
}
37+
38+
private function getService(): AccountSettingsProvider {
39+
return new AccountSettingsProvider(
40+
$this->accountManager,
41+
$this->appConfig,
42+
$this->groupManager,
43+
$this->pkcs12Handler,
44+
);
45+
}
46+
47+
public function testGetPhoneNumber(): void {
48+
$user = $this->createMock(IUser::class);
49+
50+
$accountProperty = $this->createMock(IAccountProperty::class);
51+
$accountProperty->method('getValue')->willReturn('123456789');
52+
53+
$account = $this->createMock(IAccount::class);
54+
$account->method('getProperty')->with(IAccountManager::PROPERTY_PHONE)->willReturn($accountProperty);
55+
56+
$this->accountManager->method('getAccount')->with($user)->willReturn($account);
57+
58+
$service = $this->getService();
59+
$result = $service->getPhoneNumber($user);
60+
61+
$this->assertEquals('123456789', $result);
62+
}
63+
64+
public function testGetSettingsWithUserCanSignAndHasSignature(): void {
65+
$user = $this->createMock(IUser::class);
66+
$user->method('getUID')->willReturn('user123');
67+
68+
$this->appConfig->method('getValueArray')
69+
->with(Application::APP_ID, 'groups_request_sign', ['admin'])
70+
->willReturn(['admin', 'users']);
71+
72+
$this->groupManager->method('getUserGroupIds')
73+
->with($user)
74+
->willReturn(['users', 'editors']);
75+
76+
$this->pkcs12Handler->method('getPfxOfCurrentSigner')
77+
->with('user123')
78+
->willReturn('signature_content');
79+
80+
$service = $this->getService();
81+
$result = $service->getSettings($user);
82+
83+
$this->assertTrue($result['canRequestSign']);
84+
$this->assertTrue($result['hasSignatureFile']);
85+
}
86+
87+
public function testGetSettingsWithUserCannotSign(): void {
88+
$user = $this->createMock(IUser::class);
89+
$user->method('getUID')->willReturn('user123');
90+
91+
$this->appConfig->method('getValueArray')
92+
->with(Application::APP_ID, 'groups_request_sign', ['admin'])
93+
->willReturn(['admin']);
94+
95+
$this->groupManager->method('getUserGroupIds')
96+
->with($user)
97+
->willReturn(['users', 'editors']);
98+
99+
$this->pkcs12Handler->method('getPfxOfCurrentSigner')
100+
->with('user123')
101+
->willReturn('signature_content');
102+
103+
$service = $this->getService();
104+
$result = $service->getSettings($user);
105+
106+
$this->assertFalse($result['canRequestSign']);
107+
$this->assertTrue($result['hasSignatureFile']);
108+
}
109+
110+
public function testGetSettingsWithUserNoSignatureFile(): void {
111+
$user = $this->createMock(IUser::class);
112+
$user->method('getUID')->willReturn('user123');
113+
114+
$this->appConfig->method('getValueArray')
115+
->with(Application::APP_ID, 'groups_request_sign', ['admin'])
116+
->willReturn(['users']);
117+
118+
$this->groupManager->method('getUserGroupIds')
119+
->with($user)
120+
->willReturn(['users']);
121+
122+
$this->pkcs12Handler->method('getPfxOfCurrentSigner')
123+
->with('user123')
124+
->willThrowException(new LibresignException('No signature file'));
125+
126+
$service = $this->getService();
127+
$result = $service->getSettings($user);
128+
129+
$this->assertTrue($result['canRequestSign']);
130+
$this->assertFalse($result['hasSignatureFile']);
131+
}
132+
133+
public function testGetSettingsWithNullUser(): void {
134+
$service = $this->getService();
135+
$result = $service->getSettings(null);
136+
137+
$this->assertFalse($result['canRequestSign']);
138+
$this->assertFalse($result['hasSignatureFile']);
139+
}
140+
141+
public function testGetSettingsWithEmptyAuthorizedGroups(): void {
142+
$user = $this->createMock(IUser::class);
143+
144+
$this->appConfig->method('getValueArray')
145+
->with(Application::APP_ID, 'groups_request_sign', ['admin'])
146+
->willReturn([]);
147+
148+
$service = $this->getService();
149+
$result = $service->getSettings($user);
150+
151+
$this->assertFalse($result['canRequestSign']);
152+
}
153+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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\File;
10+
11+
use OCA\Libresign\Db\File;
12+
use OCA\Libresign\Handler\SignEngine\Pkcs12Handler;
13+
use OCA\Libresign\Service\File\CertificateChainService;
14+
use OCA\Libresign\Service\File\FileResponseOptions;
15+
use OCA\Libresign\Tests\Unit\TestCase;
16+
use Psr\Log\LoggerInterface;
17+
18+
final class CertificateChainServiceTest extends TestCase {
19+
public function testGetCertificateChainReturnsAndSetsFlag(): void {
20+
$content = 'abc content for hash';
21+
22+
$stream = fopen('php://memory', 'r+');
23+
fwrite($stream, $content);
24+
rewind($stream);
25+
26+
$fileNode = new class($stream) {
27+
private $s;
28+
public function __construct($s) {
29+
$this->s = $s;
30+
}
31+
public function fopen($mode) {
32+
return $this->s;
33+
}
34+
};
35+
36+
$libreSignFile = new File();
37+
$libreSignFile->setSignedNodeId(1);
38+
$libreSignFile->setSignedHash(hash('sha256', $content));
39+
40+
$pkcs12 = $this->createMock(Pkcs12Handler::class);
41+
$pkcs12->expects($this->once())->method('setIsLibreSignFile');
42+
$pkcs12->method('getCertificateChain')->willReturn(['chain' => []]);
43+
44+
$logger = $this->createMock(LoggerInterface::class);
45+
46+
$service = new CertificateChainService($pkcs12, $logger);
47+
48+
$options = new FileResponseOptions();
49+
$options->validateFile(true);
50+
51+
$result = $service->getCertificateChain($fileNode, $libreSignFile, $options);
52+
53+
$this->assertIsArray($result);
54+
$this->assertArrayHasKey('chain', $result);
55+
}
56+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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\File;
10+
11+
use OCA\Libresign\Db\File as DbFile;
12+
use OCA\Libresign\Db\SignRequest as DbSignRequest;
13+
use OCA\Libresign\Service\File\EnvelopeAssembler;
14+
use OCA\Libresign\Service\File\FileResponseOptions;
15+
use OCA\Libresign\Service\IdentifyMethodService;
16+
use OCP\Files\IRootFolder;
17+
use Psr\Log\NullLogger;
18+
19+
final class EnvelopeAssemblerTest extends \OCA\Libresign\Tests\Unit\TestCase {
20+
public function testBuildsChildDataWithoutCertificateChain(): void {
21+
$signRequest = new DbSignRequest();
22+
$signRequest->setId(42);
23+
$signRequest->setSigned(null);
24+
$signRequest->setDisplayName('Alice');
25+
$signRequest->setStatus(1);
26+
27+
$signRequestMapper = $this->createMock(\OCA\Libresign\Db\SignRequestMapper::class);
28+
$signRequestMapper->method('getByFileId')->willReturn([$signRequest]);
29+
30+
$identify = $this->createMock(IdentifyMethodService::class);
31+
$identify->method('setIsRequest')->willReturnSelf();
32+
$identify->method('getIdentifyMethodsFromSignRequestId')->willReturn([]);
33+
34+
$fileMapper = $this->createMock(\OCA\Libresign\Db\FileMapper::class);
35+
$fileMapper->method('getTextOfStatus')->willReturn('status-text');
36+
37+
$root = $this->createMock(IRootFolder::class);
38+
39+
$signersLoader = $this->createMock(\OCA\Libresign\Service\File\SignersLoader::class);
40+
$signersLoader->expects($this->never())->method('loadSignersFromCertData');
41+
42+
$assembler = new EnvelopeAssembler(
43+
$signRequestMapper,
44+
$identify,
45+
$fileMapper,
46+
$root,
47+
$signersLoader,
48+
null,
49+
$this->createMock(\OCA\Libresign\Handler\SignEngine\Pkcs12Handler::class),
50+
new NullLogger()
51+
);
52+
53+
$childFile = new DbFile();
54+
$childFile->setId(7);
55+
$childFile->setUuid('uuid-7');
56+
$childFile->setName('child.pdf');
57+
$childFile->setStatus(2);
58+
$childFile->setNodeId(123);
59+
$childFile->setMetadata(['p' => 1]);
60+
$childFile->setSignedNodeId(null);
61+
$childFile->setUserId('user1');
62+
63+
$options = new FileResponseOptions();
64+
$result = $assembler->buildEnvelopeChildData($childFile, $options);
65+
66+
$this->assertIsObject($result);
67+
$this->assertEquals(7, $result->id);
68+
$this->assertEquals('child.pdf', $result->name);
69+
$this->assertIsArray($result->signers);
70+
$this->assertCount(1, $result->signers);
71+
$this->assertEquals(42, $result->signers[0]->signRequestId);
72+
}
73+
}

0 commit comments

Comments
 (0)