diff options
Diffstat (limited to 'apps/theming/tests/Controller/ThemingControllerTest.php')
-rw-r--r-- | apps/theming/tests/Controller/ThemingControllerTest.php | 468 |
1 files changed, 198 insertions, 270 deletions
diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php index c5ecc08b211..fb461f03a28 100644 --- a/apps/theming/tests/Controller/ThemingControllerTest.php +++ b/apps/theming/tests/Controller/ThemingControllerTest.php @@ -1,94 +1,64 @@ <?php + +declare(strict_types=1); /** - * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Calviño Sánchez <danxuliu@gmail.com> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> - * @author Julius Haertl <jus@bitgrid.net> - * @author Julius Härtl <jus@bitgrid.net> - * @author Kyle Fazzari <kyrofa@ubuntu.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Michael Weimann <mail@michael-weimann.eu> - * @author rakekniven <mark.ziegler@rakekniven.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - namespace OCA\Theming\Tests\Controller; use OC\L10N\L10N; -use OC\Template\SCSSCacher; use OCA\Theming\Controller\ThemingController; use OCA\Theming\ImageManager; +use OCA\Theming\Service\ThemesService; use OCA\Theming\ThemingDefaults; use OCP\App\IAppManager; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\NotFoundResponse; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; -use OCP\Files\IAppData; use OCP\Files\NotFoundException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\IConfig; use OCP\IL10N; +use OCP\INavigationManager; use OCP\IRequest; use OCP\ITempManager; use OCP\IURLGenerator; +use OCP\Server; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class ThemingControllerTest extends TestCase { - /** @var IRequest|MockObject */ - private $request; - /** @var IConfig|MockObject */ - private $config; - /** @var ThemingDefaults|MockObject */ - private $themingDefaults; - /** @var IL10N|MockObject */ - private $l10n; - /** @var ThemingController */ - private $themingController; - /** @var ITempManager */ - private $tempManager; - /** @var IAppManager|MockObject */ - private $appManager; - /** @var IAppData|MockObject */ - private $appData; - /** @var ImageManager|MockObject */ - private $imageManager; - /** @var SCSSCacher */ - private $scssCacher; - /** @var IURLGenerator */ - private $urlGenerator; + + private IRequest&MockObject $request; + private IConfig&MockObject $config; + private IAppConfig&MockObject $appConfig; + private ThemingDefaults&MockObject $themingDefaults; + private IL10N&MockObject $l10n; + private IAppManager&MockObject $appManager; + private ImageManager&MockObject $imageManager; + private IURLGenerator&MockObject $urlGenerator; + private ThemesService&MockObject $themesService; + private INavigationManager&MockObject $navigationManager; + + private ThemingController $themingController; protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->config = $this->createMock(IConfig::class); + $this->appConfig = $this->createMock(IAppConfig::class); $this->themingDefaults = $this->createMock(ThemingDefaults::class); $this->l10n = $this->createMock(L10N::class); - $this->appData = $this->createMock(IAppData::class); $this->appManager = $this->createMock(IAppManager::class); - $this->tempManager = \OC::$server->getTempManager(); - $this->scssCacher = $this->createMock(SCSSCacher::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->imageManager = $this->createMock(ImageManager::class); + $this->themesService = $this->createMock(ThemesService::class); + $this->navigationManager = $this->createMock(INavigationManager::class); $timeFactory = $this->createMock(ITimeFactory::class); $timeFactory->expects($this->any()) @@ -101,20 +71,20 @@ class ThemingControllerTest extends TestCase { 'theming', $this->request, $this->config, + $this->appConfig, $this->themingDefaults, $this->l10n, - $this->tempManager, - $this->appData, - $this->scssCacher, $this->urlGenerator, $this->appManager, - $this->imageManager + $this->imageManager, + $this->themesService, + $this->navigationManager, ); parent::setUp(); } - public function dataUpdateStylesheetSuccess() { + public static function dataUpdateStylesheetSuccess(): array { return [ ['name', str_repeat('a', 250), 'Saved'], ['url', 'https://nextcloud.com/' . str_repeat('a', 478), 'Saved'], @@ -127,14 +97,8 @@ class ThemingControllerTest extends TestCase { ]; } - /** - * @dataProvider dataUpdateStylesheetSuccess - * - * @param string $setting - * @param string $value - * @param string $message - */ - public function testUpdateStylesheetSuccess($setting, $value, $message) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataUpdateStylesheetSuccess')] + public function testUpdateStylesheetSuccess(string $setting, string $value, string $message): void { $this->themingDefaults ->expects($this->once()) ->method('set') @@ -145,23 +109,12 @@ class ThemingControllerTest extends TestCase { ->willReturnCallback(function ($str) { return $str; }); - $this->scssCacher - ->expects($this->once()) - ->method('getCachedSCSS') - ->with('core', '/core/css/css-variables.scss') - ->willReturn('/core/css/someHash-css-variables.scss'); - $this->urlGenerator - ->expects($this->once()) - ->method('linkTo') - ->with('', '/core/css/someHash-css-variables.scss') - ->willReturn('/nextcloudWebroot/core/css/someHash-css-variables.scss'); $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => $message, - 'serverCssUrl' => '/nextcloudWebroot/core/css/someHash-css-variables.scss', ], 'status' => 'success', ] @@ -169,31 +122,39 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->updateStylesheet($setting, $value)); } - public function dataUpdateStylesheetError() { + public static function dataUpdateStylesheetError(): array { + $urls = [ + 'url' => 'web address', + 'imprintUrl' => 'legal notice address', + 'privacyUrl' => 'privacy policy address', + ]; + + $urlTests = []; + foreach ($urls as $urlKey => $urlName) { + // Check length limit + $urlTests[] = [$urlKey, 'http://example.com/' . str_repeat('a', 501), "The given {$urlName} is too long"]; + // Check potential evil javascript + $urlTests[] = [$urlKey, 'javascript:alert(1)', "The given {$urlName} is not a valid URL"]; + // Check XSS + $urlTests[] = [$urlKey, 'https://example.com/"><script/src="alert(\'1\')"><a/href/="', "The given {$urlName} is not a valid URL"]; + } + return [ ['name', str_repeat('a', 251), 'The given name is too long'], - ['url', 'http://example.com/' . str_repeat('a', 501), 'The given web address is too long'], - ['url', str_repeat('a', 501), 'The given web address is not a valid URL'], - ['url', 'javascript:alert(1)', 'The given web address is not a valid URL'], ['slogan', str_repeat('a', 501), 'The given slogan is too long'], - ['color', '0082C9', 'The given color is invalid'], - ['color', '#0082Z9', 'The given color is invalid'], - ['color', 'Nextcloud', 'The given color is invalid'], - ['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'], - ['imprintUrl', '0082C9', 'The given legal notice address is not a valid URL'], - ['imprintUrl', 'javascript:foo', 'The given legal notice address is not a valid URL'], - ['privacyUrl', '#0082Z9', 'The given privacy policy address is not a valid URL'], + ['primary_color', '0082C9', 'The given color is invalid'], + ['primary_color', '#0082Z9', 'The given color is invalid'], + ['primary_color', 'Nextcloud', 'The given color is invalid'], + ['background_color', '0082C9', 'The given color is invalid'], + ['background_color', '#0082Z9', 'The given color is invalid'], + ['background_color', 'Nextcloud', 'The given color is invalid'], + + ...$urlTests, ]; } - /** - * @dataProvider dataUpdateStylesheetError - * - * @param string $setting - * @param string $value - * @param string $message - */ - public function testUpdateStylesheetError($setting, $value, $message) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataUpdateStylesheetError')] + public function testUpdateStylesheetError(string $setting, string $value, string $message): void { $this->themingDefaults ->expects($this->never()) ->method('set') @@ -207,8 +168,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => $message, ], 'status' => 'error', @@ -218,14 +179,14 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->updateStylesheet($setting, $value)); } - public function testUpdateLogoNoData() { + public function testUpdateLogoNoData(): void { $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('logo'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn(null); @@ -238,8 +199,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => 'No file uploaded', ], 'status' => 'failure', @@ -250,29 +211,56 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } + public function testUploadInvalidUploadKey(): void { + $this->request + ->expects($this->once()) + ->method('getParam') + ->with('key') + ->willReturn('invalid'); + $this->request + ->expects($this->never()) + ->method('getUploadedFile'); + $this->l10n + ->expects($this->any()) + ->method('t') + ->willReturnCallback(function ($str) { + return $str; + }); + + $expected = new DataResponse( + [ + 'data' + => [ + 'message' => 'Invalid key', + ], + 'status' => 'failure', + ], + Http::STATUS_BAD_REQUEST + ); + + $this->assertEquals($expected, $this->themingController->uploadImage()); + } + /** * Checks that trying to upload an SVG favicon without imagemagick * results in an unsupported media type response. - * - * @test - * @return void */ - public function testUploadSVGFaviconWithoutImagemagick() { + public function testUploadSVGFaviconWithoutImagemagick(): void { $this->imageManager ->method('shouldReplaceIcons') ->willReturn(false); $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('favicon'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ - 'tmp_name' => __DIR__ . '/../../../../tests/data/testimagelarge.svg', + 'tmp_name' => __DIR__ . '/../../../../tests/data/testimagelarge.svg', 'type' => 'image/svg', 'name' => 'testimagelarge.svg', 'error' => 0, @@ -290,8 +278,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => 'Unsupported image type', ], 'status' => 'failure' @@ -302,18 +290,18 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - public function testUpdateLogoInvalidMimeType() { + public function testUpdateLogoInvalidMimeType(): void { $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('logo'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ - 'tmp_name' => __DIR__ . '/../../../../tests/data/lorem.txt', + 'tmp_name' => __DIR__ . '/../../../../tests/data/lorem.txt', 'type' => 'application/pdf', 'name' => 'logo.pdf', 'error' => 0, @@ -331,8 +319,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => 'Unsupported image type', ], 'status' => 'failure' @@ -343,7 +331,7 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - public function dataUpdateImages() { + public static function dataUpdateImages(): array { return [ ['image/jpeg', false], ['image/jpeg', true], @@ -354,20 +342,20 @@ class ThemingControllerTest extends TestCase { ]; } - /** @dataProvider dataUpdateImages */ - public function testUpdateLogoNormalLogoUpload($mimeType, $folderExists = true) { - $tmpLogo = \OC::$server->getTempManager()->getTemporaryFolder() . '/logo.svg'; - $destination = \OC::$server->getTempManager()->getTemporaryFolder(); + #[\PHPUnit\Framework\Attributes\DataProvider('dataUpdateImages')] + public function testUpdateLogoNormalLogoUpload(string $mimeType, bool $folderExists = true): void { + $tmpLogo = Server::get(ITempManager::class)->getTemporaryFolder() . '/logo.svg'; + $destination = Server::get(ITempManager::class)->getTemporaryFolder(); touch($tmpLogo); copy(__DIR__ . '/../../../../tests/data/testimage.png', $tmpLogo); $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('logo'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ @@ -383,9 +371,6 @@ class ThemingControllerTest extends TestCase { return $str; }); - $this->urlGenerator->expects($this->once()) - ->method('linkTo') - ->willReturn('serverCss'); $this->imageManager->expects($this->once()) ->method('getImageUrl') ->with('logo') @@ -396,12 +381,11 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'name' => 'logo.svg', 'message' => 'Saved', 'url' => 'imageUrl', - 'serverCssUrl' => 'serverCss' ], 'status' => 'success' ] @@ -410,19 +394,18 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - /** @dataProvider dataUpdateImages */ - public function testUpdateLogoLoginScreenUpload($folderExists) { - $tmpLogo = \OC::$server->getTempManager()->getTemporaryFolder() . 'logo.png'; + public function testUpdateLogoLoginScreenUpload(): void { + $tmpLogo = Server::get(ITempManager::class)->getTemporaryFolder() . 'logo.png'; touch($tmpLogo); copy(__DIR__ . '/../../../../tests/data/desktopapp.png', $tmpLogo); $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('background'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ @@ -441,21 +424,17 @@ class ThemingControllerTest extends TestCase { $this->imageManager->expects($this->once()) ->method('updateImage'); - $this->urlGenerator->expects($this->once()) - ->method('linkTo') - ->willReturn('serverCss'); $this->imageManager->expects($this->once()) ->method('getImageUrl') ->with('background') ->willReturn('imageUrl'); $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'name' => 'logo.svg', 'message' => 'Saved', 'url' => 'imageUrl', - 'serverCssUrl' => 'serverCss' ], 'status' => 'success' ] @@ -463,18 +442,18 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - public function testUpdateLogoLoginScreenUploadWithInvalidImage() { - $tmpLogo = \OC::$server->getTempManager()->getTemporaryFolder() . '/logo.svg'; + public function testUpdateLogoLoginScreenUploadWithInvalidImage(): void { + $tmpLogo = Server::get(ITempManager::class)->getTemporaryFolder() . '/logo.svg'; touch($tmpLogo); - file_put_contents($tmpLogo, file_get_contents(__DIR__ . '/../../../../tests/data/data.zip')); + file_put_contents($tmpLogo, file_get_contents(__DIR__ . '/../../../../tests/data/data.zip')); $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('logo'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ @@ -496,8 +475,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => 'Unsupported image type', ], 'status' => 'failure' @@ -507,7 +486,7 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - public function dataPhpUploadErrors() { + public static function dataPhpUploadErrors(): array { return [ [UPLOAD_ERR_INI_SIZE, 'The uploaded file exceeds the upload_max_filesize directive in php.ini'], [UPLOAD_ERR_FORM_SIZE, 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'], @@ -519,17 +498,15 @@ class ThemingControllerTest extends TestCase { ]; } - /** - * @dataProvider dataPhpUploadErrors - */ - public function testUpdateLogoLoginScreenUploadWithInvalidImageUpload($error, $expectedErrorMessage) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataPhpUploadErrors')] + public function testUpdateLogoLoginScreenUploadWithInvalidImageUpload(int $error, string $expectedErrorMessage): void { $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('background'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ @@ -547,8 +524,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => $expectedErrorMessage, ], 'status' => 'failure' @@ -558,17 +535,15 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - /** - * @dataProvider dataPhpUploadErrors - */ - public function testUpdateLogoUploadWithInvalidImageUpload($error, $expectedErrorMessage) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataPhpUploadErrors')] + public function testUpdateLogoUploadWithInvalidImageUpload($error, $expectedErrorMessage): void { $this->request - ->expects($this->at(0)) + ->expects($this->once()) ->method('getParam') ->with('key') ->willReturn('background'); $this->request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getUploadedFile') ->with('image') ->willReturn([ @@ -586,8 +561,8 @@ class ThemingControllerTest extends TestCase { $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'message' => $expectedErrorMessage ], 'status' => 'failure' @@ -597,7 +572,7 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->uploadImage()); } - public function testUndo() { + public function testUndo(): void { $this->l10n ->expects($this->once()) ->method('t') @@ -608,24 +583,13 @@ class ThemingControllerTest extends TestCase { ->method('undo') ->with('MySetting') ->willReturn('MyValue'); - $this->scssCacher - ->expects($this->once()) - ->method('getCachedSCSS') - ->with('core', '/core/css/css-variables.scss') - ->willReturn('/core/css/someHash-css-variables.scss'); - $this->urlGenerator - ->expects($this->once()) - ->method('linkTo') - ->with('', '/core/css/someHash-css-variables.scss') - ->willReturn('/nextcloudWebroot/core/css/someHash-css-variables.scss'); $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'value' => 'MyValue', - 'message' => 'Saved', - 'serverCssUrl' => '/nextcloudWebroot/core/css/someHash-css-variables.scss', + 'message' => 'Saved' ], 'status' => 'success' ] @@ -633,15 +597,15 @@ class ThemingControllerTest extends TestCase { $this->assertEquals($expected, $this->themingController->undo('MySetting')); } - public function dataUndoDelete() { + public static function dataUndoDelete(): array { return [ [ 'backgroundMime', 'background' ], [ 'logoMime', 'logo' ] ]; } - /** @dataProvider dataUndoDelete */ - public function testUndoDelete($value, $filename) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataUndoDelete')] + public function testUndoDelete(string $value, string $filename): void { $this->l10n ->expects($this->once()) ->method('t') @@ -652,24 +616,13 @@ class ThemingControllerTest extends TestCase { ->method('undo') ->with($value) ->willReturn($value); - $this->scssCacher - ->expects($this->once()) - ->method('getCachedSCSS') - ->with('core', '/core/css/css-variables.scss') - ->willReturn('/core/css/someHash-css-variables.scss'); - $this->urlGenerator - ->expects($this->once()) - ->method('linkTo') - ->with('', '/core/css/someHash-css-variables.scss') - ->willReturn('/nextcloudWebroot/core/css/someHash-css-variables.scss'); $expected = new DataResponse( [ - 'data' => - [ + 'data' + => [ 'value' => $value, 'message' => 'Saved', - 'serverCssUrl' => '/nextcloudWebroot/core/css/someHash-css-variables.scss', ], 'status' => 'success' ] @@ -679,17 +632,19 @@ class ThemingControllerTest extends TestCase { - public function testGetLogoNotExistent() { + public function testGetLogoNotExistent(): void { $this->imageManager->method('getImage') ->with($this->equalTo('logo')) ->willThrowException(new NotFoundException()); - $expected = new Http\NotFoundResponse(); + $expected = new NotFoundResponse(); $this->assertEquals($expected, $this->themingController->getImage('logo')); } - public function testGetLogo() { + public function testGetLogo(): void { $file = $this->createMock(ISimpleFile::class); + $file->method('getName')->willReturn('logo.svg'); + $file->method('getMTime')->willReturn(42); $this->imageManager->expects($this->once()) ->method('getImage') ->willReturn($file); @@ -699,27 +654,29 @@ class ThemingControllerTest extends TestCase { ->with('theming', 'logoMime', '') ->willReturn('text/svg'); - @$expected = new Http\FileDisplayResponse($file); + @$expected = new FileDisplayResponse($file); $expected->cacheFor(3600); $expected->addHeader('Content-Type', 'text/svg'); $expected->addHeader('Content-Disposition', 'attachment; filename="logo"'); - $csp = new Http\ContentSecurityPolicy(); + $csp = new ContentSecurityPolicy(); $csp->allowInlineStyle(); $expected->setContentSecurityPolicy($csp); @$this->assertEquals($expected, $this->themingController->getImage('logo')); } - public function testGetLoginBackgroundNotExistent() { + public function testGetLoginBackgroundNotExistent(): void { $this->imageManager->method('getImage') ->with($this->equalTo('background')) ->willThrowException(new NotFoundException()); - $expected = new Http\NotFoundResponse(); + $expected = new NotFoundResponse(); $this->assertEquals($expected, $this->themingController->getImage('background')); } - public function testGetLoginBackground() { + public function testGetLoginBackground(): void { $file = $this->createMock(ISimpleFile::class); + $file->method('getName')->willReturn('background.png'); + $file->method('getMTime')->willReturn(42); $this->imageManager->expects($this->once()) ->method('getImage') ->willReturn($file); @@ -730,61 +687,25 @@ class ThemingControllerTest extends TestCase { ->with('theming', 'backgroundMime', '') ->willReturn('image/png'); - @$expected = new Http\FileDisplayResponse($file); + @$expected = new FileDisplayResponse($file); $expected->cacheFor(3600); $expected->addHeader('Content-Type', 'image/png'); $expected->addHeader('Content-Disposition', 'attachment; filename="background"'); - $csp = new Http\ContentSecurityPolicy(); + $csp = new ContentSecurityPolicy(); $csp->allowInlineStyle(); $expected->setContentSecurityPolicy($csp); @$this->assertEquals($expected, $this->themingController->getImage('background')); } - - public function testGetStylesheet() { - $this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn(\OC::$SERVERROOT . '/theming'); - $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); - - $response = new Http\FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']); - $response->cacheFor(86400); - - $actual = $this->themingController->getStylesheet(); - $this->assertEquals($response, $actual); - } - - public function testGetStylesheetFails() { - $this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn(\OC::$SERVERROOT . '/theming'); - $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 testGetStylesheetOutsideServerroot() { - $this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn('/outside/serverroot/theming'); - $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')->with('/outside/serverroot/theming', 'css/theming.scss', 'theming')->willReturn(true); - $this->scssCacher->expects($this->once())->method('getCachedCSS')->willReturn($file); - - $response = new Http\FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']); - $response->cacheFor(86400); - - $actual = $this->themingController->getStylesheet(); - $this->assertEquals($response, $actual); + public static function dataGetManifest(): array { + return [ + [true], + [false], + ]; } - public function testGetManifest() { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetManifest')] + public function testGetManifest(bool $standalone): void { $this->config ->expects($this->once()) ->method('getAppValue') @@ -795,24 +716,26 @@ class ThemingControllerTest extends TestCase { ->method('getName') ->willReturn('Nextcloud'); $this->urlGenerator - ->expects($this->at(0)) + ->expects($this->once()) ->method('getBaseUrl') ->willReturn('localhost'); $this->urlGenerator - ->expects($this->at(1)) - ->method('linkToRoute') - ->with('theming.Icon.getTouchIcon', ['app' => 'core']) - ->willReturn('touchicon'); - $this->urlGenerator - ->expects($this->at(2)) + ->expects($this->exactly(2)) ->method('linkToRoute') - ->with('theming.Icon.getFavicon', ['app' => 'core']) - ->willReturn('favicon'); - $response = new Http\JSONResponse([ + ->willReturnMap([ + ['theming.Icon.getTouchIcon', ['app' => 'core'], 'touchicon'], + ['theming.Icon.getFavicon', ['app' => 'core'], 'favicon'], + ]); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->with('theming.standalone_window.enabled', true) + ->willReturn($standalone); + $response = new JSONResponse([ 'name' => 'Nextcloud', 'start_url' => 'localhost', - 'icons' => - [ + 'icons' + => [ [ 'src' => 'touchicon?v=0', 'type' => 'image/png', @@ -824,7 +747,12 @@ class ThemingControllerTest extends TestCase { 'sizes' => '16x16' ] ], - 'display' => 'standalone' + 'display_override' => [$standalone ? 'minimal-ui' : ''], + 'display' => $standalone ? 'standalone' : 'browser', + 'short_name' => 'Nextcloud', + 'theme_color' => null, + 'background_color' => null, + 'description' => null ]); $response->cacheFor(3600); $this->assertEquals($response, $this->themingController->getManifest('core')); |