2015-11-16 14:57:41 -05:00
|
|
|
<?php
|
2024-05-28 10:42:42 -04:00
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
declare(strict_types=1);
|
2015-11-16 14:57:41 -05:00
|
|
|
/**
|
2024-05-28 10:42:42 -04:00
|
|
|
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
|
|
|
|
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
2015-11-16 14:57:41 -05:00
|
|
|
*/
|
|
|
|
|
namespace OCA\Files\Tests\Controller;
|
|
|
|
|
|
2024-07-15 10:29:44 -04:00
|
|
|
use OC\Files\FilenameValidator;
|
2025-02-14 03:28:58 -05:00
|
|
|
use OC\Route\Router;
|
|
|
|
|
use OC\URLGenerator;
|
2015-11-16 14:57:41 -05:00
|
|
|
use OCA\Files\Controller\ViewController;
|
2022-12-28 13:08:54 -05:00
|
|
|
use OCA\Files\Service\UserConfig;
|
2023-04-14 06:40:08 -04:00
|
|
|
use OCA\Files\Service\ViewConfig;
|
2019-11-22 14:52:10 -05:00
|
|
|
use OCP\App\IAppManager;
|
2024-10-10 06:40:31 -04:00
|
|
|
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
|
|
|
|
use OCP\AppFramework\Http\RedirectResponse;
|
|
|
|
|
use OCP\AppFramework\Http\TemplateResponse;
|
2021-01-12 05:28:04 -05:00
|
|
|
use OCP\AppFramework\Services\IInitialState;
|
2024-04-01 15:30:47 -04:00
|
|
|
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
2025-02-14 03:28:58 -05:00
|
|
|
use OCP\Diagnostics\IEventLogger;
|
2019-08-02 14:08:54 -04:00
|
|
|
use OCP\EventDispatcher\IEventDispatcher;
|
2017-10-24 09:26:53 -04:00
|
|
|
use OCP\Files\File;
|
|
|
|
|
use OCP\Files\Folder;
|
2016-08-19 02:15:30 -04:00
|
|
|
use OCP\Files\IRootFolder;
|
2021-01-12 05:28:04 -05:00
|
|
|
use OCP\Files\Template\ITemplateManager;
|
2025-02-14 03:28:58 -05:00
|
|
|
use OCP\ICacheFactory;
|
2019-11-22 14:52:10 -05:00
|
|
|
use OCP\IConfig;
|
|
|
|
|
use OCP\IL10N;
|
2015-11-16 14:57:41 -05:00
|
|
|
use OCP\IRequest;
|
|
|
|
|
use OCP\IURLGenerator;
|
2019-11-22 14:52:10 -05:00
|
|
|
use OCP\IUser;
|
2016-04-12 05:51:50 -04:00
|
|
|
use OCP\IUserSession;
|
2024-08-21 13:31:21 -04:00
|
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
2025-02-14 03:28:58 -05:00
|
|
|
use Psr\Container\ContainerInterface;
|
|
|
|
|
use Psr\Log\LoggerInterface;
|
2019-11-22 14:52:10 -05:00
|
|
|
use Test\TestCase;
|
2015-11-16 14:57:41 -05:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Class ViewControllerTest
|
|
|
|
|
*
|
2025-02-14 03:28:58 -05:00
|
|
|
*
|
2015-11-16 14:57:41 -05:00
|
|
|
* @package OCA\Files\Tests\Controller
|
|
|
|
|
*/
|
2025-10-20 19:52:40 -04:00
|
|
|
#[\PHPUnit\Framework\Attributes\Group('RoutingWeirdness')]
|
2015-11-16 14:57:41 -05:00
|
|
|
class ViewControllerTest extends TestCase {
|
2025-02-14 03:28:58 -05:00
|
|
|
private ContainerInterface&MockObject $container;
|
|
|
|
|
private IAppManager&MockObject $appManager;
|
|
|
|
|
private ICacheFactory&MockObject $cacheFactory;
|
2024-08-21 13:31:21 -04:00
|
|
|
private IConfig&MockObject $config;
|
|
|
|
|
private IEventDispatcher $eventDispatcher;
|
2025-02-14 03:28:58 -05:00
|
|
|
private IEventLogger&MockObject $eventLogger;
|
2024-08-21 13:31:21 -04:00
|
|
|
private IInitialState&MockObject $initialState;
|
2025-02-14 03:28:58 -05:00
|
|
|
private IL10N&MockObject $l10n;
|
|
|
|
|
private IRequest&MockObject $request;
|
|
|
|
|
private IRootFolder&MockObject $rootFolder;
|
2024-08-21 13:31:21 -04:00
|
|
|
private ITemplateManager&MockObject $templateManager;
|
2025-02-14 03:28:58 -05:00
|
|
|
private IURLGenerator $urlGenerator;
|
|
|
|
|
private IUser&MockObject $user;
|
|
|
|
|
private IUserSession&MockObject $userSession;
|
|
|
|
|
private LoggerInterface&MockObject $logger;
|
2024-08-21 13:31:21 -04:00
|
|
|
private UserConfig&MockObject $userConfig;
|
|
|
|
|
private ViewConfig&MockObject $viewConfig;
|
2025-02-14 03:28:58 -05:00
|
|
|
private Router $router;
|
2024-04-01 15:30:47 -04:00
|
|
|
private IRegistry&MockObject $twoFactorRegistry;
|
2024-08-21 13:31:21 -04:00
|
|
|
|
|
|
|
|
private ViewController&MockObject $viewController;
|
2015-11-16 14:57:41 -05:00
|
|
|
|
2019-11-27 09:27:18 -05:00
|
|
|
protected function setUp(): void {
|
2015-11-16 14:57:41 -05:00
|
|
|
parent::setUp();
|
2025-02-14 03:28:58 -05:00
|
|
|
$this->appManager = $this->createMock(IAppManager::class);
|
|
|
|
|
$this->config = $this->createMock(IConfig::class);
|
2019-08-02 14:08:54 -04:00
|
|
|
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
|
2025-02-14 03:28:58 -05:00
|
|
|
$this->initialState = $this->createMock(IInitialState::class);
|
|
|
|
|
$this->l10n = $this->createMock(IL10N::class);
|
|
|
|
|
$this->request = $this->createMock(IRequest::class);
|
|
|
|
|
$this->rootFolder = $this->createMock(IRootFolder::class);
|
|
|
|
|
$this->templateManager = $this->createMock(ITemplateManager::class);
|
|
|
|
|
$this->userConfig = $this->createMock(UserConfig::class);
|
|
|
|
|
$this->userSession = $this->createMock(IUserSession::class);
|
|
|
|
|
$this->viewConfig = $this->createMock(ViewConfig::class);
|
2024-04-01 15:30:47 -04:00
|
|
|
$this->twoFactorRegistry = $this->createMock(IRegistry::class);
|
2025-02-14 03:28:58 -05:00
|
|
|
|
2017-10-24 09:26:53 -04:00
|
|
|
$this->user = $this->getMockBuilder(IUser::class)->getMock();
|
2016-05-11 13:41:36 -04:00
|
|
|
$this->user->expects($this->any())
|
|
|
|
|
->method('getUID')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn('testuser1');
|
2016-04-12 05:51:50 -04:00
|
|
|
$this->userSession->expects($this->any())
|
|
|
|
|
->method('getUser')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn($this->user);
|
2024-07-15 10:29:44 -04:00
|
|
|
|
2025-02-14 03:28:58 -05:00
|
|
|
// Make sure we know the app is enabled
|
|
|
|
|
$this->appManager->expects($this->any())
|
|
|
|
|
->method('cleanAppId')
|
|
|
|
|
->willReturnArgument(0);
|
|
|
|
|
$this->appManager->expects($this->any())
|
|
|
|
|
->method('getAppPath')
|
|
|
|
|
->willReturnCallback(fn (string $appid): string => \OC::$SERVERROOT . '/apps/' . $appid);
|
2025-02-24 10:23:21 -05:00
|
|
|
$this->appManager->expects($this->any())
|
|
|
|
|
->method('isAppLoaded')
|
|
|
|
|
->willReturn(true);
|
2025-02-14 03:28:58 -05:00
|
|
|
|
|
|
|
|
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
|
|
|
|
$this->logger = $this->createMock(LoggerInterface::class);
|
|
|
|
|
$this->eventLogger = $this->createMock(IEventLogger::class);
|
|
|
|
|
$this->container = $this->createMock(ContainerInterface::class);
|
|
|
|
|
$this->router = new Router(
|
|
|
|
|
$this->logger,
|
|
|
|
|
$this->request,
|
|
|
|
|
$this->config,
|
|
|
|
|
$this->eventLogger,
|
|
|
|
|
$this->container,
|
|
|
|
|
$this->appManager,
|
|
|
|
|
);
|
2024-07-15 10:29:44 -04:00
|
|
|
|
2025-02-14 03:28:58 -05:00
|
|
|
// Create a real URLGenerator instance to generate URLs
|
|
|
|
|
$this->urlGenerator = new URLGenerator(
|
|
|
|
|
$this->config,
|
|
|
|
|
$this->userSession,
|
|
|
|
|
$this->cacheFactory,
|
|
|
|
|
$this->request,
|
|
|
|
|
$this->router
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$filenameValidator = $this->createMock(FilenameValidator::class);
|
2024-07-15 10:29:44 -04:00
|
|
|
$this->viewController = $this->getMockBuilder(ViewController::class)
|
2015-11-16 14:57:41 -05:00
|
|
|
->setConstructorArgs([
|
2020-04-09 03:22:29 -04:00
|
|
|
'files',
|
|
|
|
|
$this->request,
|
|
|
|
|
$this->urlGenerator,
|
|
|
|
|
$this->l10n,
|
|
|
|
|
$this->config,
|
|
|
|
|
$this->eventDispatcher,
|
|
|
|
|
$this->userSession,
|
|
|
|
|
$this->appManager,
|
|
|
|
|
$this->rootFolder,
|
2021-01-12 05:28:04 -05:00
|
|
|
$this->initialState,
|
|
|
|
|
$this->templateManager,
|
2022-12-28 13:08:54 -05:00
|
|
|
$this->userConfig,
|
2023-04-14 06:40:08 -04:00
|
|
|
$this->viewConfig,
|
2024-07-15 10:29:44 -04:00
|
|
|
$filenameValidator,
|
2024-04-01 15:30:47 -04:00
|
|
|
$this->twoFactorRegistry,
|
2020-04-09 03:22:29 -04:00
|
|
|
])
|
2024-08-23 09:10:27 -04:00
|
|
|
->onlyMethods([
|
|
|
|
|
'getStorageInfo',
|
|
|
|
|
])
|
|
|
|
|
->getMock();
|
2015-11-16 14:57:41 -05:00
|
|
|
}
|
|
|
|
|
|
2024-09-15 16:32:31 -04:00
|
|
|
public function testIndexWithRegularBrowser(): void {
|
2015-11-16 14:57:41 -05:00
|
|
|
$this->viewController
|
2023-01-04 13:06:52 -05:00
|
|
|
->expects($this->any())
|
2015-11-16 14:57:41 -05:00
|
|
|
->method('getStorageInfo')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn([
|
2017-06-12 04:32:25 -04:00
|
|
|
'used' => 123,
|
|
|
|
|
'quota' => 100,
|
|
|
|
|
'total' => 100,
|
2015-11-16 14:57:41 -05:00
|
|
|
'relative' => 123,
|
|
|
|
|
'owner' => 'MyName',
|
|
|
|
|
'ownerDisplayName' => 'MyDisplayName',
|
2020-03-25 17:21:27 -04:00
|
|
|
]);
|
2023-09-22 08:22:04 -04:00
|
|
|
|
2018-07-12 08:30:39 -04:00
|
|
|
$this->config
|
2016-04-12 05:51:50 -04:00
|
|
|
->method('getUserValue')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturnMap([
|
2016-04-12 05:51:50 -04:00
|
|
|
[$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'],
|
2016-04-12 11:10:09 -04:00
|
|
|
[$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc'],
|
2023-08-14 11:03:56 -04:00
|
|
|
[$this->user->getUID(), 'files', 'files_sorting_configs', '{}', '{}'],
|
2016-04-12 11:10:09 -04:00
|
|
|
[$this->user->getUID(), 'files', 'show_hidden', false, false],
|
2021-01-10 03:14:49 -05:00
|
|
|
[$this->user->getUID(), 'files', 'crop_image_previews', true, true],
|
2018-11-15 14:29:10 -05:00
|
|
|
[$this->user->getUID(), 'files', 'show_grid', true],
|
2020-03-25 17:21:27 -04:00
|
|
|
]);
|
2024-02-09 03:54:52 -05:00
|
|
|
|
2023-08-17 02:55:30 -04:00
|
|
|
$baseFolderFiles = $this->getMockBuilder(Folder::class)->getMock();
|
|
|
|
|
|
|
|
|
|
$this->rootFolder->expects($this->any())
|
|
|
|
|
->method('getUserFolder')
|
|
|
|
|
->with('testuser1')
|
|
|
|
|
->willReturn($baseFolderFiles);
|
2015-11-16 14:57:41 -05:00
|
|
|
|
2020-04-10 08:19:56 -04:00
|
|
|
$this->config
|
2023-01-04 13:06:52 -05:00
|
|
|
->expects($this->any())
|
|
|
|
|
->method('getAppValue')
|
|
|
|
|
->willReturnArgument(2);
|
2015-11-16 14:57:41 -05:00
|
|
|
|
2024-10-10 06:40:31 -04:00
|
|
|
$expected = new TemplateResponse(
|
2015-11-16 14:57:41 -05:00
|
|
|
'files',
|
|
|
|
|
'index',
|
|
|
|
|
);
|
2024-10-10 06:40:31 -04:00
|
|
|
$policy = new ContentSecurityPolicy();
|
2023-08-17 02:55:30 -04:00
|
|
|
$policy->addAllowedWorkerSrcDomain('\'self\'');
|
2015-12-02 11:30:40 -05:00
|
|
|
$policy->addAllowedFrameDomain('\'self\'');
|
|
|
|
|
$expected->setContentSecurityPolicy($policy);
|
2018-07-12 08:30:39 -04:00
|
|
|
|
2015-11-16 14:57:41 -05:00
|
|
|
$this->assertEquals($expected, $this->viewController->index('MyDir', 'MyView'));
|
|
|
|
|
}
|
2016-05-04 04:28:06 -04:00
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
public static function dataTestShortRedirect(): array {
|
2025-02-14 03:28:58 -05:00
|
|
|
// openfile is true by default
|
|
|
|
|
// opendetails is undefined by default
|
|
|
|
|
// both will be evaluated as truthy
|
|
|
|
|
return [
|
|
|
|
|
[null, null, '/index.php/apps/files/files/123456?openfile=true'],
|
|
|
|
|
['', null, '/index.php/apps/files/files/123456?openfile=true'],
|
|
|
|
|
[null, '', '/index.php/apps/files/files/123456?openfile=true&opendetails=true'],
|
|
|
|
|
['', '', '/index.php/apps/files/files/123456?openfile=true&opendetails=true'],
|
|
|
|
|
['false', '', '/index.php/apps/files/files/123456?openfile=false'],
|
|
|
|
|
[null, 'false', '/index.php/apps/files/files/123456?openfile=true&opendetails=false'],
|
|
|
|
|
['true', 'false', '/index.php/apps/files/files/123456?openfile=true&opendetails=false'],
|
|
|
|
|
['false', 'true', '/index.php/apps/files/files/123456?openfile=false&opendetails=true'],
|
|
|
|
|
['false', 'false', '/index.php/apps/files/files/123456?openfile=false&opendetails=false'],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-30 10:56:59 -04:00
|
|
|
#[\PHPUnit\Framework\Attributes\DataProvider('dataTestShortRedirect')]
|
2025-05-29 06:19:28 -04:00
|
|
|
public function testShortRedirect(?string $openfile, ?string $opendetails, string $result): void {
|
2025-02-14 03:28:58 -05:00
|
|
|
$this->appManager->expects($this->any())
|
|
|
|
|
->method('isEnabledForUser')
|
|
|
|
|
->with('files')
|
|
|
|
|
->willReturn(true);
|
|
|
|
|
|
|
|
|
|
$baseFolderFiles = $this->getMockBuilder(Folder::class)->getMock();
|
|
|
|
|
$this->rootFolder->expects($this->any())
|
|
|
|
|
->method('getUserFolder')
|
|
|
|
|
->with('testuser1')
|
|
|
|
|
->willReturn($baseFolderFiles);
|
|
|
|
|
|
|
|
|
|
$parentNode = $this->getMockBuilder(Folder::class)->getMock();
|
|
|
|
|
$parentNode->expects($this->once())
|
|
|
|
|
->method('getPath')
|
|
|
|
|
->willReturn('testuser1/files/Folder');
|
|
|
|
|
|
|
|
|
|
$node = $this->getMockBuilder(File::class)->getMock();
|
|
|
|
|
$node->expects($this->once())
|
|
|
|
|
->method('getParent')
|
|
|
|
|
->willReturn($parentNode);
|
|
|
|
|
|
|
|
|
|
$baseFolderFiles->expects($this->any())
|
|
|
|
|
->method('getFirstNodeById')
|
|
|
|
|
->with(123456)
|
|
|
|
|
->willReturn($node);
|
|
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
$response = $this->viewController->showFile('123456', $opendetails, $openfile);
|
2025-02-14 03:28:58 -05:00
|
|
|
$this->assertStringContainsString($result, $response->getHeaders()['Location']);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-15 16:32:31 -04:00
|
|
|
public function testShowFileRouteWithTrashedFile(): void {
|
2025-02-14 03:28:58 -05:00
|
|
|
$this->appManager->expects($this->exactly(2))
|
2016-05-11 13:41:36 -04:00
|
|
|
->method('isEnabledForUser')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn(true);
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
$parentNode = $this->createMock(Folder::class);
|
2016-05-11 13:41:36 -04:00
|
|
|
$parentNode->expects($this->once())
|
|
|
|
|
->method('getPath')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn('testuser1/files_trashbin/files/test.d1462861890/sub');
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
$baseFolderFiles = $this->createMock(Folder::class);
|
|
|
|
|
$baseFolderTrash = $this->createMock(Folder::class);
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2023-08-17 02:55:30 -04:00
|
|
|
$this->rootFolder->expects($this->any())
|
2016-08-19 02:15:30 -04:00
|
|
|
->method('getUserFolder')
|
|
|
|
|
->with('testuser1')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn($baseFolderFiles);
|
2022-05-24 07:02:07 -04:00
|
|
|
$this->rootFolder->expects($this->once())
|
2016-05-11 13:41:36 -04:00
|
|
|
->method('get')
|
|
|
|
|
->with('testuser1/files_trashbin/files/')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn($baseFolderTrash);
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2023-08-17 02:55:30 -04:00
|
|
|
$baseFolderFiles->expects($this->any())
|
2024-02-09 03:54:52 -05:00
|
|
|
->method('getFirstNodeById')
|
2016-05-11 13:41:36 -04:00
|
|
|
->with(123)
|
2024-02-09 03:54:52 -05:00
|
|
|
->willReturn(null);
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2025-05-29 06:19:28 -04:00
|
|
|
$node = $this->createMock(File::class);
|
2016-05-11 13:41:36 -04:00
|
|
|
$node->expects($this->once())
|
|
|
|
|
->method('getParent')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn($parentNode);
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2022-05-24 07:02:07 -04:00
|
|
|
$baseFolderTrash->expects($this->once())
|
2024-02-09 03:54:52 -05:00
|
|
|
->method('getFirstNodeById')
|
2016-05-11 13:41:36 -04:00
|
|
|
->with(123)
|
2024-02-09 03:54:52 -05:00
|
|
|
->willReturn($node);
|
2022-05-24 07:02:07 -04:00
|
|
|
$baseFolderTrash->expects($this->once())
|
2016-05-11 13:41:36 -04:00
|
|
|
->method('getRelativePath')
|
|
|
|
|
->with('testuser1/files_trashbin/files/test.d1462861890/sub')
|
2020-03-25 17:21:27 -04:00
|
|
|
->willReturn('/test.d1462861890/sub');
|
2016-05-11 13:41:36 -04:00
|
|
|
|
2025-02-14 03:28:58 -05:00
|
|
|
$expected = new RedirectResponse('/index.php/apps/files/trashbin/123?dir=/test.d1462861890/sub');
|
2022-02-21 05:35:22 -05:00
|
|
|
$this->assertEquals($expected, $this->viewController->index('', '', '123'));
|
2016-05-11 13:41:36 -04:00
|
|
|
}
|
2024-04-01 15:30:47 -04:00
|
|
|
|
|
|
|
|
public function testTwoFactorAuthEnabled(): void {
|
|
|
|
|
$this->twoFactorRegistry->method('getProviderStates')
|
|
|
|
|
->willReturn([
|
|
|
|
|
'totp' => true,
|
|
|
|
|
'backup_codes' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$invokedCountProvideInitialState = $this->exactly(9);
|
|
|
|
|
$this->initialState->expects($invokedCountProvideInitialState)
|
|
|
|
|
->method('provideInitialState')
|
2025-08-26 10:27:26 -04:00
|
|
|
->willReturnCallback(function ($key, $data) use ($invokedCountProvideInitialState): void {
|
2024-04-01 15:30:47 -04:00
|
|
|
if ($invokedCountProvideInitialState->numberOfInvocations() === 9) {
|
|
|
|
|
$this->assertEquals('isTwoFactorEnabled', $key);
|
|
|
|
|
$this->assertTrue($data);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-09-09 05:03:34 -04:00
|
|
|
$this->config
|
|
|
|
|
->method('getUserValue')
|
|
|
|
|
->willReturnMap([
|
|
|
|
|
[$this->user->getUID(), 'files', 'files_sorting_configs', '{}', '{}'],
|
|
|
|
|
]);
|
|
|
|
|
|
2024-04-01 15:30:47 -04:00
|
|
|
$this->viewController->index('', '', null);
|
|
|
|
|
}
|
2015-11-16 14:57:41 -05:00
|
|
|
}
|