IconControllerTest.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
  4. *
  5. * @author Joas Schilling <coding@schilljs.com>
  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 Morris Jobke <hey@morrisjobke.de>
  10. * @author Roeland Jago Douma <roeland@famdouma.nl>
  11. *
  12. * @license GNU AGPL version 3 or any later version
  13. *
  14. * This program is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License as
  16. * published by the Free Software Foundation, either version 3 of the
  17. * License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Affero General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Affero General Public License
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. *
  27. */
  28. namespace OCA\Theming\Tests\Controller;
  29. use OC\Files\SimpleFS\SimpleFile;
  30. use OC\IntegrityCheck\Helpers\FileAccessHelper;
  31. use OCA\Theming\Controller\IconController;
  32. use OCA\Theming\IconBuilder;
  33. use OCA\Theming\ImageManager;
  34. use OCA\Theming\ThemingDefaults;
  35. use OCP\AppFramework\Http;
  36. use OCP\AppFramework\Http\DataDisplayResponse;
  37. use OCP\AppFramework\Http\FileDisplayResponse;
  38. use OCP\AppFramework\Utility\ITimeFactory;
  39. use OCP\Files\NotFoundException;
  40. use OCP\IConfig;
  41. use OCP\IRequest;
  42. use Test\TestCase;
  43. class IconControllerTest extends TestCase {
  44. /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
  45. private $request;
  46. /** @var ThemingDefaults|\PHPUnit\Framework\MockObject\MockObject */
  47. private $themingDefaults;
  48. /** @var \OCP\AppFramework\Utility\ITimeFactory */
  49. private $timeFactory;
  50. /** @var IconController|\PHPUnit\Framework\MockObject\MockObject */
  51. private $iconController;
  52. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  53. private $config;
  54. /** @var IconBuilder|\PHPUnit\Framework\MockObject\MockObject */
  55. private $iconBuilder;
  56. /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
  57. private $fileAccessHelper;
  58. /** @var ImageManager */
  59. private $imageManager;
  60. protected function setUp(): void {
  61. $this->request = $this->createMock(IRequest::class);
  62. $this->themingDefaults = $this->createMock(ThemingDefaults::class);
  63. $this->iconBuilder = $this->createMock(IconBuilder::class);
  64. $this->imageManager = $this->createMock(ImageManager::class);
  65. $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
  66. $this->timeFactory = $this->createMock(ITimeFactory::class);
  67. $this->timeFactory->expects($this->any())
  68. ->method('getTime')
  69. ->willReturn(123);
  70. $this->overwriteService(ITimeFactory::class, $this->timeFactory);
  71. $this->iconController = new IconController(
  72. 'theming',
  73. $this->request,
  74. $this->themingDefaults,
  75. $this->iconBuilder,
  76. $this->imageManager,
  77. $this->fileAccessHelper
  78. );
  79. parent::setUp();
  80. }
  81. private function iconFileMock($filename, $data) {
  82. $icon = $this->getMockBuilder('OCP\Files\File')->getMock();
  83. $icon->expects($this->any())->method('getContent')->willReturn($data);
  84. $icon->expects($this->any())->method('getMimeType')->willReturn('image type');
  85. $icon->expects($this->any())->method('getEtag')->willReturn('my etag');
  86. $icon->expects($this->any())->method('getName')->willReturn('my name');
  87. $icon->expects($this->any())->method('getMTime')->willReturn(42);
  88. $icon->method('getName')->willReturn($filename);
  89. return new SimpleFile($icon);
  90. }
  91. public function testGetThemedIcon() {
  92. $file = $this->iconFileMock('icon-core-filetypes_folder.svg', 'filecontent');
  93. $this->imageManager->expects($this->once())
  94. ->method('getCachedImage')
  95. ->with('icon-core-filetypes_folder.svg')
  96. ->willReturn($file);
  97. $expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
  98. $expected->cacheFor(86400, false, true);
  99. $this->assertEquals($expected, $this->iconController->getThemedIcon('core', 'filetypes/folder.svg'));
  100. }
  101. public function testGetFaviconDefault() {
  102. if (!extension_loaded('imagick')) {
  103. $this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
  104. }
  105. $checkImagick = new \Imagick();
  106. if (count($checkImagick->queryFormats('SVG')) < 1) {
  107. $this->markTestSkipped('No SVG provider present.');
  108. }
  109. $file = $this->iconFileMock('filename', 'filecontent');
  110. $this->imageManager->expects($this->once())
  111. ->method('getImage', false)
  112. ->with('favicon')
  113. ->will($this->throwException(new NotFoundException()));
  114. $this->imageManager->expects($this->any())
  115. ->method('shouldReplaceIcons')
  116. ->willReturn(true);
  117. $this->imageManager->expects($this->once())
  118. ->method('getCachedImage')
  119. ->will($this->throwException(new NotFoundException()));
  120. $this->iconBuilder->expects($this->once())
  121. ->method('getFavicon')
  122. ->with('core')
  123. ->willReturn('filecontent');
  124. $this->imageManager->expects($this->once())
  125. ->method('setCachedImage')
  126. ->willReturn($file);
  127. $expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
  128. $expected->cacheFor(86400);
  129. $this->assertEquals($expected, $this->iconController->getFavicon());
  130. }
  131. public function testGetFaviconFail() {
  132. $this->imageManager->expects($this->once())
  133. ->method('getImage')
  134. ->with('favicon', false)
  135. ->will($this->throwException(new NotFoundException()));
  136. $this->imageManager->expects($this->any())
  137. ->method('shouldReplaceIcons')
  138. ->willReturn(false);
  139. $fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon.png';
  140. $this->fileAccessHelper->expects($this->once())
  141. ->method('file_get_contents')
  142. ->with($fallbackLogo)
  143. ->willReturn(file_get_contents($fallbackLogo));
  144. $expected = new DataDisplayResponse(file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
  145. $expected->cacheFor(86400);
  146. $this->assertEquals($expected, $this->iconController->getFavicon());
  147. }
  148. public function testGetTouchIconDefault() {
  149. if (!extension_loaded('imagick')) {
  150. $this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
  151. }
  152. $checkImagick = new \Imagick();
  153. if (count($checkImagick->queryFormats('SVG')) < 1) {
  154. $this->markTestSkipped('No SVG provider present.');
  155. }
  156. $this->imageManager->expects($this->once())
  157. ->method('getImage')
  158. ->will($this->throwException(new NotFoundException()));
  159. $this->imageManager->expects($this->any())
  160. ->method('shouldReplaceIcons')
  161. ->willReturn(true);
  162. $this->iconBuilder->expects($this->once())
  163. ->method('getTouchIcon')
  164. ->with('core')
  165. ->willReturn('filecontent');
  166. $file = $this->iconFileMock('filename', 'filecontent');
  167. $this->imageManager->expects($this->once())
  168. ->method('getCachedImage')
  169. ->will($this->throwException(new NotFoundException()));
  170. $this->imageManager->expects($this->once())
  171. ->method('setCachedImage')
  172. ->willReturn($file);
  173. $expected = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'image/png']);
  174. $expected->cacheFor(86400);
  175. $this->assertEquals($expected, $this->iconController->getTouchIcon());
  176. }
  177. public function testGetTouchIconFail() {
  178. $this->imageManager->expects($this->once())
  179. ->method('getImage')
  180. ->with('favicon')
  181. ->will($this->throwException(new NotFoundException()));
  182. $this->imageManager->expects($this->any())
  183. ->method('shouldReplaceIcons')
  184. ->willReturn(false);
  185. $fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon-touch.png';
  186. $this->fileAccessHelper->expects($this->once())
  187. ->method('file_get_contents')
  188. ->with($fallbackLogo)
  189. ->willReturn(file_get_contents($fallbackLogo));
  190. $expected = new DataDisplayResponse(file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/png']);
  191. $expected->cacheFor(86400);
  192. $this->assertEquals($expected, $this->iconController->getTouchIcon());
  193. }
  194. }