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:
authorMichal Polacik <mpolacik@gmail.com>2021-08-28 00:26:25 +0300
committerJulius Härtl <jus@bitgrid.net>2022-11-07 19:26:12 +0300
commit8698e2ce3fdc1d4fbba06558ab8b2a89e54918b8 (patch)
treec717dbeff2593eeb9e7f208d67ca6a6baab6aacb
parent19f466fd4d9db0698494827fe90f3c6b854617e4 (diff)
Permanently delete deck cards marked as deleted after 5 min in a cron job
Limit deleted cards in one cron job run to 500 Converted spaces to tabs Added missing import for CardMapper class Added another missing import for CardMapper class Fixed response object in findToDelete method + fixed 2 misspellings in API.md Fixed invalid parameter type Fix DeleteCronTest Signed-off-by: Marcel Klehr <mklehr@gmx.net> Fix lint errors Signed-off-by: Marcel Klehr <mklehr@gmx.net>
-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())