ThemingDefaultsTest.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Bjoern Schiessle <bjoern@schiessle.org>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Guillaume COMPAGNON <gcompagnon@outlook.com>
  9. * @author Jan-Christoph Borchardt <hey@jancborchardt.net>
  10. * @author Joas Schilling <coding@schilljs.com>
  11. * @author John Molakvoæ <skjnldsv@protonmail.com>
  12. * @author Julius Haertl <jus@bitgrid.net>
  13. * @author Julius Härtl <jus@bitgrid.net>
  14. * @author Lukas Reschke <lukas@statuscode.ch>
  15. * @author Michael Weimann <mail@michael-weimann.eu>
  16. * @author Morris Jobke <hey@morrisjobke.de>
  17. * @author Roeland Jago Douma <roeland@famdouma.nl>
  18. *
  19. * @license GNU AGPL version 3 or any later version
  20. *
  21. * This program is free software: you can redistribute it and/or modify
  22. * it under the terms of the GNU Affero General Public License as
  23. * published by the Free Software Foundation, either version 3 of the
  24. * License, or (at your option) any later version.
  25. *
  26. * This program is distributed in the hope that it will be useful,
  27. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. * GNU Affero General Public License for more details.
  30. *
  31. * You should have received a copy of the GNU Affero General Public License
  32. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  33. *
  34. */
  35. namespace OCA\Theming\Tests;
  36. use OCA\Theming\ImageManager;
  37. use OCA\Theming\Service\BackgroundService;
  38. use OCA\Theming\ThemingDefaults;
  39. use OCA\Theming\Util;
  40. use OCP\App\IAppManager;
  41. use OCP\Files\IAppData;
  42. use OCP\Files\NotFoundException;
  43. use OCP\ICache;
  44. use OCP\ICacheFactory;
  45. use OCP\IConfig;
  46. use OCP\IL10N;
  47. use OCP\INavigationManager;
  48. use OCP\IURLGenerator;
  49. use OCP\IUser;
  50. use OCP\IUserSession;
  51. use Test\TestCase;
  52. class ThemingDefaultsTest extends TestCase {
  53. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  54. private $config;
  55. /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
  56. private $l10n;
  57. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  58. private $userSession;
  59. /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
  60. private $urlGenerator;
  61. /** @var \OC_Defaults|\PHPUnit\Framework\MockObject\MockObject */
  62. private $defaults;
  63. /** @var IAppData|\PHPUnit\Framework\MockObject\MockObject */
  64. private $appData;
  65. /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
  66. private $cacheFactory;
  67. /** @var ThemingDefaults */
  68. private $template;
  69. /** @var Util|\PHPUnit\Framework\MockObject\MockObject */
  70. private $util;
  71. /** @var ICache|\PHPUnit\Framework\MockObject\MockObject */
  72. private $cache;
  73. /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */
  74. private $appManager;
  75. /** @var ImageManager|\PHPUnit\Framework\MockObject\MockObject */
  76. private $imageManager;
  77. /** @var INavigationManager|\PHPUnit\Framework\MockObject\MockObject */
  78. private $navigationManager;
  79. protected function setUp(): void {
  80. parent::setUp();
  81. $this->config = $this->createMock(IConfig::class);
  82. $this->l10n = $this->createMock(IL10N::class);
  83. $this->userSession = $this->createMock(IUserSession::class);
  84. $this->urlGenerator = $this->createMock(IURLGenerator::class);
  85. $this->cacheFactory = $this->createMock(ICacheFactory::class);
  86. $this->cache = $this->createMock(ICache::class);
  87. $this->util = $this->createMock(Util::class);
  88. $this->imageManager = $this->createMock(ImageManager::class);
  89. $this->appManager = $this->createMock(IAppManager::class);
  90. $this->navigationManager = $this->createMock(INavigationManager::class);
  91. $this->defaults = new \OC_Defaults();
  92. $this->urlGenerator
  93. ->expects($this->any())
  94. ->method('getBaseUrl')
  95. ->willReturn('');
  96. $this->template = new ThemingDefaults(
  97. $this->config,
  98. $this->l10n,
  99. $this->userSession,
  100. $this->urlGenerator,
  101. $this->cacheFactory,
  102. $this->util,
  103. $this->imageManager,
  104. $this->appManager,
  105. $this->navigationManager
  106. );
  107. }
  108. public function testGetNameWithDefault() {
  109. $this->config
  110. ->expects($this->once())
  111. ->method('getAppValue')
  112. ->with('theming', 'name', 'Nextcloud')
  113. ->willReturn('Nextcloud');
  114. $this->assertEquals('Nextcloud', $this->template->getName());
  115. }
  116. public function testGetNameWithCustom() {
  117. $this->config
  118. ->expects($this->once())
  119. ->method('getAppValue')
  120. ->with('theming', 'name', 'Nextcloud')
  121. ->willReturn('MyCustomCloud');
  122. $this->assertEquals('MyCustomCloud', $this->template->getName());
  123. }
  124. public function testGetHTMLNameWithDefault() {
  125. $this->config
  126. ->expects($this->once())
  127. ->method('getAppValue')
  128. ->with('theming', 'name', 'Nextcloud')
  129. ->willReturn('Nextcloud');
  130. $this->assertEquals('Nextcloud', $this->template->getHTMLName());
  131. }
  132. public function testGetHTMLNameWithCustom() {
  133. $this->config
  134. ->expects($this->once())
  135. ->method('getAppValue')
  136. ->with('theming', 'name', 'Nextcloud')
  137. ->willReturn('MyCustomCloud');
  138. $this->assertEquals('MyCustomCloud', $this->template->getHTMLName());
  139. }
  140. public function testGetTitleWithDefault() {
  141. $this->config
  142. ->expects($this->once())
  143. ->method('getAppValue')
  144. ->with('theming', 'name', 'Nextcloud')
  145. ->willReturn('Nextcloud');
  146. $this->assertEquals('Nextcloud', $this->template->getTitle());
  147. }
  148. public function testGetTitleWithCustom() {
  149. $this->config
  150. ->expects($this->once())
  151. ->method('getAppValue')
  152. ->with('theming', 'name', 'Nextcloud')
  153. ->willReturn('MyCustomCloud');
  154. $this->assertEquals('MyCustomCloud', $this->template->getTitle());
  155. }
  156. public function testGetEntityWithDefault() {
  157. $this->config
  158. ->expects($this->once())
  159. ->method('getAppValue')
  160. ->with('theming', 'name', 'Nextcloud')
  161. ->willReturn('Nextcloud');
  162. $this->assertEquals('Nextcloud', $this->template->getEntity());
  163. }
  164. public function testGetEntityWithCustom() {
  165. $this->config
  166. ->expects($this->once())
  167. ->method('getAppValue')
  168. ->with('theming', 'name', 'Nextcloud')
  169. ->willReturn('MyCustomCloud');
  170. $this->assertEquals('MyCustomCloud', $this->template->getEntity());
  171. }
  172. public function testGetBaseUrlWithDefault() {
  173. $this->config
  174. ->expects($this->once())
  175. ->method('getAppValue')
  176. ->with('theming', 'url', $this->defaults->getBaseUrl())
  177. ->willReturn($this->defaults->getBaseUrl());
  178. $this->assertEquals($this->defaults->getBaseUrl(), $this->template->getBaseUrl());
  179. }
  180. public function testGetBaseUrlWithCustom() {
  181. $this->config
  182. ->expects($this->once())
  183. ->method('getAppValue')
  184. ->with('theming', 'url', $this->defaults->getBaseUrl())
  185. ->willReturn('https://example.com/');
  186. $this->assertEquals('https://example.com/', $this->template->getBaseUrl());
  187. }
  188. public function legalUrlProvider() {
  189. return [
  190. [ '' ],
  191. [ 'https://example.com/legal.html']
  192. ];
  193. }
  194. /**
  195. * @param $imprintUrl
  196. * @dataProvider legalUrlProvider
  197. */
  198. public function testGetImprintURL($imprintUrl) {
  199. $this->config
  200. ->expects($this->once())
  201. ->method('getAppValue')
  202. ->with('theming', 'imprintUrl', '')
  203. ->willReturn($imprintUrl);
  204. $this->assertEquals($imprintUrl, $this->template->getImprintUrl());
  205. }
  206. /**
  207. * @param $privacyUrl
  208. * @dataProvider legalUrlProvider
  209. */
  210. public function testGetPrivacyURL($privacyUrl) {
  211. $this->config
  212. ->expects($this->once())
  213. ->method('getAppValue')
  214. ->with('theming', 'privacyUrl', '')
  215. ->willReturn($privacyUrl);
  216. $this->assertEquals($privacyUrl, $this->template->getPrivacyUrl());
  217. }
  218. public function testGetSloganWithDefault() {
  219. $this->config
  220. ->expects($this->once())
  221. ->method('getAppValue')
  222. ->with('theming', 'slogan', $this->defaults->getSlogan())
  223. ->willReturn($this->defaults->getSlogan());
  224. $this->assertEquals($this->defaults->getSlogan(), $this->template->getSlogan());
  225. }
  226. public function testGetSloganWithCustom() {
  227. $this->config
  228. ->expects($this->once())
  229. ->method('getAppValue')
  230. ->with('theming', 'slogan', $this->defaults->getSlogan())
  231. ->willReturn('My custom Slogan');
  232. $this->assertEquals('My custom Slogan', $this->template->getSlogan());
  233. }
  234. public function testGetShortFooter() {
  235. $this->config
  236. ->expects($this->exactly(5))
  237. ->method('getAppValue')
  238. ->willReturnMap([
  239. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  240. ['theming', 'name', 'Nextcloud', 'Name'],
  241. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  242. ['theming', 'imprintUrl', '', ''],
  243. ['theming', 'privacyUrl', '', ''],
  244. ]);
  245. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan', $this->template->getShortFooter());
  246. }
  247. public function testGetShortFooterEmptyUrl() {
  248. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  249. $this->config
  250. ->expects($this->exactly(5))
  251. ->method('getAppValue')
  252. ->willReturnMap([
  253. ['theming', 'url', $this->defaults->getBaseUrl(), ''],
  254. ['theming', 'name', 'Nextcloud', 'Name'],
  255. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  256. ['theming', 'imprintUrl', '', ''],
  257. ['theming', 'privacyUrl', '', ''],
  258. ]);
  259. $this->assertEquals('<span class="entity-name">Name</span> – Slogan', $this->template->getShortFooter());
  260. }
  261. public function testGetShortFooterEmptySlogan() {
  262. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  263. $this->config
  264. ->expects($this->exactly(5))
  265. ->method('getAppValue')
  266. ->willReturnMap([
  267. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  268. ['theming', 'name', 'Nextcloud', 'Name'],
  269. ['theming', 'slogan', $this->defaults->getSlogan(), ''],
  270. ['theming', 'imprintUrl', '', ''],
  271. ['theming', 'privacyUrl', '', ''],
  272. ]);
  273. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a>', $this->template->getShortFooter());
  274. }
  275. public function testGetShortFooterImprint() {
  276. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  277. $this->config
  278. ->expects($this->exactly(5))
  279. ->method('getAppValue')
  280. ->willReturnMap([
  281. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  282. ['theming', 'name', 'Nextcloud', 'Name'],
  283. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  284. ['theming', 'imprintUrl', '', 'https://example.com/imprint'],
  285. ['theming', 'privacyUrl', '', ''],
  286. ]);
  287. $this->l10n
  288. ->expects($this->any())
  289. ->method('t')
  290. ->willReturnArgument(0);
  291. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan<br/><a href="https://example.com/imprint" class="legal" target="_blank" rel="noreferrer noopener">Legal notice</a>', $this->template->getShortFooter());
  292. }
  293. public function testGetShortFooterPrivacy() {
  294. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  295. $this->config
  296. ->expects($this->exactly(5))
  297. ->method('getAppValue')
  298. ->willReturnMap([
  299. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  300. ['theming', 'name', 'Nextcloud', 'Name'],
  301. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  302. ['theming', 'imprintUrl', '', ''],
  303. ['theming', 'privacyUrl', '', 'https://example.com/privacy'],
  304. ]);
  305. $this->l10n
  306. ->expects($this->any())
  307. ->method('t')
  308. ->willReturnArgument(0);
  309. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan<br/><a href="https://example.com/privacy" class="legal" target="_blank" rel="noreferrer noopener">Privacy policy</a>', $this->template->getShortFooter());
  310. }
  311. public function testGetShortFooterAllLegalLinks() {
  312. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  313. $this->config
  314. ->expects($this->exactly(5))
  315. ->method('getAppValue')
  316. ->willReturnMap([
  317. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  318. ['theming', 'name', 'Nextcloud', 'Name'],
  319. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  320. ['theming', 'imprintUrl', '', 'https://example.com/imprint'],
  321. ['theming', 'privacyUrl', '', 'https://example.com/privacy'],
  322. ]);
  323. $this->l10n
  324. ->expects($this->any())
  325. ->method('t')
  326. ->willReturnArgument(0);
  327. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan<br/><a href="https://example.com/imprint" class="legal" target="_blank" rel="noreferrer noopener">Legal notice</a> · <a href="https://example.com/privacy" class="legal" target="_blank" rel="noreferrer noopener">Privacy policy</a>', $this->template->getShortFooter());
  328. }
  329. public function invalidLegalUrlProvider() {
  330. return [
  331. ['example.com/legal'], # missing scheme
  332. ['https:///legal'], # missing host
  333. ];
  334. }
  335. /**
  336. * @param $invalidImprintUrl
  337. * @dataProvider invalidLegalUrlProvider
  338. */
  339. public function testGetShortFooterInvalidImprint($invalidImprintUrl) {
  340. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  341. $this->config
  342. ->expects($this->exactly(5))
  343. ->method('getAppValue')
  344. ->willReturnMap([
  345. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  346. ['theming', 'name', 'Nextcloud', 'Name'],
  347. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  348. ['theming', 'imprintUrl', '', $invalidImprintUrl],
  349. ['theming', 'privacyUrl', '', ''],
  350. ]);
  351. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan', $this->template->getShortFooter());
  352. }
  353. /**
  354. * @param $invalidPrivacyUrl
  355. * @dataProvider invalidLegalUrlProvider
  356. */
  357. public function testGetShortFooterInvalidPrivacy($invalidPrivacyUrl) {
  358. $this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
  359. $this->config
  360. ->expects($this->exactly(5))
  361. ->method('getAppValue')
  362. ->willReturnMap([
  363. ['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
  364. ['theming', 'name', 'Nextcloud', 'Name'],
  365. ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'],
  366. ['theming', 'imprintUrl', '', ''],
  367. ['theming', 'privacyUrl', '', $invalidPrivacyUrl],
  368. ]);
  369. $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener" class="entity-name">Name</a> – Slogan', $this->template->getShortFooter());
  370. }
  371. public function testGetColorPrimaryWithDefault() {
  372. $this->config
  373. ->expects($this->at(0))
  374. ->method('getAppValue')
  375. ->with('theming', 'color', null)
  376. ->willReturn($this->defaults->getColorPrimary());
  377. $this->config
  378. ->expects($this->at(1))
  379. ->method('getAppValue')
  380. ->with('theming', 'disable-user-theming', 'no')
  381. ->willReturn('no');
  382. $this->assertEquals($this->defaults->getColorPrimary(), $this->template->getColorPrimary());
  383. }
  384. public function testGetColorPrimaryWithCustom() {
  385. $this->config
  386. ->expects($this->at(0))
  387. ->method('getAppValue')
  388. ->with('theming', 'color', null)
  389. ->willReturn('#fff');
  390. $this->config
  391. ->expects($this->at(1))
  392. ->method('getAppValue')
  393. ->with('theming', 'disable-user-theming', 'no')
  394. ->willReturn('no');
  395. $this->assertEquals('#fff', $this->template->getColorPrimary());
  396. }
  397. public function testGetColorPrimaryWithDefaultBackground() {
  398. $user = $this->createMock(IUser::class);
  399. $this->userSession->expects($this->any())
  400. ->method('getUser')
  401. ->willReturn($user);
  402. $user->expects($this->any())
  403. ->method('getUID')
  404. ->willReturn('user');
  405. $this->assertEquals(BackgroundService::DEFAULT_COLOR, $this->template->getColorPrimary());
  406. }
  407. public function testGetColorPrimaryWithCustomBackground() {
  408. $backgroundIndex = 2;
  409. $background = array_values(BackgroundService::SHIPPED_BACKGROUNDS)[$backgroundIndex];
  410. $user = $this->createMock(IUser::class);
  411. $this->userSession->expects($this->any())
  412. ->method('getUser')
  413. ->willReturn($user);
  414. $user->expects($this->any())
  415. ->method('getUID')
  416. ->willReturn('user');
  417. $this->config
  418. ->expects($this->once())
  419. ->method('getUserValue')
  420. ->with('user', 'theming', 'background', '')
  421. ->willReturn(array_keys(BackgroundService::SHIPPED_BACKGROUNDS)[$backgroundIndex]);
  422. $this->assertEquals($background['primary_color'], $this->template->getColorPrimary());
  423. }
  424. public function testGetColorPrimaryWithCustomBackgroundColor() {
  425. $user = $this->createMock(IUser::class);
  426. $this->userSession->expects($this->any())
  427. ->method('getUser')
  428. ->willReturn($user);
  429. $user->expects($this->any())
  430. ->method('getUID')
  431. ->willReturn('user');
  432. $this->config
  433. ->expects($this->once())
  434. ->method('getUserValue')
  435. ->with('user', 'theming', 'background', '')
  436. ->willReturn('#fff');
  437. $this->assertEquals('#fff', $this->template->getColorPrimary());
  438. }
  439. public function testGetColorPrimaryWithInvalidCustomBackgroundColor() {
  440. $user = $this->createMock(IUser::class);
  441. $this->userSession->expects($this->any())
  442. ->method('getUser')
  443. ->willReturn($user);
  444. $user->expects($this->any())
  445. ->method('getUID')
  446. ->willReturn('user');
  447. $this->config
  448. ->expects($this->once())
  449. ->method('getUserValue')
  450. ->with('user', 'theming', 'background', '')
  451. ->willReturn('nextcloud');
  452. $this->assertEquals($this->template->getDefaultColorPrimary(), $this->template->getColorPrimary());
  453. }
  454. public function testSet() {
  455. $this->config
  456. ->expects($this->exactly(2))
  457. ->method('setAppValue')
  458. ->withConsecutive(
  459. ['theming', 'MySetting', 'MyValue'],
  460. ['theming', 'cachebuster', 16],
  461. );
  462. $this->config
  463. ->expects($this->once())
  464. ->method('getAppValue')
  465. ->with('theming', 'cachebuster', '0')
  466. ->willReturn('15');
  467. $this->cacheFactory
  468. ->expects($this->exactly(2))
  469. ->method('createDistributed')
  470. ->withConsecutive(
  471. ['theming-'],
  472. ['imagePath'],
  473. )
  474. ->willReturn($this->cache);
  475. $this->cache
  476. ->expects($this->any())
  477. ->method('clear')
  478. ->with('');
  479. $this->template->set('MySetting', 'MyValue');
  480. }
  481. public function testUndoName() {
  482. $this->config
  483. ->expects($this->once())
  484. ->method('deleteAppValue')
  485. ->with('theming', 'name');
  486. $this->config
  487. ->expects($this->exactly(2))
  488. ->method('getAppValue')
  489. ->withConsecutive(
  490. ['theming', 'cachebuster', '0'],
  491. ['theming', 'name', 'Nextcloud'],
  492. )->willReturnOnConsecutiveCalls(
  493. '15',
  494. 'Nextcloud',
  495. );
  496. $this->config
  497. ->expects($this->once())
  498. ->method('setAppValue')
  499. ->with('theming', 'cachebuster', 16);
  500. $this->assertSame('Nextcloud', $this->template->undo('name'));
  501. }
  502. public function testUndoBaseUrl() {
  503. $this->config
  504. ->expects($this->once())
  505. ->method('deleteAppValue')
  506. ->with('theming', 'url');
  507. $this->config
  508. ->expects($this->exactly(2))
  509. ->method('getAppValue')
  510. ->withConsecutive(
  511. ['theming', 'cachebuster', '0'],
  512. ['theming', 'url', $this->defaults->getBaseUrl()],
  513. )->willReturnOnConsecutiveCalls(
  514. '15',
  515. $this->defaults->getBaseUrl(),
  516. );
  517. $this->config
  518. ->expects($this->once())
  519. ->method('setAppValue')
  520. ->with('theming', 'cachebuster', 16);
  521. $this->assertSame($this->defaults->getBaseUrl(), $this->template->undo('url'));
  522. }
  523. public function testUndoSlogan() {
  524. $this->config
  525. ->expects($this->once())
  526. ->method('deleteAppValue')
  527. ->with('theming', 'slogan');
  528. $this->config
  529. ->expects($this->exactly(2))
  530. ->method('getAppValue')
  531. ->withConsecutive(
  532. ['theming', 'cachebuster', '0'],
  533. ['theming', 'slogan', $this->defaults->getSlogan()],
  534. )->willReturnOnConsecutiveCalls(
  535. '15',
  536. $this->defaults->getSlogan(),
  537. );
  538. $this->config
  539. ->expects($this->once())
  540. ->method('setAppValue')
  541. ->with('theming', 'cachebuster', 16);
  542. $this->assertSame($this->defaults->getSlogan(), $this->template->undo('slogan'));
  543. }
  544. public function testUndoColor() {
  545. $this->config
  546. ->expects($this->once())
  547. ->method('deleteAppValue')
  548. ->with('theming', 'color');
  549. $this->config
  550. ->expects($this->exactly(3))
  551. ->method('getAppValue')
  552. ->withConsecutive(
  553. ['theming', 'cachebuster', '0'],
  554. ['theming', 'color', null],
  555. ['theming', 'disable-user-theming', 'no'],
  556. )->willReturnOnConsecutiveCalls(
  557. '15',
  558. $this->defaults->getColorPrimary(),
  559. 'no',
  560. );
  561. $this->config
  562. ->expects($this->once())
  563. ->method('setAppValue')
  564. ->with('theming', 'cachebuster', 16);
  565. $this->assertSame($this->defaults->getColorPrimary(), $this->template->undo('color'));
  566. }
  567. public function testUndoDefaultAction() {
  568. $this->config
  569. ->expects($this->once())
  570. ->method('deleteAppValue')
  571. ->with('theming', 'defaultitem');
  572. $this->config
  573. ->expects($this->once())
  574. ->method('getAppValue')
  575. ->with('theming', 'cachebuster', '0')
  576. ->willReturn('15');
  577. $this->config
  578. ->expects($this->once())
  579. ->method('setAppValue')
  580. ->with('theming', 'cachebuster', 16);
  581. $this->assertSame('', $this->template->undo('defaultitem'));
  582. }
  583. public function testGetBackground() {
  584. $this->imageManager
  585. ->expects($this->once())
  586. ->method('getImageUrl')
  587. ->with('background')
  588. ->willReturn('custom-background?v=0');
  589. $this->assertEquals('custom-background?v=0', $this->template->getBackground());
  590. }
  591. private function getLogoHelper($withName, $useSvg) {
  592. $this->imageManager->expects($this->any())
  593. ->method('getImage')
  594. ->with('logo')
  595. ->willThrowException(new NotFoundException());
  596. $this->config
  597. ->expects($this->exactly(2))
  598. ->method('getAppValue')
  599. ->withConsecutive(
  600. ['theming', 'logoMime'],
  601. ['theming', 'cachebuster', '0'],
  602. )->willReturnOnConsecutiveCalls(
  603. '',
  604. '0'
  605. );
  606. $this->urlGenerator->expects($this->once())
  607. ->method('imagePath')
  608. ->with('core', $withName)
  609. ->willReturn('core-logo');
  610. $this->assertEquals('core-logo?v=0', $this->template->getLogo($useSvg));
  611. }
  612. public function testGetLogoDefaultWithSvg() {
  613. $this->getLogoHelper('logo/logo.svg', true);
  614. }
  615. public function testGetLogoDefaultWithoutSvg() {
  616. $this->getLogoHelper('logo/logo.png', false);
  617. }
  618. public function testGetLogoCustom() {
  619. $this->config
  620. ->expects($this->exactly(2))
  621. ->method('getAppValue')
  622. ->withConsecutive(
  623. ['theming', 'logoMime', false],
  624. ['theming', 'cachebuster', '0'],
  625. )->willReturnOnConsecutiveCalls(
  626. 'image/svg+xml',
  627. '0',
  628. );
  629. $this->urlGenerator->expects($this->once())
  630. ->method('linkToRoute')
  631. ->with('theming.Theming.getImage')
  632. ->willReturn('custom-logo?v=0');
  633. $this->assertEquals('custom-logo' . '?v=0', $this->template->getLogo());
  634. }
  635. public function testGetScssVariablesCached() {
  636. $this->config->expects($this->any())->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('1');
  637. $this->cacheFactory->expects($this->once())
  638. ->method('createDistributed')
  639. ->with('theming-1-')
  640. ->willReturn($this->cache);
  641. $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(['foo' => 'bar']);
  642. $this->assertEquals(['foo' => 'bar'], $this->template->getScssVariables());
  643. }
  644. public function testGetScssVariables() {
  645. $this->config
  646. ->expects($this->any())
  647. ->method('getAppValue')
  648. ->willReturnMap([
  649. ['theming', 'cachebuster', '0', '0'],
  650. ['theming', 'logoMime', '', 'jpeg'],
  651. ['theming', 'backgroundMime', '', 'jpeg'],
  652. ['theming', 'logoheaderMime', '', 'jpeg'],
  653. ['theming', 'faviconMime', '', 'jpeg'],
  654. ['theming', 'color', '', $this->defaults->getColorPrimary()],
  655. ['theming', 'color', $this->defaults->getColorPrimary(), $this->defaults->getColorPrimary()],
  656. ]);
  657. $this->util->expects($this->any())->method('invertTextColor')->with($this->defaults->getColorPrimary())->willReturn(false);
  658. $this->util->expects($this->any())->method('elementColor')->with($this->defaults->getColorPrimary())->willReturn('#aaaaaa');
  659. $this->cacheFactory->expects($this->once())
  660. ->method('createDistributed')
  661. ->with('theming-0-')
  662. ->willReturn($this->cache);
  663. $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(null);
  664. $this->imageManager->expects($this->exactly(4))
  665. ->method('getImageUrl')
  666. ->willReturnMap([
  667. ['logo', true, 'custom-logo?v=0'],
  668. ['logoheader', true, 'custom-logoheader?v=0'],
  669. ['favicon', true, 'custom-favicon?v=0'],
  670. ['background', true, 'custom-background?v=0'],
  671. ]);
  672. $expected = [
  673. 'theming-cachebuster' => '\'0\'',
  674. 'theming-logo-mime' => '\'jpeg\'',
  675. 'theming-background-mime' => '\'jpeg\'',
  676. 'image-logo' => "url('custom-logo?v=0')",
  677. 'image-login-background' => "url('custom-background?v=0')",
  678. 'color-primary' => $this->defaults->getColorPrimary(),
  679. 'color-primary-text' => '#ffffff',
  680. 'image-login-plain' => 'false',
  681. 'color-primary-element' => '#aaaaaa',
  682. 'theming-logoheader-mime' => '\'jpeg\'',
  683. 'theming-favicon-mime' => '\'jpeg\'',
  684. 'image-logoheader' => "url('custom-logoheader?v=0')",
  685. 'image-favicon' => "url('custom-favicon?v=0')",
  686. 'has-legal-links' => 'false'
  687. ];
  688. $this->assertEquals($expected, $this->template->getScssVariables());
  689. }
  690. public function testGetDefaultAndroidURL() {
  691. $this->config
  692. ->expects($this->once())
  693. ->method('getAppValue')
  694. ->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
  695. ->willReturn('https://play.google.com/store/apps/details?id=com.nextcloud.client');
  696. $this->assertEquals('https://play.google.com/store/apps/details?id=com.nextcloud.client', $this->template->getAndroidClientUrl());
  697. }
  698. public function testGetCustomAndroidURL() {
  699. $this->config
  700. ->expects($this->once())
  701. ->method('getAppValue')
  702. ->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
  703. ->willReturn('https://play.google.com/store/apps/details?id=com.mycloud.client');
  704. $this->assertEquals('https://play.google.com/store/apps/details?id=com.mycloud.client', $this->template->getAndroidClientUrl());
  705. }
  706. public function testGetDefaultiOSURL() {
  707. $this->config
  708. ->expects($this->once())
  709. ->method('getAppValue')
  710. ->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
  711. ->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8');
  712. $this->assertEquals('https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8', $this->template->getiOSClientUrl());
  713. }
  714. public function testGetCustomiOSURL() {
  715. $this->config
  716. ->expects($this->once())
  717. ->method('getAppValue')
  718. ->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
  719. ->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1234567890?mt=8');
  720. $this->assertEquals('https://geo.itunes.apple.com/us/app/nextcloud/id1234567890?mt=8', $this->template->getiOSClientUrl());
  721. }
  722. public function testGetDefaultiTunesAppId() {
  723. $this->config
  724. ->expects($this->once())
  725. ->method('getAppValue')
  726. ->with('theming', 'iTunesAppId', '1125420102')
  727. ->willReturn('1125420102');
  728. $this->assertEquals('1125420102', $this->template->getiTunesAppId());
  729. }
  730. public function testGetCustomiTunesAppId() {
  731. $this->config
  732. ->expects($this->once())
  733. ->method('getAppValue')
  734. ->with('theming', 'iTunesAppId', '1125420102')
  735. ->willReturn('1234567890');
  736. $this->assertEquals('1234567890', $this->template->getiTunesAppId());
  737. }
  738. public function dataReplaceImagePath() {
  739. return [
  740. ['core', 'test.png', false],
  741. ['core', 'manifest.json'],
  742. ['core', 'favicon.ico'],
  743. ['core', 'favicon-touch.png']
  744. ];
  745. }
  746. /** @dataProvider dataReplaceImagePath */
  747. public function testReplaceImagePath($app, $image, $result = 'themingRoute?v=0') {
  748. $this->cache->expects($this->any())
  749. ->method('get')
  750. ->with('shouldReplaceIcons')
  751. ->willReturn(true);
  752. $this->config
  753. ->expects($this->any())
  754. ->method('getAppValue')
  755. ->with('theming', 'cachebuster', '0')
  756. ->willReturn('0');
  757. $this->urlGenerator
  758. ->expects($this->any())
  759. ->method('linkToRoute')
  760. ->willReturn('themingRoute');
  761. $this->assertEquals($result, $this->template->replaceImagePath($app, $image));
  762. }
  763. }