ThemingDefaultsTest.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  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->exactly(2))
  374. ->method('getAppValue')
  375. ->willReturnMap([
  376. ['theming', 'disable-user-theming', 'no', 'no'],
  377. ['theming', 'color', '', $this->defaults->getColorPrimary()],
  378. ]);
  379. $this->assertEquals($this->defaults->getColorPrimary(), $this->template->getColorPrimary());
  380. }
  381. public function testGetColorPrimaryWithCustom() {
  382. $this->config
  383. ->expects($this->exactly(2))
  384. ->method('getAppValue')
  385. ->willReturnMap([
  386. ['theming', 'disable-user-theming', 'no', 'no'],
  387. ['theming', 'color', '', '#fff'],
  388. ]);
  389. $this->assertEquals('#fff', $this->template->getColorPrimary());
  390. }
  391. public function testGetColorPrimaryWithDefaultBackground() {
  392. $user = $this->createMock(IUser::class);
  393. $this->userSession->expects($this->any())
  394. ->method('getUser')
  395. ->willReturn($user);
  396. $user->expects($this->any())
  397. ->method('getUID')
  398. ->willReturn('user');
  399. $this->config
  400. ->expects($this->exactly(2))
  401. ->method('getAppValue')
  402. ->willReturnMap([
  403. ['theming', 'disable-user-theming', 'no', 'no'],
  404. ['theming', 'color', '', ''],
  405. ]);
  406. $this->config
  407. ->expects($this->once())
  408. ->method('getUserValue')
  409. ->with('user', 'theming', 'background_color')
  410. ->willReturn('');
  411. $this->assertEquals(BackgroundService::DEFAULT_COLOR, $this->template->getColorPrimary());
  412. }
  413. public function testGetColorPrimaryWithCustomBackground() {
  414. $backgroundIndex = 2;
  415. $background = array_values(BackgroundService::SHIPPED_BACKGROUNDS)[$backgroundIndex];
  416. $user = $this->createMock(IUser::class);
  417. $this->userSession->expects($this->any())
  418. ->method('getUser')
  419. ->willReturn($user);
  420. $user->expects($this->any())
  421. ->method('getUID')
  422. ->willReturn('user');
  423. $this->config
  424. ->expects($this->once())
  425. ->method('getUserValue')
  426. ->with('user', 'theming', 'background_color', '')
  427. ->willReturn($background['primary_color']);
  428. $this->config
  429. ->expects($this->exactly(2))
  430. ->method('getAppValue')
  431. ->willReturnMap([
  432. ['theming', 'color', '', ''],
  433. ['theming', 'disable-user-theming', 'no', 'no'],
  434. ]);
  435. $this->assertEquals($background['primary_color'], $this->template->getColorPrimary());
  436. }
  437. public function testGetColorPrimaryWithCustomBackgroundColor() {
  438. $user = $this->createMock(IUser::class);
  439. $this->userSession->expects($this->any())
  440. ->method('getUser')
  441. ->willReturn($user);
  442. $user->expects($this->any())
  443. ->method('getUID')
  444. ->willReturn('user');
  445. $this->config
  446. ->expects($this->once())
  447. ->method('getUserValue')
  448. ->with('user', 'theming', 'background_color', '')
  449. ->willReturn('#fff');
  450. $this->config
  451. ->expects($this->exactly(2))
  452. ->method('getAppValue')
  453. ->willReturnMap([
  454. ['theming', 'color', '', ''],
  455. ['theming', 'disable-user-theming', 'no', 'no'],
  456. ]);
  457. $this->assertEquals('#fff', $this->template->getColorPrimary());
  458. }
  459. public function testGetColorPrimaryWithInvalidCustomBackgroundColor() {
  460. $user = $this->createMock(IUser::class);
  461. $this->userSession->expects($this->any())
  462. ->method('getUser')
  463. ->willReturn($user);
  464. $user->expects($this->any())
  465. ->method('getUID')
  466. ->willReturn('user');
  467. $this->config
  468. ->expects($this->once())
  469. ->method('getUserValue')
  470. ->with('user', 'theming', 'background_color', '')
  471. ->willReturn('nextcloud');
  472. $this->config
  473. ->expects($this->exactly(3))
  474. ->method('getAppValue')
  475. ->willReturnMap([
  476. ['theming', 'color', '', ''],
  477. ['theming', 'disable-user-theming', 'no', 'no'],
  478. ]);
  479. $this->assertEquals($this->template->getDefaultColorPrimary(), $this->template->getColorPrimary());
  480. }
  481. public function testSet() {
  482. $this->config
  483. ->expects($this->exactly(2))
  484. ->method('setAppValue')
  485. ->withConsecutive(
  486. ['theming', 'MySetting', 'MyValue'],
  487. ['theming', 'cachebuster', 16],
  488. );
  489. $this->config
  490. ->expects($this->once())
  491. ->method('getAppValue')
  492. ->with('theming', 'cachebuster', '0')
  493. ->willReturn('15');
  494. $this->cacheFactory
  495. ->expects($this->exactly(2))
  496. ->method('createDistributed')
  497. ->withConsecutive(
  498. ['theming-'],
  499. ['imagePath'],
  500. )
  501. ->willReturn($this->cache);
  502. $this->cache
  503. ->expects($this->any())
  504. ->method('clear')
  505. ->with('');
  506. $this->template->set('MySetting', 'MyValue');
  507. }
  508. public function testUndoName() {
  509. $this->config
  510. ->expects($this->once())
  511. ->method('deleteAppValue')
  512. ->with('theming', 'name');
  513. $this->config
  514. ->expects($this->exactly(2))
  515. ->method('getAppValue')
  516. ->withConsecutive(
  517. ['theming', 'cachebuster', '0'],
  518. ['theming', 'name', 'Nextcloud'],
  519. )->willReturnOnConsecutiveCalls(
  520. '15',
  521. 'Nextcloud',
  522. );
  523. $this->config
  524. ->expects($this->once())
  525. ->method('setAppValue')
  526. ->with('theming', 'cachebuster', 16);
  527. $this->assertSame('Nextcloud', $this->template->undo('name'));
  528. }
  529. public function testUndoBaseUrl() {
  530. $this->config
  531. ->expects($this->once())
  532. ->method('deleteAppValue')
  533. ->with('theming', 'url');
  534. $this->config
  535. ->expects($this->exactly(2))
  536. ->method('getAppValue')
  537. ->withConsecutive(
  538. ['theming', 'cachebuster', '0'],
  539. ['theming', 'url', $this->defaults->getBaseUrl()],
  540. )->willReturnOnConsecutiveCalls(
  541. '15',
  542. $this->defaults->getBaseUrl(),
  543. );
  544. $this->config
  545. ->expects($this->once())
  546. ->method('setAppValue')
  547. ->with('theming', 'cachebuster', 16);
  548. $this->assertSame($this->defaults->getBaseUrl(), $this->template->undo('url'));
  549. }
  550. public function testUndoSlogan() {
  551. $this->config
  552. ->expects($this->once())
  553. ->method('deleteAppValue')
  554. ->with('theming', 'slogan');
  555. $this->config
  556. ->expects($this->exactly(2))
  557. ->method('getAppValue')
  558. ->withConsecutive(
  559. ['theming', 'cachebuster', '0'],
  560. ['theming', 'slogan', $this->defaults->getSlogan()],
  561. )->willReturnOnConsecutiveCalls(
  562. '15',
  563. $this->defaults->getSlogan(),
  564. );
  565. $this->config
  566. ->expects($this->once())
  567. ->method('setAppValue')
  568. ->with('theming', 'cachebuster', 16);
  569. $this->assertSame($this->defaults->getSlogan(), $this->template->undo('slogan'));
  570. }
  571. public function testUndoColor() {
  572. $this->config
  573. ->expects($this->once())
  574. ->method('deleteAppValue')
  575. ->with('theming', 'color');
  576. $this->config
  577. ->expects($this->exactly(2))
  578. ->method('getAppValue')
  579. ->withConsecutive(
  580. ['theming', 'cachebuster', '0'],
  581. ['theming', 'color', null],
  582. )->willReturnOnConsecutiveCalls(
  583. '15',
  584. $this->defaults->getColorPrimary(),
  585. );
  586. $this->config
  587. ->expects($this->once())
  588. ->method('setAppValue')
  589. ->with('theming', 'cachebuster', 16);
  590. $this->assertSame($this->defaults->getColorPrimary(), $this->template->undo('color'));
  591. }
  592. public function testUndoDefaultAction() {
  593. $this->config
  594. ->expects($this->once())
  595. ->method('deleteAppValue')
  596. ->with('theming', 'defaultitem');
  597. $this->config
  598. ->expects($this->once())
  599. ->method('getAppValue')
  600. ->with('theming', 'cachebuster', '0')
  601. ->willReturn('15');
  602. $this->config
  603. ->expects($this->once())
  604. ->method('setAppValue')
  605. ->with('theming', 'cachebuster', 16);
  606. $this->assertSame('', $this->template->undo('defaultitem'));
  607. }
  608. public function testGetBackground() {
  609. $this->imageManager
  610. ->expects($this->once())
  611. ->method('getImageUrl')
  612. ->with('background')
  613. ->willReturn('custom-background?v=0');
  614. $this->assertEquals('custom-background?v=0', $this->template->getBackground());
  615. }
  616. private function getLogoHelper($withName, $useSvg) {
  617. $this->imageManager->expects($this->any())
  618. ->method('getImage')
  619. ->with('logo')
  620. ->willThrowException(new NotFoundException());
  621. $this->config
  622. ->expects($this->exactly(2))
  623. ->method('getAppValue')
  624. ->withConsecutive(
  625. ['theming', 'logoMime'],
  626. ['theming', 'cachebuster', '0'],
  627. )->willReturnOnConsecutiveCalls(
  628. '',
  629. '0'
  630. );
  631. $this->urlGenerator->expects($this->once())
  632. ->method('imagePath')
  633. ->with('core', $withName)
  634. ->willReturn('core-logo');
  635. $this->assertEquals('core-logo?v=0', $this->template->getLogo($useSvg));
  636. }
  637. public function testGetLogoDefaultWithSvg() {
  638. $this->getLogoHelper('logo/logo.svg', true);
  639. }
  640. public function testGetLogoDefaultWithoutSvg() {
  641. $this->getLogoHelper('logo/logo.png', false);
  642. }
  643. public function testGetLogoCustom() {
  644. $this->config
  645. ->expects($this->exactly(2))
  646. ->method('getAppValue')
  647. ->withConsecutive(
  648. ['theming', 'logoMime', false],
  649. ['theming', 'cachebuster', '0'],
  650. )->willReturnOnConsecutiveCalls(
  651. 'image/svg+xml',
  652. '0',
  653. );
  654. $this->urlGenerator->expects($this->once())
  655. ->method('linkToRoute')
  656. ->with('theming.Theming.getImage')
  657. ->willReturn('custom-logo?v=0');
  658. $this->assertEquals('custom-logo' . '?v=0', $this->template->getLogo());
  659. }
  660. public function testGetScssVariablesCached() {
  661. $this->config->expects($this->any())->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('1');
  662. $this->cacheFactory->expects($this->once())
  663. ->method('createDistributed')
  664. ->with('theming-1-')
  665. ->willReturn($this->cache);
  666. $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(['foo' => 'bar']);
  667. $this->assertEquals(['foo' => 'bar'], $this->template->getScssVariables());
  668. }
  669. public function testGetScssVariables() {
  670. $this->config
  671. ->expects($this->any())
  672. ->method('getAppValue')
  673. ->willReturnMap([
  674. ['theming', 'cachebuster', '0', '0'],
  675. ['theming', 'logoMime', '', 'jpeg'],
  676. ['theming', 'backgroundMime', '', 'jpeg'],
  677. ['theming', 'logoheaderMime', '', 'jpeg'],
  678. ['theming', 'faviconMime', '', 'jpeg'],
  679. ['theming', 'color', '', $this->defaults->getColorPrimary()],
  680. ['theming', 'color', $this->defaults->getColorPrimary(), $this->defaults->getColorPrimary()],
  681. ]);
  682. $this->util->expects($this->any())->method('invertTextColor')->with($this->defaults->getColorPrimary())->willReturn(false);
  683. $this->util->expects($this->any())->method('elementColor')->with($this->defaults->getColorPrimary())->willReturn('#aaaaaa');
  684. $this->cacheFactory->expects($this->once())
  685. ->method('createDistributed')
  686. ->with('theming-0-')
  687. ->willReturn($this->cache);
  688. $this->cache->expects($this->once())->method('get')->with('getScssVariables')->willReturn(null);
  689. $this->imageManager->expects($this->exactly(4))
  690. ->method('getImageUrl')
  691. ->willReturnMap([
  692. ['logo', 'custom-logo?v=0'],
  693. ['logoheader', 'custom-logoheader?v=0'],
  694. ['favicon', 'custom-favicon?v=0'],
  695. ['background', 'custom-background?v=0'],
  696. ]);
  697. $expected = [
  698. 'theming-cachebuster' => '\'0\'',
  699. 'theming-logo-mime' => '\'jpeg\'',
  700. 'theming-background-mime' => '\'jpeg\'',
  701. 'image-logo' => "url('custom-logo?v=0')",
  702. 'image-login-background' => "url('custom-background?v=0')",
  703. 'color-primary' => $this->defaults->getColorPrimary(),
  704. 'color-primary-text' => '#ffffff',
  705. 'image-login-plain' => 'false',
  706. 'color-primary-element' => '#aaaaaa',
  707. 'theming-logoheader-mime' => '\'jpeg\'',
  708. 'theming-favicon-mime' => '\'jpeg\'',
  709. 'image-logoheader' => "url('custom-logoheader?v=0')",
  710. 'image-favicon' => "url('custom-favicon?v=0')",
  711. 'has-legal-links' => 'false'
  712. ];
  713. $this->assertEquals($expected, $this->template->getScssVariables());
  714. }
  715. public function testGetDefaultAndroidURL() {
  716. $this->config
  717. ->expects($this->once())
  718. ->method('getAppValue')
  719. ->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
  720. ->willReturn('https://play.google.com/store/apps/details?id=com.nextcloud.client');
  721. $this->assertEquals('https://play.google.com/store/apps/details?id=com.nextcloud.client', $this->template->getAndroidClientUrl());
  722. }
  723. public function testGetCustomAndroidURL() {
  724. $this->config
  725. ->expects($this->once())
  726. ->method('getAppValue')
  727. ->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
  728. ->willReturn('https://play.google.com/store/apps/details?id=com.mycloud.client');
  729. $this->assertEquals('https://play.google.com/store/apps/details?id=com.mycloud.client', $this->template->getAndroidClientUrl());
  730. }
  731. public function testGetDefaultiOSURL() {
  732. $this->config
  733. ->expects($this->once())
  734. ->method('getAppValue')
  735. ->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
  736. ->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8');
  737. $this->assertEquals('https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8', $this->template->getiOSClientUrl());
  738. }
  739. public function testGetCustomiOSURL() {
  740. $this->config
  741. ->expects($this->once())
  742. ->method('getAppValue')
  743. ->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
  744. ->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1234567890?mt=8');
  745. $this->assertEquals('https://geo.itunes.apple.com/us/app/nextcloud/id1234567890?mt=8', $this->template->getiOSClientUrl());
  746. }
  747. public function testGetDefaultiTunesAppId() {
  748. $this->config
  749. ->expects($this->once())
  750. ->method('getAppValue')
  751. ->with('theming', 'iTunesAppId', '1125420102')
  752. ->willReturn('1125420102');
  753. $this->assertEquals('1125420102', $this->template->getiTunesAppId());
  754. }
  755. public function testGetCustomiTunesAppId() {
  756. $this->config
  757. ->expects($this->once())
  758. ->method('getAppValue')
  759. ->with('theming', 'iTunesAppId', '1125420102')
  760. ->willReturn('1234567890');
  761. $this->assertEquals('1234567890', $this->template->getiTunesAppId());
  762. }
  763. public function dataReplaceImagePath() {
  764. return [
  765. ['core', 'test.png', false],
  766. ['core', 'manifest.json'],
  767. ['core', 'favicon.ico'],
  768. ['core', 'favicon-touch.png']
  769. ];
  770. }
  771. /** @dataProvider dataReplaceImagePath */
  772. public function testReplaceImagePath($app, $image, $result = 'themingRoute?v=1234abcd') {
  773. $this->cache->expects($this->any())
  774. ->method('get')
  775. ->with('shouldReplaceIcons')
  776. ->willReturn(true);
  777. $this->config
  778. ->expects($this->any())
  779. ->method('getAppValue')
  780. ->with('theming', 'cachebuster', '0')
  781. ->willReturn('0');
  782. $this->urlGenerator
  783. ->expects($this->any())
  784. ->method('linkToRoute')
  785. ->willReturn('themingRoute');
  786. if ($result) {
  787. $this->util
  788. ->expects($this->once())
  789. ->method('getCacheBuster')
  790. ->willReturn('1234abcd');
  791. }
  792. $this->assertEquals($result, $this->template->replaceImagePath($app, $image));
  793. }
  794. }