diff options
author | Julius Haertl <jus@bitgrid.net> | 2017-02-17 16:42:07 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2017-04-25 11:39:45 +0200 |
commit | 68a63ad3f33c683d726219a508bb31de7b9ab1d0 (patch) | |
tree | 910932971b761689c8ca843860119a1df6e29573 /apps/theming/tests | |
parent | 133f3fdc9aec28383dba323d58569eddd160b0df (diff) | |
download | nextcloud-server-68a63ad3f33c683d726219a508bb31de7b9ab1d0.tar.gz nextcloud-server-68a63ad3f33c683d726219a508bb31de7b9ab1d0.zip |
Implement scss variable injection by OC_Defaults
Signed-off-by: Julius Haertl <jus@bitgrid.net>
Add Scss variables to example theme and theming app
Signed-off-by: Julius Haertl <jus@bitgrid.net>
Use SCSSCacher to build theming css
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Update theming.scss
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Code cleanup
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Fix tests
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Inject SCSSCacher for easier testing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Fix typehint
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Generate absolute URLs
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Fix tests to always use absolute urls for theming images
Signed-off-by: Julius Härtl <jus@bitgrid.net>
MailheaderColor -> ColorPrimary
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'apps/theming/tests')
-rw-r--r-- | apps/theming/tests/Controller/ThemingControllerTest.php | 566 | ||||
-rw-r--r-- | apps/theming/tests/ThemingDefaultsTest.php | 85 |
2 files changed, 125 insertions, 526 deletions
diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php index cc7f73f742f..0aa9ead3742 100644 --- a/apps/theming/tests/Controller/ThemingControllerTest.php +++ b/apps/theming/tests/Controller/ThemingControllerTest.php @@ -24,7 +24,9 @@ */ namespace OCA\Theming\Tests\Controller; +use OC\Files\AppData\Factory; use OC\L10N\L10N; +use OC\Template\SCSSCacher; use OCA\Theming\Controller\ThemingController; use OCA\Theming\Util; use OCP\App\IAppManager; @@ -38,8 +40,10 @@ use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IConfig; use OCP\IL10N; +use OCP\ILogger; use OCP\IRequest; use OCP\ITempManager; +use OCP\IURLGenerator; use Test\TestCase; use OCA\Theming\ThemingDefaults; @@ -49,7 +53,7 @@ class ThemingControllerTest extends TestCase { /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; /** @var ThemingDefaults|\PHPUnit_Framework_MockObject_MockObject */ - private $template; + private $themingDefaults; /** @var Util */ private $util; /** @var \OCP\AppFramework\Utility\ITimeFactory */ @@ -66,11 +70,13 @@ class ThemingControllerTest extends TestCase { private $appManager; /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ private $appData; + /** @var SCSSCacher */ + private $scssCacher; public function setUp() { $this->request = $this->createMock(IRequest::class); $this->config = $this->createMock(IConfig::class); - $this->template = $this->createMock(ThemingDefaults::class); + $this->themingDefaults = $this->createMock(ThemingDefaults::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->l10n = $this->createMock(L10N::class); $this->rootFolder = $this->createMock(IRootFolder::class); @@ -81,17 +87,19 @@ class ThemingControllerTest extends TestCase { ->willReturn(123); $this->tempManager = \OC::$server->getTempManager(); $this->appData = $this->createMock(IAppData::class); + $this->scssCacher = $this->createMock(SCSSCacher::class); $this->themingController = new ThemingController( 'theming', $this->request, $this->config, - $this->template, + $this->themingDefaults, $this->util, $this->timeFactory, $this->l10n, $this->tempManager, - $this->appData + $this->appData, + $this->scssCacher ); return parent::setUp(); @@ -122,7 +130,7 @@ class ThemingControllerTest extends TestCase { * @param string $message */ public function testUpdateStylesheet($setting, $value, $status, $message) { - $this->template + $this->themingDefaults ->expects($status === 'success' ? $this->once() : $this->never()) ->method('set') ->with($setting, $value); @@ -358,7 +366,7 @@ class ThemingControllerTest extends TestCase { ->method('t') ->with('Saved') ->willReturn('Saved'); - $this->template + $this->themingDefaults ->expects($this->once()) ->method('undo') ->with('MySetting') @@ -455,533 +463,53 @@ class ThemingControllerTest extends TestCase { @$this->assertEquals($expected, $this->themingController->getLoginBackground()); } - public function testGetStylesheetWithOnlyColor() { - - $color = '#000'; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn($color); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn(''); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn(''); - - $expectedData = sprintf( - '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n", - $color - ); - $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' . - 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' . - 'background-color: %s; background-position: center center; background-size:contain;' . - 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' . - "}\n", - \OC::$WEBROOT, - $color - ); - $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . - 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' . - "}\n"; - $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . - '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'color: #ffffff;'. - "}\n" . - '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . - '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'color: #ffffff;'. - "}\n" . - '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . - '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . - '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'opacity: 0.4;' . - 'color: #ffffff;'. - "}\n"; - $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; - $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . - 'border: 1px solid ' . $color . ';' . - 'color: ' . $color . ';' . - "}\n"; - $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . - 'color: ' . $color . ';' . - "}\n"; - $expectedData .= ' - #firstrunwizard .firstrunwizard-header { - background-color: ' . $color . '; - } - #firstrunwizard p a { - color: ' . $color . '; - } - '; - $expectedData .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color); - $expectedData .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color); - $expectedData .= sprintf('#app-navigation li:hover > a, #app-navigation li:focus > a, #app-navigation a:focus, #app-navigation .selected, #app-navigation .selected a, #app-navigation .active, #app-navigation .active a {box-shadow: inset 2px 0 %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'); - - $expected->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); - } - - public function testGetStylesheetWithOnlyColorInvert() { - - $color = '#fff'; - $elementColor = '#555555'; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn($color); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn(''); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn(''); - - $expectedData = sprintf( - '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n", - $color - ); - $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' . - 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' . - 'background-color: #555555; background-position: center center; background-size:contain;' . - 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' . - "}\n", - \OC::$WEBROOT - ); - $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . - 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' . - "}\n"; - $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . - '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'color: #000000;'. - "}\n" . - '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . - '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'color: #000000;'. - "}\n" . - '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . - '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . - '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'opacity: 0.4;' . - 'color: #000000;'. - "}\n"; - $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; - $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . - 'border: 1px solid ' . $color . ';' . - 'color: ' . $elementColor . ';' . - "}\n"; - $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . - 'color: ' . $elementColor . ';' . - "}\n"; - $expectedData .= ' - #firstrunwizard .firstrunwizard-header { - background-color: ' . $color . '; - } - #firstrunwizard p a { - color: ' . $color . '; - } - '; - $expectedData .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color); - $expectedData .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color); - $expectedData .= sprintf('#app-navigation li:hover > a, #app-navigation li:focus > a, #app-navigation a:focus, #app-navigation .selected, #app-navigation .selected a, #app-navigation .active, #app-navigation .active a {box-shadow: inset 2px 0 %s}' . "\n", $color); - $expectedData .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n"; - $expectedData .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n"; - $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n"; - $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n"; - $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->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); - } - - public function testGetStylesheetWithOnlyHeaderLogo() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn(''); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn('image/png'); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn(''); - - $expectedData = '#header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#header .logo-icon {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#firstrunwizard .firstrunwizard-header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - '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'); + public function testGetStylesheet() { - $expected->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); - } - - public function testGetStylesheetWithOnlyBackgroundLogin() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn(''); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn(''); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn('text/svg'); - - $expectedData = '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n"; - $expectedData .= '#firstrunwizard .firstrunwizard-header {' . - 'background-image: url(\'./loginbackground?v=0\');' . - '}' . "\n"; - $expectedData .= '.nc-theming-contrast {color: #ffffff}' . "\n"; - - $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); - - $expected->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); - } - - public function testGetStylesheetWithAllCombined() { - - $color = '#000'; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn($color); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn('text/svg'); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn('image/png'); - - $expectedData = sprintf( - '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n", - $color); + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->any())->method('getName')->willReturn('theming.css'); + $file->expects($this->any())->method('getContent')->willReturn('compiled'); + $this->scssCacher->expects($this->once())->method('process')->willReturn(true); + $this->scssCacher->expects($this->once())->method('getCachedCSS')->willReturn($file); - $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' . - 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' . - 'background-color: %s; background-position: center center; background-size:contain;' . - 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' . - "}\n", - \OC::$WEBROOT, - $color - ); - $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . - 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' . - "}\n"; - $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . - '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'color: #ffffff;'. - "}\n" . - '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . - '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'color: #ffffff;'. - "}\n" . - '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . - '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . - '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . - 'border: 1px solid '.$color.';'. - 'background-color: '.$color.';'. - 'opacity: 0.4;' . - 'color: #ffffff;'. - "}\n"; - $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; - $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . - 'border: 1px solid ' . $color . ';' . - 'color: ' . $color . ';' . - "}\n"; - $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . - 'color: ' . $color . ';' . - "}\n"; - $expectedData .= ' - #firstrunwizard .firstrunwizard-header { - background-color: ' . $color . '; - } - #firstrunwizard p a { - color: ' . $color . '; - } - '; - $expectedData .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color); - $expectedData .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color); - $expectedData .= sprintf('#app-navigation li:hover > a, #app-navigation li:focus > a, #app-navigation a:focus, #app-navigation .selected, #app-navigation .selected a, #app-navigation .active, #app-navigation .active a {box-shadow: inset 2px 0 %s}' . "\n", $color); - $expectedData .= sprintf( - '#header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#header .logo-icon {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#firstrunwizard .firstrunwizard-header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" - ); - $expectedData .= '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n"; - $expectedData .= '#firstrunwizard .firstrunwizard-header {' . - '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'); + $response = new Http\FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']); + $response->cacheFor(86400); + $expires = new \DateTime(); + $expires->setTimestamp($this->timeFactory->getTime()); + $expires->add(new \DateInterval('PT24H')); + $response->addHeader('Expires', $expires->format(\DateTime::RFC1123)); + $response->addHeader('Pragma', 'cache'); - $expected->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); + $actual = $this->themingController->getStylesheet(); + $this->assertEquals($response, $actual); } - public function testGetStylesheetWithAllCombinedInverted() { - - $color = '#fff'; - $elementColor = '#555555'; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('theming', 'cachebuster', '0') - ->willReturn('0'); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('theming', 'color', '') - ->willReturn('#fff'); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('theming', 'logoMime', '') - ->willReturn('text/svg'); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('theming', 'backgroundMime', '') - ->willReturn('image/png'); - - $expectedData = sprintf( - '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n", - $color); - - $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' . - 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' . - 'background-color: #555555; background-position: center center; background-size:contain;' . - 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' . - "}\n", - \OC::$WEBROOT - ); - $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . - 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' . - "}\n"; - $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . - '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'color: #000000;'. - "}\n" . - '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . - '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'color: #000000;'. - "}\n" . - '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . - '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . - '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . - 'border: 1px solid '.$elementColor.';'. - 'background-color: '.$elementColor.';'. - 'opacity: 0.4;' . - 'color: #000000;'. - "}\n"; - $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; - $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . - 'border: 1px solid ' . $color . ';' . - 'color: ' . $elementColor . ';' . - "}\n"; - $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . - 'color: ' . $elementColor . ';' . - "}\n"; - $expectedData .= ' - #firstrunwizard .firstrunwizard-header { - background-color: ' . $color . '; - } - #firstrunwizard p a { - color: ' . $color . '; - } - '; - $expectedData .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color); - $expectedData .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color); - $expectedData .= sprintf('#app-navigation li:hover > a, #app-navigation li:focus > a, #app-navigation a:focus, #app-navigation .selected, #app-navigation .selected a, #app-navigation .active, #app-navigation .active a {box-shadow: inset 2px 0 %s}' . "\n", $color); - $expectedData .= sprintf( - '#header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#header .logo-icon {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" . - '#firstrunwizard .firstrunwizard-header .logo {' . - 'background-image: url(\'./logo?v=0\');' . - 'background-size: contain;' . - '}' . "\n" - ); - $expectedData .= '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n"; - $expectedData .= '#firstrunwizard .firstrunwizard-header {' . - 'background-image: url(\'./loginbackground?v=0\');' . - '}' . "\n"; - $expectedData .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n"; - $expectedData .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n"; - $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n"; - $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n"; - $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->cacheFor(3600); - $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); - $expected->addHeader('Pragma', 'cache'); - @$this->assertEquals($expected, $this->themingController->getStylesheet()); + public function testGetStylesheetFails() { + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->any())->method('getName')->willReturn('theming.css'); + $file->expects($this->any())->method('getContent')->willReturn('compiled'); + $this->scssCacher->expects($this->once())->method('process')->willReturn(true); + $this->scssCacher->expects($this->once())->method('getCachedCSS')->willThrowException(new NotFoundException()); + $response = new Http\NotFoundResponse(); + + $actual = $this->themingController->getStylesheet(); + $this->assertEquals($response, $actual); } public function testGetJavascript() { - $this->template + $this->themingDefaults ->expects($this->at(0)) ->method('getName') ->willReturn(""); - $this->template + $this->themingDefaults ->expects($this->at(1)) ->method('getBaseUrl') ->willReturn(""); - $this->template + $this->themingDefaults ->expects($this->at(2)) ->method('getSlogan') ->willReturn(""); - $this->template + $this->themingDefaults ->expects($this->at(3)) ->method('getColorPrimary') ->willReturn("#000"); @@ -1004,19 +532,19 @@ class ThemingControllerTest extends TestCase { @$this->assertEquals($expected, $this->themingController->getJavascript()); } public function testGetJavascriptInverted() { - $this->template + $this->themingDefaults ->expects($this->at(0)) ->method('getName') ->willReturn("Nextcloud"); - $this->template + $this->themingDefaults ->expects($this->at(1)) ->method('getBaseUrl') ->willReturn("nextcloudurl"); - $this->template + $this->themingDefaults ->expects($this->at(2)) ->method('getSlogan') ->willReturn("awesome"); - $this->template + $this->themingDefaults ->expects($this->any()) ->method('getColorPrimary') ->willReturn("#ffffff"); diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php index ad8f86f1c13..dfa226c403d 100644 --- a/apps/theming/tests/ThemingDefaultsTest.php +++ b/apps/theming/tests/ThemingDefaultsTest.php @@ -25,7 +25,11 @@ namespace OCA\Theming\Tests; use OCA\Theming\ThemingDefaults; use OCP\Files\IAppData; +use OCA\Theming\Util; +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\IL10N; @@ -47,14 +51,20 @@ class ThemingDefaultsTest extends TestCase { private $cacheFactory; /** @var ThemingDefaults */ private $template; + /** @var Util|\PHPUnit_Framework_MockObject_MockObject */ + private $util; + /** @var ICache|\PHPUnit_Framework_MockObject_MockObject */ + private $cache; public function setUp() { parent::setUp(); $this->config = $this->getMockBuilder(IConfig::class)->getMock(); $this->l10n = $this->getMockBuilder(IL10N::class)->getMock(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock(); + $this->urlGenerator = \OC::$server->query(IURLGenerator::class); $this->appData = $this->createMock(IAppData::class); - $this->cacheFactory = $this->getMockBuilder(ICacheFactory::class)->getMock(); + $this->cacheFactory = $this->createMock(ICacheFactory::class); + $this->cache = $this->createMock(ICache::class); + $this->util = $this->createMock(Util::class); $this->defaults = $this->getMockBuilder(\OC_Defaults::class) ->disableOriginalConstructor() ->getMock(); @@ -74,13 +84,19 @@ class ThemingDefaultsTest extends TestCase { ->expects($this->at(3)) ->method('getColorPrimary') ->willReturn('#000'); + $this->cacheFactory + ->expects($this->any()) + ->method('create') + ->with('theming') + ->willReturn($this->cache); $this->template = new ThemingDefaults( $this->config, $this->l10n, $this->urlGenerator, $this->defaults, $this->appData, - $this->cacheFactory + $this->cacheFactory, + $this->util ); } @@ -265,7 +281,10 @@ class ThemingDefaultsTest extends TestCase { ->expects($this->at(2)) ->method('setAppValue') ->with('theming', 'cachebuster', 16); - + $this->cache + ->expects($this->once()) + ->method('clear') + ->with('getScssVariables'); $this->template->set('MySetting', 'MyValue'); } @@ -380,6 +399,11 @@ class ThemingDefaultsTest extends TestCase { } public function testGetBackgroundDefault() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $this->appData->expects($this->once()) + ->method('getFolder') + ->willThrowException(new NotFoundException()); $this->config ->expects($this->once()) ->method('getAppValue') @@ -395,6 +419,12 @@ class ThemingDefaultsTest extends TestCase { } public function testGetBackgroundCustom() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $folder->expects($this->once())->method('getFile')->willReturn($file); + $this->appData->expects($this->once()) + ->method('getFolder') + ->willReturn($folder); $this->config ->expects($this->once()) ->method('getAppValue') @@ -411,11 +441,14 @@ class ThemingDefaultsTest extends TestCase { ->method('getFile') ->with('background') ->willReturn(''); - $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground'); + $expected = $this->urlGenerator->linkToRouteAbsolute('theming.Theming.getLoginBackground'); $this->assertEquals($expected, $this->template->getBackground()); } public function testGetLogoDefault() { + $this->appData->expects($this->once()) + ->method('getFolder') + ->willThrowException(new NotFoundException()); $this->config ->expects($this->at(0)) ->method('getAppValue') @@ -431,11 +464,17 @@ class ThemingDefaultsTest extends TestCase { ->method('getFolder') ->with('images') ->willThrowException(new \Exception()); - $expected = $this->urlGenerator->imagePath('core','logo.svg') . '?v=0'; + $expected = $this->urlGenerator->getAbsoluteURL('/core/img/logo.svg') . '?v=0'; $this->assertEquals($expected, $this->template->getLogo()); } public function testGetLogoCustom() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $folder->expects($this->once())->method('getFile')->willReturn($file); + $this->appData->expects($this->once()) + ->method('getFolder') + ->willReturn($folder); $this->config ->expects($this->at(0)) ->method('getAppValue') @@ -457,7 +496,39 @@ class ThemingDefaultsTest extends TestCase { ->method('getFile') ->with('logo') ->willReturn(''); - $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLogo') . '?v=0'; + $expected = $this->urlGenerator->getAbsoluteURL('index.php/apps/theming/logo') . '?v=0'; $this->assertEquals($expected, $this->template->getLogo()); } + + public function testGetScssVariablesCached() { + $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(['foo'=>'bar']); + $this->assertEquals(['foo'=>'bar'], $this->template->getScssVariables()); + } + + public function testGetScssVariables() { + $this->config->expects($this->at(0))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0'); + $this->config->expects($this->at(1))->method('getAppValue')->with('theming', 'logoMime', false)->willReturn('jpeg'); + $this->config->expects($this->at(2))->method('getAppValue')->with('theming', 'backgroundMime', false)->willReturn('jpeg'); + $this->config->expects($this->at(3))->method('getAppValue')->with('theming', 'color', null)->willReturn('#000000'); + $this->config->expects($this->at(4))->method('getAppValue')->with('theming', 'color', '#000')->willReturn('#000000'); + $this->config->expects($this->at(5))->method('getAppValue')->with('theming', 'color', '#000')->willReturn('#000000'); + + $this->util->expects($this->any())->method('invertTextColor')->with('#000000')->willReturn(false); + $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(null); + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $folder->expects($this->any())->method('getFile')->willReturn($file); + $this->appData->expects($this->any()) + ->method('getFolder') + ->willReturn($folder); + $expected = [ + 'theming-cachebuster' => '\'0\'', + 'image-logo' => '\'' . $this->urlGenerator->getAbsoluteURL('index.php/apps/theming/logo') . '?v=0\'', + 'image-login-background' => '\'' . $this->urlGenerator->getAbsoluteURL('index.php/apps/theming/loginbackground') . '\'', + 'color-primary' => '#000000', + 'color-primary-text' => '#ffffff' + + ]; + $this->assertEquals($expected, $this->template->getScssVariables()); + } } |