2016-08-25 10:26:28 -04:00
|
|
|
<?php
|
2025-05-20 17:04:05 -04:00
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2016-08-25 10:26:28 -04:00
|
|
|
/**
|
2024-05-30 14:13:41 -04:00
|
|
|
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
|
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
2016-08-25 10:26:28 -04:00
|
|
|
*/
|
|
|
|
|
namespace OCA\Theming\Tests\Controller;
|
|
|
|
|
|
2016-09-18 14:15:06 -04:00
|
|
|
use OC\Files\SimpleFS\SimpleFile;
|
2017-05-18 04:45:42 -04:00
|
|
|
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
2019-11-22 14:52:10 -05:00
|
|
|
use OCA\Theming\Controller\IconController;
|
2017-04-20 07:10:34 -04:00
|
|
|
use OCA\Theming\IconBuilder;
|
2016-09-18 14:15:06 -04:00
|
|
|
use OCA\Theming\ImageManager;
|
2017-04-20 07:10:34 -04:00
|
|
|
use OCA\Theming\ThemingDefaults;
|
2023-12-11 02:59:45 -05:00
|
|
|
use OCP\App\IAppManager;
|
2016-08-25 10:26:28 -04:00
|
|
|
use OCP\AppFramework\Http;
|
2017-05-14 17:48:51 -04:00
|
|
|
use OCP\AppFramework\Http\DataDisplayResponse;
|
2019-11-22 14:52:10 -05:00
|
|
|
use OCP\AppFramework\Http\FileDisplayResponse;
|
|
|
|
|
use OCP\AppFramework\Utility\ITimeFactory;
|
2026-01-07 08:21:48 -05:00
|
|
|
use OCP\Files\File;
|
2016-10-17 10:31:07 -04:00
|
|
|
use OCP\Files\NotFoundException;
|
2025-09-15 17:37:47 -04:00
|
|
|
use OCP\IConfig;
|
2016-08-25 10:26:28 -04:00
|
|
|
use OCP\IRequest;
|
2025-05-20 17:04:05 -04:00
|
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
2016-08-25 10:26:28 -04:00
|
|
|
use Test\TestCase;
|
|
|
|
|
|
2016-08-29 05:53:44 -04:00
|
|
|
class IconControllerTest extends TestCase {
|
2025-05-20 17:04:05 -04:00
|
|
|
private IRequest&MockObject $request;
|
|
|
|
|
private ThemingDefaults&MockObject $themingDefaults;
|
|
|
|
|
private ITimeFactory&MockObject $timeFactory;
|
|
|
|
|
private IconBuilder&MockObject $iconBuilder;
|
|
|
|
|
private FileAccessHelper&MockObject $fileAccessHelper;
|
|
|
|
|
private IAppManager&MockObject $appManager;
|
|
|
|
|
private ImageManager&MockObject $imageManager;
|
|
|
|
|
private IconController $iconController;
|
2025-09-15 17:37:47 -04:00
|
|
|
private IConfig&MockObject $config;
|
2016-08-25 10:26:28 -04:00
|
|
|
|
2019-11-27 09:27:18 -05:00
|
|
|
protected function setUp(): void {
|
2018-03-28 08:56:31 -04:00
|
|
|
$this->request = $this->createMock(IRequest::class);
|
|
|
|
|
$this->themingDefaults = $this->createMock(ThemingDefaults::class);
|
|
|
|
|
$this->iconBuilder = $this->createMock(IconBuilder::class);
|
|
|
|
|
$this->imageManager = $this->createMock(ImageManager::class);
|
2017-05-18 04:45:42 -04:00
|
|
|
$this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
|
2023-12-11 02:59:45 -05:00
|
|
|
$this->appManager = $this->createMock(IAppManager::class);
|
2025-09-15 17:37:47 -04:00
|
|
|
$this->config = $this->createMock(IConfig::class);
|
2018-06-13 16:54:08 -04:00
|
|
|
|
|
|
|
|
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
2016-08-25 10:26:28 -04:00
|
|
|
$this->timeFactory->expects($this->any())
|
|
|
|
|
->method('getTime')
|
|
|
|
|
->willReturn(123);
|
|
|
|
|
|
2018-06-13 16:54:08 -04:00
|
|
|
$this->overwriteService(ITimeFactory::class, $this->timeFactory);
|
|
|
|
|
|
2016-08-25 10:26:28 -04:00
|
|
|
$this->iconController = new IconController(
|
|
|
|
|
'theming',
|
|
|
|
|
$this->request,
|
2025-09-15 17:37:47 -04:00
|
|
|
$this->config,
|
2016-08-25 10:26:28 -04:00
|
|
|
$this->themingDefaults,
|
2016-09-18 14:15:06 -04:00
|
|
|
$this->iconBuilder,
|
2017-05-18 04:45:42 -04:00
|
|
|
$this->imageManager,
|
2023-12-11 02:59:45 -05:00
|
|
|
$this->fileAccessHelper,
|
|
|
|
|
$this->appManager,
|
2016-08-25 10:26:28 -04:00
|
|
|
);
|
|
|
|
|
|
2016-08-30 03:03:42 -04:00
|
|
|
parent::setUp();
|
2016-08-25 10:26:28 -04:00
|
|
|
}
|
|
|
|
|
|
2026-01-07 08:21:48 -05:00
|
|
|
private function iconFileMock($filename, $data): SimpleFile {
|
|
|
|
|
$icon = $this->createMock(File::class);
|
2016-09-18 14:15:06 -04:00
|
|
|
$icon->expects($this->any())->method('getContent')->willReturn($data);
|
|
|
|
|
$icon->expects($this->any())->method('getMimeType')->willReturn('image type');
|
|
|
|
|
$icon->expects($this->any())->method('getEtag')->willReturn('my etag');
|
2021-10-26 10:42:19 -04:00
|
|
|
$icon->expects($this->any())->method('getName')->willReturn('my name');
|
|
|
|
|
$icon->expects($this->any())->method('getMTime')->willReturn(42);
|
2016-09-18 14:15:06 -04:00
|
|
|
$icon->method('getName')->willReturn($filename);
|
|
|
|
|
return new SimpleFile($icon);
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-25 10:26:28 -04:00
|
|
|
public function testGetThemedIcon(): void {
|
2016-09-18 14:15:06 -04:00
|
|
|
$file = $this->iconFileMock('icon-core-filetypes_folder.svg', 'filecontent');
|
|
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getCachedImage')
|
|
|
|
|
->with('icon-core-filetypes_folder.svg')
|
|
|
|
|
->willReturn($file);
|
|
|
|
|
$expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
|
2022-02-11 16:14:04 -05:00
|
|
|
$expected->cacheFor(86400, false, true);
|
2017-04-20 07:10:34 -04:00
|
|
|
$this->assertEquals($expected, $this->iconController->getThemedIcon('core', 'filetypes/folder.svg'));
|
2016-08-25 10:26:28 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-15 17:37:47 -04:00
|
|
|
public function testGetFaviconThemed(): void {
|
2016-09-18 14:15:06 -04:00
|
|
|
if (!extension_loaded('imagick')) {
|
2016-08-30 03:03:42 -04:00
|
|
|
$this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
|
|
|
|
|
}
|
|
|
|
|
$checkImagick = new \Imagick();
|
|
|
|
|
if (count($checkImagick->queryFormats('SVG')) < 1) {
|
|
|
|
|
$this->markTestSkipped('No SVG provider present.');
|
|
|
|
|
}
|
2018-03-28 08:56:31 -04:00
|
|
|
$file = $this->iconFileMock('filename', 'filecontent');
|
|
|
|
|
$this->imageManager->expects($this->once())
|
2018-09-02 08:17:17 -04:00
|
|
|
->method('getImage', false)
|
2018-03-28 08:56:31 -04:00
|
|
|
->with('favicon')
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2018-06-05 10:59:05 -04:00
|
|
|
$this->imageManager->expects($this->any())
|
2025-09-15 17:37:47 -04:00
|
|
|
->method('canConvert')
|
|
|
|
|
->willReturnMap([
|
|
|
|
|
['SVG', true],
|
|
|
|
|
['PNG', true],
|
|
|
|
|
['ICO', true],
|
|
|
|
|
]);
|
2018-03-28 08:56:31 -04:00
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getCachedImage')
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2016-08-30 03:03:42 -04:00
|
|
|
$this->iconBuilder->expects($this->once())
|
|
|
|
|
->method('getFavicon')
|
2016-08-29 05:53:44 -04:00
|
|
|
->with('core')
|
2016-09-18 14:15:06 -04:00
|
|
|
->willReturn('filecontent');
|
|
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('setCachedImage')
|
|
|
|
|
->willReturn($file);
|
2016-08-30 03:03:42 -04:00
|
|
|
|
2016-09-18 14:15:06 -04:00
|
|
|
$expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
|
2016-08-25 10:26:28 -04:00
|
|
|
$expected->cacheFor(86400);
|
2016-09-18 14:15:06 -04:00
|
|
|
$this->assertEquals($expected, $this->iconController->getFavicon());
|
2016-08-25 10:26:28 -04:00
|
|
|
}
|
2016-09-18 14:15:06 -04:00
|
|
|
|
2025-09-15 17:37:47 -04:00
|
|
|
public function testGetFaviconDefault(): void {
|
2018-03-28 08:56:31 -04:00
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getImage')
|
2018-09-02 08:17:17 -04:00
|
|
|
->with('favicon', false)
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2018-06-05 10:59:05 -04:00
|
|
|
$this->imageManager->expects($this->any())
|
2025-09-15 17:37:47 -04:00
|
|
|
->method('canConvert')
|
|
|
|
|
->willReturnMap([
|
|
|
|
|
['SVG', false],
|
|
|
|
|
['PNG', false],
|
|
|
|
|
['ICO', false],
|
|
|
|
|
]);
|
2017-05-14 17:48:51 -04:00
|
|
|
$fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon.png';
|
2017-05-18 04:45:42 -04:00
|
|
|
$this->fileAccessHelper->expects($this->once())
|
|
|
|
|
->method('file_get_contents')
|
|
|
|
|
->with($fallbackLogo)
|
|
|
|
|
->willReturn(file_get_contents($fallbackLogo));
|
2025-09-15 17:37:47 -04:00
|
|
|
$expected = new DataDisplayResponse(file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/png']);
|
2017-05-14 17:48:51 -04:00
|
|
|
$expected->cacheFor(86400);
|
|
|
|
|
$this->assertEquals($expected, $this->iconController->getFavicon());
|
2016-09-18 14:15:06 -04:00
|
|
|
}
|
|
|
|
|
|
2016-08-25 10:26:28 -04:00
|
|
|
public function testGetTouchIconDefault(): void {
|
2016-09-18 14:15:06 -04:00
|
|
|
if (!extension_loaded('imagick')) {
|
2016-08-30 03:03:42 -04:00
|
|
|
$this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
|
|
|
|
|
}
|
|
|
|
|
$checkImagick = new \Imagick();
|
|
|
|
|
if (count($checkImagick->queryFormats('SVG')) < 1) {
|
|
|
|
|
$this->markTestSkipped('No SVG provider present.');
|
|
|
|
|
}
|
2018-06-05 10:59:05 -04:00
|
|
|
|
|
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getImage')
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2018-06-05 10:59:05 -04:00
|
|
|
$this->imageManager->expects($this->any())
|
2025-09-15 17:37:47 -04:00
|
|
|
->method('canConvert')
|
|
|
|
|
->with('PNG')
|
2016-08-30 03:03:42 -04:00
|
|
|
->willReturn(true);
|
|
|
|
|
$this->iconBuilder->expects($this->once())
|
|
|
|
|
->method('getTouchIcon')
|
2016-08-29 05:53:44 -04:00
|
|
|
->with('core')
|
2016-09-18 14:15:06 -04:00
|
|
|
->willReturn('filecontent');
|
|
|
|
|
$file = $this->iconFileMock('filename', 'filecontent');
|
2016-10-17 10:31:07 -04:00
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getCachedImage')
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2016-09-18 14:15:06 -04:00
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('setCachedImage')
|
|
|
|
|
->willReturn($file);
|
2016-08-25 10:26:28 -04:00
|
|
|
|
2016-09-18 14:15:06 -04:00
|
|
|
$expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/png']);
|
2016-08-25 10:26:28 -04:00
|
|
|
$expected->cacheFor(86400);
|
2016-09-18 14:15:06 -04:00
|
|
|
$this->assertEquals($expected, $this->iconController->getTouchIcon());
|
2016-08-25 10:26:28 -04:00
|
|
|
}
|
|
|
|
|
|
2016-08-30 03:03:42 -04:00
|
|
|
public function testGetTouchIconFail(): void {
|
2018-03-28 08:56:31 -04:00
|
|
|
$this->imageManager->expects($this->once())
|
|
|
|
|
->method('getImage')
|
|
|
|
|
->with('favicon')
|
2025-06-30 10:56:59 -04:00
|
|
|
->willThrowException(new NotFoundException());
|
2018-06-05 10:59:05 -04:00
|
|
|
$this->imageManager->expects($this->any())
|
2025-09-15 17:37:47 -04:00
|
|
|
->method('canConvert')
|
|
|
|
|
->with('PNG')
|
2016-08-30 03:03:42 -04:00
|
|
|
->willReturn(false);
|
2017-05-14 17:48:51 -04:00
|
|
|
$fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon-touch.png';
|
2017-05-18 04:45:42 -04:00
|
|
|
$this->fileAccessHelper->expects($this->once())
|
|
|
|
|
->method('file_get_contents')
|
|
|
|
|
->with($fallbackLogo)
|
|
|
|
|
->willReturn(file_get_contents($fallbackLogo));
|
2017-05-17 04:10:40 -04:00
|
|
|
$expected = new DataDisplayResponse(file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/png']);
|
2017-05-14 17:48:51 -04:00
|
|
|
$expected->cacheFor(86400);
|
|
|
|
|
$this->assertEquals($expected, $this->iconController->getTouchIcon());
|
2016-08-30 03:03:42 -04:00
|
|
|
}
|
2016-08-25 10:26:28 -04:00
|
|
|
}
|