UserAvatarTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\Avatar;
  9. use OC\Files\SimpleFS\SimpleFolder;
  10. use OC\User\User;
  11. use OCP\Files\File;
  12. use OCP\Files\Folder;
  13. use OCP\Files\NotFoundException;
  14. use OCP\Files\SimpleFS\ISimpleFile;
  15. use OCP\IConfig;
  16. use OCP\IL10N;
  17. use OCP\ILogger;
  18. class UserAvatarTest extends \Test\TestCase {
  19. /** @var Folder | \PHPUnit_Framework_MockObject_MockObject */
  20. private $folder;
  21. /** @var \OC\Avatar\UserAvatar */
  22. private $avatar;
  23. /** @var \OC\User\User | \PHPUnit_Framework_MockObject_MockObject $user */
  24. private $user;
  25. /** @var \OCP\IConfig|\PHPUnit_Framework_MockObject_MockObject */
  26. private $config;
  27. public function setUp() {
  28. parent::setUp();
  29. $this->folder = $this->createMock(SimpleFolder::class);
  30. /** @var \OCP\IL10N | \PHPUnit_Framework_MockObject_MockObject $l */
  31. $l = $this->createMock(IL10N::class);
  32. $l->method('t')->will($this->returnArgument(0));
  33. $this->user = $this->createMock(User::class);
  34. $this->config = $this->createMock(IConfig::class);
  35. $this->avatar = new \OC\Avatar\UserAvatar(
  36. $this->folder,
  37. $l,
  38. $this->user,
  39. $this->createMock(ILogger::class),
  40. $this->config
  41. );
  42. // abcdefghi is a convenient name that our algorithm convert to our nextcloud blue 0082c9
  43. $this->user->method('getDisplayName')->willReturn('abcdefghi');
  44. }
  45. public function testGetNoAvatar() {
  46. $file = $this->createMock(ISimpleFile::class);
  47. $this->folder->method('newFile')
  48. ->willReturn($file);
  49. $this->folder->method('getFile')
  50. ->will($this->returnCallback(function($path) {
  51. if ($path === 'avatar.64.png') {
  52. throw new NotFoundException();
  53. }
  54. }));
  55. $this->folder->method('fileExists')
  56. ->will($this->returnCallback(function($path) {
  57. if ($path === 'generated') {
  58. return true;
  59. }
  60. return false;
  61. }));
  62. $data = NULL;
  63. $file->method('putContent')
  64. ->with($this->callback(function ($d) use (&$data) {
  65. $data = $d;
  66. return true;
  67. }));
  68. $file->method('getContent')
  69. ->willReturn($data);
  70. $this->assertEquals($data, $this->avatar->get()->data());
  71. }
  72. public function testGetAvatarSizeMatch() {
  73. $this->folder->method('fileExists')
  74. ->will($this->returnValueMap([
  75. ['avatar.jpg', true],
  76. ['avatar.128.jpg', true],
  77. ]));
  78. $expected = new \OC_Image();
  79. $expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
  80. $file = $this->createMock(File::class);
  81. $file->method('getContent')->willReturn($expected->data());
  82. $this->folder->method('getFile')->with('avatar.128.jpg')->willReturn($file);
  83. $this->assertEquals($expected->data(), $this->avatar->get(128)->data());
  84. }
  85. public function testGetAvatarSizeMinusOne() {
  86. $this->folder->method('fileExists')
  87. ->will($this->returnValueMap([
  88. ['avatar.jpg', true],
  89. ]));
  90. $expected = new \OC_Image();
  91. $expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
  92. $file = $this->createMock(File::class);
  93. $file->method('getContent')->willReturn($expected->data());
  94. $this->folder->method('getFile')->with('avatar.jpg')->willReturn($file);
  95. $this->assertEquals($expected->data(), $this->avatar->get(-1)->data());
  96. }
  97. public function testGetAvatarNoSizeMatch() {
  98. $this->folder->method('fileExists')
  99. ->will($this->returnValueMap([
  100. ['avatar.png', true],
  101. ['avatar.32.png', false],
  102. ]));
  103. $expected = new \OC_Image();
  104. $expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
  105. $expected2 = new \OC_Image();
  106. $expected2->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
  107. $expected2->resize(32);
  108. $file = $this->createMock(File::class);
  109. $file->method('getContent')->willReturn($expected->data());
  110. $this->folder->method('getFile')
  111. ->will($this->returnCallback(
  112. function($path) use ($file) {
  113. if ($path === 'avatar.png') {
  114. return $file;
  115. } else {
  116. throw new \OCP\Files\NotFoundException;
  117. }
  118. }
  119. ));
  120. $newFile = $this->createMock(File::class);
  121. $newFile->expects($this->once())
  122. ->method('putContent')
  123. ->with($expected2->data());
  124. $newFile->expects($this->once())
  125. ->method('getContent')
  126. ->willReturn($expected2->data());
  127. $this->folder->expects($this->once())
  128. ->method('newFile')
  129. ->with('avatar.32.png')
  130. ->willReturn($newFile);
  131. $this->assertEquals($expected2->data(), $this->avatar->get(32)->data());
  132. }
  133. public function testExistsNo() {
  134. $this->assertFalse($this->avatar->exists());
  135. }
  136. public function testExiststJPG() {
  137. $this->folder->method('fileExists')
  138. ->will($this->returnValueMap([
  139. ['avatar.jpg', true],
  140. ['avatar.png', false],
  141. ]));
  142. $this->assertTrue($this->avatar->exists());
  143. }
  144. public function testExistsPNG() {
  145. $this->folder->method('fileExists')
  146. ->will($this->returnValueMap([
  147. ['avatar.jpg', false],
  148. ['avatar.png', true],
  149. ]));
  150. $this->assertTrue($this->avatar->exists());
  151. }
  152. public function testSetAvatar() {
  153. $avatarFileJPG = $this->createMock(File::class);
  154. $avatarFileJPG->method('getName')
  155. ->willReturn('avatar.jpg');
  156. $avatarFileJPG->expects($this->once())->method('delete');
  157. $avatarFilePNG = $this->createMock(File::class);
  158. $avatarFilePNG->method('getName')
  159. ->willReturn('avatar.png');
  160. $avatarFilePNG->expects($this->once())->method('delete');
  161. $resizedAvatarFile = $this->createMock(File::class);
  162. $resizedAvatarFile->method('getName')
  163. ->willReturn('avatar.32.jpg');
  164. $resizedAvatarFile->expects($this->once())->method('delete');
  165. $this->folder->method('getDirectoryListing')
  166. ->willReturn([$avatarFileJPG, $avatarFilePNG, $resizedAvatarFile]);
  167. $generated = $this->createMock(File::class);
  168. $this->folder->method('getFile')
  169. ->with('generated')
  170. ->willReturn($generated);
  171. $newFile = $this->createMock(File::class);
  172. $this->folder->expects($this->once())
  173. ->method('newFile')
  174. ->with('avatar.png')
  175. ->willReturn($newFile);
  176. $image = new \OC_Image();
  177. $image->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
  178. $newFile->expects($this->once())
  179. ->method('putContent')
  180. ->with($image->data());
  181. $this->config->expects($this->exactly(3))
  182. ->method('setUserValue');
  183. $this->config->expects($this->once())
  184. ->method('getUserValue');
  185. // One on remove and once on setting the new avatar
  186. $this->user->expects($this->exactly(2))->method('triggerChange');
  187. $this->avatar->set($image->data());
  188. }
  189. public function testGenerateSvgAvatar() {
  190. $avatar = $this->invokePrivate($this->avatar, 'getAvatarVector', [64]);
  191. $svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  192. <svg width="64" height="64" version="1.1" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
  193. <rect width="100%" height="100%" fill="#0082c9"></rect>
  194. <text x="50%" y="350" style="font-weight:normal;font-size:280px;font-family:\'Noto Sans\';text-anchor:middle;fill:#fff">A</text>
  195. </svg>';
  196. $this->assertEquals($avatar, $svg);
  197. }
  198. public function testHashToInt() {
  199. $hashToInt = $this->invokePrivate($this->avatar, 'hashToInt', ['abcdef', 18]);
  200. $this->assertTrue(gettype($hashToInt) === 'integer');
  201. }
  202. public function testMixPalette() {
  203. $colorFrom = new \OC\Color(0,0,0);
  204. $colorTo = new \OC\Color(6,12,18);
  205. $steps = 6;
  206. $palette = $this->invokePrivate($this->avatar, 'mixPalette', [$steps, $colorFrom, $colorTo]);
  207. foreach($palette as $j => $color) {
  208. // calc increment
  209. $incR = $colorTo->r / $steps * $j;
  210. $incG = $colorTo->g / $steps * $j;
  211. $incB = $colorTo->b / $steps * $j;
  212. // ensure everything is equal
  213. $this->assertEquals($color, new \OC\Color($incR, $incG,$incB));
  214. }
  215. $hashToInt = $this->invokePrivate($this->avatar, 'hashToInt', ['abcdef', 18]);
  216. $this->assertTrue(gettype($hashToInt) === 'integer');
  217. }
  218. }