Skip to content

Commit f05bb61

Browse files
committed
fix(cardDav): Only update user card on actual mapped propreties changes
fix(cardDav): Only update user card on actual mapped propreties changes Signed-off-by: Hamza <hamzamahjoubi221@g
1 parent 705e647 commit f05bb61

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

apps/dav/lib/CardDAV/SyncService.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,12 @@ public function updateUser(IUser $user): void {
152152
if (is_null($vCard)) {
153153
$this->backend->deleteCard($addressBookId, $cardId);
154154
} else {
155-
$this->backend->updateCard($addressBookId, $cardId, $vCard->serialize());
155+
$cardData = $vCard->serialize();
156+
// Writing an identical card would still bump the address book
157+
// sync token and make every client re-download the card
158+
if ($card['carddata'] !== $cardData) {
159+
$this->backend->updateCard($addressBookId, $cardId, $cardData);
160+
}
156161
}
157162
}
158163
}, $this->dbConnection);

apps/dav/tests/unit/CardDAV/SyncServiceTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,45 @@ public function testUpdateAndDeleteUser(bool $activated, int $createCalls, int $
459459
$ss->deleteUser($user);
460460
}
461461

462+
public function testUpdateUserSkipsUnchangedCard(): void {
463+
$vCard = new VCard();
464+
$vCard->VERSION = '3.0';
465+
$vCard->UID = 'test-user';
466+
$vCard->FN = 'test-user';
467+
468+
/** @var CardDavBackend&MockObject $backend */
469+
$backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock();
470+
$logger = $this->createMock(LoggerInterface::class);
471+
472+
$backend->expects($this->never())->method('createCard');
473+
$backend->expects($this->never())->method('updateCard');
474+
$backend->expects($this->never())->method('deleteCard');
475+
476+
$backend->method('getCard')->willReturn(['carddata' => $vCard->serialize()]);
477+
$backend->method('getAddressBooksByUri')
478+
->with('principals/system/system', 'system')
479+
->willReturn(['id' => -1]);
480+
481+
$user = $this->createMock(IUser::class);
482+
$user->method('getBackendClassName')->willReturn('unittest');
483+
$user->method('getUID')->willReturn('test-user');
484+
$user->method('isEnabled')->willReturn(true);
485+
486+
$converter = $this->createMock(Converter::class);
487+
$converter->method('createCardFromUser')->willReturn($vCard);
488+
489+
$ss = new SyncService(
490+
$this->createMock(IClientService::class),
491+
$this->createMock(IConfig::class),
492+
$backend,
493+
$this->createMock(IUserManager::class),
494+
$this->createMock(IDBConnection::class),
495+
$logger,
496+
$converter,
497+
);
498+
$ss->updateUser($user);
499+
}
500+
462501
public function testDeleteAddressbookWhenAccessRevoked(): void {
463502
$this->expectException(ClientExceptionInterface::class);
464503

0 commit comments

Comments
 (0)