Skip to content

Commit e1b957e

Browse files
committed
fix(userstatus): CALL status should overwrite MEETING status
Signed-off-by: Anna Larch <anna@nextcloud.com>
1 parent 0f48549 commit e1b957e

File tree

3 files changed

+110
-25
lines changed

3 files changed

+110
-25
lines changed

apps/dav/lib/CalDAV/Status/StatusService.php

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ public function processCalendarStatus(string $userId): void {
7777
return;
7878
}
7979

80-
$userStatusTimestamp = null;
81-
$currentStatus = null;
8280
try {
8381
$currentStatus = $this->userStatusService->findByUserId($userId);
84-
$userStatusTimestamp = $currentStatus->getIsUserDefined() ? $currentStatus->getStatusTimestamp() : null;
82+
// Was the status set by anything other than the calendar automation?
83+
$userStatusTimestamp = $currentStatus->getIsUserDefined() && $currentStatus->getMessageId() !== IUserStatus::MESSAGE_CALENDAR_BUSY ? $currentStatus->getStatusTimestamp() : null;
8584
} catch (DoesNotExistException) {
85+
$userStatusTimestamp = null;
86+
$currentStatus = null;
8687
}
8788

8889
if($currentStatus !== null && $currentStatus->getMessageId() === IUserStatus::MESSAGE_CALL
@@ -123,19 +124,21 @@ public function processCalendarStatus(string $userId): void {
123124
return;
124125
}
125126

126-
// One event that fulfills all status conditions is enough
127-
// 1. Not an OOO event
128-
// 2. Current user status was not set after the start of this event
129-
// 3. Event is not set to be transparent
130-
$count = count($applicableEvents);
131-
$this->logger->debug("Found $count applicable event(s), changing user status", ['user' => $userId]);
132-
$this->userStatusService->setUserStatus(
133-
$userId,
134-
IUserStatus::AWAY,
135-
IUserStatus::MESSAGE_CALENDAR_BUSY,
136-
true
137-
);
138-
127+
// Only update the status if it's neccesary otherwise we mess up the timestamp
128+
if($currentStatus !== null && $currentStatus->getMessageId() !== IUserStatus::MESSAGE_CALENDAR_BUSY) {
129+
// One event that fulfills all status conditions is enough
130+
// 1. Not an OOO event
131+
// 2. Current user status (that is not a calendar status) was not set after the start of this event
132+
// 3. Event is not set to be transparent
133+
$count = count($applicableEvents);
134+
$this->logger->debug("Found $count applicable event(s), changing user status", ['user' => $userId]);
135+
$this->userStatusService->setUserStatus(
136+
$userId,
137+
IUserStatus::AWAY,
138+
IUserStatus::MESSAGE_CALENDAR_BUSY,
139+
true
140+
);
141+
}
139142
}
140143

141144
private function getCalendarEvents(User $user): array {

apps/user_status/lib/Service/StatusService.php

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ public function setStatus(string $userId,
172172
throw new InvalidStatusTypeException('Status-type "' . $status . '" is not supported');
173173
}
174174

175-
176-
177175
if ($statusTimestamp === null) {
178176
$statusTimestamp = $this->timeFactory->getTime();
179177
}
@@ -257,21 +255,38 @@ public function setUserStatus(string $userId,
257255
throw new InvalidMessageIdException('Message-Id "' . $messageId . '" is not supported');
258256
}
259257

258+
try {
259+
$userStatus = $this->mapper->findByUserId($userId);
260+
} catch (DoesNotExistException $e) {
261+
// We don't need to do anything
262+
$userStatus = new UserStatus();
263+
$userStatus->setUserId($userId);
264+
}
265+
266+
// CALL trumps CALENDAR status, but we don't need to do anything but overwrite the message
267+
if ($userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY && $messageId === IUserStatus::MESSAGE_CALL) {
268+
$userStatus->setStatus($status);
269+
$userStatus->setStatusTimestamp($this->timeFactory->getTime());
270+
$userStatus->setIsUserDefined(true);
271+
$userStatus->setIsBackup(false);
272+
$userStatus->setMessageId($messageId);
273+
$userStatus->setCustomIcon(null);
274+
$userStatus->setCustomMessage($customMessage);
275+
$userStatus->setClearAt(null);
276+
$userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp());
277+
return $this->mapper->update($userStatus);
278+
}
279+
260280
if ($createBackup) {
261281
if ($this->backupCurrentStatus($userId) === false) {
262282
return null; // Already a status set automatically => abort.
263283
}
264284

265285
// If we just created the backup
286+
// we need to create a new status to insert
287+
// Unfortunatley there's no way to unset the DB ID on an Entity
266288
$userStatus = new UserStatus();
267289
$userStatus->setUserId($userId);
268-
} else {
269-
try {
270-
$userStatus = $this->mapper->findByUserId($userId);
271-
} catch (DoesNotExistException $ex) {
272-
$userStatus = new UserStatus();
273-
$userStatus->setUserId($userId);
274-
}
275290
}
276291

277292
$userStatus->setStatus($status);

apps/user_status/tests/Integration/Service/StatusServiceIntegrationTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,73 @@ public function testCreateRestoreBackupAutomatically(): void {
126126
);
127127
}
128128

129+
public function testCallOverwritesMeetingStatus(): void {
130+
$this->service->setStatus(
131+
'test123',
132+
IUserStatus::ONLINE,
133+
null,
134+
false,
135+
);
136+
$this->service->setUserStatus(
137+
'test123',
138+
IUserStatus::AWAY,
139+
IUserStatus::MESSAGE_CALENDAR_BUSY,
140+
true,
141+
);
142+
self::assertSame(
143+
'meeting',
144+
$this->service->findByUserId('test123')->getMessageId(),
145+
);
146+
147+
$this->service->setUserStatus(
148+
'test123',
149+
IUserStatus::AWAY,
150+
IUserStatus::MESSAGE_CALL,
151+
true,
152+
);
153+
self::assertSame(
154+
IUserStatus::AWAY,
155+
$this->service->findByUserId('test123')->getStatus(),
156+
);
157+
158+
self::assertSame(
159+
IUserStatus::MESSAGE_CALL,
160+
$this->service->findByUserId('test123')->getMessageId(),
161+
);
162+
}
163+
164+
public function testOtherAutomationsDoNotOverwriteEachOther(): void {
165+
$this->service->setStatus(
166+
'test123',
167+
IUserStatus::ONLINE,
168+
null,
169+
false,
170+
);
171+
$this->service->setUserStatus(
172+
'test123',
173+
IUserStatus::AWAY,
174+
IUserStatus::MESSAGE_CALENDAR_BUSY,
175+
true,
176+
);
177+
self::assertSame(
178+
'meeting',
179+
$this->service->findByUserId('test123')->getMessageId(),
180+
);
181+
182+
$nostatus = $this->service->setUserStatus(
183+
'test123',
184+
IUserStatus::AWAY,
185+
IUserStatus::MESSAGE_AVAILABILITY,
186+
true,
187+
);
188+
189+
self::assertNull($nostatus);
190+
self::assertSame(
191+
IUserStatus::MESSAGE_CALENDAR_BUSY,
192+
$this->service->findByUserId('test123')->getMessageId(),
193+
);
194+
}
195+
129196
public function testCi(): void {
130197
// TODO: remove if CI turns red
131198
self::assertTrue(false);

0 commit comments

Comments
 (0)