Skip to content

Commit

Permalink
Make sure activities are not created when a deleted calendar object e…
Browse files Browse the repository at this point in the history
…xpires

Closes nextcloud/activity#784

Signed-off-by: Thomas Citharel <[email protected]>
  • Loading branch information
tcitworld authored and backportbot-nextcloud[bot] committed Jun 1, 2022
1 parent ae19916 commit 5043cbe
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 4 deletions.
5 changes: 3 additions & 2 deletions apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ public function getDeletedCalendarObjectsByPrincipal(string $principalUri): arra
*/
public function getCalendarObject($calendarId, $objectUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification', 'deleted_at'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
Expand All @@ -1181,7 +1181,8 @@ public function getCalendarObject($calendarId, $objectUri, int $calendarType = s
'size' => (int)$row['size'],
'calendardata' => $this->readBlob($row['calendardata']),
'component' => strtolower($row['componenttype']),
'classification' => (int)$row['classification']
'classification' => (int)$row['classification'],
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'] === null ? $row['deleted_at'] : (int) $row['deleted_at'],
];
}

Expand Down
6 changes: 4 additions & 2 deletions apps/dav/tests/unit/CalDAV/CalDavBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\DAV\Sharing\Plugin as SharingPlugin;
use OCA\DAV\Events\CalendarDeletedEvent;
use OCP\IConfig;
use OCP\IL10N;
Expand Down Expand Up @@ -230,13 +231,13 @@ public function testCalendarObjectsOperations() {
->method('dispatchTyped');
$this->backend->createCalendarObject($calendarId, $uri, $calData);

// get all the cards
// get all the calendar objects
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
$this->assertCount(1, $calendarObjects);
$this->assertEquals($calendarId, $calendarObjects[0]['calendarid']);
$this->assertArrayHasKey('classification', $calendarObjects[0]);

// get the cards
// get the calendar objects
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri);
$this->assertNotNull($calendarObject);
$this->assertArrayHasKey('id', $calendarObject);
Expand All @@ -245,6 +246,7 @@ public function testCalendarObjectsOperations() {
$this->assertArrayHasKey('etag', $calendarObject);
$this->assertArrayHasKey('size', $calendarObject);
$this->assertArrayHasKey('classification', $calendarObject);
$this->assertArrayHasKey('{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at', $calendarObject);
$this->assertEquals($calData, $calendarObject['calendardata']);

// update the card
Expand Down
104 changes: 104 additions & 0 deletions apps/dav/tests/unit/Listener/ActivityUpdaterListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

/**
* @copyright 2022 Thomas Citharel <[email protected]>
*
* @author Thomas Citharel <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\Tests\Unit\Listener;

use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend;
use OCA\DAV\CalDAV\Activity\Provider\Event;
use OCA\DAV\DAV\Sharing\Plugin as SharingPlugin;
use OCA\DAV\Events\CalendarDeletedEvent;
use OCA\DAV\Events\CalendarObjectDeletedEvent;
use OCA\DAV\Listener\ActivityUpdaterListener;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Test\TestCase;

class ActivityUpdaterListenerTest extends TestCase {

/** @var ActivityBackend|MockObject */
private $activityBackend;
/** @var LoggerInterface|MockObject */
private $logger;
/** @var ActivityUpdaterListener */
private ActivityUpdaterListener $listener;

protected function setUp(): void {
parent::setUp();

$this->activityBackend = $this->createMock(ActivityBackend::class);
$this->logger = $this->createMock(LoggerInterface::class);

$this->listener = new ActivityUpdaterListener(
$this->activityBackend,
$this->logger
);
}

/**
* @dataProvider dataForTestHandleCalendarObjectDeletedEvent
*/
public function testHandleCalendarObjectDeletedEvent(int $calendarId, array $calendarData, array $shares, array $objectData, bool $createsActivity): void {
$event = new CalendarObjectDeletedEvent($calendarId, $calendarData, $shares, $objectData);
$this->logger->expects($this->once())->method('debug')->with(
$createsActivity ? "Activity generated for deleted calendar object in calendar $calendarId" : "Calendar object in calendar $calendarId was already in trashbin, skipping deletion activity"
);
$this->activityBackend->expects($createsActivity ? $this->once() : $this->never())->method('onTouchCalendarObject')->with(
Event::SUBJECT_OBJECT_DELETE,
$calendarData,
$shares,
$objectData
);
$this->listener->handle($event);
}

public function dataForTestHandleCalendarObjectDeletedEvent(): array {
return [
[1, [], [], [], true],
[1, [], [], ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], false],
];
}

/**
* @dataProvider dataForTestHandleCalendarDeletedEvent
*/
public function testHandleCalendarDeletedEvent(int $calendarId, array $calendarData, array $shares, bool $createsActivity): void {
$event = new CalendarDeletedEvent($calendarId, $calendarData, $shares);
$this->logger->expects($this->once())->method('debug')->with(
$createsActivity ? "Activity generated for deleted calendar $calendarId" : "Calendar $calendarId was already in trashbin, skipping deletion activity"
);
$this->activityBackend->expects($createsActivity ? $this->once() : $this->never())->method('onCalendarDelete')->with(
$calendarData,
$shares
);
$this->listener->handle($event);
}

public function dataForTestHandleCalendarDeletedEvent(): array {
return [
[1, [], [], true],
[1, ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], [], false],
];
}
}

0 comments on commit 5043cbe

Please sign in to comment.