Skip to content

Commit 45a76e0

Browse files
committed
refactor(metadata): improve nodeId precedence and test coverage
- Clarify signedNodeId takes precedence over nodeId - Add DataProvider for nodeId precedence scenarios - Add DataProvider for metadata field scenarios - Remove redundant test cases - Consolidate metadata defaults testing Tests now use parameterized tests for better coverage and clearer test intent. The nodeId resolution logic is explicitly tested for both precedence and fallback cases. Signed-off-by: Vitor Mattos <[email protected]>
1 parent 8e10b39 commit 45a76e0

2 files changed

Lines changed: 40 additions & 69 deletions

File tree

lib/Service/File/MetadataLoader.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public function loadMetadata(?File $file, stdClass $fileData): void {
3333

3434
try {
3535
$fileNode = $this->getFileNode($file);
36+
$metadata = $file->getMetadata() ?? [];
37+
38+
$fileData->metadata = $metadata;
3639

3740
if (method_exists($fileNode, 'getSize')) {
3841
$fileData->size = $fileNode->getSize();
@@ -46,9 +49,15 @@ public function loadMetadata(?File $file, stdClass $fileData): void {
4649
}
4750

4851
$fileData->pages = $this->getPages($file);
52+
53+
$fileData->totalPages = (int)($metadata['p'] ?? count($fileData->pages ?? []));
54+
$fileData->pdfVersion = (string)($metadata['pdfVersion'] ?? '');
4955
} catch (\Throwable $e) {
5056
$this->logger->warning('Failed to load file metadata: ' . $e->getMessage());
5157
}
58+
59+
$fileData->totalPages ??= 0;
60+
$fileData->pdfVersion ??= '';
5261
}
5362

5463
/**

tests/php/Unit/Service/File/MetadataLoaderTest.php

Lines changed: 31 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\Files\IMimeTypeDetector;
1717
use OCP\Files\IRootFolder;
1818
use OCP\IURLGenerator;
19+
use PHPUnit\Framework\Attributes\DataProvider;
1920
use PHPUnit\Framework\MockObject\MockObject;
2021
use Psr\Log\LoggerInterface;
2122
use stdClass;
@@ -117,40 +118,6 @@ public function testLoadMetadataWithPages(): void {
117118
$this->assertEquals(200, $fileData->pages[1]['resolution']);
118119
}
119120

120-
public function testLoadMetadataUsesContentProviderWhenNoMimeType(): void {
121-
$file = new File();
122-
$file->setId(1);
123-
$file->setUserId('user123');
124-
$file->setSignedNodeId(123);
125-
$file->setMetadata(['p' => 1, 'd' => [100]]);
126-
$file->setUuid('uuid-123');
127-
128-
// Create a mock that implements the File interface but doesn't define getMimeType
129-
$fileNode = $this->createMock(\OCP\Files\File::class);
130-
$fileNode->method('getSize')->willReturn(5000);
131-
132-
$userFolder = $this->createMock(Folder::class);
133-
$userFolder->method('getFirstNodeById')->with(123)->willReturn($fileNode);
134-
135-
$this->root->method('getUserFolder')->with('user123')->willReturn($userFolder);
136-
137-
// Since the mock will have getMimeType available, we expect it to be called
138-
// The test needs to be adjusted - it tests the else branch when method_exists is false
139-
// But with mocks, method_exists will always return true
140-
// So this test is actually not testing the right scenario
141-
// Let's just test that getMimeType is called
142-
$fileNode->method('getMimeType')->willReturn('application/pdf');
143-
144-
$this->urlGenerator->method('linkToRoute')->willReturn('http://example.com/page.pdf');
145-
146-
$fileData = new stdClass();
147-
148-
$service = $this->getService();
149-
$service->loadMetadata($file, $fileData);
150-
151-
$this->assertEquals('application/pdf', $fileData->mime);
152-
}
153-
154121
public function testLoadMetadataLogsWarningOnError(): void {
155122
$file = new File();
156123
$file->setId(1);
@@ -176,11 +143,13 @@ public function testLoadMetadataLogsWarningOnError(): void {
176143
$this->assertTrue(true);
177144
}
178145

179-
public function testLoadMetadataUsesSignedNodeIdFirst(): void {
146+
#[DataProvider('provideNodeIdPrecedenceScenarios')]
147+
public function testNodeIdPrecedenceAndFallback(?int $signedNodeId, ?int $nodeId, int $expectedNodeId): void {
180148
$file = new File();
181149
$file->setId(1);
182150
$file->setUserId('user123');
183-
$file->setSignedNodeId(123);
151+
$file->setSignedNodeId($signedNodeId);
152+
$file->setNodeId($nodeId);
184153
$file->setMetadata(['p' => 0, 'd' => []]);
185154

186155
$fileNode = $this->createMock(\OCP\Files\File::class);
@@ -191,7 +160,7 @@ public function testLoadMetadataUsesSignedNodeIdFirst(): void {
191160
$userFolder
192161
->expects($this->once())
193162
->method('getFirstNodeById')
194-
->with(123)
163+
->with($expectedNodeId)
195164
->willReturn($fileNode);
196165

197166
$this->root->method('getUserFolder')->with('user123')->willReturn($userFolder);
@@ -206,43 +175,25 @@ public function testLoadMetadataUsesSignedNodeIdFirst(): void {
206175
$this->assertEquals(5000, $fileData->size);
207176
}
208177

209-
public function testLoadMetadataFallsBackToNodeId(): void {
210-
$file = new File();
211-
$file->setId(1);
212-
$file->setUserId('user123');
213-
$file->setSignedNodeId(null);
214-
$file->setNodeId(456);
215-
$file->setMetadata(['p' => 0, 'd' => []]);
216-
217-
$fileNode = $this->createMock(\OCP\Files\File::class);
218-
$fileNode->method('getSize')->willReturn(5000);
219-
$fileNode->method('getMimeType')->willReturn('application/pdf');
220-
221-
$userFolder = $this->createMock(Folder::class);
222-
$userFolder
223-
->expects($this->once())
224-
->method('getFirstNodeById')
225-
->with(456)
226-
->willReturn($fileNode);
227-
228-
$this->root->method('getUserFolder')->with('user123')->willReturn($userFolder);
229-
230-
$this->urlGenerator->method('linkToRoute')->willReturn('http://example.com/page.pdf');
231-
232-
$fileData = new stdClass();
233-
234-
$service = $this->getService();
235-
$service->loadMetadata($file, $fileData);
236-
237-
$this->assertEquals(5000, $fileData->size);
178+
public static function provideNodeIdPrecedenceScenarios(): array {
179+
return [
180+
'signedNodeId takes precedence when present' => [123, 456, 123],
181+
'fallback to nodeId when signedNodeId is null' => [null, 456, 456],
182+
];
238183
}
239184

240-
public function testLoadMetadataHandlesNoPages(): void {
185+
#[DataProvider('provideMetadataFieldScenarios')]
186+
public function testLoadMetadataDefaults(int $pageCount, ?string $pdfVersion, int $expectedPages, string $expectedPdfVersion): void {
241187
$file = new File();
242188
$file->setId(1);
243189
$file->setUserId('user123');
244190
$file->setSignedNodeId(123);
245-
$file->setMetadata(['p' => 0, 'd' => []]);
191+
$metadata = ['p' => $pageCount];
192+
if ($pdfVersion !== null) {
193+
$metadata['pdfVersion'] = $pdfVersion;
194+
}
195+
$file->setMetadata($metadata);
196+
$file->setUuid('uuid-123');
246197

247198
$fileNode = $this->createMock(\OCP\Files\File::class);
248199
$fileNode->method('getSize')->willReturn(5000);
@@ -253,11 +204,22 @@ public function testLoadMetadataHandlesNoPages(): void {
253204

254205
$this->root->method('getUserFolder')->with('user123')->willReturn($userFolder);
255206

207+
$this->urlGenerator->method('linkToRoute')->willReturn('http://example.com/page.pdf');
208+
256209
$fileData = new stdClass();
257210

258211
$service = $this->getService();
259212
$service->loadMetadata($file, $fileData);
260213

261-
$this->assertCount(0, $fileData->pages);
214+
$this->assertEquals($expectedPages, $fileData->totalPages);
215+
$this->assertEquals($expectedPdfVersion, $fileData->pdfVersion);
216+
}
217+
218+
public static function provideMetadataFieldScenarios(): array {
219+
return [
220+
'no pages with no pdfVersion' => [0, null, 0, ''],
221+
'multiple pages with pdf version' => [5, '1.7', 5, '1.7'],
222+
'single page with pdf version' => [1, '1.5', 1, '1.5'],
223+
];
262224
}
263225
}

0 commit comments

Comments
 (0)