FilesPluginTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
  5. * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
  6. *
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Joas Schilling <coding@schilljs.com>
  9. * @author Markus Goetz <markus@woboq.com>
  10. * @author Morris Jobke <hey@morrisjobke.de>
  11. * @author Robin Appelman <robin@icewind.nl>
  12. * @author Roeland Jago Douma <roeland@famdouma.nl>
  13. * @author Stefan Weil <sw@weilnetz.de>
  14. * @author Thomas Müller <thomas.mueller@tmit.eu>
  15. * @author Vincent Petry <vincent@nextcloud.com>
  16. *
  17. * @license AGPL-3.0
  18. *
  19. * This code is free software: you can redistribute it and/or modify
  20. * it under the terms of the GNU Affero General Public License, version 3,
  21. * as published by the Free Software Foundation.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU Affero General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Affero General Public License, version 3,
  29. * along with this program. If not, see <http://www.gnu.org/licenses/>
  30. *
  31. */
  32. namespace OCA\DAV\Tests\unit\Connector\Sabre;
  33. use OC\User\User;
  34. use OCA\DAV\Connector\Sabre\Directory;
  35. use OCA\DAV\Connector\Sabre\File;
  36. use OCA\DAV\Connector\Sabre\FilesPlugin;
  37. use OCA\DAV\Connector\Sabre\Node;
  38. use OCP\Files\FileInfo;
  39. use OCP\Files\StorageNotAvailableException;
  40. use OCP\IConfig;
  41. use OCP\IPreview;
  42. use OCP\IRequest;
  43. use OCP\IUserSession;
  44. use PHPUnit\Framework\MockObject\MockObject;
  45. use Sabre\DAV\PropFind;
  46. use Sabre\DAV\PropPatch;
  47. use Sabre\DAV\Server;
  48. use Sabre\DAV\Tree;
  49. use Sabre\HTTP\RequestInterface;
  50. use Sabre\HTTP\ResponseInterface;
  51. use Sabre\Xml\Service;
  52. use Test\TestCase;
  53. /**
  54. * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
  55. * This file is licensed under the Affero General Public License version 3 or
  56. * later.
  57. * See the COPYING-README file.
  58. */
  59. class FilesPluginTest extends TestCase {
  60. public const GETETAG_PROPERTYNAME = FilesPlugin::GETETAG_PROPERTYNAME;
  61. public const FILEID_PROPERTYNAME = FilesPlugin::FILEID_PROPERTYNAME;
  62. public const INTERNAL_FILEID_PROPERTYNAME = FilesPlugin::INTERNAL_FILEID_PROPERTYNAME;
  63. public const SIZE_PROPERTYNAME = FilesPlugin::SIZE_PROPERTYNAME;
  64. public const PERMISSIONS_PROPERTYNAME = FilesPlugin::PERMISSIONS_PROPERTYNAME;
  65. public const LASTMODIFIED_PROPERTYNAME = FilesPlugin::LASTMODIFIED_PROPERTYNAME;
  66. public const CREATIONDATE_PROPERTYNAME = FilesPlugin::CREATIONDATE_PROPERTYNAME;
  67. public const DOWNLOADURL_PROPERTYNAME = FilesPlugin::DOWNLOADURL_PROPERTYNAME;
  68. public const OWNER_ID_PROPERTYNAME = FilesPlugin::OWNER_ID_PROPERTYNAME;
  69. public const OWNER_DISPLAY_NAME_PROPERTYNAME = FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME;
  70. public const DATA_FINGERPRINT_PROPERTYNAME = FilesPlugin::DATA_FINGERPRINT_PROPERTYNAME;
  71. public const HAS_PREVIEW_PROPERTYNAME = FilesPlugin::HAS_PREVIEW_PROPERTYNAME;
  72. /**
  73. * @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject
  74. */
  75. private $server;
  76. /**
  77. * @var \Sabre\DAV\Tree | \PHPUnit\Framework\MockObject\MockObject
  78. */
  79. private $tree;
  80. /**
  81. * @var FilesPlugin
  82. */
  83. private $plugin;
  84. /**
  85. * @var \OCP\IConfig | \PHPUnit\Framework\MockObject\MockObject
  86. */
  87. private $config;
  88. /**
  89. * @var \OCP\IRequest | \PHPUnit\Framework\MockObject\MockObject
  90. */
  91. private $request;
  92. /**
  93. * @var \OCP\IPreview | \PHPUnit\Framework\MockObject\MockObject
  94. */
  95. private $previewManager;
  96. /** @var IUserSession|MockObject */
  97. private $userSession;
  98. protected function setUp(): void {
  99. parent::setUp();
  100. $this->server = $this->createMock(Server::class);
  101. $this->tree = $this->createMock(Tree::class);
  102. $this->config = $this->createMock(IConfig::class);
  103. $this->config->expects($this->any())->method('getSystemValue')
  104. ->with($this->equalTo('data-fingerprint'), $this->equalTo(''))
  105. ->willReturn('my_fingerprint');
  106. $this->request = $this->createMock(IRequest::class);
  107. $this->previewManager = $this->createMock(IPreview::class);
  108. $this->userSession = $this->createMock(IUserSession::class);
  109. $this->plugin = new FilesPlugin(
  110. $this->tree,
  111. $this->config,
  112. $this->request,
  113. $this->previewManager,
  114. $this->userSession
  115. );
  116. $response = $this->getMockBuilder(ResponseInterface::class)
  117. ->disableOriginalConstructor()
  118. ->getMock();
  119. $this->server->httpResponse = $response;
  120. $this->server->xml = new Service();
  121. $this->plugin->initialize($this->server);
  122. }
  123. /**
  124. * @param string $class
  125. * @return \PHPUnit\Framework\MockObject\MockObject
  126. */
  127. private function createTestNode($class, $path = '/dummypath') {
  128. $node = $this->getMockBuilder($class)
  129. ->disableOriginalConstructor()
  130. ->getMock();
  131. $node->expects($this->any())
  132. ->method('getId')
  133. ->willReturn(123);
  134. $this->tree->expects($this->any())
  135. ->method('getNodeForPath')
  136. ->with($path)
  137. ->willReturn($node);
  138. $node->expects($this->any())
  139. ->method('getFileId')
  140. ->willReturn('00000123instanceid');
  141. $node->expects($this->any())
  142. ->method('getInternalFileId')
  143. ->willReturn('123');
  144. $node->expects($this->any())
  145. ->method('getEtag')
  146. ->willReturn('"abc"');
  147. $node->expects($this->any())
  148. ->method('getDavPermissions')
  149. ->willReturn('DWCKMSR');
  150. $fileInfo = $this->createMock(FileInfo::class);
  151. $fileInfo->expects($this->any())
  152. ->method('isReadable')
  153. ->willReturn(true);
  154. $fileInfo->expects($this->any())
  155. ->method('getCreationTime')
  156. ->willReturn(123456789);
  157. $node->expects($this->any())
  158. ->method('getFileInfo')
  159. ->willReturn($fileInfo);
  160. return $node;
  161. }
  162. public function testGetPropertiesForFile(): void {
  163. /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit\Framework\MockObject\MockObject $node */
  164. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
  165. $propFind = new PropFind(
  166. '/dummyPath',
  167. [
  168. self::GETETAG_PROPERTYNAME,
  169. self::FILEID_PROPERTYNAME,
  170. self::INTERNAL_FILEID_PROPERTYNAME,
  171. self::SIZE_PROPERTYNAME,
  172. self::PERMISSIONS_PROPERTYNAME,
  173. self::DOWNLOADURL_PROPERTYNAME,
  174. self::OWNER_ID_PROPERTYNAME,
  175. self::OWNER_DISPLAY_NAME_PROPERTYNAME,
  176. self::DATA_FINGERPRINT_PROPERTYNAME,
  177. self::CREATIONDATE_PROPERTYNAME,
  178. ],
  179. 0
  180. );
  181. $user = $this->getMockBuilder(User::class)
  182. ->disableOriginalConstructor()->getMock();
  183. $user
  184. ->expects($this->once())
  185. ->method('getUID')
  186. ->willReturn('foo');
  187. $user
  188. ->expects($this->once())
  189. ->method('getDisplayName')
  190. ->willReturn('M. Foo');
  191. $node->expects($this->once())
  192. ->method('getDirectDownload')
  193. ->willReturn(['url' => 'http://example.com/']);
  194. $node->expects($this->exactly(2))
  195. ->method('getOwner')
  196. ->willReturn($user);
  197. $this->plugin->handleGetProperties(
  198. $propFind,
  199. $node
  200. );
  201. $this->assertEquals('"abc"', $propFind->get(self::GETETAG_PROPERTYNAME));
  202. $this->assertEquals('00000123instanceid', $propFind->get(self::FILEID_PROPERTYNAME));
  203. $this->assertEquals('123', $propFind->get(self::INTERNAL_FILEID_PROPERTYNAME));
  204. $this->assertEquals('1973-11-29T21:33:09+00:00', $propFind->get(self::CREATIONDATE_PROPERTYNAME));
  205. $this->assertEquals(0, $propFind->get(self::SIZE_PROPERTYNAME));
  206. $this->assertEquals('DWCKMSR', $propFind->get(self::PERMISSIONS_PROPERTYNAME));
  207. $this->assertEquals('http://example.com/', $propFind->get(self::DOWNLOADURL_PROPERTYNAME));
  208. $this->assertEquals('foo', $propFind->get(self::OWNER_ID_PROPERTYNAME));
  209. $this->assertEquals('M. Foo', $propFind->get(self::OWNER_DISPLAY_NAME_PROPERTYNAME));
  210. $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
  211. $this->assertEquals([], $propFind->get404Properties());
  212. }
  213. public function testGetPropertiesStorageNotAvailable(): void {
  214. /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit\Framework\MockObject\MockObject $node */
  215. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
  216. $propFind = new PropFind(
  217. '/dummyPath',
  218. [
  219. self::DOWNLOADURL_PROPERTYNAME,
  220. ],
  221. 0
  222. );
  223. $node->expects($this->once())
  224. ->method('getDirectDownload')
  225. ->will($this->throwException(new StorageNotAvailableException()));
  226. $this->plugin->handleGetProperties(
  227. $propFind,
  228. $node
  229. );
  230. $this->assertEquals(null, $propFind->get(self::DOWNLOADURL_PROPERTYNAME));
  231. }
  232. public function testGetPublicPermissions(): void {
  233. $this->plugin = new FilesPlugin(
  234. $this->tree,
  235. $this->config,
  236. $this->getMockBuilder(IRequest::class)
  237. ->disableOriginalConstructor()
  238. ->getMock(),
  239. $this->previewManager,
  240. $this->userSession,
  241. true);
  242. $this->plugin->initialize($this->server);
  243. $propFind = new PropFind(
  244. '/dummyPath',
  245. [
  246. self::PERMISSIONS_PROPERTYNAME,
  247. ],
  248. 0
  249. );
  250. /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit\Framework\MockObject\MockObject $node */
  251. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
  252. $node->expects($this->any())
  253. ->method('getDavPermissions')
  254. ->willReturn('DWCKMSR');
  255. $this->plugin->handleGetProperties(
  256. $propFind,
  257. $node
  258. );
  259. $this->assertEquals('DWCKR', $propFind->get(self::PERMISSIONS_PROPERTYNAME));
  260. }
  261. public function testGetPropertiesForDirectory(): void {
  262. /** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit\Framework\MockObject\MockObject $node */
  263. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory');
  264. $propFind = new PropFind(
  265. '/dummyPath',
  266. [
  267. self::GETETAG_PROPERTYNAME,
  268. self::FILEID_PROPERTYNAME,
  269. self::SIZE_PROPERTYNAME,
  270. self::PERMISSIONS_PROPERTYNAME,
  271. self::DOWNLOADURL_PROPERTYNAME,
  272. self::DATA_FINGERPRINT_PROPERTYNAME,
  273. ],
  274. 0
  275. );
  276. $node->expects($this->once())
  277. ->method('getSize')
  278. ->willReturn(1025);
  279. $this->plugin->handleGetProperties(
  280. $propFind,
  281. $node
  282. );
  283. $this->assertEquals('"abc"', $propFind->get(self::GETETAG_PROPERTYNAME));
  284. $this->assertEquals('00000123instanceid', $propFind->get(self::FILEID_PROPERTYNAME));
  285. $this->assertEquals(1025, $propFind->get(self::SIZE_PROPERTYNAME));
  286. $this->assertEquals('DWCKMSR', $propFind->get(self::PERMISSIONS_PROPERTYNAME));
  287. $this->assertEquals(null, $propFind->get(self::DOWNLOADURL_PROPERTYNAME));
  288. $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
  289. $this->assertEquals([self::DOWNLOADURL_PROPERTYNAME], $propFind->get404Properties());
  290. }
  291. public function testGetPropertiesForRootDirectory(): void {
  292. /** @var \OCA\DAV\Connector\Sabre\Directory|\PHPUnit\Framework\MockObject\MockObject $node */
  293. $node = $this->getMockBuilder(Directory::class)
  294. ->disableOriginalConstructor()
  295. ->getMock();
  296. $node->expects($this->any())->method('getPath')->willReturn('/');
  297. $fileInfo = $this->createMock(FileInfo::class);
  298. $fileInfo->expects($this->any())
  299. ->method('isReadable')
  300. ->willReturn(true);
  301. $node->expects($this->any())
  302. ->method('getFileInfo')
  303. ->willReturn($fileInfo);
  304. $propFind = new PropFind(
  305. '/',
  306. [
  307. self::DATA_FINGERPRINT_PROPERTYNAME,
  308. ],
  309. 0
  310. );
  311. $this->plugin->handleGetProperties(
  312. $propFind,
  313. $node
  314. );
  315. $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
  316. }
  317. public function testGetPropertiesWhenNoPermission(): void {
  318. // No read permissions can be caused by files access control.
  319. // But we still want to load the directory list, so this is okay for us.
  320. // $this->expectException(\Sabre\DAV\Exception\NotFound::class);
  321. /** @var \OCA\DAV\Connector\Sabre\Directory|\PHPUnit\Framework\MockObject\MockObject $node */
  322. $node = $this->getMockBuilder(Directory::class)
  323. ->disableOriginalConstructor()
  324. ->getMock();
  325. $node->expects($this->any())->method('getPath')->willReturn('/');
  326. $fileInfo = $this->createMock(FileInfo::class);
  327. $fileInfo->expects($this->any())
  328. ->method('isReadable')
  329. ->willReturn(false);
  330. $node->expects($this->any())
  331. ->method('getFileInfo')
  332. ->willReturn($fileInfo);
  333. $propFind = new PropFind(
  334. '/test',
  335. [
  336. self::DATA_FINGERPRINT_PROPERTYNAME,
  337. ],
  338. 0
  339. );
  340. $this->plugin->handleGetProperties(
  341. $propFind,
  342. $node
  343. );
  344. $this->addToAssertionCount(1);
  345. }
  346. public function testUpdateProps(): void {
  347. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
  348. $testDate = 'Fri, 13 Feb 2015 00:01:02 GMT';
  349. $testCreationDate = '2007-08-31T16:47+00:00';
  350. $node->expects($this->once())
  351. ->method('touch')
  352. ->with($testDate);
  353. $node->expects($this->once())
  354. ->method('setEtag')
  355. ->with('newetag')
  356. ->willReturn(true);
  357. $node->expects($this->once())
  358. ->method('setCreationTime')
  359. ->with('1188578820');
  360. // properties to set
  361. $propPatch = new PropPatch([
  362. self::GETETAG_PROPERTYNAME => 'newetag',
  363. self::LASTMODIFIED_PROPERTYNAME => $testDate,
  364. self::CREATIONDATE_PROPERTYNAME => $testCreationDate,
  365. ]);
  366. $this->plugin->handleUpdateProperties(
  367. '/dummypath',
  368. $propPatch
  369. );
  370. $propPatch->commit();
  371. $this->assertEmpty($propPatch->getRemainingMutations());
  372. $result = $propPatch->getResult();
  373. $this->assertEquals(200, $result[self::LASTMODIFIED_PROPERTYNAME]);
  374. $this->assertEquals(200, $result[self::GETETAG_PROPERTYNAME]);
  375. $this->assertEquals(200, $result[self::CREATIONDATE_PROPERTYNAME]);
  376. }
  377. public function testUpdatePropsForbidden(): void {
  378. $propPatch = new PropPatch([
  379. self::OWNER_ID_PROPERTYNAME => 'user2',
  380. self::OWNER_DISPLAY_NAME_PROPERTYNAME => 'User Two',
  381. self::FILEID_PROPERTYNAME => 12345,
  382. self::PERMISSIONS_PROPERTYNAME => 'C',
  383. self::SIZE_PROPERTYNAME => 123,
  384. self::DOWNLOADURL_PROPERTYNAME => 'http://example.com/',
  385. ]);
  386. $this->plugin->handleUpdateProperties(
  387. '/dummypath',
  388. $propPatch
  389. );
  390. $propPatch->commit();
  391. $this->assertEmpty($propPatch->getRemainingMutations());
  392. $result = $propPatch->getResult();
  393. $this->assertEquals(403, $result[self::OWNER_ID_PROPERTYNAME]);
  394. $this->assertEquals(403, $result[self::OWNER_DISPLAY_NAME_PROPERTYNAME]);
  395. $this->assertEquals(403, $result[self::FILEID_PROPERTYNAME]);
  396. $this->assertEquals(403, $result[self::PERMISSIONS_PROPERTYNAME]);
  397. $this->assertEquals(403, $result[self::SIZE_PROPERTYNAME]);
  398. $this->assertEquals(403, $result[self::DOWNLOADURL_PROPERTYNAME]);
  399. }
  400. /**
  401. * Testcase from https://github.com/owncloud/core/issues/5251
  402. *
  403. * |-FolderA
  404. * |-text.txt
  405. * |-test.txt
  406. *
  407. * FolderA is an incoming shared folder and there are no delete permissions.
  408. * Thus moving /FolderA/test.txt to /test.txt should fail already on that check
  409. *
  410. */
  411. public function testMoveSrcNotDeletable(): void {
  412. $this->expectException(\Sabre\DAV\Exception\Forbidden::class);
  413. $this->expectExceptionMessage('FolderA/test.txt cannot be deleted');
  414. $fileInfoFolderATestTXT = $this->getMockBuilder(FileInfo::class)
  415. ->disableOriginalConstructor()
  416. ->getMock();
  417. $fileInfoFolderATestTXT->expects($this->once())
  418. ->method('isDeletable')
  419. ->willReturn(false);
  420. $node = $this->getMockBuilder(Node::class)
  421. ->disableOriginalConstructor()
  422. ->getMock();
  423. $node->expects($this->once())
  424. ->method('getFileInfo')
  425. ->willReturn($fileInfoFolderATestTXT);
  426. $this->tree->expects($this->once())->method('getNodeForPath')
  427. ->willReturn($node);
  428. $this->plugin->checkMove('FolderA/test.txt', 'test.txt');
  429. }
  430. public function testMoveSrcDeletable(): void {
  431. $fileInfoFolderATestTXT = $this->getMockBuilder(FileInfo::class)
  432. ->disableOriginalConstructor()
  433. ->getMock();
  434. $fileInfoFolderATestTXT->expects($this->once())
  435. ->method('isDeletable')
  436. ->willReturn(true);
  437. $node = $this->getMockBuilder(Node::class)
  438. ->disableOriginalConstructor()
  439. ->getMock();
  440. $node->expects($this->once())
  441. ->method('getFileInfo')
  442. ->willReturn($fileInfoFolderATestTXT);
  443. $this->tree->expects($this->once())->method('getNodeForPath')
  444. ->willReturn($node);
  445. $this->plugin->checkMove('FolderA/test.txt', 'test.txt');
  446. }
  447. public function testMoveSrcNotExist(): void {
  448. $this->expectException(\Sabre\DAV\Exception\NotFound::class);
  449. $this->expectExceptionMessage('FolderA/test.txt does not exist');
  450. $node = $this->getMockBuilder(Node::class)
  451. ->disableOriginalConstructor()
  452. ->getMock();
  453. $node->expects($this->once())
  454. ->method('getFileInfo')
  455. ->willReturn(null);
  456. $this->tree->expects($this->once())->method('getNodeForPath')
  457. ->willReturn($node);
  458. $this->plugin->checkMove('FolderA/test.txt', 'test.txt');
  459. }
  460. public function downloadHeadersProvider() {
  461. return [
  462. [
  463. false,
  464. 'attachment; filename*=UTF-8\'\'somefile.xml; filename="somefile.xml"'
  465. ],
  466. [
  467. true,
  468. 'attachment; filename="somefile.xml"'
  469. ],
  470. ];
  471. }
  472. /**
  473. * @dataProvider downloadHeadersProvider
  474. */
  475. public function testDownloadHeaders($isClumsyAgent, $contentDispositionHeader): void {
  476. $request = $this->getMockBuilder(RequestInterface::class)
  477. ->disableOriginalConstructor()
  478. ->getMock();
  479. $response = $this->getMockBuilder(ResponseInterface::class)
  480. ->disableOriginalConstructor()
  481. ->getMock();
  482. $request
  483. ->expects($this->once())
  484. ->method('getPath')
  485. ->willReturn('test/somefile.xml');
  486. $node = $this->getMockBuilder(File::class)
  487. ->disableOriginalConstructor()
  488. ->getMock();
  489. $node
  490. ->expects($this->once())
  491. ->method('getName')
  492. ->willReturn('somefile.xml');
  493. $this->tree
  494. ->expects($this->once())
  495. ->method('getNodeForPath')
  496. ->with('test/somefile.xml')
  497. ->willReturn($node);
  498. $this->request
  499. ->expects($this->once())
  500. ->method('isUserAgent')
  501. ->willReturn($isClumsyAgent);
  502. $response
  503. ->expects($this->exactly(2))
  504. ->method('addHeader')
  505. ->withConsecutive(
  506. ['Content-Disposition', $contentDispositionHeader],
  507. ['X-Accel-Buffering', 'no']
  508. );
  509. $this->plugin->httpGet($request, $response);
  510. }
  511. public function testHasPreview(): void {
  512. /** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit\Framework\MockObject\MockObject $node */
  513. $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory');
  514. $propFind = new PropFind(
  515. '/dummyPath',
  516. [
  517. self::HAS_PREVIEW_PROPERTYNAME
  518. ],
  519. 0
  520. );
  521. $this->previewManager->expects($this->once())
  522. ->method('isAvailable')
  523. ->willReturn(false);
  524. $this->plugin->handleGetProperties(
  525. $propFind,
  526. $node
  527. );
  528. $this->assertEquals("false", $propFind->get(self::HAS_PREVIEW_PROPERTYNAME));
  529. }
  530. }