2016-09-18 21:15:06 +03:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
|
|
|
*
|
2020-04-29 12:57:22 +03:00
|
|
|
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
2017-11-06 17:56:42 +03:00
|
|
|
* @author Julius Haertl <jus@bitgrid.net>
|
2019-12-03 21:57:53 +03:00
|
|
|
* @author Julius Härtl <jus@bitgrid.net>
|
|
|
|
* @author Michael Weimann <mail@michael-weimann.eu>
|
2020-08-24 15:54:25 +03:00
|
|
|
* @author Morris Jobke <hey@morrisjobke.de>
|
2019-12-03 21:57:53 +03:00
|
|
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
2016-09-18 21:15:06 +03:00
|
|
|
*
|
|
|
|
* @license GNU AGPL version 3 or any later version
|
|
|
|
*
|
2017-11-06 17:56:42 +03:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
2016-09-18 21:15:06 +03:00
|
|
|
*
|
2017-11-06 17:56:42 +03:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
2016-09-18 21:15:06 +03:00
|
|
|
*
|
2017-11-06 17:56:42 +03:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
2019-12-03 21:57:53 +03:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2016-09-18 21:15:06 +03:00
|
|
|
*
|
|
|
|
*/
|
2019-11-22 22:52:10 +03:00
|
|
|
|
2016-09-18 21:15:06 +03:00
|
|
|
namespace OCA\Theming\Tests;
|
|
|
|
|
2018-03-28 15:56:31 +03:00
|
|
|
use OCA\Theming\ImageManager;
|
2019-11-22 22:52:10 +03:00
|
|
|
use OCP\Files\IAppData;
|
|
|
|
use OCP\Files\NotFoundException;
|
2016-09-18 21:15:06 +03:00
|
|
|
use OCP\Files\SimpleFS\ISimpleFile;
|
2019-11-22 22:52:10 +03:00
|
|
|
use OCP\Files\SimpleFS\ISimpleFolder;
|
2018-05-08 13:40:20 +03:00
|
|
|
use OCP\ICacheFactory;
|
2016-09-18 21:15:06 +03:00
|
|
|
use OCP\IConfig;
|
2018-06-14 17:55:44 +03:00
|
|
|
use OCP\ILogger;
|
2020-09-24 09:20:03 +03:00
|
|
|
use OCP\ITempManager;
|
2018-03-28 15:56:31 +03:00
|
|
|
use OCP\IURLGenerator;
|
2020-09-24 09:20:03 +03:00
|
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
2016-09-18 21:15:06 +03:00
|
|
|
use Test\TestCase;
|
|
|
|
|
2018-03-28 15:56:31 +03:00
|
|
|
class ImageManagerTest extends TestCase {
|
2016-09-18 21:15:06 +03:00
|
|
|
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var IConfig|MockObject */
|
2016-09-18 21:15:06 +03:00
|
|
|
protected $config;
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var IAppData|MockObject */
|
2016-09-18 21:15:06 +03:00
|
|
|
protected $appData;
|
|
|
|
/** @var ImageManager */
|
|
|
|
protected $imageManager;
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var IURLGenerator|MockObject */
|
2018-03-28 15:56:31 +03:00
|
|
|
private $urlGenerator;
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var ICacheFactory|MockObject */
|
2018-05-08 13:40:20 +03:00
|
|
|
private $cacheFactory;
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var ILogger|MockObject */
|
2018-06-14 17:55:44 +03:00
|
|
|
private $logger;
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var ITempManager|MockObject */
|
|
|
|
private $tempManager;
|
2016-09-18 21:15:06 +03:00
|
|
|
|
2019-11-21 18:40:38 +03:00
|
|
|
protected function setUp(): void {
|
2016-09-18 21:15:06 +03:00
|
|
|
parent::setUp();
|
2018-03-28 15:56:31 +03:00
|
|
|
$this->config = $this->createMock(IConfig::class);
|
|
|
|
$this->appData = $this->createMock(IAppData::class);
|
|
|
|
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
2018-06-14 17:55:44 +03:00
|
|
|
$this->logger = $this->createMock(ILogger::class);
|
2020-09-24 09:20:03 +03:00
|
|
|
$this->tempManager = $this->createMock(ITempManager::class);
|
2018-03-28 15:56:31 +03:00
|
|
|
$this->imageManager = new ImageManager(
|
2016-09-18 21:15:06 +03:00
|
|
|
$this->config,
|
2018-03-28 15:56:31 +03:00
|
|
|
$this->appData,
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->urlGenerator,
|
2018-06-14 17:55:44 +03:00
|
|
|
$this->cacheFactory,
|
2020-09-24 09:20:03 +03:00
|
|
|
$this->logger,
|
|
|
|
$this->tempManager
|
2016-09-18 21:15:06 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-05-08 13:40:20 +03:00
|
|
|
private function checkImagick() {
|
2020-04-10 15:19:56 +03:00
|
|
|
if (!extension_loaded('imagick')) {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
|
|
|
|
}
|
|
|
|
$checkImagick = new \Imagick();
|
2018-06-05 17:59:05 +03:00
|
|
|
if (empty($checkImagick->queryFormats('SVG'))) {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->markTestSkipped('No SVG provider present.');
|
|
|
|
}
|
2018-06-05 17:59:05 +03:00
|
|
|
if (empty($checkImagick->queryFormats('PNG'))) {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->markTestSkipped('No PNG provider present.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-10 12:14:27 +03:00
|
|
|
public function mockGetImage($key, $file) {
|
2020-09-24 09:20:03 +03:00
|
|
|
/** @var MockObject $folder */
|
2018-04-10 12:14:27 +03:00
|
|
|
$folder = $this->createMock(ISimpleFolder::class);
|
|
|
|
if ($file === null) {
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('getFile')
|
|
|
|
->with('logo')
|
|
|
|
->willThrowException(new NotFoundException());
|
|
|
|
} else {
|
2018-05-08 13:40:20 +03:00
|
|
|
$file->expects($this->once())
|
|
|
|
->method('getContent')
|
|
|
|
->willReturn(file_get_contents(__DIR__ . '/../../../tests/data/testimage.png'));
|
|
|
|
$folder->expects($this->at(0))
|
|
|
|
->method('fileExists')
|
|
|
|
->with('logo')
|
|
|
|
->willReturn(true);
|
|
|
|
$folder->expects($this->at(1))
|
|
|
|
->method('fileExists')
|
|
|
|
->with('logo.png')
|
|
|
|
->willReturn(false);
|
|
|
|
$folder->expects($this->at(2))
|
2018-04-10 12:14:27 +03:00
|
|
|
->method('getFile')
|
|
|
|
->with('logo')
|
|
|
|
->willReturn($file);
|
2018-05-08 13:40:20 +03:00
|
|
|
$newFile = $this->createMock(ISimpleFile::class);
|
|
|
|
$folder->expects($this->at(3))
|
|
|
|
->method('newFile')
|
|
|
|
->with('logo.png')
|
|
|
|
->willReturn($newFile);
|
|
|
|
$newFile->expects($this->once())
|
|
|
|
->method('putContent');
|
2018-04-10 12:14:27 +03:00
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willReturn($folder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetImageUrl() {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->checkImagick();
|
2018-04-10 12:14:27 +03:00
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$this->config->expects($this->exactly(2))
|
|
|
|
->method('getAppValue')
|
|
|
|
->withConsecutive(
|
|
|
|
['theming', 'cachebuster', '0'],
|
2018-05-08 13:40:20 +03:00
|
|
|
['theming', 'logoMime', '']
|
2018-04-10 12:14:27 +03:00
|
|
|
)
|
|
|
|
->willReturn(0);
|
|
|
|
$this->mockGetImage('logo', $file);
|
|
|
|
$this->urlGenerator->expects($this->once())
|
|
|
|
->method('linkToRoute')
|
|
|
|
->willReturn('url-to-image');
|
2018-05-08 14:06:31 +03:00
|
|
|
$this->assertEquals('url-to-image?v=0', $this->imageManager->getImageUrl('logo', false));
|
2018-04-10 12:14:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetImageUrlDefault() {
|
|
|
|
$this->config->expects($this->exactly(2))
|
|
|
|
->method('getAppValue')
|
|
|
|
->withConsecutive(
|
|
|
|
['theming', 'cachebuster', '0'],
|
|
|
|
['theming', 'logoMime', false]
|
|
|
|
)
|
|
|
|
->willReturnOnConsecutiveCalls(0, false);
|
|
|
|
$this->urlGenerator->expects($this->once())
|
|
|
|
->method('imagePath')
|
2018-08-28 16:58:27 +03:00
|
|
|
->with('core', 'logo/logo.png')
|
|
|
|
->willReturn('logo/logo.png');
|
|
|
|
$this->assertEquals('logo/logo.png?v=0', $this->imageManager->getImageUrl('logo'));
|
2018-04-10 12:14:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetImageUrlAbsolute() {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->checkImagick();
|
2018-04-10 12:14:27 +03:00
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$this->config->expects($this->exactly(2))
|
|
|
|
->method('getAppValue')
|
|
|
|
->withConsecutive(
|
|
|
|
['theming', 'cachebuster', '0'],
|
2018-05-08 13:40:20 +03:00
|
|
|
['theming', 'logoMime', '']
|
2018-04-10 12:14:27 +03:00
|
|
|
)
|
|
|
|
->willReturn(0);
|
|
|
|
$this->mockGetImage('logo', $file);
|
|
|
|
$this->urlGenerator->expects($this->at(0))
|
2018-05-08 13:40:20 +03:00
|
|
|
->method('getBaseUrl')
|
|
|
|
->willReturn('baseurl');
|
2018-04-10 12:14:27 +03:00
|
|
|
$this->urlGenerator->expects($this->at(1))
|
|
|
|
->method('getAbsoluteUrl')
|
2018-05-08 13:40:20 +03:00
|
|
|
->willReturn('url-to-image-absolute?v=0');
|
|
|
|
$this->urlGenerator->expects($this->at(2))
|
|
|
|
->method('getAbsoluteUrl')
|
2018-04-10 12:14:27 +03:00
|
|
|
->willReturn('url-to-image-absolute?v=0');
|
2018-05-08 14:06:31 +03:00
|
|
|
$this->assertEquals('url-to-image-absolute?v=0', $this->imageManager->getImageUrlAbsolute('logo', false));
|
2018-04-10 12:14:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetImage() {
|
2018-05-08 13:40:20 +03:00
|
|
|
$this->checkImagick();
|
2018-04-10 12:14:27 +03:00
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')->with('theming', 'logoMime', false)
|
|
|
|
->willReturn('png');
|
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$this->mockGetImage('logo', $file);
|
2018-05-08 14:06:31 +03:00
|
|
|
$this->assertEquals($file, $this->imageManager->getImage('logo', false));
|
2018-04-10 12:14:27 +03:00
|
|
|
}
|
|
|
|
|
2020-08-11 22:32:18 +03:00
|
|
|
|
2018-04-10 12:14:27 +03:00
|
|
|
public function testGetImageUnset() {
|
2019-11-27 17:27:18 +03:00
|
|
|
$this->expectException(\OCP\Files\NotFoundException::class);
|
|
|
|
|
2018-04-10 12:14:27 +03:00
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')->with('theming', 'logoMime', false)
|
|
|
|
->willReturn(false);
|
|
|
|
$this->imageManager->getImage('logo');
|
|
|
|
}
|
|
|
|
|
2016-09-18 21:15:06 +03:00
|
|
|
public function testGetCacheFolder() {
|
|
|
|
$folder = $this->createMock(ISimpleFolder::class);
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('theming', 'cachebuster', '0')
|
|
|
|
->willReturn('0');
|
|
|
|
$this->appData->expects($this->at(0))
|
|
|
|
->method('getFolder')
|
|
|
|
->with('0')
|
|
|
|
->willReturn($folder);
|
|
|
|
$this->assertEquals($folder, $this->imageManager->getCacheFolder());
|
|
|
|
}
|
|
|
|
public function testGetCacheFolderCreate() {
|
|
|
|
$folder = $this->createMock(ISimpleFolder::class);
|
|
|
|
$this->config->expects($this->exactly(2))
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('theming', 'cachebuster', '0')
|
|
|
|
->willReturn('0');
|
|
|
|
$this->appData->expects($this->at(0))
|
|
|
|
->method('getFolder')
|
|
|
|
->willThrowException(new NotFoundException());
|
|
|
|
$this->appData->expects($this->at(1))
|
|
|
|
->method('newFolder')
|
|
|
|
->with('0')
|
|
|
|
->willReturn($folder);
|
|
|
|
$this->appData->expects($this->at(2))
|
|
|
|
->method('getFolder')
|
|
|
|
->with('0')
|
|
|
|
->willReturn($folder);
|
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getDirectoryListing')
|
|
|
|
->willReturn([]);
|
|
|
|
$this->assertEquals($folder, $this->imageManager->getCacheFolder());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetCachedImage() {
|
2018-03-28 15:56:31 +03:00
|
|
|
$expected = $this->createMock(ISimpleFile::class);
|
2016-09-18 21:15:06 +03:00
|
|
|
$folder = $this->setupCacheFolder();
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('getFile')
|
|
|
|
->with('filename')
|
2018-03-28 15:56:31 +03:00
|
|
|
->willReturn($expected);
|
2016-09-18 21:15:06 +03:00
|
|
|
$this->assertEquals($expected, $this->imageManager->getCachedImage('filename'));
|
|
|
|
}
|
|
|
|
|
2020-08-11 22:32:18 +03:00
|
|
|
|
2016-09-18 21:15:06 +03:00
|
|
|
public function testGetCachedImageNotFound() {
|
2019-11-27 17:27:18 +03:00
|
|
|
$this->expectException(\OCP\Files\NotFoundException::class);
|
|
|
|
|
2016-09-18 21:15:06 +03:00
|
|
|
$folder = $this->setupCacheFolder();
|
|
|
|
$folder->expects($this->once())
|
2016-10-17 17:31:07 +03:00
|
|
|
->method('getFile')
|
2016-09-18 21:15:06 +03:00
|
|
|
->with('filename')
|
2016-10-17 17:31:07 +03:00
|
|
|
->will($this->throwException(new \OCP\Files\NotFoundException()));
|
|
|
|
$image = $this->imageManager->getCachedImage('filename');
|
2016-09-18 21:15:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetCachedImage() {
|
|
|
|
$folder = $this->setupCacheFolder();
|
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('fileExists')
|
|
|
|
->with('filename')
|
|
|
|
->willReturn(true);
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('getFile')
|
|
|
|
->with('filename')
|
|
|
|
->willReturn($file);
|
|
|
|
$file->expects($this->once())
|
|
|
|
->method('putContent')
|
|
|
|
->with('filecontent');
|
|
|
|
$this->assertEquals($file, $this->imageManager->setCachedImage('filename', 'filecontent'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetCachedImageCreate() {
|
|
|
|
$folder = $this->setupCacheFolder();
|
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('fileExists')
|
|
|
|
->with('filename')
|
|
|
|
->willReturn(false);
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('newFile')
|
|
|
|
->with('filename')
|
|
|
|
->willReturn($file);
|
|
|
|
$file->expects($this->once())
|
|
|
|
->method('putContent')
|
|
|
|
->with('filecontent');
|
|
|
|
$this->assertEquals($file, $this->imageManager->setCachedImage('filename', 'filecontent'));
|
|
|
|
}
|
|
|
|
|
|
|
|
private function setupCacheFolder() {
|
|
|
|
$folder = $this->createMock(ISimpleFolder::class);
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('theming', 'cachebuster', '0')
|
|
|
|
->willReturn('0');
|
|
|
|
$this->appData->expects($this->at(0))
|
|
|
|
->method('getFolder')
|
|
|
|
->with('0')
|
|
|
|
->willReturn($folder);
|
|
|
|
return $folder;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCleanup() {
|
|
|
|
$folders = [
|
|
|
|
$this->createMock(ISimpleFolder::class),
|
|
|
|
$this->createMock(ISimpleFolder::class),
|
|
|
|
$this->createMock(ISimpleFolder::class)
|
2020-04-09 10:22:29 +03:00
|
|
|
];
|
2016-09-18 21:15:06 +03:00
|
|
|
foreach ($folders as $index=>$folder) {
|
|
|
|
$folder->expects($this->any())
|
|
|
|
->method('getName')
|
|
|
|
->willReturn($index);
|
|
|
|
}
|
|
|
|
$folders[0]->expects($this->once())->method('delete');
|
|
|
|
$folders[1]->expects($this->once())->method('delete');
|
|
|
|
$folders[2]->expects($this->never())->method('delete');
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('theming','cachebuster','0')
|
|
|
|
->willReturn('2');
|
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getDirectoryListing')
|
|
|
|
->willReturn($folders);
|
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('2')
|
|
|
|
->willReturn($folders[2]);
|
|
|
|
$this->imageManager->cleanup();
|
|
|
|
}
|
2020-09-24 09:20:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
public function dataUpdateImage() {
|
|
|
|
return [
|
|
|
|
['background', __DIR__ . '/../../../tests/data/testimage.png', true, true],
|
|
|
|
['background', __DIR__ . '/../../../tests/data/testimage.png', false, true],
|
|
|
|
['background', __DIR__ . '/../../../tests/data/testimage.jpg', true, true],
|
|
|
|
['logo', __DIR__ . '/../../../tests/data/testimagelarge.svg', true, false],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataUpdateImage
|
|
|
|
*/
|
|
|
|
public function testUpdateImage($key, $tmpFile, $folderExists, $shouldConvert) {
|
|
|
|
$file = $this->createMock(ISimpleFile::class);
|
|
|
|
$folder = $this->createMock(ISimpleFolder::class);
|
|
|
|
$oldFile = $this->createMock(ISimpleFile::class);
|
|
|
|
$folder->expects($this->any())
|
|
|
|
->method('getFile')
|
|
|
|
->willReturn($oldFile);
|
|
|
|
if ($folderExists) {
|
|
|
|
$this->appData
|
|
|
|
->expects($this->any())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willReturn($folder);
|
|
|
|
} else {
|
|
|
|
$this->appData
|
|
|
|
->expects($this->any())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willThrowException(new NotFoundException());
|
|
|
|
$this->appData
|
|
|
|
->expects($this->any())
|
|
|
|
->method('newFolder')
|
|
|
|
->with('images')
|
|
|
|
->willReturn($folder);
|
|
|
|
}
|
|
|
|
$folder->expects($this->once())
|
|
|
|
->method('newFile')
|
|
|
|
->with($key)
|
|
|
|
->willReturn($file);
|
|
|
|
|
|
|
|
if ($shouldConvert) {
|
|
|
|
$this->tempManager->expects($this->once())
|
|
|
|
->method('getTemporaryFile')
|
|
|
|
->willReturn('/tmp/randomtempfile-theming');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->imageManager->updateImage($key, $tmpFile);
|
|
|
|
}
|
2016-09-18 21:15:06 +03:00
|
|
|
}
|