diff options
author | Morris Jobke <hey@morrisjobke.de> | 2016-11-18 15:35:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-18 15:35:34 +0100 |
commit | faee255ff47873ed2f8908c7d6b6e603ded11618 (patch) | |
tree | 87a46252211e9c0dbab91609e4115082401656ee /apps/theming/tests | |
parent | e8511660f01faeebcc692b57cabdacd97845da92 (diff) | |
parent | 2ab4d1e0a3f15af2b8f04edcf18b7fe3fc0be262 (diff) | |
download | nextcloud-server-faee255ff47873ed2f8908c7d6b6e603ded11618.tar.gz nextcloud-server-faee255ff47873ed2f8908c7d6b6e603ded11618.zip |
Merge pull request #840 from nextcloud/theming-icon-endpoint
Add dynamic icon creation
Diffstat (limited to 'apps/theming/tests')
-rw-r--r-- | apps/theming/tests/Controller/IconControllerTest.php | 201 | ||||
-rw-r--r-- | apps/theming/tests/Controller/ThemingControllerTest.php | 39 | ||||
-rw-r--r-- | apps/theming/tests/IconBuilderTest.php | 192 | ||||
-rw-r--r-- | apps/theming/tests/ImageManagerTest.php | 183 | ||||
-rw-r--r-- | apps/theming/tests/ThemingDefaultsTest.php | 7 | ||||
-rw-r--r-- | apps/theming/tests/UtilTest.php | 75 | ||||
-rw-r--r-- | apps/theming/tests/data/favicon-original.ico | bin | 0 -> 1618 bytes | |||
-rw-r--r-- | apps/theming/tests/data/touch-comments.png | bin | 0 -> 21814 bytes | |||
-rw-r--r-- | apps/theming/tests/data/touch-core-red.png | bin | 0 -> 23415 bytes | |||
-rw-r--r-- | apps/theming/tests/data/touch-original-png.png | bin | 0 -> 32785 bytes | |||
-rw-r--r-- | apps/theming/tests/data/touch-original.png | bin | 0 -> 29078 bytes | |||
-rw-r--r-- | apps/theming/tests/data/touch-testing-red.png | bin | 0 -> 23438 bytes |
12 files changed, 694 insertions, 3 deletions
diff --git a/apps/theming/tests/Controller/IconControllerTest.php b/apps/theming/tests/Controller/IconControllerTest.php new file mode 100644 index 00000000000..591c1075492 --- /dev/null +++ b/apps/theming/tests/Controller/IconControllerTest.php @@ -0,0 +1,201 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Theming\Tests\Controller; + + +use OC\Files\SimpleFS\SimpleFile; +use OCA\Theming\ImageManager; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\NotFoundResponse; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\IConfig; +use OCP\IRequest; +use Test\TestCase; +use OCA\Theming\Util; +use OCA\Theming\Controller\IconController; +use OCP\AppFramework\Http\FileDisplayResponse; + + +class IconControllerTest extends TestCase { + /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ + private $request; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + private $themingDefaults; + /** @var Util */ + private $util; + /** @var \OCP\AppFramework\Utility\ITimeFactory */ + private $timeFactory; + /** @var IconController|\PHPUnit_Framework_MockObject_MockObject */ + private $iconController; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */ + private $iconBuilder; + /** @var ImageManager */ + private $imageManager; + + public function setUp() { + $this->request = $this->getMockBuilder('OCP\IRequest')->getMock(); + $this->themingDefaults = $this->getMockBuilder('OCA\Theming\ThemingDefaults') + ->disableOriginalConstructor()->getMock(); + $this->util = $this->getMockBuilder('\OCA\Theming\Util')->disableOriginalConstructor() + ->setMethods(['getAppImage', 'getAppIcon', 'elementColor'])->getMock(); + $this->timeFactory = $this->getMockBuilder('OCP\AppFramework\Utility\ITimeFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->config = $this->getMockBuilder('OCP\IConfig')->getMock(); + $this->iconBuilder = $this->getMockBuilder('OCA\Theming\IconBuilder') + ->disableOriginalConstructor()->getMock(); + $this->imageManager = $this->getMockBuilder('OCA\Theming\ImageManager')->disableOriginalConstructor()->getMock(); + $this->timeFactory->expects($this->any()) + ->method('getTime') + ->willReturn(123); + + $this->iconController = new IconController( + 'theming', + $this->request, + $this->themingDefaults, + $this->util, + $this->timeFactory, + $this->config, + $this->iconBuilder, + $this->imageManager + ); + + parent::setUp(); + } + + private function iconFileMock($filename, $data) { + $icon = $this->getMockBuilder('OCP\Files\File')->getMock(); + $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'); + $icon->method('getName')->willReturn($filename); + return new SimpleFile($icon); + } + + public function testGetThemedIcon() { + $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']); + $expected->cacheFor(86400); + $expires = new \DateTime(); + $expires->setTimestamp($this->timeFactory->getTime()); + $expires->add(new \DateInterval('PT24H')); + $expected->addHeader('Expires', $expires->format(\DateTime::RFC2822)); + $expected->addHeader('Pragma', 'cache'); + @$this->assertEquals($expected, $this->iconController->getThemedIcon('core', 'filetypes/folder.svg')); + } + + public function testGetFaviconDefault() { + if (!extension_loaded('imagick')) { + $this->markTestSkipped('Imagemagick is required for dynamic icon generation.'); + } + $checkImagick = new \Imagick(); + if (count($checkImagick->queryFormats('SVG')) < 1) { + $this->markTestSkipped('No SVG provider present.'); + } + $this->themingDefaults->expects($this->any()) + ->method('shouldReplaceIcons') + ->willReturn(true); + + $this->iconBuilder->expects($this->once()) + ->method('getFavicon') + ->with('core') + ->willReturn('filecontent'); + $file = $this->iconFileMock('filename', 'filecontent'); + $this->imageManager->expects($this->once()) + ->method('getCachedImage') + ->will($this->throwException(new NotFoundException())); + $this->imageManager->expects($this->once()) + ->method('setCachedImage') + ->willReturn($file); + + $expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']); + $expected->cacheFor(86400); + $expires = new \DateTime(); + $expires->setTimestamp($this->timeFactory->getTime()); + $expires->add(new \DateInterval('PT24H')); + $expected->addHeader('Expires', $expires->format(\DateTime::RFC2822)); + $expected->addHeader('Pragma', 'cache'); + $this->assertEquals($expected, $this->iconController->getFavicon()); + } + + public function testGetFaviconFail() { + $this->themingDefaults->expects($this->any()) + ->method('shouldReplaceIcons') + ->willReturn(false); + $expected = new Http\Response(); + $expected->setStatus(Http::STATUS_NOT_FOUND); + $expected->cacheFor(0); + $expected->setLastModified(new \DateTime('now', new \DateTimeZone('GMT'))); + $this->assertInstanceOf(NotFoundResponse::class, $this->iconController->getFavicon()); + } + + public function testGetTouchIconDefault() { + if (!extension_loaded('imagick')) { + $this->markTestSkipped('Imagemagick is required for dynamic icon generation.'); + } + $checkImagick = new \Imagick(); + if (count($checkImagick->queryFormats('SVG')) < 1) { + $this->markTestSkipped('No SVG provider present.'); + } + $this->themingDefaults->expects($this->any()) + ->method('shouldReplaceIcons') + ->willReturn(true); + + $this->iconBuilder->expects($this->once()) + ->method('getTouchIcon') + ->with('core') + ->willReturn('filecontent'); + $file = $this->iconFileMock('filename', 'filecontent'); + $this->imageManager->expects($this->once()) + ->method('getCachedImage') + ->will($this->throwException(new NotFoundException())); + $this->imageManager->expects($this->once()) + ->method('setCachedImage') + ->willReturn($file); + + $expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/png']); + $expected->cacheFor(86400); + $expires = new \DateTime(); + $expires->setTimestamp($this->timeFactory->getTime()); + $expires->add(new \DateInterval('PT24H')); + $expected->addHeader('Expires', $expires->format(\DateTime::RFC2822)); + $expected->addHeader('Pragma', 'cache'); + $this->assertEquals($expected, $this->iconController->getTouchIcon()); + } + + public function testGetTouchIconFail() { + $this->themingDefaults->expects($this->any()) + ->method('shouldReplaceIcons') + ->willReturn(false); + $this->assertInstanceOf(NotFoundResponse::class, $this->iconController->getTouchIcon()); + } + +} diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php index c9f6ff8a885..d42e5afb245 100644 --- a/apps/theming/tests/Controller/ThemingControllerTest.php +++ b/apps/theming/tests/Controller/ThemingControllerTest.php @@ -26,6 +26,7 @@ namespace OCA\Theming\Tests\Controller; use OCA\Theming\Controller\ThemingController; use OCA\Theming\Util; +use OCP\App\IAppManager; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\Files\File; @@ -57,18 +58,21 @@ class ThemingControllerTest extends TestCase { private $rootFolder; /** @var ITempManager */ private $tempManager; + /** @var IAppManager */ + private $appManager; public function setUp() { $this->request = $this->getMockBuilder('OCP\IRequest')->getMock(); $this->config = $this->getMockBuilder('OCP\IConfig')->getMock(); $this->template = $this->getMockBuilder('OCA\Theming\ThemingDefaults') ->disableOriginalConstructor()->getMock(); - $this->util = new Util(); $this->timeFactory = $this->getMockBuilder('OCP\AppFramework\Utility\ITimeFactory') ->disableOriginalConstructor() ->getMock(); $this->l10n = $this->getMockBuilder('OCP\IL10N')->getMock(); $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); + $this->appManager = $this->getMockBuilder('OCP\App\IAppManager')->getMock(); + $this->util = new Util($this->config, $this->rootFolder, $this->appManager); $this->timeFactory->expects($this->any()) ->method('getTime') ->willReturn(123); @@ -484,6 +488,12 @@ class ThemingControllerTest extends TestCase { $expectedData .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color); $expectedData .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color); $expectedData .= '.nc-theming-contrast {color: #ffffff}' . "\n"; + $expectedData .= '.icon-file,.icon-filetype-text {' . + 'background-image: url(\'./img/core/filetypes/text.svg?v=0\');' . "}\n" . + '.icon-folder, .icon-filetype-folder {' . + 'background-image: url(\'./img/core/filetypes/folder.svg?v=0\');' . "}\n" . + '.icon-filetype-folder-drag-accept {' . + 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v=0\')!important;' . "}\n"; $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); @@ -578,6 +588,12 @@ class ThemingControllerTest extends TestCase { $expectedData .= '#body-login input.login { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/confirm.svg?v=2\'); }' . "\n"; $expectedData .= '.nc-theming-contrast {color: #000000}' . "\n"; $expectedData .= '.ui-widget-header { color: #000000; }' . "\n"; + $expectedData .= '.icon-file,.icon-filetype-text {' . + 'background-image: url(\'./img/core/filetypes/text.svg?v=0\');' . "}\n" . + '.icon-folder, .icon-filetype-folder {' . + 'background-image: url(\'./img/core/filetypes/folder.svg?v=0\');' . "}\n" . + '.icon-filetype-folder-drag-accept {' . + 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v=0\')!important;' . "}\n"; $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); @@ -623,6 +639,12 @@ class ThemingControllerTest extends TestCase { 'background-size: contain;' . '}' . "\n"; $expectedData .= '.nc-theming-contrast {color: #ffffff}' . "\n"; + $expectedData .= '.icon-file,.icon-filetype-text {' . + 'background-image: url(\'./img/core/filetypes/text.svg?v=0\');' . "}\n" . + '.icon-folder, .icon-filetype-folder {' . + 'background-image: url(\'./img/core/filetypes/folder.svg?v=0\');' . "}\n" . + '.icon-filetype-folder-drag-accept {' . + 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v=0\')!important;' . "}\n"; $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); @@ -765,6 +787,12 @@ class ThemingControllerTest extends TestCase { 'background-image: url(\'./loginbackground?v=0\');' . '}' . "\n"; $expectedData .= '.nc-theming-contrast {color: #ffffff}' . "\n"; + $expectedData .= '.icon-file,.icon-filetype-text {' . + 'background-image: url(\'./img/core/filetypes/text.svg?v=0\');' . "}\n" . + '.icon-folder, .icon-filetype-folder {' . + 'background-image: url(\'./img/core/filetypes/folder.svg?v=0\');' . "}\n" . + '.icon-filetype-folder-drag-accept {' . + 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v=0\')!important;' . "}\n"; $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); $expected->cacheFor(3600); @@ -876,6 +904,13 @@ class ThemingControllerTest extends TestCase { $expectedData .= '#body-login input.login { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/confirm.svg?v=2\'); }' . "\n"; $expectedData .= '.nc-theming-contrast {color: #000000}' . "\n"; $expectedData .= '.ui-widget-header { color: #000000; }' . "\n"; + $expectedData .= '.icon-file,.icon-filetype-text {' . + 'background-image: url(\'./img/core/filetypes/text.svg?v=0\');' . "}\n" . + '.icon-folder, .icon-filetype-folder {' . + 'background-image: url(\'./img/core/filetypes/folder.svg?v=0\');' . "}\n" . + '.icon-filetype-folder-drag-accept {' . + 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v=0\')!important;' . "}\n"; + $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); $expected->cacheFor(3600); @@ -910,6 +945,7 @@ class ThemingControllerTest extends TestCase { slogan: "", color: "#000", inverted: false, + cacheBuster: null }; })();'; $expected = new Http\DataDisplayResponse($expectedResponse); @@ -944,6 +980,7 @@ class ThemingControllerTest extends TestCase { slogan: "awesome", color: "#ffffff", inverted: true, + cacheBuster: null }; })();'; $expected = new Http\DataDisplayResponse($expectedResponse); diff --git a/apps/theming/tests/IconBuilderTest.php b/apps/theming/tests/IconBuilderTest.php new file mode 100644 index 00000000000..54850c8f3c2 --- /dev/null +++ b/apps/theming/tests/IconBuilderTest.php @@ -0,0 +1,192 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Theming\Tests; + +use OCA\Theming\IconBuilder; +use OCA\Theming\ThemingDefaults; +use OCA\Theming\Util; +use OCP\App\IAppManager; +use OCP\AppFramework\Http\NotFoundResponse; +use OCP\Files\IRootFolder; +use OCP\IConfig; +use Test\TestCase; + +class IconBuilderTest extends TestCase { + + /** @var IConfig */ + protected $config; + /** @var IRootFolder */ + protected $rootFolder; + /** @var ThemingDefaults */ + protected $themingDefaults; + /** @var Util */ + protected $util; + /** @var IconBuilder */ + protected $iconBuilder; + /** @var IAppManager */ + protected $appManager; + + protected function setUp() { + parent::setUp(); + + $this->config = $this->getMockBuilder('\OCP\IConfig')->getMock(); + $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); + $this->themingDefaults = $this->getMockBuilder('OCA\Theming\ThemingDefaults') + ->disableOriginalConstructor()->getMock(); + $this->appManager = $this->getMockBuilder('OCP\App\IAppManager')->getMock(); + $this->util = new Util($this->config, $this->rootFolder, $this->appManager); + $this->iconBuilder = new IconBuilder($this->themingDefaults, $this->util); + } + + private function checkImagick() { + if(!extension_loaded('imagick')) { + $this->markTestSkipped('Imagemagick is required for dynamic icon generation.'); + } + $checkImagick = new \Imagick(); + if (count($checkImagick->queryFormats('SVG')) < 1) { + $this->markTestSkipped('No SVG provider present.'); + } + } + + 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) { + $this->checkImagick(); + $this->themingDefaults->expects($this->once()) + ->method('getMailHeaderColor') + ->willReturn($color); + + $expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file); + $icon = $this->iconBuilder->renderAppIcon($app); + + $this->assertEquals(true, $icon->valid()); + $this->assertEquals(512, $icon->getImageWidth()); + $this->assertEquals(512, $icon->getImageHeight()); + $this->assertEquals($icon, $expectedIcon); + $icon->destroy(); + $expectedIcon->destroy(); + // FIXME: We may need some comparison of the generated and the test images + // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1]) + } + + /** + * @dataProvider dataRenderAppIcon + * @param $app + * @param $color + * @param $file + */ + public function testGetTouchIcon($app, $color, $file) { + $this->checkImagick(); + $this->themingDefaults->expects($this->once()) + ->method('getMailHeaderColor') + ->willReturn($color); + + $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(); + // FIXME: We may need some comparison of the generated and the test images + // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1]) + } + + /** + * @dataProvider dataRenderAppIcon + * @param $app + * @param $color + * @param $file + */ + public function testGetFavicon($app, $color, $file) { + $this->checkImagick(); + $this->themingDefaults->expects($this->once()) + ->method('getMailHeaderColor') + ->willReturn($color); + + $expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file); + $icon = new \Imagick(); + $icon->readImageBlob($this->iconBuilder->getFavicon($app)); + + $this->assertEquals(true, $icon->valid()); + $this->assertEquals(32, $icon->getImageWidth()); + $this->assertEquals(32, $icon->getImageHeight()); + $icon->destroy(); + $expectedIcon->destroy(); + // FIXME: We may need some comparison of the generated and the test images + // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1]) + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + */ + public function testGetFaviconNotFound() { + $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock(); + $iconBuilder = new IconBuilder($this->themingDefaults, $util); + $util->expects($this->once()) + ->method('getAppIcon') + ->willReturn('notexistingfile'); + $this->assertFalse($iconBuilder->getFavicon('noapp')); + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + */ + public function testGetTouchIconNotFound() { + $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock(); + $iconBuilder = new IconBuilder($this->themingDefaults, $util); + $util->expects($this->once()) + ->method('getAppIcon') + ->willReturn('notexistingfile'); + $this->assertFalse($iconBuilder->getTouchIcon('noapp')); + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + */ + public function testColorSvgNotFound() { + $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock(); + $iconBuilder = new IconBuilder($this->themingDefaults, $util); + $util->expects($this->once()) + ->method('getAppImage') + ->willReturn('notexistingfile'); + $this->assertFalse($iconBuilder->colorSvg('noapp','noimage')); + } +} diff --git a/apps/theming/tests/ImageManagerTest.php b/apps/theming/tests/ImageManagerTest.php new file mode 100644 index 00000000000..4df49633d80 --- /dev/null +++ b/apps/theming/tests/ImageManagerTest.php @@ -0,0 +1,183 @@ +<?php +/** + * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Theming\Tests; + +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\IConfig; +use Test\TestCase; +use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; + +class ImageManager extends TestCase { + + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ + protected $appData; + /** @var ImageManager */ + protected $imageManager; + + protected function setUp() { + parent::setUp(); + $this->config = $this->getMockBuilder('\OCP\IConfig')->getMock(); + $this->appData = $this->getMockBuilder('OCP\Files\IAppData')->getMock(); + $this->imageManager = new \OCA\Theming\ImageManager( + $this->config, + $this->appData + ); + } + + 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() { + $folder = $this->setupCacheFolder(); + $folder->expects($this->once()) + ->method('getFile') + ->with('filename') + ->willReturn('filecontent'); + $expected = 'filecontent'; + $this->assertEquals($expected, $this->imageManager->getCachedImage('filename')); + } + + /** + * @expectedException \OCP\Files\NotFoundException + */ + public function testGetCachedImageNotFound() { + $folder = $this->setupCacheFolder(); + $folder->expects($this->once()) + ->method('getFile') + ->with('filename') + ->will($this->throwException(new \OCP\Files\NotFoundException())); + $image = $this->imageManager->getCachedImage('filename'); + } + + 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) + ]; + 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(); + } + +} diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php index 204c96d86d5..cd3a90e760a 100644 --- a/apps/theming/tests/ThemingDefaultsTest.php +++ b/apps/theming/tests/ThemingDefaultsTest.php @@ -24,6 +24,7 @@ namespace OCA\Theming\Tests; use OCA\Theming\ThemingDefaults; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IL10N; use OCP\IURLGenerator; @@ -43,6 +44,8 @@ class ThemingDefaultsTest extends TestCase { private $template; /** @var IRootFolder */ private $rootFolder; + /** @var ICacheFactory */ + private $cacheFactory; public function setUp() { parent::setUp(); @@ -52,6 +55,7 @@ class ThemingDefaultsTest extends TestCase { $this->rootFolder = $this->getMockBuilder(IRootFolder::class) ->disableOriginalConstructor() ->getMock(); + $this->cacheFactory = $this->getMockBuilder(ICacheFactory::class)->getMock(); $this->defaults = $this->getMockBuilder(\OC_Defaults::class) ->disableOriginalConstructor() ->getMock(); @@ -76,7 +80,8 @@ class ThemingDefaultsTest extends TestCase { $this->l10n, $this->urlGenerator, $this->defaults, - $this->rootFolder + $this->rootFolder, + $this->cacheFactory ); } diff --git a/apps/theming/tests/UtilTest.php b/apps/theming/tests/UtilTest.php index c7fc385d25d..83895208fea 100644 --- a/apps/theming/tests/UtilTest.php +++ b/apps/theming/tests/UtilTest.php @@ -23,16 +23,28 @@ namespace OCA\Theming\Tests; use OCA\Theming\Util; +use OCP\App\IAppManager; +use OCP\IConfig; +use OCP\Files\IRootFolder; use Test\TestCase; class UtilTest extends TestCase { /** @var Util */ protected $util; + /** @var IConfig */ + protected $config; + /** @var IRootFolder */ + protected $rootFolder; + /** @var IAppManager */ + protected $appManager; protected function setUp() { parent::setUp(); - $this->util = new Util(); + $this->config = $this->getMockBuilder('\OCP\IConfig')->getMock(); + $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); + $this->appManager = $this->getMockBuilder('OCP\App\IAppManager')->getMock(); + $this->util = new Util($this->config, $this->rootFolder, $this->appManager); } public function testInvertTextColorLight() { @@ -89,9 +101,70 @@ class UtilTest extends TestCase { $expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiNmZmZmZmYiLz48L3N2Zz4='; $this->assertEquals($expected, $button); } + public function testGenerateRadioButtonBlack() { $button = $this->util->generateRadioButton('#000000'); $expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiMwMDAwMDAiLz48L3N2Zz4='; $this->assertEquals($expected, $button); } + + /** + * @dataProvider dataGetAppIcon + */ + public function testGetAppIcon($app, $expected) { + $this->appManager->expects($this->once()) + ->method('getAppPath') + ->with($app) + ->willReturn(\OC_App::getAppPath($app)); + $icon = $this->util->getAppIcon($app); + $this->assertEquals($expected, $icon); + } + + public function dataGetAppIcon() { + return [ + ['user_ldap', \OC_App::getAppPath('user_ldap') . '/img/app.svg'], + ['noapplikethis', \OC::$SERVERROOT . '/core/img/logo.svg'], + ['comments', \OC_App::getAppPath('comments') . '/img/comments.svg'], + ]; + } + + public function testGetAppIconThemed() { + $this->rootFolder->expects($this->once()) + ->method('nodeExists') + ->with('/themedinstancelogo') + ->willReturn(true); + $expected = '/themedinstancelogo'; + $icon = $this->util->getAppIcon('noapplikethis'); + $this->assertEquals($expected, $icon); + } + + /** + * @dataProvider dataGetAppImage + */ + public function testGetAppImage($app, $image, $expected) { + if($app !== 'core') { + $this->appManager->expects($this->once()) + ->method('getAppPath') + ->with($app) + ->willReturn(\OC_App::getAppPath($app)); + } + $this->assertEquals($expected, $this->util->getAppImage($app, $image)); + } + + public function dataGetAppImage() { + return [ + ['core', 'logo.svg', \OC::$SERVERROOT . '/core/img/logo.svg'], + ['files', 'external', \OC::$SERVERROOT . '/apps/files/img/external.svg'], + ['files', 'external.svg', \OC::$SERVERROOT . '/apps/files/img/external.svg'], + ['noapplikethis', 'foobar.svg', false], + ]; + } + + public function testColorizeSvg() { + $input = "#0082c9 #0082C9 #000000 #FFFFFF"; + $expected = "#AAAAAA #AAAAAA #000000 #FFFFFF"; + $result = $this->util->colorizeSvg($input, '#AAAAAA'); + $this->assertEquals($expected, $result); + } + } diff --git a/apps/theming/tests/data/favicon-original.ico b/apps/theming/tests/data/favicon-original.ico Binary files differnew file mode 100644 index 00000000000..fab2f7f0231 --- /dev/null +++ b/apps/theming/tests/data/favicon-original.ico diff --git a/apps/theming/tests/data/touch-comments.png b/apps/theming/tests/data/touch-comments.png Binary files differnew file mode 100644 index 00000000000..af0d2ca579b --- /dev/null +++ b/apps/theming/tests/data/touch-comments.png diff --git a/apps/theming/tests/data/touch-core-red.png b/apps/theming/tests/data/touch-core-red.png Binary files differnew file mode 100644 index 00000000000..7a492f10e21 --- /dev/null +++ b/apps/theming/tests/data/touch-core-red.png diff --git a/apps/theming/tests/data/touch-original-png.png b/apps/theming/tests/data/touch-original-png.png Binary files differnew file mode 100644 index 00000000000..6997dfc6b88 --- /dev/null +++ b/apps/theming/tests/data/touch-original-png.png diff --git a/apps/theming/tests/data/touch-original.png b/apps/theming/tests/data/touch-original.png Binary files differnew file mode 100644 index 00000000000..ac39872aa6e --- /dev/null +++ b/apps/theming/tests/data/touch-original.png diff --git a/apps/theming/tests/data/touch-testing-red.png b/apps/theming/tests/data/touch-testing-red.png Binary files differnew file mode 100644 index 00000000000..4cbdfbbb42c --- /dev/null +++ b/apps/theming/tests/data/touch-testing-red.png |