IconBuilderTest.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
  4. *
  5. * @author Jan-Christoph Borchardt <hey@jancborchardt.net>
  6. * @author Julius Haertl <jus@bitgrid.net>
  7. * @author Julius Härtl <jus@bitgrid.net>
  8. * @author Morris Jobke <hey@morrisjobke.de>
  9. *
  10. * @license GNU AGPL version 3 or any later version
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License as
  14. * published by the Free Software Foundation, either version 3 of the
  15. * License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. *
  25. */
  26. namespace OCA\Theming\Tests;
  27. use OC\Files\AppData\AppData;
  28. use OCA\Theming\IconBuilder;
  29. use OCA\Theming\ImageManager;
  30. use OCA\Theming\ThemingDefaults;
  31. use OCA\Theming\Util;
  32. use OCP\App\IAppManager;
  33. use OCP\Files\NotFoundException;
  34. use OCP\IConfig;
  35. use PHPUnit\Framework\Error\Warning;
  36. use Test\TestCase;
  37. class IconBuilderTest extends TestCase {
  38. /** @var IConfig */
  39. protected $config;
  40. /** @var AppData */
  41. protected $appData;
  42. /** @var ThemingDefaults */
  43. protected $themingDefaults;
  44. /** @var Util */
  45. protected $util;
  46. /** @var ImageManager */
  47. protected $imageManager;
  48. /** @var IconBuilder */
  49. protected $iconBuilder;
  50. /** @var IAppManager */
  51. protected $appManager;
  52. protected function setUp() {
  53. parent::setUp();
  54. $this->config = $this->createMock(IConfig::class);
  55. $this->appData = $this->createMock(AppData::class);
  56. $this->themingDefaults = $this->createMock(ThemingDefaults::class);
  57. $this->appManager = $this->createMock(IAppManager::class);
  58. $this->imageManager = $this->createMock(ImageManager::class);
  59. $this->util = new Util($this->config, $this->appManager, $this->appData);
  60. $this->iconBuilder = new IconBuilder($this->themingDefaults, $this->util, $this->imageManager);
  61. }
  62. private function checkImagick() {
  63. if(!extension_loaded('imagick')) {
  64. $this->markTestSkipped('Imagemagick is required for dynamic icon generation.');
  65. }
  66. $checkImagick = new \Imagick();
  67. if (count($checkImagick->queryFormats('SVG')) < 1) {
  68. $this->markTestSkipped('No SVG provider present.');
  69. }
  70. if (count($checkImagick->queryFormats('PNG')) < 1) {
  71. $this->markTestSkipped('No PNG provider present.');
  72. }
  73. }
  74. public function dataRenderAppIcon() {
  75. return [
  76. ['core', '#0082c9', 'touch-original.png'],
  77. ['core', '#FF0000', 'touch-core-red.png'],
  78. ['testing', '#FF0000', 'touch-testing-red.png'],
  79. ['comments', '#0082c9', 'touch-comments.png'],
  80. ['core', '#0082c9', 'touch-original-png.png'],
  81. ];
  82. }
  83. /**
  84. * @dataProvider dataRenderAppIcon
  85. * @param $app
  86. * @param $color
  87. * @param $file
  88. */
  89. public function testRenderAppIcon($app, $color, $file) {
  90. $this->checkImagick();
  91. $this->themingDefaults->expects($this->once())
  92. ->method('getColorPrimary')
  93. ->willReturn($color);
  94. $this->appData->expects($this->once())
  95. ->method('getFolder')
  96. ->with('images')
  97. ->willThrowException(new NotFoundException());
  98. $expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
  99. $icon = $this->iconBuilder->renderAppIcon($app, 512);
  100. $this->assertEquals(true, $icon->valid());
  101. $this->assertEquals(512, $icon->getImageWidth());
  102. $this->assertEquals(512, $icon->getImageHeight());
  103. $this->assertEquals($icon, $expectedIcon);
  104. $icon->destroy();
  105. $expectedIcon->destroy();
  106. // FIXME: We may need some comparison of the generated and the test images
  107. // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
  108. }
  109. /**
  110. * @dataProvider dataRenderAppIcon
  111. * @param $app
  112. * @param $color
  113. * @param $file
  114. */
  115. public function testGetTouchIcon($app, $color, $file) {
  116. $this->checkImagick();
  117. $this->themingDefaults->expects($this->once())
  118. ->method('getColorPrimary')
  119. ->willReturn($color);
  120. $this->appData->expects($this->once())
  121. ->method('getFolder')
  122. ->with('images')
  123. ->willThrowException(new NotFoundException());
  124. $expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
  125. $icon = new \Imagick();
  126. $icon->readImageBlob($this->iconBuilder->getTouchIcon($app));
  127. $this->assertEquals(true, $icon->valid());
  128. $this->assertEquals(512, $icon->getImageWidth());
  129. $this->assertEquals(512, $icon->getImageHeight());
  130. $this->assertEquals($icon, $expectedIcon);
  131. $icon->destroy();
  132. $expectedIcon->destroy();
  133. // FIXME: We may need some comparison of the generated and the test images
  134. // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
  135. }
  136. /**
  137. * @dataProvider dataRenderAppIcon
  138. * @param $app
  139. * @param $color
  140. * @param $file
  141. */
  142. public function testGetFavicon($app, $color, $file) {
  143. $this->checkImagick();
  144. $this->imageManager->expects($this->once())
  145. ->method('shouldReplaceIcons')
  146. ->willReturn(true);
  147. $this->themingDefaults->expects($this->once())
  148. ->method('getColorPrimary')
  149. ->willReturn($color);
  150. $this->appData->expects($this->once())
  151. ->method('getFolder')
  152. ->with('images')
  153. ->willThrowException(new NotFoundException());
  154. $expectedIcon = new \Imagick(realpath(dirname(__FILE__)). "/data/" . $file);
  155. $actualIcon = $this->iconBuilder->getFavicon($app);
  156. $icon = new \Imagick();
  157. $icon->setFormat('ico');
  158. $icon->readImageBlob($actualIcon);
  159. $this->assertEquals(true, $icon->valid());
  160. $this->assertEquals(128, $icon->getImageWidth());
  161. $this->assertEquals(128, $icon->getImageHeight());
  162. $icon->destroy();
  163. $expectedIcon->destroy();
  164. // FIXME: We may need some comparison of the generated and the test images
  165. // cloud be something like $expectedIcon->compareImages($icon, Imagick::METRIC_MEANABSOLUTEERROR)[1])
  166. }
  167. public function testGetFaviconNotFound() {
  168. $this->checkImagick();
  169. $this->expectException(Warning::class);
  170. $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
  171. $iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
  172. $this->imageManager->expects($this->once())
  173. ->method('shouldReplaceIcons')
  174. ->willReturn(true);
  175. $util->expects($this->once())
  176. ->method('getAppIcon')
  177. ->willReturn('notexistingfile');
  178. $this->assertFalse($iconBuilder->getFavicon('noapp'));
  179. }
  180. public function testGetTouchIconNotFound() {
  181. $this->checkImagick();
  182. $this->expectException(Warning::class);
  183. $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
  184. $iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
  185. $util->expects($this->once())
  186. ->method('getAppIcon')
  187. ->willReturn('notexistingfile');
  188. $this->assertFalse($iconBuilder->getTouchIcon('noapp'));
  189. }
  190. public function testColorSvgNotFound() {
  191. $this->checkImagick();
  192. $this->expectException(Warning::class);
  193. $util = $this->getMockBuilder(Util::class)->disableOriginalConstructor()->getMock();
  194. $iconBuilder = new IconBuilder($this->themingDefaults, $util, $this->imageManager);
  195. $util->expects($this->once())
  196. ->method('getAppImage')
  197. ->willReturn('notexistingfile');
  198. $this->assertFalse($iconBuilder->colorSvg('noapp','noimage'));
  199. }
  200. }