Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2022-11-07 20:26:06 +0300
committerGitHub <noreply@github.com>2022-11-07 20:26:06 +0300
commit95837d0626cb7f610ee996a2b057acff9639e1e6 (patch)
treec717dbeff2593eeb9e7f208d67ca6a6baab6aacb
parent19f466fd4d9db0698494827fe90f3c6b854617e4 (diff)
parent8698e2ce3fdc1d4fbba06558ab8b2a89e54918b8 (diff)
Merge pull request #4194 from nextcloud/3on108/master
Permanently delete deck cards marked as deleted after 5 min in a cron job
-rw-r--r--docs/API.md4
-rw-r--r--lib/Cron/DeleteCron.php12
-rw-r--r--lib/Db/CardMapper.php11
-rw-r--r--tests/unit/Cron/DeleteCronTest.php27
4 files changed, 49 insertions, 5 deletions
diff --git a/docs/API.md b/docs/API.md
index 9f96b516..654f78b8 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -1,7 +1,7 @@
The REST API provides access for authenticated users to their data inside the Deck app. To get a better understanding of Decks data models and their relations, please have a look at the [data structure](structure.md) documentation.
-# Prequisited
+# Prerequisites
- All requests require a `OCS-APIRequest` HTTP header to be set to `true` and a `Content-Type` of `application/json`.
- The API is located at https://nextcloud.local/index.php/apps/deck/api/v1.0
@@ -9,7 +9,7 @@ The REST API provides access for authenticated users to their data inside the De
## Naming
-- Board is the the project like grouping of tasks that can be shared to different users and groups
+- Board is the project like grouping of tasks that can be shared to different users and groups
- Stack is the grouping of cards which is rendered in vertical columns in the UI
diff --git a/lib/Cron/DeleteCron.php b/lib/Cron/DeleteCron.php
index 41d027b5..f766931d 100644
--- a/lib/Cron/DeleteCron.php
+++ b/lib/Cron/DeleteCron.php
@@ -28,6 +28,7 @@ use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
use OCA\Deck\Db\AttachmentMapper;
use OCA\Deck\Db\BoardMapper;
+use OCA\Deck\Db\CardMapper;
use OCA\Deck\InvalidAttachmentType;
use OCA\Deck\Service\AttachmentService;
use OCP\BackgroundJob\IJob;
@@ -36,14 +37,17 @@ class DeleteCron extends TimedJob {
/** @var BoardMapper */
private $boardMapper;
+ /** @var CardMapper */
+ private $cardMapper;
/** @var AttachmentService */
private $attachmentService;
/** @var AttachmentMapper */
private $attachmentMapper;
- public function __construct(ITimeFactory $time, BoardMapper $boardMapper, AttachmentService $attachmentService, AttachmentMapper $attachmentMapper) {
+ public function __construct(ITimeFactory $time, BoardMapper $boardMapper, CardMapper $cardMapper, AttachmentService $attachmentService, AttachmentMapper $attachmentMapper) {
parent::__construct($time);
$this->boardMapper = $boardMapper;
+ $this->cardMapper = $cardMapper;
$this->attachmentService = $attachmentService;
$this->attachmentMapper = $attachmentMapper;
@@ -61,6 +65,12 @@ class DeleteCron extends TimedJob {
$this->boardMapper->delete($board);
}
+ $timeLimit = time() - (60 * 5); // 5 min buffer
+ $cards = $this->cardMapper->findToDelete($timeLimit, 500);
+ foreach ($cards as $card) {
+ $this->cardMapper->delete($card);
+ }
+
$attachments = $this->attachmentMapper->findToDelete();
foreach ($attachments as $attachment) {
try {
diff --git a/lib/Db/CardMapper.php b/lib/Db/CardMapper.php
index e23f8046..e245c032 100644
--- a/lib/Db/CardMapper.php
+++ b/lib/Db/CardMapper.php
@@ -177,6 +177,17 @@ class CardMapper extends QBMapper implements IPermissionMapper {
return $qb;
}
+ public function findToDelete($timeLimit, $limit = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('id', 'title', 'owner', 'archived', 'deleted_at', 'last_modified')
+ ->from('deck_cards')
+ ->where($qb->expr()->gt('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->lt('deleted_at', $qb->createNamedParameter($timeLimit, IQueryBuilder::PARAM_INT)))
+ ->orderBy('deleted_at')
+ ->setMaxResults($limit);
+ return $this->findEntities($qb);
+ }
+
public function findDeleted($boardId, $limit = null, $offset = null) {
$qb = $this->queryCardsByBoard($boardId);
$qb->andWhere($qb->expr()->neq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
diff --git a/tests/unit/Cron/DeleteCronTest.php b/tests/unit/Cron/DeleteCronTest.php
index 94e390e5..88d73b8a 100644
--- a/tests/unit/Cron/DeleteCronTest.php
+++ b/tests/unit/Cron/DeleteCronTest.php
@@ -27,6 +27,8 @@ use OCA\Deck\Db\Attachment;
use OCA\Deck\Db\AttachmentMapper;
use OCA\Deck\Db\Board;
use OCA\Deck\Db\BoardMapper;
+use OCA\Deck\Db\Card;
+use OCA\Deck\Db\CardMapper;
use OCA\Deck\InvalidAttachmentType;
use OCA\Deck\Service\AttachmentService;
use OCA\Deck\Service\IAttachmentService;
@@ -40,7 +42,9 @@ class DeleteCronTest extends TestCase {
private $timeFactory;
/** @var BoardMapper|MockObject */
protected $boardMapper;
- /** @var AttachmentService|MockObject */
+ /** @var CardMapper|\PHPUnit\Framework\MockObject\MockObject */
+ protected $cardMapper;
+ /** @var AttachmentService|\PHPUnit\Framework\MockObject\MockObject */
private $attachmentService;
/** @var AttachmentMapper|MockObject */
private $attachmentMapper;
@@ -51,9 +55,10 @@ class DeleteCronTest extends TestCase {
parent::setUp();
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->boardMapper = $this->createMock(BoardMapper::class);
+ $this->cardMapper = $this->createMock(CardMapper::class);
$this->attachmentService = $this->createMock(AttachmentService::class);
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
- $this->deleteCron = new DeleteCron($this->timeFactory, $this->boardMapper, $this->attachmentService, $this->attachmentMapper);
+ $this->deleteCron = new DeleteCron($this->timeFactory, $this->boardMapper, $this->cardMapper, $this->attachmentService, $this->attachmentMapper);
}
protected function getBoard($id) {
@@ -62,6 +67,12 @@ class DeleteCronTest extends TestCase {
return $board;
}
+ protected function getCard($id) {
+ $card = new Card();
+ $card->setId($id);
+ return $card;
+ }
+
public function testDeleteCron() {
$boards = [
$this->getBoard(1),
@@ -81,6 +92,14 @@ class DeleteCronTest extends TestCase {
[$boards[3]]
);
+ $cards = [ $this->getCard(10) ];
+ $this->cardMapper->expects($this->once())
+ ->method('findToDelete')
+ ->willReturn($cards);
+ $this->cardMapper->expects($this->once())
+ ->method('delete')
+ ->with($cards[0]);
+
$attachment = new Attachment();
$attachment->setType('deck_file');
$this->attachmentMapper->expects($this->once())
@@ -107,6 +126,10 @@ class DeleteCronTest extends TestCase {
->method('findToDelete')
->willReturn($boards);
+ $this->cardMapper->expects($this->once())
+ ->method('findToDelete')
+ ->willReturn([]);
+
$attachment = new Attachment();
$attachment->setType('deck_file_invalid');
$this->attachmentMapper->expects($this->once())