PreviewControllerTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace Tests\Core\Controller;
  7. use OC\Core\Controller\PreviewController;
  8. use OCP\AppFramework\Http;
  9. use OCP\AppFramework\Http\DataResponse;
  10. use OCP\Files\File;
  11. use OCP\Files\Folder;
  12. use OCP\Files\IRootFolder;
  13. use OCP\Files\NotFoundException;
  14. use OCP\Files\SimpleFS\ISimpleFile;
  15. use OCP\Files\Storage\ISharedStorage;
  16. use OCP\Files\Storage\IStorage;
  17. use OCP\IPreview;
  18. use OCP\IRequest;
  19. use OCP\Preview\IMimeIconProvider;
  20. use OCP\Share\IAttributes;
  21. use OCP\Share\IShare;
  22. use PHPUnit\Framework\MockObject\MockObject;
  23. class PreviewControllerTest extends \Test\TestCase {
  24. private string $userId;
  25. private PreviewController $controller;
  26. private IRootFolder&MockObject $rootFolder;
  27. private IPreview&MockObject $previewManager;
  28. private IRequest&MockObject $request;
  29. protected function setUp(): void {
  30. parent::setUp();
  31. $this->userId = 'user';
  32. $this->rootFolder = $this->createMock(IRootFolder::class);
  33. $this->previewManager = $this->createMock(IPreview::class);
  34. $this->request = $this->createMock(IRequest::class);
  35. $this->controller = new PreviewController(
  36. 'core',
  37. $this->request,
  38. $this->previewManager,
  39. $this->rootFolder,
  40. $this->userId,
  41. $this->createMock(IMimeIconProvider::class)
  42. );
  43. }
  44. public function testInvalidFile(): void {
  45. $res = $this->controller->getPreview('');
  46. $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
  47. $this->assertEquals($expected, $res);
  48. }
  49. public function testInvalidWidth(): void {
  50. $res = $this->controller->getPreview('file', 0);
  51. $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
  52. $this->assertEquals($expected, $res);
  53. }
  54. public function testInvalidHeight(): void {
  55. $res = $this->controller->getPreview('file', 10, 0);
  56. $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
  57. $this->assertEquals($expected, $res);
  58. }
  59. public function testFileNotFound(): void {
  60. $userFolder = $this->createMock(Folder::class);
  61. $this->rootFolder->method('getUserFolder')
  62. ->with($this->equalTo($this->userId))
  63. ->willReturn($userFolder);
  64. $userFolder->method('get')
  65. ->with($this->equalTo('file'))
  66. ->willThrowException(new NotFoundException());
  67. $res = $this->controller->getPreview('file');
  68. $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
  69. $this->assertEquals($expected, $res);
  70. }
  71. public function testNotAFile(): void {
  72. $userFolder = $this->createMock(Folder::class);
  73. $this->rootFolder->method('getUserFolder')
  74. ->with($this->equalTo($this->userId))
  75. ->willReturn($userFolder);
  76. $folder = $this->createMock(Folder::class);
  77. $userFolder->method('get')
  78. ->with($this->equalTo('file'))
  79. ->willReturn($folder);
  80. $res = $this->controller->getPreview('file');
  81. $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
  82. $this->assertEquals($expected, $res);
  83. }
  84. public function testNoPreviewAndNoIcon(): void {
  85. $userFolder = $this->createMock(Folder::class);
  86. $this->rootFolder->method('getUserFolder')
  87. ->with($this->equalTo($this->userId))
  88. ->willReturn($userFolder);
  89. $file = $this->createMock(File::class);
  90. $userFolder->method('get')
  91. ->with($this->equalTo('file'))
  92. ->willReturn($file);
  93. $this->previewManager->method('isAvailable')
  94. ->with($this->equalTo($file))
  95. ->willReturn(false);
  96. $res = $this->controller->getPreview('file', 10, 10, true, false);
  97. $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
  98. $this->assertEquals($expected, $res);
  99. }
  100. public function testNoPreview() {
  101. $userFolder = $this->createMock(Folder::class);
  102. $this->rootFolder->method('getUserFolder')
  103. ->with($this->equalTo($this->userId))
  104. ->willReturn($userFolder);
  105. $file = $this->createMock(File::class);
  106. $userFolder->method('get')
  107. ->with($this->equalTo('file'))
  108. ->willReturn($file);
  109. $storage = $this->createMock(IStorage::class);
  110. $file->method('getStorage')
  111. ->willReturn($storage);
  112. $this->previewManager->method('isAvailable')
  113. ->with($this->equalTo($file))
  114. ->willReturn(true);
  115. $file->method('isReadable')
  116. ->willReturn(true);
  117. $this->previewManager->method('getPreview')
  118. ->with($this->equalTo($file), 10, 10, false, $this->equalTo('myMode'))
  119. ->willThrowException(new NotFoundException());
  120. $res = $this->controller->getPreview('file', 10, 10, true, true, 'myMode');
  121. $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
  122. $this->assertEquals($expected, $res);
  123. }
  124. public function testFileWithoutReadPermission() {
  125. $userFolder = $this->createMock(Folder::class);
  126. $this->rootFolder->method('getUserFolder')
  127. ->with($this->equalTo($this->userId))
  128. ->willReturn($userFolder);
  129. $file = $this->createMock(File::class);
  130. $userFolder->method('get')
  131. ->with($this->equalTo('file'))
  132. ->willReturn($file);
  133. $this->previewManager->method('isAvailable')
  134. ->with($this->equalTo($file))
  135. ->willReturn(true);
  136. $file->method('isReadable')
  137. ->willReturn(false);
  138. $res = $this->controller->getPreview('file', 10, 10, true, true);
  139. $expected = new DataResponse([], Http::STATUS_FORBIDDEN);
  140. $this->assertEquals($expected, $res);
  141. }
  142. public function testFileWithoutDownloadPermission() {
  143. $userFolder = $this->createMock(Folder::class);
  144. $this->rootFolder->method('getUserFolder')
  145. ->with($this->equalTo($this->userId))
  146. ->willReturn($userFolder);
  147. $file = $this->createMock(File::class);
  148. $file->method('getId')->willReturn(123);
  149. $userFolder->method('get')
  150. ->with($this->equalTo('file'))
  151. ->willReturn($file);
  152. $this->previewManager->method('isAvailable')
  153. ->with($this->equalTo($file))
  154. ->willReturn(true);
  155. $shareAttributes = $this->createMock(IAttributes::class);
  156. $shareAttributes->expects(self::atLeastOnce())
  157. ->method('getAttribute')
  158. ->with('permissions', 'download')
  159. ->willReturn(false);
  160. $share = $this->createMock(IShare::class);
  161. $share->method('getAttributes')
  162. ->willReturn($shareAttributes);
  163. $storage = $this->createMock(ISharedStorage::class);
  164. $storage->method('instanceOfStorage')
  165. ->with(ISharedStorage::class)
  166. ->willReturn(true);
  167. $storage->method('getShare')
  168. ->willReturn($share);
  169. $file->method('getStorage')
  170. ->willReturn($storage);
  171. $file->method('isReadable')
  172. ->willReturn(true);
  173. $this->request->method('getHeader')->willReturn('');
  174. $res = $this->controller->getPreview('file', 10, 10, true, true);
  175. $expected = new DataResponse([], Http::STATUS_FORBIDDEN);
  176. $this->assertEquals($expected, $res);
  177. }
  178. public function testFileWithoutDownloadPermissionButHeader() {
  179. $userFolder = $this->createMock(Folder::class);
  180. $this->rootFolder->method('getUserFolder')
  181. ->with($this->equalTo($this->userId))
  182. ->willReturn($userFolder);
  183. $file = $this->createMock(File::class);
  184. $file->method('getId')->willReturn(123);
  185. $userFolder->method('get')
  186. ->with($this->equalTo('file'))
  187. ->willReturn($file);
  188. $this->previewManager->method('isAvailable')
  189. ->with($this->equalTo($file))
  190. ->willReturn(true);
  191. $shareAttributes = $this->createMock(IAttributes::class);
  192. $shareAttributes->method('getAttribute')
  193. ->with('permissions', 'download')
  194. ->willReturn(false);
  195. $share = $this->createMock(IShare::class);
  196. $share->method('getAttributes')
  197. ->willReturn($shareAttributes);
  198. $storage = $this->createMock(ISharedStorage::class);
  199. $storage->method('instanceOfStorage')
  200. ->with(ISharedStorage::class)
  201. ->willReturn(true);
  202. $storage->method('getShare')
  203. ->willReturn($share);
  204. $file->method('getStorage')
  205. ->willReturn($storage);
  206. $file->method('isReadable')
  207. ->willReturn(true);
  208. $this->request
  209. ->method('getHeader')
  210. ->with('X-NC-Preview')
  211. ->willReturn('true');
  212. $preview = $this->createMock(ISimpleFile::class);
  213. $preview->method('getName')->willReturn('my name');
  214. $preview->method('getMTime')->willReturn(42);
  215. $this->previewManager->method('getPreview')
  216. ->with($this->equalTo($file), 10, 10, false, $this->equalTo('myMode'))
  217. ->willReturn($preview);
  218. $preview->method('getMimeType')
  219. ->willReturn('myMime');
  220. $res = $this->controller->getPreview('file', 10, 10, true, true, 'myMode');
  221. $this->assertEquals('myMime', $res->getHeaders()['Content-Type']);
  222. $this->assertEquals(Http::STATUS_OK, $res->getStatus());
  223. $this->assertEquals($preview, $this->invokePrivate($res, 'file'));
  224. }
  225. public function testValidPreview(): void {
  226. $userFolder = $this->createMock(Folder::class);
  227. $this->rootFolder->method('getUserFolder')
  228. ->with($this->equalTo($this->userId))
  229. ->willReturn($userFolder);
  230. $file = $this->createMock(File::class);
  231. $file->method('getId')->willReturn(123);
  232. $userFolder->method('get')
  233. ->with($this->equalTo('file'))
  234. ->willReturn($file);
  235. $this->previewManager->method('isAvailable')
  236. ->with($this->equalTo($file))
  237. ->willReturn(true);
  238. $file->method('isReadable')
  239. ->willReturn(true);
  240. $storage = $this->createMock(IStorage::class);
  241. $file->method('getStorage')
  242. ->willReturn($storage);
  243. $preview = $this->createMock(ISimpleFile::class);
  244. $preview->method('getName')->willReturn('my name');
  245. $preview->method('getMTime')->willReturn(42);
  246. $this->previewManager->method('getPreview')
  247. ->with($this->equalTo($file), 10, 10, false, $this->equalTo('myMode'))
  248. ->willReturn($preview);
  249. $preview->method('getMimeType')
  250. ->willReturn('myMime');
  251. $res = $this->controller->getPreview('file', 10, 10, true, true, 'myMode');
  252. $this->assertEquals('myMime', $res->getHeaders()['Content-Type']);
  253. $this->assertEquals(Http::STATUS_OK, $res->getStatus());
  254. $this->assertEquals($preview, $this->invokePrivate($res, 'file'));
  255. }
  256. public function testValidPreviewOfShare() {
  257. $userFolder = $this->createMock(Folder::class);
  258. $this->rootFolder->method('getUserFolder')
  259. ->with($this->equalTo($this->userId))
  260. ->willReturn($userFolder);
  261. $file = $this->createMock(File::class);
  262. $file->method('getId')->willReturn(123);
  263. $userFolder->method('get')
  264. ->with($this->equalTo('file'))
  265. ->willReturn($file);
  266. $this->previewManager->method('isAvailable')
  267. ->with($this->equalTo($file))
  268. ->willReturn(true);
  269. // No attributes set -> download permitted
  270. $share = $this->createMock(IShare::class);
  271. $share->method('getAttributes')
  272. ->willReturn(null);
  273. $storage = $this->createMock(ISharedStorage::class);
  274. $storage->method('instanceOfStorage')
  275. ->with(ISharedStorage::class)
  276. ->willReturn(true);
  277. $storage->method('getShare')
  278. ->willReturn($share);
  279. $file->method('getStorage')
  280. ->willReturn($storage);
  281. $file->method('isReadable')
  282. ->willReturn(true);
  283. $this->request
  284. ->method('getHeader')
  285. ->willReturn('');
  286. $preview = $this->createMock(ISimpleFile::class);
  287. $preview->method('getName')->willReturn('my name');
  288. $preview->method('getMTime')->willReturn(42);
  289. $this->previewManager->method('getPreview')
  290. ->with($this->equalTo($file), 10, 10, false, $this->equalTo('myMode'))
  291. ->willReturn($preview);
  292. $preview->method('getMimeType')
  293. ->willReturn('myMime');
  294. $res = $this->controller->getPreview('file', 10, 10, true, true, 'myMode');
  295. $this->assertEquals('myMime', $res->getHeaders()['Content-Type']);
  296. $this->assertEquals(Http::STATUS_OK, $res->getStatus());
  297. $this->assertEquals($preview, $this->invokePrivate($res, 'file'));
  298. }
  299. }