You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
10 KiB

  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
  4. *
  5. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  6. * @author Julius Haertl <jus@bitgrid.net>
  7. * @author Julius Härtl <jus@bitgrid.net>
  8. * @author Michael Weimann <mail@michael-weimann.eu>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OCA\Theming\Tests;
  28. use OCA\Theming\ImageManager;
  29. use OCP\Files\IAppData;
  30. use OCP\Files\NotFoundException;
  31. use OCP\Files\SimpleFS\ISimpleFile;
  32. use OCP\Files\SimpleFS\ISimpleFolder;
  33. use OCP\ICacheFactory;
  34. use OCP\IConfig;
  35. use OCP\ILogger;
  36. use OCP\IURLGenerator;
  37. use Test\TestCase;
  38. class ImageManagerTest extends TestCase {
  39. /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
  40. protected $config;
  41. /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */
  42. protected $appData;
  43. /** @var ImageManager */
  44. protected $imageManager;
  45. /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
  46. private $urlGenerator;
  47. /** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */
  48. private $cacheFactory;
  49. /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
  50. private $logger;
  51. protected function setUp(): void {
  52. parent::setUp();
  53. $this->config = $this->createMock(IConfig::class);
  54. $this->appData = $this->createMock(IAppData::class);
  55. $this->urlGenerator = $this->createMock(IURLGenerator::class);
  56. $this->cacheFactory = $this->createMock(ICacheFactory::class);
  57. $this->logger = $this->createMock(ILogger::class);
  58. $this->imageManager = new ImageManager(
  59. $this->config,
  60. $this->appData,
  61. $this->urlGenerator,
  62. $this->cacheFactory,
  63. $this->logger
  64. );
  65. }
  66. private function checkImagick() {
  67. if (!extension_loaded('imagick')) {
  68. $this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
  69. }
  70. $checkImagick = new \Imagick();
  71. if (empty($checkImagick->queryFormats('SVG'))) {
  72. $this->markTestSkipped('No SVG provider present.');
  73. }
  74. if (empty($checkImagick->queryFormats('PNG'))) {
  75. $this->markTestSkipped('No PNG provider present.');
  76. }
  77. }
  78. public function mockGetImage($key, $file) {
  79. /** @var \PHPUnit_Framework_MockObject_MockObject $folder */
  80. $folder = $this->createMock(ISimpleFolder::class);
  81. if ($file === null) {
  82. $folder->expects($this->once())
  83. ->method('getFile')
  84. ->with('logo')
  85. ->willThrowException(new NotFoundException());
  86. } else {
  87. $file->expects($this->once())
  88. ->method('getContent')
  89. ->willReturn(file_get_contents(__DIR__ . '/../../../tests/data/testimage.png'));
  90. $folder->expects($this->at(0))
  91. ->method('fileExists')
  92. ->with('logo')
  93. ->willReturn(true);
  94. $folder->expects($this->at(1))
  95. ->method('fileExists')
  96. ->with('logo.png')
  97. ->willReturn(false);
  98. $folder->expects($this->at(2))
  99. ->method('getFile')
  100. ->with('logo')
  101. ->willReturn($file);
  102. $newFile = $this->createMock(ISimpleFile::class);
  103. $folder->expects($this->at(3))
  104. ->method('newFile')
  105. ->with('logo.png')
  106. ->willReturn($newFile);
  107. $newFile->expects($this->once())
  108. ->method('putContent');
  109. $this->appData->expects($this->once())
  110. ->method('getFolder')
  111. ->with('images')
  112. ->willReturn($folder);
  113. }
  114. }
  115. public function testGetImageUrl() {
  116. $this->checkImagick();
  117. $file = $this->createMock(ISimpleFile::class);
  118. $this->config->expects($this->exactly(2))
  119. ->method('getAppValue')
  120. ->withConsecutive(
  121. ['theming', 'cachebuster', '0'],
  122. ['theming', 'logoMime', '']
  123. )
  124. ->willReturn(0);
  125. $this->mockGetImage('logo', $file);
  126. $this->urlGenerator->expects($this->once())
  127. ->method('linkToRoute')
  128. ->willReturn('url-to-image');
  129. $this->assertEquals('url-to-image?v=0', $this->imageManager->getImageUrl('logo', false));
  130. }
  131. public function testGetImageUrlDefault() {
  132. $this->config->expects($this->exactly(2))
  133. ->method('getAppValue')
  134. ->withConsecutive(
  135. ['theming', 'cachebuster', '0'],
  136. ['theming', 'logoMime', false]
  137. )
  138. ->willReturnOnConsecutiveCalls(0, false);
  139. $this->urlGenerator->expects($this->once())
  140. ->method('imagePath')
  141. ->with('core', 'logo/logo.png')
  142. ->willReturn('logo/logo.png');
  143. $this->assertEquals('logo/logo.png?v=0', $this->imageManager->getImageUrl('logo'));
  144. }
  145. public function testGetImageUrlAbsolute() {
  146. $this->checkImagick();
  147. $file = $this->createMock(ISimpleFile::class);
  148. $this->config->expects($this->exactly(2))
  149. ->method('getAppValue')
  150. ->withConsecutive(
  151. ['theming', 'cachebuster', '0'],
  152. ['theming', 'logoMime', '']
  153. )
  154. ->willReturn(0);
  155. $this->mockGetImage('logo', $file);
  156. $this->urlGenerator->expects($this->at(0))
  157. ->method('getBaseUrl')
  158. ->willReturn('baseurl');
  159. $this->urlGenerator->expects($this->at(1))
  160. ->method('getAbsoluteUrl')
  161. ->willReturn('url-to-image-absolute?v=0');
  162. $this->urlGenerator->expects($this->at(2))
  163. ->method('getAbsoluteUrl')
  164. ->willReturn('url-to-image-absolute?v=0');
  165. $this->assertEquals('url-to-image-absolute?v=0', $this->imageManager->getImageUrlAbsolute('logo', false));
  166. }
  167. public function testGetImage() {
  168. $this->checkImagick();
  169. $this->config->expects($this->once())
  170. ->method('getAppValue')->with('theming', 'logoMime', false)
  171. ->willReturn('png');
  172. $file = $this->createMock(ISimpleFile::class);
  173. $this->mockGetImage('logo', $file);
  174. $this->assertEquals($file, $this->imageManager->getImage('logo', false));
  175. }
  176. public function testGetImageUnset() {
  177. $this->expectException(\OCP\Files\NotFoundException::class);
  178. $this->config->expects($this->once())
  179. ->method('getAppValue')->with('theming', 'logoMime', false)
  180. ->willReturn(false);
  181. $this->imageManager->getImage('logo');
  182. }
  183. public function testGetCacheFolder() {
  184. $folder = $this->createMock(ISimpleFolder::class);
  185. $this->config->expects($this->once())
  186. ->method('getAppValue')
  187. ->with('theming', 'cachebuster', '0')
  188. ->willReturn('0');
  189. $this->appData->expects($this->at(0))
  190. ->method('getFolder')
  191. ->with('0')
  192. ->willReturn($folder);
  193. $this->assertEquals($folder, $this->imageManager->getCacheFolder());
  194. }
  195. public function testGetCacheFolderCreate() {
  196. $folder = $this->createMock(ISimpleFolder::class);
  197. $this->config->expects($this->exactly(2))
  198. ->method('getAppValue')
  199. ->with('theming', 'cachebuster', '0')
  200. ->willReturn('0');
  201. $this->appData->expects($this->at(0))
  202. ->method('getFolder')
  203. ->willThrowException(new NotFoundException());
  204. $this->appData->expects($this->at(1))
  205. ->method('newFolder')
  206. ->with('0')
  207. ->willReturn($folder);
  208. $this->appData->expects($this->at(2))
  209. ->method('getFolder')
  210. ->with('0')
  211. ->willReturn($folder);
  212. $this->appData->expects($this->once())
  213. ->method('getDirectoryListing')
  214. ->willReturn([]);
  215. $this->assertEquals($folder, $this->imageManager->getCacheFolder());
  216. }
  217. public function testGetCachedImage() {
  218. $expected = $this->createMock(ISimpleFile::class);
  219. $folder = $this->setupCacheFolder();
  220. $folder->expects($this->once())
  221. ->method('getFile')
  222. ->with('filename')
  223. ->willReturn($expected);
  224. $this->assertEquals($expected, $this->imageManager->getCachedImage('filename'));
  225. }
  226. public function testGetCachedImageNotFound() {
  227. $this->expectException(\OCP\Files\NotFoundException::class);
  228. $folder = $this->setupCacheFolder();
  229. $folder->expects($this->once())
  230. ->method('getFile')
  231. ->with('filename')
  232. ->will($this->throwException(new \OCP\Files\NotFoundException()));
  233. $image = $this->imageManager->getCachedImage('filename');
  234. }
  235. public function testSetCachedImage() {
  236. $folder = $this->setupCacheFolder();
  237. $file = $this->createMock(ISimpleFile::class);
  238. $folder->expects($this->once())
  239. ->method('fileExists')
  240. ->with('filename')
  241. ->willReturn(true);
  242. $folder->expects($this->once())
  243. ->method('getFile')
  244. ->with('filename')
  245. ->willReturn($file);
  246. $file->expects($this->once())
  247. ->method('putContent')
  248. ->with('filecontent');
  249. $this->assertEquals($file, $this->imageManager->setCachedImage('filename', 'filecontent'));
  250. }
  251. public function testSetCachedImageCreate() {
  252. $folder = $this->setupCacheFolder();
  253. $file = $this->createMock(ISimpleFile::class);
  254. $folder->expects($this->once())
  255. ->method('fileExists')
  256. ->with('filename')
  257. ->willReturn(false);
  258. $folder->expects($this->once())
  259. ->method('newFile')
  260. ->with('filename')
  261. ->willReturn($file);
  262. $file->expects($this->once())
  263. ->method('putContent')
  264. ->with('filecontent');
  265. $this->assertEquals($file, $this->imageManager->setCachedImage('filename', 'filecontent'));
  266. }
  267. private function setupCacheFolder() {
  268. $folder = $this->createMock(ISimpleFolder::class);
  269. $this->config->expects($this->once())
  270. ->method('getAppValue')
  271. ->with('theming', 'cachebuster', '0')
  272. ->willReturn('0');
  273. $this->appData->expects($this->at(0))
  274. ->method('getFolder')
  275. ->with('0')
  276. ->willReturn($folder);
  277. return $folder;
  278. }
  279. public function testCleanup() {
  280. $folders = [
  281. $this->createMock(ISimpleFolder::class),
  282. $this->createMock(ISimpleFolder::class),
  283. $this->createMock(ISimpleFolder::class)
  284. ];
  285. foreach ($folders as $index=>$folder) {
  286. $folder->expects($this->any())
  287. ->method('getName')
  288. ->willReturn($index);
  289. }
  290. $folders[0]->expects($this->once())->method('delete');
  291. $folders[1]->expects($this->once())->method('delete');
  292. $folders[2]->expects($this->never())->method('delete');
  293. $this->config->expects($this->once())
  294. ->method('getAppValue')
  295. ->with('theming','cachebuster','0')
  296. ->willReturn('2');
  297. $this->appData->expects($this->once())
  298. ->method('getDirectoryListing')
  299. ->willReturn($folders);
  300. $this->appData->expects($this->once())
  301. ->method('getFolder')
  302. ->with('2')
  303. ->willReturn($folders[2]);
  304. $this->imageManager->cleanup();
  305. }
  306. }