All checks were successful
PHPUnit SQLite / versions (pull_request) Successful in 4s
PHPUnit SQLite / changes (pull_request) Successful in 1s
Lint info.xml / info.xml lint (pull_request) Successful in 3s
PHP / versions (pull_request) Successful in 5s
Static analysis / versions (pull_request) Successful in 3s
REUSE Compliance Check / reuse-compliance-check (pull_request) Successful in 3s
Node / NPM (pull_request) Successful in 21s
PHP / PHP 8.5 (8.5) (pull_request) Successful in 54s
PHP / PHP 8.2 (8.2) (pull_request) Successful in 2m16s
PHPUnit SQLite / SQLite PHP 8.5 Nextcloud master (8.5, master) (pull_request) Successful in 2m27s
PHPUnit SQLite / phpunit-sqlite-summary (pull_request) Successful in 1s
Static analysis / static-psalm-analysis dev-stable34 (dev-stable34, 8.5) (pull_request) Successful in 1m48s
Static analysis / static-psalm-analysis dev-stable33 (dev-stable33, 8.5) (pull_request) Successful in 2m30s
Static analysis / static-psalm-analysis dev-master (dev-master, 8.5) (pull_request) Successful in 2m49s
Static analysis / static-psalm-analysis-summary (pull_request) Successful in 1s
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
173 lines
7.1 KiB
PHP
173 lines
7.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2026 Lukas Schaefer
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Shortcuts\Tests\Unit\Service;
|
|
|
|
use OCA\Shortcuts\Exception\ConflictException;
|
|
use OCA\Shortcuts\Exception\InvalidPathException;
|
|
use OCA\Shortcuts\Service\ShortcutService;
|
|
use OCP\Constants;
|
|
use OCP\Files\File;
|
|
use OCP\Files\Folder;
|
|
use OCP\Files\IRootFolder;
|
|
use OCP\IUser;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class ShortcutServiceTest extends TestCase {
|
|
private IRootFolder&MockObject $rootFolder;
|
|
private Folder&MockObject $userFolder;
|
|
private IUser&MockObject $user;
|
|
private ShortcutService $service;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
$this->rootFolder = $this->createMock(IRootFolder::class);
|
|
$this->userFolder = $this->createMock(Folder::class);
|
|
$this->user = $this->createMock(IUser::class);
|
|
$this->user->method('getUID')->willReturn('admin');
|
|
$this->rootFolder->method('getUserFolder')->with('admin')->willReturn($this->userFolder);
|
|
$this->service = new ShortcutService($this->rootFolder);
|
|
}
|
|
|
|
public function testCreateWritesBareFileId(): void {
|
|
$target = $this->createMock(File::class);
|
|
$target->method('getId')->willReturn(320);
|
|
$target->method('getName')->willReturn('main.tex');
|
|
$target->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$target->method('getMimeType')->willReturn('application/x-tex');
|
|
|
|
$destination = $this->createMock(Folder::class);
|
|
$destination->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$destination->method('nodeExists')->with('main.tex.nextcloudshortcut')->willReturn(false);
|
|
|
|
$created = $this->createMock(File::class);
|
|
$created->method('getId')->willReturn(999);
|
|
$created->method('getName')->willReturn('main.tex.nextcloudshortcut');
|
|
$created->method('getPath')->willReturn('/admin/files/test/main.tex.nextcloudshortcut');
|
|
|
|
$destination->expects($this->once())
|
|
->method('newFile')
|
|
->with('main.tex.nextcloudshortcut', '320')
|
|
->willReturn($created);
|
|
|
|
$this->userFolder->method('getFirstNodeById')->with(320)->willReturn($target);
|
|
$this->userFolder->method('get')->with('/test')->willReturn($destination);
|
|
$this->userFolder->method('getRelativePath')
|
|
->with('/admin/files/test/main.tex.nextcloudshortcut')
|
|
->willReturn('/test/main.tex.nextcloudshortcut');
|
|
|
|
$result = $this->service->create($this->user, 320, '/test');
|
|
$this->assertSame(999, $result['fileId']);
|
|
$this->assertSame(320, $result['targetFileId']);
|
|
$this->assertSame('file', $result['targetType']);
|
|
$this->assertSame('main.tex.nextcloudshortcut', $result['name']);
|
|
}
|
|
|
|
public function testCreateConflict(): void {
|
|
$target = $this->createMock(File::class);
|
|
$target->method('getId')->willReturn(1);
|
|
$target->method('getName')->willReturn('a.txt');
|
|
$target->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$target->method('getMimeType')->willReturn('text/plain');
|
|
|
|
$this->userFolder->method('getFirstNodeById')->willReturn($target);
|
|
$this->userFolder->method('get')->with('/')->willReturn($this->userFolder);
|
|
$this->userFolder->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$this->userFolder->method('nodeExists')->with('a.txt.nextcloudshortcut')->willReturn(true);
|
|
|
|
$this->expectException(ConflictException::class);
|
|
$this->service->create($this->user, 1, '/');
|
|
}
|
|
|
|
public function testResolveFile(): void {
|
|
$shortcut = $this->createMock(File::class);
|
|
$shortcut->method('getId')->willReturn(50);
|
|
$shortcut->method('getName')->willReturn('main.tex.nextcloudshortcut');
|
|
$shortcut->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$shortcut->method('getMimeType')->willReturn('application/x-nextcloud-shortcut');
|
|
$shortcut->method('getContent')->willReturn("320\n");
|
|
|
|
$target = $this->createMock(File::class);
|
|
$target->method('getId')->willReturn(320);
|
|
$target->method('getName')->willReturn('main.tex');
|
|
$target->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$target->method('getMimeType')->willReturn('application/x-tex');
|
|
$target->method('getPath')->willReturn('/admin/files/docs/main.tex');
|
|
|
|
$parent = $this->createMock(Folder::class);
|
|
$parent->method('getPath')->willReturn('/admin/files/docs');
|
|
$target->method('getParent')->willReturn($parent);
|
|
|
|
$this->userFolder->method('getFirstNodeById')->willReturnMap([
|
|
[50, $shortcut],
|
|
[320, $target],
|
|
]);
|
|
$this->userFolder->method('getRelativePath')->willReturnMap([
|
|
['/admin/files/docs/main.tex', '/docs/main.tex'],
|
|
['/admin/files/docs', '/docs'],
|
|
]);
|
|
|
|
$result = $this->service->resolve($this->user, 50);
|
|
$this->assertSame(320, $result['targetFileId']);
|
|
$this->assertSame('file', $result['targetType']);
|
|
$this->assertSame('/docs/main.tex', $result['path']);
|
|
$this->assertSame('/docs', $result['dirname']);
|
|
}
|
|
|
|
public function testResolveInvalidContents(): void {
|
|
$shortcut = $this->createMock(File::class);
|
|
$shortcut->method('getName')->willReturn('bad.nextcloudshortcut');
|
|
$shortcut->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$shortcut->method('getMimeType')->willReturn('application/x-nextcloud-shortcut');
|
|
$shortcut->method('getContent')->willReturn('not-an-id');
|
|
|
|
$this->userFolder->method('getFirstNodeById')->willReturn($shortcut);
|
|
|
|
$this->expectException(InvalidPathException::class);
|
|
$this->service->resolve($this->user, 1);
|
|
}
|
|
|
|
public function testCreateCanonicalizesShortcutTarget(): void {
|
|
$innerShortcut = $this->createMock(File::class);
|
|
$innerShortcut->method('getId')->willReturn(10);
|
|
$innerShortcut->method('getName')->willReturn('a.nextcloudshortcut');
|
|
$innerShortcut->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$innerShortcut->method('getMimeType')->willReturn('application/x-nextcloud-shortcut');
|
|
$innerShortcut->method('getContent')->willReturn('320');
|
|
|
|
$realTarget = $this->createMock(File::class);
|
|
$realTarget->method('getId')->willReturn(320);
|
|
$realTarget->method('getName')->willReturn('main.tex');
|
|
$realTarget->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$realTarget->method('getMimeType')->willReturn('application/x-tex');
|
|
|
|
$created = $this->createMock(File::class);
|
|
$created->method('getId')->willReturn(11);
|
|
$created->method('getName')->willReturn('main.tex.nextcloudshortcut');
|
|
$created->method('getPath')->willReturn('/admin/files/main.tex.nextcloudshortcut');
|
|
|
|
$this->userFolder->method('getFirstNodeById')->willReturnMap([
|
|
[10, $innerShortcut],
|
|
[320, $realTarget],
|
|
]);
|
|
$this->userFolder->method('get')->with('/')->willReturn($this->userFolder);
|
|
$this->userFolder->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
|
|
$this->userFolder->method('nodeExists')->with('main.tex.nextcloudshortcut')->willReturn(false);
|
|
$this->userFolder->expects($this->once())
|
|
->method('newFile')
|
|
->with('main.tex.nextcloudshortcut', '320')
|
|
->willReturn($created);
|
|
$this->userFolder->method('getRelativePath')->willReturn('/main.tex.nextcloudshortcut');
|
|
|
|
$result = $this->service->create($this->user, 10, '/');
|
|
$this->assertSame(320, $result['targetFileId']);
|
|
$this->assertSame(11, $result['fileId']);
|
|
}
|
|
}
|