Skip to content

Commit

Permalink
feat: add dto for card event data
Browse files Browse the repository at this point in the history
Signed-off-by: nicolashimmelmann <nhimmelmann@mailbox.org>
  • Loading branch information
nicolashimmelmann committed Dec 9, 2024
1 parent 616af0c commit ac6a301
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 0 deletions.
28 changes: 28 additions & 0 deletions lib/Db/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use DateTime;
use DateTimeZone;
use Sabre\VObject\Component\VCalendar;
use OCA\Deck\Model\Public\CardEventData;

/**
* @method string getTitle()
Expand Down Expand Up @@ -175,4 +176,31 @@ public function getCalendarPrefix(): string {
public function getETag(): string {
return md5((string)$this->getLastModified());
}

public function toEventData(?array $previousValues = null): CardEventData {
return new CardEventData(
title: $this->getTitle(),
description: $this->getDescription(),
boardId: $this->getRelatedBoard()->getId(),
stackId: $this->getStackId(),
lastModified: new DateTime('@' . $this->getLastModified()),
createdAt: new DateTime('@' . $this->getCreatedAt()),
labels: array_map(fn($label) => [
'id' => $label->getId(),
'title' => $label->getTitle()
], $this->getLabels() ?? []),
assignedUsers: $this->getAssignedUsers() ?: [],
order: $this->getOrder(),
archived: $this->getArchived(),
commentsUnread: $this->getCommentsUnread(),
commentsCount: $this->getCommentsCount(),
owner: $this->getOwner(),
lastEditor: $this->getLastEditor(),
duedate: $this->getDuedate(),
doneAt: $this->getDone(),
deletedAt: ($this->getDeletedAt() > 0)
? new DateTime('@' . $this->getDeletedAt())
: null
);
}
}
125 changes: 125 additions & 0 deletions lib/Model/Public/CardEventData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Deck\Model\Public;

use JsonSerializable;

/**
* A data transfer object representation of the card data to be used as a
* public-facing event payload.
*
* @since 2.0.0
*/
final class CardEventData implements JsonSerializable {

/**
* @param string $title
* @param string $description
* @param int $boardId
* @param int $stackId
* @param \DateTime $lastModified
* @param \DateTime $createdAt
* @param array<int,string> $labels
* @param array<int,string> $assignedUsers
* @param int $order
* @param bool $archived
* @param int $commentsUnread
* @param int $commentsCount
* @param ?string $owner
* @param ?string $lastEditor
* @param ?\DateTime $duedate
* @param ?\DateTime $doneAt
* @param ?\DateTime $deletedAt
*
* @since 2.0.0
*/
public function __construct(
/** @readonly */
public string $title,
/** @readonly */
public string $description,
/** @readonly */
public int $boardId,
/** @readonly */
public int $stackId,
/** @readonly */
public \DateTime $lastModified,
/** @readonly */
public \DateTime $createdAt,
/** @readonly */
public array $labels = [],
/** @readonly */
public array $assignedUsers = [],
/** @readonly */
public int $order = 0,
/** @readonly */
public bool $archived = false,
/** @readonly */
public int $commentsUnread = 0,
/** @readonly */
public int $commentsCount = 0,
/** @readonly */
public ?string $owner = null,
/** @readonly */
public ?string $lastEditor,
/** @readonly */
public ?\DateTime $duedate = null,
/** @readonly */
public ?\DateTime $doneAt = null,
/** @readonly */
public ?\DateTime $deletedAt = null,
) {
}


/**
* Serialize the object to a JSON-compatible array.
*
* @return array{
* title: string,
* description: string,
* boardId: int,
* stackId: int,
* lastModified: int,
* createdAt: int,
* labels: array<int,string>,
* assignedUsers: array<int,string>,
* order: int,
* archived: bool,
* commentsUnread: int,
* commentsCount: int,
* owner: ?string,
* lastEditor: ?string,
* duedate: ?string,
* doneAt: ?string,
* deletedAt: ?int,
* }
*/
public function jsonSerialize(): array
{
return [
'title' => $this->title,
'description' => $this->description,
'boardId' => $this->boardId,
'stackId' => $this->stackId,
'lastModified' => $this->lastModified->format(DATE_ATOM),
'createdAt' => $this->createdAt->format(DATE_ATOM),
'labels' => $this->labels,
'assignedUsers' => $this->assignedUsers,
'order' => $this->order,
'archived' => $this->archived,
'commentsUnread' => $this->commentsUnread,
'commentsCount' => $this->commentsCount,
'owner' => $this->owner,
'lastEditor' => $this->lastEditor,
'duedate' => $this->duedate?->format(DATE_ATOM),
'doneAt' => $this->doneAt?->format(DATE_ATOM),
'deletedAt' => $this->deletedAt?->format(DATE_ATOM),
];
}
}
90 changes: 90 additions & 0 deletions tests/unit/Db/CardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use DateInterval;
use DateTime;
use OCA\Deck\Model\CardDetails;
use OCA\Deck\Db\Board;
use Test\TestCase;

class CardTest extends TestCase {
Expand All @@ -46,6 +47,14 @@ private function createCard() {
return $card;
}

private function createLabel() {
$label = new Label();
$label->setId(1);
$label->setTitle('Label 1');
$label->setColor('000000');
return $label;
}

public function dataDuedate() {
return [
[(new DateTime()), Card::DUEDATE_NOW],
Expand Down Expand Up @@ -149,4 +158,85 @@ public function testJsonSerializeAsignedUsers() {
'done' => false,
], (new CardDetails($card))->jsonSerialize());
}

public function testToEventDataSerializationSimple() {
$card = $this->createCard();
$board = new Board();
$board->setId(1);
$card->setRelatedBoard($board);

$lastmodified = new DateTime('2024-01-01 00:00:00');
$card->setLastModified($lastmodified->getTimestamp());
$created = new DateTime('2024-01-02 00:00:00');
$card->setCreatedAt($created->getTimestamp());

$this->assertEquals([
'title' => 'My Card',
'description' => 'a long description',
'boardId' => 1,
'stackId' => 1,
'lastModified' => $lastmodified->format(DATE_ATOM),
'createdAt' => $created->format(DATE_ATOM),
'labels' => [],
'assignedUsers' => [],
'order' => 12,
'archived' => false,
'commentsUnread' => 0,
'commentsCount' => 0,
'owner' => 'admin',
'lastEditor' => null,
'duedate' => null,
'doneAt' => null,
'deletedAt' => null,
], $card->toEventData()->jsonSerialize());
}

public function testToEventDataSerializationFull() {
$card = $this->createCard();

$board = new Board();
$board->setId(1);
$card->setRelatedBoard($board);

$card->setAssignedUsers([ 'user1' ]);
$card->setLabels([$this->createLabel()]);
$card->setLastEditor('someuser');
$card->setArchived(true);

$lastModified = new DateTime('2024-01-01 00:00:00');
$card->setLastModified($lastModified->getTimestamp());
$createdAt = new DateTime('2024-01-02 00:00:00');
$card->setCreatedAt($createdAt->getTimestamp());
$doneAt = new DateTime('2024-01-03 00:00:00');
$card->setDone($doneAt);
$duedate = new DateTime('2024-01-05 00:00:00');
$card->setDuedate($duedate);
$deletedAt = new DateTime('2024-01-05 00:00:00');
$card->setDeletedAt($deletedAt->getTimestamp());

$this->assertEquals([
'title' => 'My Card',
'description' => 'a long description',
'boardId' => 1,
'stackId' => 1,
'lastModified' => $lastModified->format(DATE_ATOM),
'createdAt' => $createdAt->format(DATE_ATOM),
'labels' => [
[
'id' => 1,
'title' => 'Label 1'
]
],
'assignedUsers' => ['user1'],
'order' => 12,
'archived' => true,
'commentsUnread' => 0,
'commentsCount' => 0,
'doneAt' => $doneAt->format(DATE_ATOM),
'owner' => 'admin',
'lastEditor' => 'someuser',
'duedate' => $duedate->format(DATE_ATOM),
'deletedAt' => $deletedAt->format(DATE_ATOM),
], $card->toEventData()->jsonSerialize());
}
}

0 comments on commit ac6a301

Please sign in to comment.