Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/API.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

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
- All request parameters are required, unless otherwise specified

## 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

Expand Down
12 changes: 11 additions & 1 deletion lib/Cron/DeleteCron.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand All @@ -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;

Expand All @@ -61,6 +65,12 @@ protected function run($argument) {
$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 {
Expand Down
11 changes: 11 additions & 0 deletions lib/Db/CardMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ public function queryCardsByBoards(array $boardIds): IQueryBuilder {
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)))
Expand Down
27 changes: 25 additions & 2 deletions tests/unit/Cron/DeleteCronTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
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;
Expand All @@ -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;
Expand All @@ -51,9 +55,10 @@ public function setUp(): void {
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) {
Expand All @@ -62,6 +67,12 @@ protected function getBoard($id) {
return $board;
}

protected function getCard($id) {
$card = new Card();
$card->setId($id);
return $card;
}

public function testDeleteCron() {
$boards = [
$this->getBoard(1),
Expand All @@ -81,6 +92,14 @@ public function testDeleteCron() {
[$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())
Expand All @@ -107,6 +126,10 @@ public function testDeleteCronInvalidAttachment() {
->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())
Expand Down