QuotaPluginTest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2013-2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\DAV\Tests\unit\Connector\Sabre;
  8. use OC\Files\View;
  9. use OCA\DAV\Connector\Sabre\QuotaPlugin;
  10. use OCP\Files\FileInfo;
  11. use Test\TestCase;
  12. class QuotaPluginTest extends TestCase {
  13. /** @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject */
  14. private $server;
  15. /** @var QuotaPlugin|\PHPUnit\Framework\MockObject\MockObject */
  16. private $plugin;
  17. private function init($quota, $checkedPath = ''): void {
  18. $view = $this->buildFileViewMock($quota, $checkedPath);
  19. $this->server = new \Sabre\DAV\Server();
  20. $this->plugin = $this->getMockBuilder(QuotaPlugin::class)
  21. ->setConstructorArgs([$view])
  22. ->setMethods(['getFileChunking'])
  23. ->getMock();
  24. $this->plugin->initialize($this->server);
  25. }
  26. /**
  27. * @dataProvider lengthProvider
  28. */
  29. public function testLength($expected, $headers): void {
  30. $this->init(0);
  31. $this->plugin->expects($this->never())
  32. ->method('getFileChunking');
  33. $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers);
  34. $length = $this->plugin->getLength();
  35. $this->assertEquals($expected, $length);
  36. }
  37. /**
  38. * @dataProvider quotaOkayProvider
  39. */
  40. public function testCheckQuota($quota, $headers): void {
  41. $this->init($quota);
  42. $this->plugin->expects($this->never())
  43. ->method('getFileChunking');
  44. $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers);
  45. $result = $this->plugin->checkQuota('');
  46. $this->assertTrue($result);
  47. }
  48. /**
  49. * @dataProvider quotaExceededProvider
  50. */
  51. public function testCheckExceededQuota($quota, $headers): void {
  52. $this->expectException(\Sabre\DAV\Exception\InsufficientStorage::class);
  53. $this->init($quota);
  54. $this->plugin->expects($this->never())
  55. ->method('getFileChunking');
  56. $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers);
  57. $this->plugin->checkQuota('');
  58. }
  59. /**
  60. * @dataProvider quotaOkayProvider
  61. */
  62. public function testCheckQuotaOnPath($quota, $headers): void {
  63. $this->init($quota, 'sub/test.txt');
  64. $this->plugin->expects($this->never())
  65. ->method('getFileChunking');
  66. $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers);
  67. $result = $this->plugin->checkQuota('/sub/test.txt');
  68. $this->assertTrue($result);
  69. }
  70. public function quotaOkayProvider() {
  71. return [
  72. [1024, []],
  73. [1024, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  74. [1024, ['CONTENT-LENGTH' => '512']],
  75. [1024, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  76. [FileInfo::SPACE_UNKNOWN, []],
  77. [FileInfo::SPACE_UNKNOWN, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  78. [FileInfo::SPACE_UNKNOWN, ['CONTENT-LENGTH' => '512']],
  79. [FileInfo::SPACE_UNKNOWN, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  80. [FileInfo::SPACE_UNLIMITED, []],
  81. [FileInfo::SPACE_UNLIMITED, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  82. [FileInfo::SPACE_UNLIMITED, ['CONTENT-LENGTH' => '512']],
  83. [FileInfo::SPACE_UNLIMITED, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  84. ];
  85. }
  86. public function quotaExceededProvider() {
  87. return [
  88. [1023, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  89. [511, ['CONTENT-LENGTH' => '512']],
  90. [2047, ['OC-TOTAL-LENGTH' => '2048', 'CONTENT-LENGTH' => '1024']],
  91. ];
  92. }
  93. public function lengthProvider() {
  94. return [
  95. [null, []],
  96. [1024, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  97. [512, ['CONTENT-LENGTH' => '512']],
  98. [2048, ['OC-TOTAL-LENGTH' => '2048', 'CONTENT-LENGTH' => '1024']],
  99. [4096, ['OC-TOTAL-LENGTH' => '2048', 'X-EXPECTED-ENTITY-LENGTH' => '4096']],
  100. [null, ['X-EXPECTED-ENTITY-LENGTH' => 'A']],
  101. [null, ['CONTENT-LENGTH' => 'A']],
  102. [1024, ['OC-TOTAL-LENGTH' => 'A', 'CONTENT-LENGTH' => '1024']],
  103. [1024, ['OC-TOTAL-LENGTH' => 'A', 'X-EXPECTED-ENTITY-LENGTH' => '1024']],
  104. [2048, ['OC-TOTAL-LENGTH' => '2048', 'X-EXPECTED-ENTITY-LENGTH' => 'A']],
  105. [2048, ['OC-TOTAL-LENGTH' => '2048', 'CONTENT-LENGTH' => 'A']],
  106. ];
  107. }
  108. public function quotaChunkedOkProvider() {
  109. return [
  110. [1024, 0, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  111. [1024, 0, ['CONTENT-LENGTH' => '512']],
  112. [1024, 0, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  113. // with existing chunks (allowed size = total length - chunk total size)
  114. [400, 128, ['X-EXPECTED-ENTITY-LENGTH' => '512']],
  115. [400, 128, ['CONTENT-LENGTH' => '512']],
  116. [400, 128, ['OC-TOTAL-LENGTH' => '512', 'CONTENT-LENGTH' => '500']],
  117. // \OCP\Files\FileInfo::SPACE-UNKNOWN = -2
  118. [-2, 0, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  119. [-2, 0, ['CONTENT-LENGTH' => '512']],
  120. [-2, 0, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  121. [-2, 128, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  122. [-2, 128, ['CONTENT-LENGTH' => '512']],
  123. [-2, 128, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  124. ];
  125. }
  126. public function quotaChunkedFailProvider() {
  127. return [
  128. [400, 0, ['X-EXPECTED-ENTITY-LENGTH' => '1024']],
  129. [400, 0, ['CONTENT-LENGTH' => '512']],
  130. [400, 0, ['OC-TOTAL-LENGTH' => '1024', 'CONTENT-LENGTH' => '512']],
  131. // with existing chunks (allowed size = total length - chunk total size)
  132. [380, 128, ['X-EXPECTED-ENTITY-LENGTH' => '512']],
  133. [380, 128, ['CONTENT-LENGTH' => '512']],
  134. [380, 128, ['OC-TOTAL-LENGTH' => '512', 'CONTENT-LENGTH' => '500']],
  135. ];
  136. }
  137. private function buildFileViewMock($quota, $checkedPath) {
  138. // mock filesysten
  139. $view = $this->getMockBuilder(View::class)
  140. ->setMethods(['free_space'])
  141. ->disableOriginalConstructor()
  142. ->getMock();
  143. $view->expects($this->any())
  144. ->method('free_space')
  145. ->with($this->identicalTo($checkedPath))
  146. ->willReturn($quota);
  147. return $view;
  148. }
  149. }