Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v14.0.0beta1
* @since 11.0.0 | * @since 11.0.0 | ||||
*/ | */ | ||||
public function getIcon() { | public function getIcon() { | ||||
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar-dark.svg')); | |||||
return $this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar.svg')); | |||||
} | } | ||||
/** | /** |
public function testGetIcon() { | public function testGetIcon() { | ||||
$this->url->expects($this->once()) | $this->url->expects($this->once()) | ||||
->method('imagePath') | ->method('imagePath') | ||||
->with('core', 'places/calendar-dark.svg') | |||||
->with('core', 'places/calendar.svg') | |||||
->willReturn('path-to-icon'); | ->willReturn('path-to-icon'); | ||||
$this->url->expects($this->once()) | $this->url->expects($this->once()) |
do | do | ||||
FILE=$(basename $SCSSFILE) | FILE=$(basename $SCSSFILE) | ||||
FILENAME="${FILE%.*}" | FILENAME="${FILE%.*}" | ||||
printf "@import 'variables.scss'; @import '${FILE}';" | ./build/bin/node-sass --include-path core/css/ > tests/css/${FILE}.css | |||||
printf "\$webroot:''; @import 'functions.scss'; @import 'variables.scss'; @import '${FILE}';" | ./build/bin/node-sass --include-path core/css/ > tests/css/${FILE}.css | |||||
done | done | ||||
KARMA="$PREFIX/node_modules/karma/bin/karma" | KARMA="$PREFIX/node_modules/karma/bin/karma" |
*/ | */ | ||||
@mixin icon-color($icon, $dir, $color, $core: false) { | @mixin icon-color($icon, $dir, $color, $core: false) { | ||||
// remove # from color | // remove # from color | ||||
$index: str-index($color, '#'); | |||||
// inspect cast int to string | |||||
$index: str-index(inspect($color), '#'); | |||||
@if $index { | @if $index { | ||||
$color: str-slice($color, 2); | |||||
$color: str-slice(inspect($color), 2); | |||||
} | } | ||||
$varName: "--icon-#{$icon}-#{$color}"; | $varName: "--icon-#{$icon}-#{$color}"; | ||||
@if $core { | @if $core { |
use OC\Share20\ShareHelper; | use OC\Share20\ShareHelper; | ||||
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory; | use OC\SystemTag\ManagerFactory as SystemTagManagerFactory; | ||||
use OC\Tagging\TagMapper; | use OC\Tagging\TagMapper; | ||||
use OC\Template\IconsCacher; | |||||
use OC\Template\JSCombiner; | use OC\Template\JSCombiner; | ||||
use OC\Template\SCSSCacher; | use OC\Template\SCSSCacher; | ||||
use OCA\Theming\ImageManager; | use OCA\Theming\ImageManager; | ||||
$c->getConfig(), | $c->getConfig(), | ||||
$c->getThemingDefaults(), | $c->getThemingDefaults(), | ||||
\OC::$SERVERROOT, | \OC::$SERVERROOT, | ||||
$this->getMemCacheFactory() | |||||
$this->getMemCacheFactory(), | |||||
$c->query(IconsCacher::class) | |||||
); | ); | ||||
}); | }); | ||||
$this->registerService(JSCombiner::class, function (Server $c) { | $this->registerService(JSCombiner::class, function (Server $c) { |
use OCP\Files\IAppData; | use OCP\Files\IAppData; | ||||
use OCP\Files\NotFoundException; | use OCP\Files\NotFoundException; | ||||
use OCP\Files\SimpleFS\ISimpleFolder; | use OCP\Files\SimpleFS\ISimpleFolder; | ||||
use OCP\Files\SimpleFS\ISimpleFile; | |||||
use OCP\ILogger; | use OCP\ILogger; | ||||
use OCP\IURLGenerator; | use OCP\IURLGenerator; | ||||
use OC\Files\AppData\Factory; | use OC\Files\AppData\Factory; | ||||
*/ | */ | ||||
public function setIconsCss(string $css) { | public function setIconsCss(string $css) { | ||||
try { | |||||
$currentData = $this->folder->getFile($this->fileName)->getContent(); | |||||
} catch (NotFoundException $e) { | |||||
$cachedFile = $this->getCachedCSS(); | |||||
if (!$cachedFile) { | |||||
$currentData = ''; | $currentData = ''; | ||||
} else { | |||||
$currentData = $cachedFile->getContent(); | |||||
} | } | ||||
// remove :root | // remove :root | ||||
} | } | ||||
if (strlen($data) > 0) { | if (strlen($data) > 0) { | ||||
try { | |||||
$cachedfile = $this->folder->getFile($this->fileName); | |||||
} catch (NotFoundException $e) { | |||||
$cachedfile = $this->folder->newFile($this->fileName); | |||||
if (!$cachedFile) { | |||||
$cachedFile = $this->folder->newFile($this->fileName); | |||||
} | } | ||||
$data = ":root { | $data = ":root { | ||||
$data | $data | ||||
}"; | }"; | ||||
$cachedfile->putContent($data); | |||||
$cachedFile->putContent($data); | |||||
} | } | ||||
return preg_replace($this->iconVarRE, '', $css); | return preg_replace($this->iconVarRE, '', $css); |
* @param \OC_Defaults $defaults | * @param \OC_Defaults $defaults | ||||
* @param string $serverRoot | * @param string $serverRoot | ||||
* @param ICacheFactory $cacheFactory | * @param ICacheFactory $cacheFactory | ||||
* @param IconsCacher $iconsCacher | |||||
*/ | */ | ||||
public function __construct(ILogger $logger, | public function __construct(ILogger $logger, | ||||
Factory $appDataFactory, | Factory $appDataFactory, | ||||
IConfig $config, | IConfig $config, | ||||
\OC_Defaults $defaults, | \OC_Defaults $defaults, | ||||
$serverRoot, | $serverRoot, | ||||
ICacheFactory $cacheFactory) { | |||||
ICacheFactory $cacheFactory, | |||||
IconsCacher $iconsCacher) { | |||||
$this->logger = $logger; | $this->logger = $logger; | ||||
$this->appData = $appDataFactory->get('css'); | $this->appData = $appDataFactory->get('css'); | ||||
$this->urlGenerator = $urlGenerator; | $this->urlGenerator = $urlGenerator; | ||||
$this->serverRoot = $serverRoot; | $this->serverRoot = $serverRoot; | ||||
$this->cacheFactory = $cacheFactory; | $this->cacheFactory = $cacheFactory; | ||||
$this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl())); | $this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl())); | ||||
$this->iconsCacher = new IconsCacher( | |||||
$this->logger, | |||||
$appDataFactory, | |||||
$this->urlGenerator | |||||
); | |||||
$this->iconsCacher = $iconsCacher; | |||||
} | } | ||||
/** | /** |
['core', 'actions/settings-dark.svg', '1'], | ['core', 'actions/settings-dark.svg', '1'], | ||||
['core', 'actions/share.svg', '2'], | ['core', 'actions/share.svg', '2'], | ||||
['core', 'actions/password.svg', '3'], | ['core', 'actions/password.svg', '3'], | ||||
['core', 'places/contacts-dark.svg', '5'], | |||||
['core', 'places/contacts.svg', '5'], | |||||
['settings', 'help.svg', '4'], | ['settings', 'help.svg', '4'], | ||||
]); | ]); | ||||
['core', 'actions/settings-dark.svg', '1'], | ['core', 'actions/settings-dark.svg', '1'], | ||||
['core', 'actions/share.svg', '2'], | ['core', 'actions/share.svg', '2'], | ||||
['core', 'actions/password.svg', '3'], | ['core', 'actions/password.svg', '3'], | ||||
['core', 'places/contacts-dark.svg', '5'], | |||||
['core', 'places/contacts.svg', '5'], | |||||
['settings', 'help.svg', '4'], | ['settings', 'help.svg', '4'], | ||||
]); | ]); | ||||
use OCP\IURLGenerator; | use OCP\IURLGenerator; | ||||
use OCP\IConfig; | use OCP\IConfig; | ||||
use OCA\Theming\ThemingDefaults; | use OCA\Theming\ThemingDefaults; | ||||
use OC\Template\IconsCacher; | |||||
use OC\Template\SCSSCacher; | use OC\Template\SCSSCacher; | ||||
use OC\Template\CSSResourceLocator; | use OC\Template\CSSResourceLocator; | ||||
protected $cacheFactory; | protected $cacheFactory; | ||||
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ | /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ | ||||
protected $logger; | protected $logger; | ||||
/** @var IconsCacher|\PHPUnit_Framework_MockObject_MockObject */ | |||||
protected $iconsCacher; | |||||
protected function setUp() { | protected function setUp() { | ||||
parent::setUp(); | parent::setUp(); | ||||
$this->config = $this->createMock(IConfig::class); | $this->config = $this->createMock(IConfig::class); | ||||
$this->cacheFactory = $this->createMock(ICacheFactory::class); | $this->cacheFactory = $this->createMock(ICacheFactory::class); | ||||
$this->themingDefaults = $this->createMock(ThemingDefaults::class); | $this->themingDefaults = $this->createMock(ThemingDefaults::class); | ||||
$this->iconsCacher = $this->createMock(IconsCacher::class); | |||||
} | } | ||||
private function cssResourceLocator() { | private function cssResourceLocator() { | ||||
$this->config, | $this->config, | ||||
$this->themingDefaults, | $this->themingDefaults, | ||||
\OC::$SERVERROOT, | \OC::$SERVERROOT, | ||||
$this->cacheFactory | |||||
$this->cacheFactory, | |||||
$this->iconsCacher | |||||
); | ); | ||||
return new CSSResourceLocator( | return new CSSResourceLocator( | ||||
$this->logger, | $this->logger, |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2018, John Molakvoæ (skjnldsv@protonmail.com) | |||||
* | |||||
* @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | |||||
* | |||||
* @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 Test\Template; | |||||
use OC\Files\AppData\AppData; | |||||
use OC\Files\AppData\Factory; | |||||
use OC\Template\IconsCacher; | |||||
use OCA\Theming\ThemingDefaults; | |||||
use OCP\Files\IAppData; | |||||
use OCP\Files\NotFoundException; | |||||
use OCP\Files\SimpleFS\ISimpleFile; | |||||
use OCP\Files\SimpleFS\ISimpleFolder; | |||||
use OCP\ICache; | |||||
use OCP\ICacheFactory; | |||||
use OCP\IConfig; | |||||
use OCP\ILogger; | |||||
use OCP\IURLGenerator; | |||||
use OC_App; | |||||
class IconsCacherTest extends \Test\TestCase { | |||||
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ | |||||
protected $logger; | |||||
/** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ | |||||
protected $appData; | |||||
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ | |||||
protected $urlGenerator; | |||||
protected function setUp() { | |||||
$this->logger = $this->createMock(ILogger::class); | |||||
$this->appData = $this->createMock(AppData::class); | |||||
/** @var Factory|\PHPUnit_Framework_MockObject_MockObject $factory */ | |||||
$factory = $this->createMock(Factory::class); | |||||
$factory->method('get')->with('css')->willReturn($this->appData); | |||||
$this->folder = $this->createMock(ISimpleFolder::class); | |||||
$this->appData->method('getFolder')->willReturn($this->folder); | |||||
$this->urlGenerator = $this->createMock(IURLGenerator::class); | |||||
$this->iconsCacher = new IconsCacher( | |||||
$this->logger, | |||||
$factory, | |||||
$this->urlGenerator | |||||
); | |||||
} | |||||
public function testGetIconsFromEmptyCss() { | |||||
$css = " | |||||
icon.test { | |||||
color: #aaa; | |||||
} | |||||
"; | |||||
$icons = self::invokePrivate($this->iconsCacher, 'getIconsFromCss', [$css]); | |||||
$this->assertTrue(empty($icons)); | |||||
} | |||||
public function testGetIconsFromValidCss() { | |||||
$css = " | |||||
icon.test { | |||||
--icon-test: url('/svg/core/actions/add/000'); | |||||
background-image: var(--icon-test); | |||||
} | |||||
"; | |||||
$actual = self::invokePrivate($this->iconsCacher, 'getIconsFromCss', [$css]); | |||||
$expected = array( | |||||
'icon-test' => '/svg/core/actions/add/000' | |||||
); | |||||
$this->assertEquals($expected, $actual); | |||||
} | |||||
public function testSetIconsFromEmptyCss() { | |||||
$expected = " | |||||
icon.test { | |||||
color: #aaa; | |||||
} | |||||
"; | |||||
$actual = $this->iconsCacher->setIconsCss($expected); | |||||
$this->assertEquals($expected, $actual); | |||||
} | |||||
public function testSetIconsFromValidCss() { | |||||
$css = " | |||||
icon.test { | |||||
--icon-test: url('/svg/core/actions/add/000'); | |||||
background-image: var(--icon-test); | |||||
} | |||||
"; | |||||
$expected = " | |||||
icon.test { | |||||
background-image: var(--icon-test); | |||||
} | |||||
"; | |||||
$iconsFile = $this->createMock(ISimpleFile::class); | |||||
$this->folder->expects($this->once()) | |||||
->method('getFile') | |||||
->willReturn($iconsFile); | |||||
$actual = $this->iconsCacher->setIconsCss($css); | |||||
$this->assertEquals($expected, $actual); | |||||
} | |||||
} |
use OC\Files\AppData\AppData; | use OC\Files\AppData\AppData; | ||||
use OC\Files\AppData\Factory; | use OC\Files\AppData\Factory; | ||||
use OC\Template\SCSSCacher; | use OC\Template\SCSSCacher; | ||||
use OC\Template\IconsCacher; | |||||
use OCA\Theming\ThemingDefaults; | use OCA\Theming\ThemingDefaults; | ||||
use OCP\Files\IAppData; | use OCP\Files\IAppData; | ||||
use OCP\Files\NotFoundException; | use OCP\Files\NotFoundException; | ||||
protected $depsCache; | protected $depsCache; | ||||
/** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */ | /** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */ | ||||
protected $cacheFactory; | protected $cacheFactory; | ||||
/** @var IconsCacher|\PHPUnit_Framework_MockObject_MockObject */ | |||||
protected $iconsCacher; | |||||
protected function setUp() { | protected function setUp() { | ||||
parent::setUp(); | parent::setUp(); | ||||
$this->logger = $this->createMock(ILogger::class); | $this->logger = $this->createMock(ILogger::class); | ||||
$this->appData = $this->createMock(AppData::class); | $this->appData = $this->createMock(AppData::class); | ||||
$this->iconsCacher = $this->createMock(IconsCacher::class); | |||||
/** @var Factory|\PHPUnit_Framework_MockObject_MockObject $factory */ | /** @var Factory|\PHPUnit_Framework_MockObject_MockObject $factory */ | ||||
$factory = $this->createMock(Factory::class); | $factory = $this->createMock(Factory::class); | ||||
$this->themingDefaults = $this->createMock(ThemingDefaults::class); | $this->themingDefaults = $this->createMock(ThemingDefaults::class); | ||||
$this->themingDefaults->expects($this->any())->method('getScssVariables')->willReturn([]); | $this->themingDefaults->expects($this->any())->method('getScssVariables')->willReturn([]); | ||||
$iconsFile = $this->createMock(ISimpleFile::class); | |||||
$this->iconsCacher->expects($this->any()) | |||||
->method('getCachedCSS') | |||||
->willReturn($iconsFile); | |||||
$this->scssCacher = new SCSSCacher( | $this->scssCacher = new SCSSCacher( | ||||
$this->logger, | $this->logger, | ||||
$factory, | $factory, | ||||
$this->config, | $this->config, | ||||
$this->themingDefaults, | $this->themingDefaults, | ||||
\OC::$SERVERROOT, | \OC::$SERVERROOT, | ||||
$this->cacheFactory | |||||
$this->cacheFactory, | |||||
$this->iconsCacher | |||||
); | ); | ||||
} | } | ||||
->method('getBaseUrl') | ->method('getBaseUrl') | ||||
->willReturn('http://localhost/nextcloud'); | ->willReturn('http://localhost/nextcloud'); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | ||||
$this->assertTrue($actual); | $this->assertTrue($actual); | ||||
} | } | ||||
->with($filePrefix.'styles.css.deps') | ->with($filePrefix.'styles.css.deps') | ||||
->willReturn($fileDeps); | ->willReturn($fileDeps); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | ||||
$this->assertTrue($actual); | $this->assertTrue($actual); | ||||
} | } | ||||
$this->fail(); | $this->fail(); | ||||
})); | })); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | ||||
$this->assertTrue($actual); | $this->assertTrue($actual); | ||||
} | } | ||||
$this->fail(); | $this->fail(); | ||||
})); | })); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); | ||||
$this->assertTrue($actual); | $this->assertTrue($actual); | ||||
} | } | ||||
throw new \Exception(); | throw new \Exception(); | ||||
})); | })); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$file->expects($this->once())->method('putContent'); | $file->expects($this->once())->method('putContent'); | ||||
$depsFile->expects($this->once())->method('putContent'); | $depsFile->expects($this->once())->method('putContent'); | ||||
$gzipFile->expects($this->once())->method('putContent'); | $gzipFile->expects($this->once())->method('putContent'); | ||||
$depsFile->expects($this->once())->method('putContent'); | $depsFile->expects($this->once())->method('putContent'); | ||||
$gzipFile->expects($this->once())->method('putContent'); | $gzipFile->expects($this->once())->method('putContent'); | ||||
$this->iconsCacher->expects($this->any()) | |||||
->method('setIconsCss') | |||||
->willReturn('scss {}'); | |||||
$actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); | $actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); | ||||
$this->assertTrue($actual); | $this->assertTrue($actual); | ||||
} | } | ||||
throw new \Exception(); | throw new \Exception(); | ||||
})); | })); | ||||
$this->iconsCacher->expects($this->at(0)) | |||||
->method('setIconsCss') | |||||
->willReturn('body{background-color:#0082c9}'); | |||||
$file->expects($this->at(0))->method('putContent')->with($this->callback( | $file->expects($this->at(0))->method('putContent')->with($this->callback( | ||||
function ($content){ | function ($content){ | ||||
return 'body{background-color:#0082c9}' === $content; | return 'body{background-color:#0082c9}' === $content; |