aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_trashbin/tests/Command
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_trashbin/tests/Command')
-rw-r--r--apps/files_trashbin/tests/Command/CleanUpTest.php84
-rw-r--r--apps/files_trashbin/tests/Command/ExpireTest.php2
-rw-r--r--apps/files_trashbin/tests/Command/ExpireTrashTest.php156
3 files changed, 192 insertions, 50 deletions
diff --git a/apps/files_trashbin/tests/Command/CleanUpTest.php b/apps/files_trashbin/tests/Command/CleanUpTest.php
index 25d38752e91..41ed0e1e960 100644
--- a/apps/files_trashbin/tests/Command/CleanUpTest.php
+++ b/apps/files_trashbin/tests/Command/CleanUpTest.php
@@ -1,4 +1,6 @@
<?php
+
+declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -6,12 +8,13 @@
*/
namespace OCA\Files_Trashbin\Tests\Command;
-use OC\User\Manager;
use OCA\Files_Trashbin\Command\CleanUp;
use OCP\Files\IRootFolder;
use OCP\IDBConnection;
+use OCP\IUserManager;
use OCP\Server;
use OCP\UserInterface;
+use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\NullOutput;
@@ -26,31 +29,17 @@ use Test\TestCase;
* @package OCA\Files_Trashbin\Tests\Command
*/
class CleanUpTest extends TestCase {
-
- /** @var CleanUp */
- protected $cleanup;
-
- /** @var \PHPUnit\Framework\MockObject\MockObject | Manager */
- protected $userManager;
-
- /** @var \PHPUnit\Framework\MockObject\MockObject | IRootFolder */
- protected $rootFolder;
-
- /** @var IDBConnection */
- protected $dbConnection;
-
- /** @var string */
- protected $trashTable = 'files_trash';
-
- /** @var string */
- protected $user0 = 'user0';
+ protected IUserManager&MockObject $userManager;
+ protected IRootFolder&MockObject $rootFolder;
+ protected IDBConnection $dbConnection;
+ protected CleanUp $cleanup;
+ protected string $trashTable = 'files_trash';
+ protected string $user0 = 'user0';
protected function setUp(): void {
parent::setUp();
- $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')
- ->disableOriginalConstructor()->getMock();
- $this->userManager = $this->getMockBuilder('OC\User\Manager')
- ->disableOriginalConstructor()->getMock();
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->userManager = $this->createMock(IUserManager::class);
$this->dbConnection = Server::get(IDBConnection::class);
@@ -60,9 +49,9 @@ class CleanUpTest extends TestCase {
/**
* populate files_trash table with 10 dummy values
*/
- public function initTable() {
+ public function initTable(): void {
$query = $this->dbConnection->getQueryBuilder();
- $query->delete($this->trashTable)->execute();
+ $query->delete($this->trashTable)->executeStatement();
for ($i = 0; $i < 10; $i++) {
$query->insert($this->trashTable)
->values([
@@ -70,20 +59,17 @@ class CleanUpTest extends TestCase {
'timestamp' => $query->expr()->literal($i),
'location' => $query->expr()->literal('.'),
'user' => $query->expr()->literal('user' . $i % 2)
- ])->execute();
+ ])->executeStatement();
}
$getAllQuery = $this->dbConnection->getQueryBuilder();
$result = $getAllQuery->select('id')
->from($this->trashTable)
- ->execute()
+ ->executeQuery()
->fetchAll();
- $this->assertSame(10, count($result));
+ $this->assertCount(10, $result);
}
- /**
- * @dataProvider dataTestRemoveDeletedFiles
- * @param boolean $nodeExists
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestRemoveDeletedFiles')]
public function testRemoveDeletedFiles(bool $nodeExists): void {
$this->initTable();
$this->rootFolder
@@ -101,7 +87,7 @@ class CleanUpTest extends TestCase {
$this->rootFolder->expects($this->never())->method('get');
$this->rootFolder->expects($this->never())->method('delete');
}
- $this->invokePrivate($this->cleanup, 'removeDeletedFiles', [$this->user0, new NullOutput(), false]);
+ self::invokePrivate($this->cleanup, 'removeDeletedFiles', [$this->user0, new NullOutput(), false]);
if ($nodeExists) {
// if the delete operation was executed only files from user1
@@ -110,11 +96,11 @@ class CleanUpTest extends TestCase {
$query->select('user')
->from($this->trashTable);
- $qResult = $query->execute();
+ $qResult = $query->executeQuery();
$result = $qResult->fetchAll();
$qResult->closeCursor();
- $this->assertSame(5, count($result));
+ $this->assertCount(5, $result);
foreach ($result as $r) {
$this->assertSame('user1', $r['user']);
}
@@ -124,12 +110,12 @@ class CleanUpTest extends TestCase {
$getAllQuery = $this->dbConnection->getQueryBuilder();
$result = $getAllQuery->select('id')
->from($this->trashTable)
- ->execute()
+ ->executeQuery()
->fetchAll();
- $this->assertSame(10, count($result));
+ $this->assertCount(10, $result);
}
}
- public function dataTestRemoveDeletedFiles() {
+ public static function dataTestRemoveDeletedFiles(): array {
return [
[true],
[false]
@@ -141,8 +127,8 @@ class CleanUpTest extends TestCase {
*/
public function testExecuteDeleteListOfUsers(): void {
$userIds = ['user1', 'user2', 'user3'];
- $instance = $this->getMockBuilder('OCA\Files_Trashbin\Command\CleanUp')
- ->setMethods(['removeDeletedFiles'])
+ $instance = $this->getMockBuilder(CleanUp::class)
+ ->onlyMethods(['removeDeletedFiles'])
->setConstructorArgs([$this->rootFolder, $this->userManager, $this->dbConnection])
->getMock();
$instance->expects($this->exactly(count($userIds)))
@@ -152,8 +138,7 @@ class CleanUpTest extends TestCase {
});
$this->userManager->expects($this->exactly(count($userIds)))
->method('userExists')->willReturn(true);
- $inputInterface = $this->getMockBuilder('\Symfony\Component\Console\Input\InputInterface')
- ->disableOriginalConstructor()->getMock();
+ $inputInterface = $this->createMock(\Symfony\Component\Console\Input\InputInterface::class);
$inputInterface->method('getArgument')
->with('user_id')
->willReturn($userIds);
@@ -162,9 +147,8 @@ class CleanUpTest extends TestCase {
['all-users', false],
['verbose', false],
]);
- $outputInterface = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')
- ->disableOriginalConstructor()->getMock();
- $this->invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]);
+ $outputInterface = $this->createMock(\Symfony\Component\Console\Output\OutputInterface::class);
+ self::invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]);
}
/**
@@ -173,8 +157,8 @@ class CleanUpTest extends TestCase {
public function testExecuteAllUsers(): void {
$userIds = [];
$backendUsers = ['user1', 'user2'];
- $instance = $this->getMockBuilder('OCA\Files_Trashbin\Command\CleanUp')
- ->setMethods(['removeDeletedFiles'])
+ $instance = $this->getMockBuilder(CleanUp::class)
+ ->onlyMethods(['removeDeletedFiles'])
->setConstructorArgs([$this->rootFolder, $this->userManager, $this->dbConnection])
->getMock();
$backend = $this->createMock(UserInterface::class);
@@ -199,7 +183,7 @@ class CleanUpTest extends TestCase {
$this->userManager
->method('getBackends')
->willReturn([$backend]);
- $this->invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]);
+ self::invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]);
}
public function testExecuteNoUsersAndNoAllUsers(): void {
@@ -217,7 +201,7 @@ class CleanUpTest extends TestCase {
$this->expectException(InvalidOptionException::class);
$this->expectExceptionMessage('Either specify a user_id or --all-users');
- $this->invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]);
+ self::invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]);
}
public function testExecuteUsersAndAllUsers(): void {
@@ -235,6 +219,6 @@ class CleanUpTest extends TestCase {
$this->expectException(InvalidOptionException::class);
$this->expectExceptionMessage('Either specify a user_id or --all-users');
- $this->invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]);
+ self::invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]);
}
}
diff --git a/apps/files_trashbin/tests/Command/ExpireTest.php b/apps/files_trashbin/tests/Command/ExpireTest.php
index 4402e07bbb0..5a66dac8c6e 100644
--- a/apps/files_trashbin/tests/Command/ExpireTest.php
+++ b/apps/files_trashbin/tests/Command/ExpireTest.php
@@ -1,4 +1,6 @@
<?php
+
+declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
diff --git a/apps/files_trashbin/tests/Command/ExpireTrashTest.php b/apps/files_trashbin/tests/Command/ExpireTrashTest.php
new file mode 100644
index 00000000000..23bf0d8f121
--- /dev/null
+++ b/apps/files_trashbin/tests/Command/ExpireTrashTest.php
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Trashbin\Tests\Command;
+
+use OCA\Files_Trashbin\Command\ExpireTrash;
+use OCA\Files_Trashbin\Expiration;
+use OCA\Files_Trashbin\Helper;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IConfig;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Server;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+/**
+ * Class ExpireTrashTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Trashbin\Tests\Command
+ */
+class ExpireTrashTest extends TestCase {
+ private Expiration $expiration;
+ private Node $userFolder;
+ private IConfig $config;
+ private IUserManager $userManager;
+ private IUser $user;
+ private ITimeFactory $timeFactory;
+
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->config = Server::get(IConfig::class);
+ $this->timeFactory = $this->createMock(ITimeFactory::class);
+ $this->expiration = Server::get(Expiration::class);
+ $this->invokePrivate($this->expiration, 'timeFactory', [$this->timeFactory]);
+
+ $userId = self::getUniqueID('user');
+ $this->userManager = Server::get(IUserManager::class);
+ $this->user = $this->userManager->createUser($userId, $userId);
+
+ $this->loginAsUser($userId);
+ $this->userFolder = Server::get(IRootFolder::class)->getUserFolder($userId);
+ }
+
+ protected function tearDown(): void {
+ $this->logout();
+
+ if (isset($this->user)) {
+ $this->user->delete();
+ }
+
+ $this->invokePrivate($this->expiration, 'timeFactory', [Server::get(ITimeFactory::class)]);
+ parent::tearDown();
+ }
+
+ /**
+ * @dataProvider retentionObligationProvider
+ */
+ public function testRetentionObligation(string $obligation, string $quota, int $elapsed, int $fileSize, bool $shouldExpire): void {
+ $this->config->setSystemValues(['trashbin_retention_obligation' => $obligation]);
+ $this->expiration->setRetentionObligation($obligation);
+
+ $this->user->setQuota($quota);
+
+ $bytes = 'ABCDEFGHIKLMNOPQRSTUVWXYZ';
+
+ $file = 'foo.txt';
+ $this->userFolder->newFile($file, substr($bytes, 0, $fileSize));
+
+ $filemtime = $this->userFolder->get($file)->getMTime();
+ $this->timeFactory->expects($this->any())
+ ->method('getTime')
+ ->willReturn($filemtime + $elapsed);
+ $this->userFolder->get($file)->delete();
+ $this->userFolder->getStorage()
+ ->getCache()
+ ->put('files_trashbin', ['size' => $fileSize, 'unencrypted_size' => $fileSize]);
+
+ $userId = $this->user->getUID();
+ $trashFiles = Helper::getTrashFiles('/', $userId);
+ $this->assertEquals(1, count($trashFiles));
+
+ $outputInterface = $this->createMock(OutputInterface::class);
+ $inputInterface = $this->createMock(InputInterface::class);
+ $inputInterface->expects($this->any())
+ ->method('getArgument')
+ ->with('user_id')
+ ->willReturn([$userId]);
+
+ $command = new ExpireTrash(
+ Server::get(LoggerInterface::class),
+ Server::get(IUserManager::class),
+ $this->expiration
+ );
+
+ $this->invokePrivate($command, 'execute', [$inputInterface, $outputInterface]);
+
+ $trashFiles = Helper::getTrashFiles('/', $userId);
+ $this->assertEquals($shouldExpire ? 0 : 1, count($trashFiles));
+ }
+
+ public function retentionObligationProvider(): array {
+ $hour = 3600; // 60 * 60
+
+ $oneDay = 24 * $hour;
+ $fiveDays = 24 * 5 * $hour;
+ $tenDays = 24 * 10 * $hour;
+ $elevenDays = 24 * 11 * $hour;
+
+ return [
+ ['disabled', '20 B', 0, 1, false],
+
+ ['auto', '20 B', 0, 5, false],
+ ['auto', '20 B', 0, 21, true],
+
+ ['0, auto', '20 B', 0, 21, true],
+ ['0, auto', '20 B', $oneDay, 5, false],
+ ['0, auto', '20 B', $oneDay, 19, true],
+ ['0, auto', '20 B', 0, 19, true],
+
+ ['auto, 0', '20 B', $oneDay, 19, true],
+ ['auto, 0', '20 B', $oneDay, 21, true],
+ ['auto, 0', '20 B', 0, 5, false],
+ ['auto, 0', '20 B', 0, 19, true],
+
+ ['1, auto', '20 B', 0, 5, false],
+ ['1, auto', '20 B', $fiveDays, 5, false],
+ ['1, auto', '20 B', $fiveDays, 21, true],
+
+ ['auto, 1', '20 B', 0, 21, true],
+ ['auto, 1', '20 B', 0, 5, false],
+ ['auto, 1', '20 B', $fiveDays, 5, true],
+ ['auto, 1', '20 B', $oneDay, 5, false],
+
+ ['2, 10', '20 B', $fiveDays, 5, false],
+ ['2, 10', '20 B', $fiveDays, 20, true],
+ ['2, 10', '20 B', $elevenDays, 5, true],
+
+ ['10, 2', '20 B', $fiveDays, 5, false],
+ ['10, 2', '20 B', $fiveDays, 21, false],
+ ['10, 2', '20 B', $tenDays, 5, false],
+ ['10, 2', '20 B', $elevenDays, 5, true]
+ ];
+ }
+}