FilesPluginTest.php 18 KB

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