Skip to content

Commit f877bb3

Browse files
chore: cover with unit tests
Signed-off-by: Vitor Mattos <vitor@php.rio>
1 parent 9bfe787 commit f877bb3

File tree

5 files changed

+198
-9
lines changed

5 files changed

+198
-9
lines changed

lib/Controller/AdminController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use OCP\IL10N;
3333
use OCP\IRequest;
3434
use OCP\ISession;
35+
use UnexpectedValueException;
3536

3637
/**
3738
* @psalm-import-type LibresignEngineHandler from ResponseDefinitions
@@ -565,7 +566,7 @@ public function saveCertificatePolicy(): DataResponse {
565566
}
566567
try {
567568
$cps = $this->certificatePolicyService->updateFile($pdf['tmp_name']);
568-
} catch (\Exception $e) {
569+
} catch (UnexpectedValueException $e) {
569570
return new DataResponse(
570571
[
571572
'message' => $e->getMessage(),

lib/Controller/CertificatePolicyController.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCP\AppFramework\Http\Attribute\PublicPage;
1919
use OCP\AppFramework\Http\DataResponse;
2020
use OCP\AppFramework\Http\FileDisplayResponse;
21+
use OCP\Files\NotFoundException;
2122
use OCP\IRequest;
2223

2324
class CertificatePolicyController extends Controller {
@@ -40,11 +41,15 @@ public function __construct(
4041
#[NoCSRFRequired]
4142
#[AnonRateLimit(limit: 10, period: 60)]
4243
#[FrontpageRoute(verb: 'GET', url: '/certificate-policy.pdf')]
43-
public function getCertificatePolicy(): FileDisplayResponse {
44-
$file = $this->certificatePolicyService->getFile();
45-
return new FileDisplayResponse($file, Http::STATUS_OK, [
46-
'Content-Disposition' => 'inline; filename="certificate-policy.pdf"',
47-
'Content-Type' => 'application/pdf',
48-
]);
44+
public function getCertificatePolicy(): FileDisplayResponse|DataResponse {
45+
try {
46+
$file = $this->certificatePolicyService->getFile();
47+
return new FileDisplayResponse($file, Http::STATUS_OK, [
48+
'Content-Disposition' => 'inline; filename="certificate-policy.pdf"',
49+
'Content-Type' => 'application/pdf',
50+
]);
51+
} catch (NotFoundException $e) {
52+
return new DataResponse([], Http::STATUS_NOT_FOUND);
53+
}
4954
}
5055
}

lib/Service/CertificatePolicyService.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\IAppConfig;
1717
use OCP\IL10N;
1818
use OCP\IURLGenerator;
19+
use UnexpectedValueException;
1920

2021
class CertificatePolicyService {
2122
public function __construct(
@@ -28,8 +29,8 @@ public function __construct(
2829

2930
public function updateFile(string $tmpFile): string {
3031
$detectedMimeType = mime_content_type($tmpFile);
31-
if (!in_array($detectedMimeType, ['application/pdf'], true)) {
32-
throw new \Exception('Unsupported image type: ' . $detectedMimeType);
32+
if ($detectedMimeType !== 'application/pdf') {
33+
throw new UnexpectedValueException('Unsupported image type: ' . $detectedMimeType);
3334
}
3435

3536
$blob = file_get_contents($tmpFile);
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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;
10+
11+
use bovigo\vfs\vfsStream;
12+
use OCA\Libresign\AppInfo\Application;
13+
use OCA\Libresign\Exception\LibresignException;
14+
use OCA\Libresign\Service\CertificatePolicyService;
15+
use OCP\Files\IAppData;
16+
use OCP\Files\NotFoundException;
17+
use OCP\Files\SimpleFS\ISimpleFile;
18+
use OCP\Files\SimpleFS\ISimpleFolder;
19+
use OCP\IAppConfig;
20+
use OCP\IL10N;
21+
use OCP\IURLGenerator;
22+
use OCP\L10N\IFactory as IL10NFactory;
23+
use PHPUnit\Framework\Attributes\DataProvider;
24+
use PHPUnit\Framework\MockObject\MockObject;
25+
26+
final class CertificatePolicyServiceTest extends \OCA\Libresign\Tests\Unit\TestCase {
27+
28+
private IAppData&MockObject $appData;
29+
private IURLGenerator&MockObject $urlGenerator;
30+
private IAppConfig $appConfig;
31+
private IL10N $l10n;
32+
33+
public function setUp(): void {
34+
$this->appData = $this->createMock(IAppData::class);
35+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
36+
$this->appConfig = $this->getMockAppConfig();
37+
$this->l10n = \OCP\Server::get(IL10NFactory::class)->get(Application::APP_ID);
38+
}
39+
40+
private function getService(): CertificatePolicyService {
41+
return new CertificatePolicyService(
42+
$this->appData,
43+
$this->urlGenerator,
44+
$this->appConfig,
45+
$this->l10n
46+
);
47+
}
48+
49+
#[DataProvider('providerUpdateOidWithValidValue')]
50+
public function testUpdateOidWithValidValue(string $oid): void {
51+
$result = $this->getService()->updateOid($oid);
52+
$this->assertEquals($oid, $result);
53+
}
54+
55+
public static function providerUpdateOidWithValidValue(): array {
56+
return [
57+
['1.2.3.4'],
58+
['2.5.4.10'],
59+
['0.9.2342.19200300.100.1.1'],
60+
[''],
61+
];
62+
}
63+
64+
#[DataProvider('providerUpdateOidWithInvalidValue')]
65+
public function testUpdateOidWithInvalidValue(string $oid): void {
66+
$this->expectException(LibresignException::class);
67+
$this->getService()->updateOid($oid);
68+
}
69+
70+
public static function providerUpdateOidWithInvalidValue(): array {
71+
return [
72+
['1.2..3'],
73+
['3.2.1'],
74+
['1'],
75+
];
76+
}
77+
78+
public function testUpdateOid(): void {
79+
$service = $this->getService();
80+
81+
$result = $service->updateOid('1.2.3');
82+
$this->assertEquals('1.2.3', $result);
83+
$current = $this->appConfig->getValueString('libresign', 'certificate_policies_oid');
84+
$this->assertEquals('1.2.3', $current);
85+
$this->assertEquals('1.2.3', $service->getOid());
86+
87+
$result = $service->updateOid('');
88+
$this->assertEquals('', $result);
89+
$this->assertEquals('', $service->getOid());
90+
91+
$condition = $this->appConfig->hasKey('libresign', 'certificate_policies_oid');
92+
$this->assertFalse($condition);
93+
}
94+
95+
#[DataProvider('providerGetCps')]
96+
public function testGetCps(bool $fileExists, string $expected): void {
97+
$folder = $this->createMock(ISimpleFolder::class);
98+
99+
if ($fileExists) {
100+
$file = $this->createMock(ISimpleFile::class);
101+
$folder->method('getFile')->willReturn($file);
102+
$this->urlGenerator->method('linkToRouteAbsolute')->willReturn($expected);
103+
} else {
104+
$folder->method('getFile')->willThrowException(new NotFoundException());
105+
}
106+
107+
$this->appData->method('getFolder')->willReturn($folder);
108+
$service = $this->getService();
109+
$this->assertSame($expected, $service->getCps());
110+
}
111+
112+
public static function providerGetCps(): array {
113+
return [
114+
'file exists' => [true, 'https://example.coop/cps'],
115+
'file not found' => [false, ''],
116+
];
117+
}
118+
119+
#[DataProvider('providerGetFile')]
120+
public function testGetFile(bool $exists): void {
121+
$folder = $this->createMock(ISimpleFolder::class);
122+
$this->appData->method('getFolder')->willReturn($folder);
123+
$service = $this->getService();
124+
125+
if ($exists) {
126+
$file = $this->createMock(ISimpleFile::class);
127+
$folder->method('getFile')->with('certificate-policy.pdf')->willReturn($file);
128+
$this->assertSame($file, $service->getFile());
129+
} else {
130+
$folder->method('getFile')->willThrowException(new NotFoundException());
131+
$this->expectException(NotFoundException::class);
132+
$service->getFile();
133+
}
134+
}
135+
136+
public static function providerGetFile(): array {
137+
return [
138+
'success' => [true],
139+
'not found' => [false],
140+
];
141+
}
142+
143+
#[DataProvider('providerUpdateFileWithValidPdf')]
144+
public function testUpdateFileWithValidPdf(string $pdfContent): void {
145+
vfsStream::setup('uploaded');
146+
$pdfPath = 'vfs://uploaded/test.pdf';
147+
file_put_contents($pdfPath, $pdfContent);
148+
149+
$this->urlGenerator->method('linkToRouteAbsolute')->willReturn('https://example.coop/cps');
150+
151+
$service = $this->getService();
152+
$result = $service->updateFile($pdfPath);
153+
$this->assertSame('https://example.coop/cps', $result);
154+
}
155+
156+
public static function providerUpdateFileWithValidPdf(): array {
157+
return [
158+
['%PDF-1.0' . "\n" . '%LibreSign Test File' . "\n", '1.0'],
159+
['%PDF-1.1' . "\n" . '%LibreSign Test File' . "\n", '1.1'],
160+
['%PDF-1.2' . "\n" . '%LibreSign Test File' . "\n", '1.2'],
161+
['%PDF-1.3' . "\n" . '%LibreSign Test File' . "\n", '1.3'],
162+
['%PDF-1.4' . "\n" . '%LibreSign Test File' . "\n", '1.4'],
163+
['%PDF-1.5' . "\n" . '%LibreSign Test File' . "\n", '1.5'],
164+
['%PDF-1.6' . "\n" . '%LibreSign Test File' . "\n", '1.6'],
165+
['%PDF-1.7' . "\n" . '%LibreSign Test File' . "\n", '1.7'],
166+
['%PDF-2.0' . "\n" . '%LibreSign Test File' . "\n", '2.0'],
167+
];
168+
}
169+
170+
public function testUpdateFileWithInvalidType(): void {
171+
$tmpFile = tempnam(sys_get_temp_dir(), 'txt');
172+
file_put_contents($tmpFile, 'just text');
173+
174+
$service = $this->getService();
175+
$this->expectException(\Exception::class);
176+
$service->updateFile($tmpFile);
177+
}
178+
}

tests/lib/AppConfigOverwrite.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,8 @@ public function setValueString(string $app, string $key, string $value, bool $la
9494
$this->overWrite[$app][$key] = $value;
9595
return true;
9696
}
97+
98+
public function deleteKey(string $app, string $key): void {
99+
unset($this->overWrite[$app][$key]);
100+
}
97101
}

0 commit comments

Comments
 (0)