Skip to content

Commit daaecc2

Browse files
committed
test: update unit tests and psalm baseline for refactor\n\nAdjust tests to new services and response shapes; refresh psalm baseline.
Signed-off-by: Vitor Mattos <[email protected]>
1 parent a6076c1 commit daaecc2

5 files changed

Lines changed: 288 additions & 302 deletions

File tree

tests/php/Unit/Service/FileServiceTest.php

Lines changed: 67 additions & 296 deletions
Original file line numberDiff line numberDiff line change
@@ -5,320 +5,91 @@
55
* SPDX-FileCopyrightText: 2024 LibreCode coop and contributors
66
* SPDX-License-Identifier: AGPL-3.0-or-later
77
*/
8-
9-
namespace OCA\Libresign\Service;
10-
11-
/**
12-
* Overwrite is_uploaded_file in the OCA\Libresign\Service namespace.
13-
*/
14-
function is_uploaded_file($filename) {
15-
return file_exists($filename);
16-
}
17-
188
namespace OCA\Libresign\Tests\Unit\Service;
199

20-
use bovigo\vfs\vfsDirectory;
21-
use bovigo\vfs\vfsStream;
22-
use InvalidArgumentException;
23-
use OCA\Libresign\AppInfo\Application;
24-
use OCA\Libresign\Db\FileElementMapper;
25-
use OCA\Libresign\Db\FileMapper;
26-
use OCA\Libresign\Db\IdDocsMapper;
27-
use OCA\Libresign\Db\SignRequestMapper;
28-
use OCA\Libresign\Handler\DocMdpHandler;
29-
use OCA\Libresign\Handler\SignEngine\Pkcs12Handler;
30-
use OCA\Libresign\Helper\FileUploadHelper;
31-
use OCA\Libresign\Helper\ValidateHelper;
32-
use OCA\Libresign\Service\AccountService;
33-
use OCA\Libresign\Service\EnvelopeService;
34-
use OCA\Libresign\Service\File\FileListService;
35-
use OCA\Libresign\Service\File\SignersLoader;
36-
use OCA\Libresign\Service\FileElementService;
10+
use OCA\Libresign\Exception\LibresignException;
3711
use OCA\Libresign\Service\FileService;
38-
use OCA\Libresign\Service\FolderService;
39-
use OCA\Libresign\Service\IdentifyMethodService;
40-
use OCA\Libresign\Service\PdfParserService;
41-
use OCA\Libresign\Tests\Fixtures\PdfGenerator;
42-
use OCP\Accounts\IAccountManager;
43-
use OCP\Files\IMimeTypeDetector;
44-
use OCP\Files\IRootFolder;
45-
use OCP\Http\Client\IClientService;
46-
use OCP\IAppConfig;
47-
use OCP\IDateTimeFormatter;
48-
use OCP\IL10N;
49-
use OCP\IURLGenerator;
50-
use OCP\IUserManager;
51-
use OCP\IUserSession;
52-
use OCP\L10N\IFactory as IL10NFactory;
53-
use PHPUnit\Framework\Attributes\DataProvider;
54-
use PHPUnit\Framework\Attributes\Group;
55-
use PHPUnit\Framework\MockObject\MockObject;
56-
use Psr\Log\LoggerInterface;
5712

58-
/**
59-
* @internal
60-
*/
61-
#[Group('DB')]
6213
final class FileServiceTest extends \OCA\Libresign\Tests\Unit\TestCase {
63-
protected FileMapper $fileMapper;
64-
protected SignRequestMapper $signRequestMapper;
65-
protected FileElementMapper $fileElementMapper;
66-
protected FileElementService $fileElementService;
67-
protected FolderService $folderService;
68-
protected ValidateHelper $validateHelper;
69-
protected PdfParserService $pdfParserService;
70-
protected IdDocsMapper $idDocsMapper;
71-
private AccountService&MockObject $accountService;
72-
private IdentifyMethodService $identifyMethodService;
73-
private IUserSession $userSession;
74-
private IUserManager&MockObject $userManager;
75-
private IAccountManager&MockObject $accountManager;
76-
protected IClientService $client;
77-
private IDateTimeFormatter $dateTimeFormatter;
78-
private IAppConfig $appConfig;
79-
private IURLGenerator $urlGenerator;
80-
protected IMimeTypeDetector $mimeTypeDetector;
81-
protected Pkcs12Handler $pkcs12Handler;
82-
protected DocMdpHandler $docMdpHandler;
83-
protected IRootFolder $root;
84-
protected LoggerInterface $logger;
85-
protected IL10N $l10n;
86-
protected EnvelopeService $envelopeService;
87-
protected vfsDirectory $tempFolder;
88-
protected SignersLoader $signersLoader;
89-
protected fileListService $fileListService;
90-
protected FileUploadHelper $uploadHelper;
91-
92-
public function setUp(): void {
93-
// Disable lazy objects to avoid PHP 8.4 dependency injection issues in tests
94-
\OC\AppFramework\Utility\SimpleContainer::$useLazyObjects = false;
95-
96-
$this->tempFolder = vfsStream::setup('uploaded');
97-
$appConfig = $this->getMockAppConfig();
98-
$appConfig->setValueInt(Application::APP_ID, 'length_of_page', 100);
99-
$appConfig->setValueBool(Application::APP_ID, 'identification_documents', false);
100-
}
101-
102-
private function getService(): FileService {
103-
$this->fileMapper = \OCP\Server::get(FileMapper::class);
104-
$this->signRequestMapper = \OCP\Server::get(SignRequestMapper::class);
105-
$this->fileElementMapper = \OCP\Server::get(FileElementMapper::class);
106-
$this->fileElementService = \OCP\Server::get(FileElementService::class);
107-
$this->folderService = \OCP\Server::get(FolderService::class);
108-
$this->validateHelper = \OCP\Server::get(ValidateHelper::class);
109-
$this->pdfParserService = \OCP\Server::get(PdfParserService::class);
110-
$this->idDocsMapper = \OCP\Server::get(IdDocsMapper::class);
111-
$this->accountService = $this->createMock(AccountService::class);
112-
$this->identifyMethodService = \OCP\Server::get(IdentifyMethodService::class);
113-
$this->userSession = \OCP\Server::get(IUserSession::class);
114-
$this->userManager = $this->createMock(IUserManager::class);
115-
$this->accountManager = $this->createMock(IAccountManager::class);
116-
$this->client = \OCP\Server::get(IClientService::class);
117-
$this->dateTimeFormatter = \OCP\Server::get(IDateTimeFormatter::class);
118-
$this->appConfig = $this->getMockAppConfigWithReset();
119-
$this->urlGenerator = \OCP\Server::get(IURLGenerator::class);
120-
$this->mimeTypeDetector = \OCP\Server::get(IMimeTypeDetector::class);
121-
$this->pkcs12Handler = \OCP\Server::get(Pkcs12Handler::class);
122-
$this->docMdpHandler = \OCP\Server::get(DocMdpHandler::class);
123-
$this->root = \OCP\Server::get(IRootFolder::class);
124-
$this->logger = \OCP\Server::get(LoggerInterface::class);
125-
$this->l10n = \OCP\Server::get(IL10NFactory::class)->get(Application::APP_ID);
126-
$this->envelopeService = \OCP\Server::get(EnvelopeService::class);
127-
$this->signersLoader = \OCP\Server::get(SignersLoader::class);
128-
$this->fileListService = \OCP\Server::get(FileListService::class);
129-
$this->uploadHelper = \OCP\Server::get(FileUploadHelper::class);
130-
131-
return new FileService(
132-
$this->fileMapper,
133-
$this->signRequestMapper,
134-
$this->fileElementMapper,
135-
$this->fileElementService,
136-
$this->folderService,
137-
$this->validateHelper,
138-
$this->pdfParserService,
139-
$this->idDocsMapper,
140-
$this->accountService,
141-
$this->identifyMethodService,
142-
$this->userSession,
143-
$this->userManager,
144-
$this->accountManager,
145-
$this->client,
146-
$this->dateTimeFormatter,
147-
$this->appConfig,
148-
$this->urlGenerator,
149-
$this->mimeTypeDetector,
150-
$this->pkcs12Handler,
151-
$this->docMdpHandler,
152-
$this->root,
153-
$this->logger,
154-
$this->l10n,
155-
$this->envelopeService,
156-
$this->signersLoader,
157-
$this->fileListService,
158-
$this->uploadHelper,
159-
);
160-
}
161-
162-
#[DataProvider('dataToArray')]
163-
public function testToArray(callable $arguments, array $expected): void {
164-
if (shell_exec('which pdfsig') === null) {
165-
$this->markTestSkipped();
166-
return;
167-
}
168-
$service = $this->getService();
169-
if (is_callable($arguments)) {
170-
$arguments = $arguments($this, $service);
171-
}
172-
$actual = $service->toArray();
173-
174-
// Remove 'purposes' field from comparison as it varies between OpenSSL versions
175-
$this->removePurposesField($expected);
176-
$this->removePurposesField($actual);
177-
178-
$this->removeDocMdpFields($expected);
179-
$this->removeDocMdpFields($actual);
180-
$this->mockUuid($expected, $actual);
181-
182-
$this->assertEquals($expected, $actual);
183-
}
184-
185-
/**
186-
* Was necessary to create this because the method that handle the uuid
187-
* is very internal of subclasses and wasn't easy to mock this.
188-
*/
189-
private function mockUuid(array $expected, array &$actual): void {
190-
if (isset($actual['signers'])) {
191-
foreach ($actual['signers'] as $key => &$signer) {
192-
if (isset($signer['uid']) && isset($expected['signers'][$key])) {
193-
$signer['uid'] = $expected['signers'][$key]['uid'];
194-
}
195-
}
196-
}
197-
}
198-
199-
private function removePurposesField(array &$data): void {
200-
if (isset($data['signers'])) {
201-
foreach ($data['signers'] as &$signer) {
202-
unset($signer['purposes']);
203-
if (isset($signer['chain'])) {
204-
foreach ($signer['chain'] as &$chainItem) {
205-
unset($chainItem['purposes']);
206-
}
207-
}
208-
}
209-
}
210-
}
211-
212-
private function removeDocMdpFields(array &$data): void {
213-
if (isset($data['signers'])) {
214-
foreach ($data['signers'] as &$signer) {
215-
unset($signer['docmdp']);
216-
unset($signer['modifications']);
217-
unset($signer['modification_validation']);
218-
}
219-
}
220-
}
221-
222-
public static function dataToArray(): array {
223-
return [
224-
'empty' => [fn () => null, []],
225-
'No file provided' => [
226-
function (self $self, FileService $service): void {
227-
$self->expectException(InvalidArgumentException::class);
228-
$self->expectExceptionMessage('No file provided');
229-
$service
230-
->setFileFromRequest(null);
231-
},
232-
[]
233-
],
234-
'error when upload' => [
235-
function (self $self, FileService $service): void {
236-
$self->expectException(InvalidArgumentException::class);
237-
$self->expectExceptionMessage('Invalid file provided');
238-
$service
239-
->setFileFromRequest(['tmp_name' => tempnam(sys_get_temp_dir(), 'empty_file'), 'error' => 1]);
240-
},
241-
[]
242-
],
243-
'blacklisted file' => [
244-
function (self $self, FileService $service): void {
245-
$path = 'vfs://uploaded/.htaccess';
246-
file_put_contents($path, '');
247-
$self->expectException(InvalidArgumentException::class);
248-
$self->expectExceptionMessage('Invalid file provided');
249-
$service
250-
->setFileFromRequest(['tmp_name' => $path, 'error' => 0]);
251-
},
252-
[]
253-
],
254-
'File is too big' => [
255-
function (self $self, FileService $service): void {
256-
$path = 'vfs://uploaded/file.pdf';
257-
file_put_contents($path, '');
258-
$self->expectException(InvalidArgumentException::class);
259-
$self->expectExceptionMessage('File is too big');
260-
$service
261-
->setFileFromRequest(['tmp_name' => $path, 'error' => 0, 'size' => \OCP\Util::uploadLimit() + 1]);
262-
},
263-
[]
264-
],
265-
'Invalid file provided' => [
266-
function (self $self, FileService $service): void {
267-
$path = 'vfs://uploaded/file.php';
268-
file_put_contents($path, '');
269-
$self->expectException(InvalidArgumentException::class);
270-
$self->expectExceptionMessage('Invalid file provided');
271-
$service
272-
->setFileFromRequest([
273-
'tmp_name' => $path,
274-
'error' => 0,
275-
'size' => 0,
276-
]);
277-
},
278-
[]
279-
],
14+
private function createFileService(array $overrides = []): FileService {
15+
$mocks = [
16+
\OCA\Libresign\Db\FileMapper::class,
17+
\OCA\Libresign\Db\SignRequestMapper::class,
18+
\OCA\Libresign\Db\FileElementMapper::class,
19+
\OCA\Libresign\Service\FileElementService::class,
20+
\OCA\Libresign\Service\FolderService::class,
21+
\OCA\Libresign\Helper\ValidateHelper::class,
22+
\OCA\Libresign\Service\PdfParserService::class,
23+
\OCA\Libresign\Db\IdDocsMapper::class,
24+
\OCA\Libresign\Service\AccountService::class,
25+
\OCA\Libresign\Service\IdentifyMethodService::class,
26+
\OCP\IUserSession::class,
27+
\OCP\IUserManager::class,
28+
\OCP\Accounts\IAccountManager::class,
29+
\OCP\Http\Client\IClientService::class,
30+
\OCP\IDateTimeFormatter::class,
31+
\OCP\IAppConfig::class,
32+
\OCP\IURLGenerator::class,
33+
\OCP\Files\IMimeTypeDetector::class,
34+
\OCA\Libresign\Handler\SignEngine\Pkcs12Handler::class,
35+
\OCA\Libresign\Handler\DocMdpHandler::class,
36+
\OCA\Libresign\Service\File\PdfValidator::class,
37+
\OCP\Files\IRootFolder::class,
38+
\Psr\Log\LoggerInterface::class,
39+
\OCP\IL10N::class,
40+
\OCA\Libresign\Service\EnvelopeService::class,
41+
\OCA\Libresign\Service\File\SignersLoader::class,
42+
\OCA\Libresign\Service\File\FileListService::class,
43+
\OCA\Libresign\Service\File\FileDataAssembler::class,
44+
\OCA\Libresign\Helper\FileUploadHelper::class,
45+
\OCA\Libresign\Service\File\EnvelopeAssembler::class,
46+
\OCA\Libresign\Service\File\EnvelopeProgressService::class,
47+
\OCA\Libresign\Service\File\CertificateChainService::class,
28048
];
281-
}
282-
283-
public function testValidateFileContentRejectsDocMdpLevel1(): void {
284-
$pdfContent = PdfGenerator::createCompletePdfStructure(1);
285-
$service = $this->getService();
28649

287-
$this->expectException(\OCA\Libresign\Exception\LibresignException::class);
50+
$args = array_map(function ($c) use ($overrides) {
51+
return $overrides[$c] ?? $this->createMock($c);
52+
}, $mocks);
28853

289-
$service->validateFileContent($pdfContent, 'pdf');
54+
return new FileService(...$args);
29055
}
29156

292-
public function testValidateFileContentAllowsDocMdpLevel2(): void {
293-
$this->expectNotToPerformAssertions();
294-
$pdfContent = PdfGenerator::createCompletePdfStructure(2);
295-
$service = $this->getService();
57+
public function testValidateFileContentSkipsNonPdfFiles(): void {
58+
$docMdpHandler = $this->createMock(\OCA\Libresign\Handler\DocMdpHandler::class);
59+
$service = $this->createFileService([
60+
\OCA\Libresign\Handler\DocMdpHandler::class => $docMdpHandler,
61+
]);
29662

297-
$service->validateFileContent($pdfContent, 'pdf');
63+
$this->expectNotToPerformAssertions();
64+
$service->validateFileContent('any content', 'txt');
65+
$service->validateFileContent('{"json": true}', 'json');
29866
}
29967

300-
public function testValidateFileContentAllowsDocMdpLevel3(): void {
301-
$this->expectNotToPerformAssertions();
302-
$pdfContent = PdfGenerator::createCompletePdfStructure(3);
303-
$service = $this->getService();
68+
public function testSetFileByTypeThrowsOnInvalid(): void {
69+
$fileMapper = $this->createMock(\OCA\Libresign\Db\FileMapper::class);
70+
$fileMapper->method('getByFileId')->willThrowException(new \Exception('not found'));
30471

305-
$service->validateFileContent($pdfContent, 'pdf');
72+
$service = $this->createFileService([
73+
\OCA\Libresign\Db\FileMapper::class => $fileMapper,
74+
]);
75+
76+
$this->expectException(LibresignException::class);
77+
$service->setFileByType('FileId', 123);
30678
}
30779

308-
public function testValidateFileContentAllowsUnsignedPdf(): void {
309-
$this->expectNotToPerformAssertions();
310-
$pdfPath = __DIR__ . '/../../fixtures/pdfs/small_valid.pdf';
311-
$pdfContent = file_get_contents($pdfPath);
312-
$service = $this->getService();
80+
public function testSetFileByTypeSetsFile(): void {
81+
$file = new \OCA\Libresign\Db\File();
82+
$file->setStatus(1);
31383

314-
$service->validateFileContent($pdfContent, 'pdf');
315-
}
84+
$fileMapper = $this->createMock(\OCA\Libresign\Db\FileMapper::class);
85+
$fileMapper->method('getByFileId')->willReturn($file);
31686

317-
public function testValidateFileContentSkipsNonPdfFiles(): void {
318-
$this->expectNotToPerformAssertions();
319-
$service = $this->getService();
87+
$service = $this->createFileService([
88+
\OCA\Libresign\Db\FileMapper::class => $fileMapper,
89+
]);
32090

321-
$service->validateFileContent('any content', 'txt');
322-
$service->validateFileContent('{"json": true}', 'json');
91+
$returned = $service->setFileByType('FileId', 123);
92+
$this->assertInstanceOf(FileService::class, $returned);
93+
$this->assertSame(1, $service->getStatus());
32394
}
32495
}

0 commit comments

Comments
 (0)