2016-08-30 10:03:06 +03:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
|
|
|
*
|
2017-11-06 17:56:42 +03:00
|
|
|
* @author Jan-Christoph Borchardt <hey@jancborchardt.net>
|
2019-12-03 21:57:53 +03:00
|
|
|
* @author Joas Schilling <coding@schilljs.com>
|
2017-11-06 17:56:42 +03:00
|
|
|
* @author Julius Haertl <jus@bitgrid.net>
|
2016-08-30 10:03:06 +03:00
|
|
|
* @author Julius Härtl <jus@bitgrid.net>
|
2019-12-03 21:57:53 +03:00
|
|
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
2016-08-30 10:03: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-08-30 10:03: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-08-30 10:03: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-08-30 10:03:06 +03:00
|
|
|
*
|
|
|
|
*/
|
2019-11-22 22:52:10 +03:00
|
|
|
|
2016-08-30 10:03:06 +03:00
|
|
|
namespace OCA\Theming\Tests;
|
|
|
|
|
2018-05-08 21:59:31 +03:00
|
|
|
use OC\Files\AppData\AppData;
|
2016-08-30 10:03:06 +03:00
|
|
|
use OCA\Theming\IconBuilder;
|
2018-06-05 17:59:05 +03:00
|
|
|
use OCA\Theming\ImageManager;
|
2016-08-30 10:03:06 +03:00
|
|
|
use OCA\Theming\ThemingDefaults;
|
|
|
|
use OCA\Theming\Util;
|
2016-11-18 12:49:03 +03:00
|
|
|
use OCP\App\IAppManager;
|
2017-05-15 00:52:14 +03:00
|
|
|
use OCP\Files\NotFoundException;
|
2016-08-30 10:03:06 +03:00
|
|
|
use OCP\IConfig;
|
2018-01-24 20:10:16 +03:00
|
|
|
use PHPUnit\Framework\Error\Warning;
|
2016-08-30 10:03:06 +03:00
|
|
|
use Test\TestCase;
|
|
|
|
|
|
|
|
class IconBuilderTest extends TestCase {
|
|
|
|
|
|
|
|
/** @var IConfig */
|
|
|
|
protected $config;
|
2018-05-08 21:59:31 +03:00
|
|
|
/** @var AppData */
|
2017-05-15 00:52:14 +03:00
|
|
|
protected $appData;
|
2016-08-30 10:03:06 +03:00
|
|
|
/** @var ThemingDefaults */
|
|
|
|
protected $themingDefaults;
|
|
|
|
/** @var Util */
|
|
|
|
protected $util;
|
2018-06-05 17:59:05 +03:00
|
|
|
/** @var ImageManager */
|
|
|
|
protected $imageManager;
|
2016-08-30 10:03:06 +03:00
|
|
|
/** @var IconBuilder */
|
|
|
|
protected $iconBuilder;
|
2016-11-18 12:49:03 +03:00
|
|
|
/** @var IAppManager */
|
|
|
|
protected $appManager;
|
2016-08-30 10:03:06 +03:00
|
|
|
|
2019-11-21 18:40:38 +03:00
|
|
|
protected function setUp(): void {
|
2016-08-30 10:03:06 +03:00
|
|
|
parent::setUp();
|
|
|
|
|
2018-06-05 17:59:05 +03:00
|
|
|
$this->config = $this->createMock(IConfig::class);
|
2018-05-08 21:59:31 +03:00
|
|
|
$this->appData = $this->createMock(AppData::class);
|
2018-06-05 17:59:05 +03:00
|
|
|
$this->themingDefaults = $this->createMock(ThemingDefaults::class);
|
|
|
|
$this->appManager = $this->createMock(IAppManager::class);
|
|
|
|
$this->imageManager = $this->createMock(ImageManager::class);
|
2017-05-15 00:52:14 +03:00
|
|
|
$this->util = new Util($this->config, $this->appManager, $this->appData);
|
2018-06-05 17:59:05 +03:00
|
|
|
$this->iconBuilder = new IconBuilder($this->themingDefaults, $this->util, $this->imageManager);
|
2016-09-18 21:15:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private function checkImagick() {
|
2020-04-10 15:19:56 +03:00
|
|
|
if (!extension_loaded('imagick')) {
|
2016-08-30 10:03:06 +03: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.');
|
|
|
|
}
|
2017-09-12 13:05:03 +03:00
|
|
|
if (count($checkImagick->queryFormats('PNG')) < 1) {
|
|
|
|
$this->markTestSkipped('No PNG provider present.');
|
|
|
|
}
|
2016-08-30 10:03:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function dataRenderAppIcon() {
|
|
|
|
return [
|
|
|
|
['core', '#0082c9', 'touch-original.png'],
|
|
|
|
['core', '#FF0000', 'touch-core-red.png'],
|
|
|
|
['testing', '#FF0000', 'touch-testing-red.png'],
|
|
|
|
['comments', '#0082c9', 'touch-comments.png'],
|
|
|
|
['core', '#0082c9', 'touch-original-png.png'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataRenderAppIcon
|
|
|
|
* @param $app
|
|
|
|
* @param $color
|
|
|
|
* @param $file
|
|
|
|
*/
|
|
|
|
public function testRenderAppIcon($app, $color, $file) {
|
2016-09-18 21:15:06 +03:00
|
|
|
$this->checkImagick();
|
2016-08-30 10:03:06 +03:00
|
|
|
$this->themingDefaults->expects($this->once())
|
2017-03-28 02:37:47 +03:00
|
|
|
->method('getColorPrimary')
|
2016-08-30 10:03:06 +03:00
|
|
|
->willReturn($color);
|
2017-05-15 00:52:14 +03:00
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willThrowException(new NotFoundException());
|
2016-08-30 10:03:06 +03:00
|
|
|
|
|
|
|
$expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
|
2016-12-04 15:02:17 +03:00
|
|
|
$icon = $this->iconBuilder->renderAppIcon($app, 512);
|
2016-08-30 10:03:06 +03:00
|
|
|
|
|
|
|
$this->assertEquals(true, $icon->valid());
|
|
|
|
$this->assertEquals(512, $icon->getImageWidth());
|
|
|
|
$this->assertEquals(512, $icon->getImageHeight());
|
|
|
|
$this->assertEquals($icon, $expectedIcon);
|
|
|
|
$icon->destroy();
|
|
|
|
$expectedIcon->destroy();
|
2016-08-30 12:51:48 +03:00
|
|
|
// FIXME: We may need some comparison of the generated and the test images
|
|
|
|
// cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
|
2016-08-30 10:03:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataRenderAppIcon
|
|
|
|
* @param $app
|
|
|
|
* @param $color
|
|
|
|
* @param $file
|
|
|
|
*/
|
|
|
|
public function testGetTouchIcon($app, $color, $file) {
|
2016-09-18 21:15:06 +03:00
|
|
|
$this->checkImagick();
|
2016-08-30 10:03:06 +03:00
|
|
|
$this->themingDefaults->expects($this->once())
|
2017-03-28 02:37:47 +03:00
|
|
|
->method('getColorPrimary')
|
2016-08-30 10:03:06 +03:00
|
|
|
->willReturn($color);
|
2018-05-08 21:59:31 +03:00
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willThrowException(new NotFoundException());
|
2016-08-30 10:03:06 +03:00
|
|
|
|
|
|
|
$expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
|
|
|
|
$icon = new \Imagick();
|
|
|
|
$icon->readImageBlob($this->iconBuilder->getTouchIcon($app));
|
|
|
|
|
|
|
|
$this->assertEquals(true, $icon->valid());
|
|
|
|
$this->assertEquals(512, $icon->getImageWidth());
|
|
|
|
$this->assertEquals(512, $icon->getImageHeight());
|
|
|
|
$this->assertEquals($icon, $expectedIcon);
|
|
|
|
$icon->destroy();
|
|
|
|
$expectedIcon->destroy();
|
2016-08-30 12:51:48 +03:00
|
|
|
// FIXME: We may need some comparison of the generated and the test images
|
|
|
|
// cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
|
2016-08-30 10:03:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataRenderAppIcon
|
|
|
|
* @param $app
|
|
|
|
* @param $color
|
|
|
|
* @param $file
|
|
|
|
*/
|
|
|
|
public function testGetFavicon($app, $color, $file) {
|
2016-09-18 21:15:06 +03:00
|
|
|
$this->checkImagick();
|
2018-06-05 17:59:05 +03:00
|
|
|
$this->imageManager->expects($this->once())
|
2017-09-23 12:35:45 +03:00
|
|
|
->method('shouldReplaceIcons')
|
|
|
|
->willReturn(true);
|
2016-08-30 10:03:06 +03:00
|
|
|
$this->themingDefaults->expects($this->once())
|
2017-03-28 02:37:47 +03:00
|
|
|
->method('getColorPrimary')
|
2016-08-30 10:03:06 +03:00
|
|
|
->willReturn($color);
|
2018-05-08 21:59:31 +03:00
|
|
|
$this->appData->expects($this->once())
|
|
|
|
->method('getFolder')
|
|
|
|
->with('images')
|
|
|
|
->willThrowException(new NotFoundException());
|
2016-08-30 10:03:06 +03:00
|
|
|
|
|
|
|
$expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
|
2017-09-23 12:35:45 +03:00
|
|
|
$actualIcon = $this->iconBuilder->getFavicon($app);
|
|
|
|
|
2016-08-30 10:03:06 +03:00
|
|
|
$icon = new \Imagick();
|
2017-09-23 12:35:45 +03:00
|
|
|
$icon->setFormat('ico');
|
|
|
|
$icon->readImageBlob($actualIcon);
|
2016-08-30 10:03:06 +03:00
|
|
|
|
|
|
|
$this->assertEquals(true, $icon->valid());
|
2017-09-23 12:35:45 +03:00
|
|
|
$this->assertEquals(128, $icon->getImageWidth());
|
|
|
|
$this->assertEquals(128, $icon->getImageHeight());
|
2016-08-30 10:03:06 +03:00
|
|
|
$icon->destroy();
|
|
|
|
$expectedIcon->destroy();
|
2016-08-30 12:51:48 +03:00
|
|
|
// FIXME: We may need some comparison of the generated and the test images
|
|
|
|
// cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
|
2016-08-30 10:03:06 +03:00
|
|
|
}
|
|
|
|
|
2016-11-05 22:11:49 +03:00
|
|
|
public function testGetFaviconNotFound() {
|
2017-09-23 12:35:45 +03:00
|
|
|
$this->checkImagick();
|
2018-01-24 20:10:16 +03:00
|
|
|
$this->expectException(Warning::class);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
|
2018-06-05 17:59:05 +03:00
|
|
|
$iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
|
|
|
|
$this->imageManager->expects($this->once())
|
2017-09-23 12:35:45 +03:00
|
|
|
->method('shouldReplaceIcons')
|
|
|
|
->willReturn(true);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util->expects($this->once())
|
|
|
|
->method('getAppIcon')
|
|
|
|
->willReturn('notexistingfile');
|
|
|
|
$this->assertFalse($iconBuilder->getFavicon('noapp'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetTouchIconNotFound() {
|
2017-09-23 12:35:45 +03:00
|
|
|
$this->checkImagick();
|
2018-01-24 20:10:16 +03:00
|
|
|
$this->expectException(Warning::class);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
|
2018-06-05 17:59:05 +03:00
|
|
|
$iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util->expects($this->once())
|
|
|
|
->method('getAppIcon')
|
|
|
|
->willReturn('notexistingfile');
|
|
|
|
$this->assertFalse($iconBuilder->getTouchIcon('noapp'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testColorSvgNotFound() {
|
2017-09-23 12:35:45 +03:00
|
|
|
$this->checkImagick();
|
2018-01-24 20:10:16 +03:00
|
|
|
$this->expectException(Warning::class);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
|
2018-06-05 17:59:05 +03:00
|
|
|
$iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
|
2016-11-05 22:11:49 +03:00
|
|
|
$util->expects($this->once())
|
|
|
|
->method('getAppImage')
|
|
|
|
->willReturn('notexistingfile');
|
|
|
|
$this->assertFalse($iconBuilder->colorSvg('noapp','noimage'));
|
|
|
|
}
|
2016-08-30 10:03:06 +03:00
|
|
|
}
|