Skip to content

Commit e5540f9

Browse files
authored
Merge pull request #32692 from nextcloud/backport/32471/stable24
[stable24] Make sure activities are not created when a deleted calendar object expires
2 parents 7ba6738 + 3820de9 commit e5540f9

File tree

3 files changed

+111
-4
lines changed

3 files changed

+111
-4
lines changed

apps/dav/lib/CalDAV/CalDavBackend.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ public function getDeletedCalendarObjectsByPrincipal(string $principalUri): arra
11501150
*/
11511151
public function getCalendarObject($calendarId, $objectUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR) {
11521152
$query = $this->db->getQueryBuilder();
1153-
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
1153+
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification', 'deleted_at'])
11541154
->from('calendarobjects')
11551155
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
11561156
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
@@ -1172,7 +1172,8 @@ public function getCalendarObject($calendarId, $objectUri, int $calendarType = s
11721172
'size' => (int)$row['size'],
11731173
'calendardata' => $this->readBlob($row['calendardata']),
11741174
'component' => strtolower($row['componenttype']),
1175-
'classification' => (int)$row['classification']
1175+
'classification' => (int)$row['classification'],
1176+
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'] === null ? $row['deleted_at'] : (int) $row['deleted_at'],
11761177
];
11771178
}
11781179

apps/dav/tests/unit/CalDAV/CalDavBackendTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use DateTimeZone;
3636
use OCA\DAV\CalDAV\CalDavBackend;
3737
use OCA\DAV\CalDAV\Calendar;
38+
use OCA\DAV\DAV\Sharing\Plugin as SharingPlugin;
3839
use OCA\DAV\Events\CalendarDeletedEvent;
3940
use OCP\IConfig;
4041
use OCP\IL10N;
@@ -232,13 +233,13 @@ public function testCalendarObjectsOperations() {
232233
->method('dispatchTyped');
233234
$this->backend->createCalendarObject($calendarId, $uri, $calData);
234235

235-
// get all the cards
236+
// get all the calendar objects
236237
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
237238
$this->assertCount(1, $calendarObjects);
238239
$this->assertEquals($calendarId, $calendarObjects[0]['calendarid']);
239240
$this->assertArrayHasKey('classification', $calendarObjects[0]);
240241

241-
// get the cards
242+
// get the calendar objects
242243
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri);
243244
$this->assertNotNull($calendarObject);
244245
$this->assertArrayHasKey('id', $calendarObject);
@@ -247,6 +248,7 @@ public function testCalendarObjectsOperations() {
247248
$this->assertArrayHasKey('etag', $calendarObject);
248249
$this->assertArrayHasKey('size', $calendarObject);
249250
$this->assertArrayHasKey('classification', $calendarObject);
251+
$this->assertArrayHasKey('{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at', $calendarObject);
250252
$this->assertEquals($calData, $calendarObject['calendardata']);
251253

252254
// update the card
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* @copyright 2022 Thomas Citharel <[email protected]>
7+
*
8+
* @author Thomas Citharel <[email protected]>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*
25+
*/
26+
namespace OCA\DAV\Tests\Unit\Listener;
27+
28+
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend;
29+
use OCA\DAV\CalDAV\Activity\Provider\Event;
30+
use OCA\DAV\DAV\Sharing\Plugin as SharingPlugin;
31+
use OCA\DAV\Events\CalendarDeletedEvent;
32+
use OCA\DAV\Events\CalendarObjectDeletedEvent;
33+
use OCA\DAV\Listener\ActivityUpdaterListener;
34+
use PHPUnit\Framework\MockObject\MockObject;
35+
use Psr\Log\LoggerInterface;
36+
use Test\TestCase;
37+
38+
class ActivityUpdaterListenerTest extends TestCase {
39+
40+
/** @var ActivityBackend|MockObject */
41+
private $activityBackend;
42+
/** @var LoggerInterface|MockObject */
43+
private $logger;
44+
/** @var ActivityUpdaterListener */
45+
private ActivityUpdaterListener $listener;
46+
47+
protected function setUp(): void {
48+
parent::setUp();
49+
50+
$this->activityBackend = $this->createMock(ActivityBackend::class);
51+
$this->logger = $this->createMock(LoggerInterface::class);
52+
53+
$this->listener = new ActivityUpdaterListener(
54+
$this->activityBackend,
55+
$this->logger
56+
);
57+
}
58+
59+
/**
60+
* @dataProvider dataForTestHandleCalendarObjectDeletedEvent
61+
*/
62+
public function testHandleCalendarObjectDeletedEvent(int $calendarId, array $calendarData, array $shares, array $objectData, bool $createsActivity): void {
63+
$event = new CalendarObjectDeletedEvent($calendarId, $calendarData, $shares, $objectData);
64+
$this->logger->expects($this->once())->method('debug')->with(
65+
$createsActivity ? "Activity generated for deleted calendar object in calendar $calendarId" : "Calendar object in calendar $calendarId was already in trashbin, skipping deletion activity"
66+
);
67+
$this->activityBackend->expects($createsActivity ? $this->once() : $this->never())->method('onTouchCalendarObject')->with(
68+
Event::SUBJECT_OBJECT_DELETE,
69+
$calendarData,
70+
$shares,
71+
$objectData
72+
);
73+
$this->listener->handle($event);
74+
}
75+
76+
public function dataForTestHandleCalendarObjectDeletedEvent(): array {
77+
return [
78+
[1, [], [], [], true],
79+
[1, [], [], ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], false],
80+
];
81+
}
82+
83+
/**
84+
* @dataProvider dataForTestHandleCalendarDeletedEvent
85+
*/
86+
public function testHandleCalendarDeletedEvent(int $calendarId, array $calendarData, array $shares, bool $createsActivity): void {
87+
$event = new CalendarDeletedEvent($calendarId, $calendarData, $shares);
88+
$this->logger->expects($this->once())->method('debug')->with(
89+
$createsActivity ? "Activity generated for deleted calendar $calendarId" : "Calendar $calendarId was already in trashbin, skipping deletion activity"
90+
);
91+
$this->activityBackend->expects($createsActivity ? $this->once() : $this->never())->method('onCalendarDelete')->with(
92+
$calendarData,
93+
$shares
94+
);
95+
$this->listener->handle($event);
96+
}
97+
98+
public function dataForTestHandleCalendarDeletedEvent(): array {
99+
return [
100+
[1, [], [], true],
101+
[1, ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], [], false],
102+
];
103+
}
104+
}

0 commit comments

Comments
 (0)