FilesPluginTest.php 18 KB

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