em = static::getContainer()->get(EntityManagerInterface::class); /** @var \PDO $pdo */ $pdo = $this->em->getConnection()->getNativeConnection(); $this->backend = new CardDavBackend($pdo); $this->em->getConnection()->beginTransaction(); } protected function tearDown(): void { $this->em->getConnection()->rollBack(); parent::tearDown(); } /** * Builds an address book that has already seen ten changes: it now sits at sync token 11, * with a contact added at token 9 and another modified at token 10. */ private function createAddressBookAtTokenEleven(): int { /** @var \PDO $pdo */ $pdo = $this->em->getConnection()->getNativeConnection(); $id = $this->backend->createAddressBook(self::PRINCIPAL, 'sync-token-test', ['{DAV:}displayname' => 'Sync token test']); $pdo->prepare('UPDATE addressbooks SET synctoken = 11 WHERE id = ?')->execute([$id]); $insert = $pdo->prepare('INSERT INTO addressbookchanges (addressbookid, uri, synctoken, operation) VALUES (?, ?, ?, ?)'); $insert->execute([$id, 'added.vcf', 9, 1]); $insert->execute([$id, 'changed.vcf', 10, 2]); return (int) $id; } /** * Sync tokens are compared numerically, so a client syncing across a decimal-width * boundary gets every change in the range. Compared as text, `'10' < '9'` would hide them. */ public function testChangesAcrossADecimalBoundaryAreReported(): void { $addressBookId = $this->createAddressBookAtTokenEleven(); $changes = $this->backend->getChangesForAddressBook((string) $addressBookId, '9', 1); $this->assertNotNull($changes); $this->assertSame(11, (int) $changes['syncToken']); $this->assertSame(['added.vcf'], $changes['added']); $this->assertSame(['changed.vcf'], $changes['modified']); $this->assertSame([], $changes['deleted']); } public function testChangesAreOrderedNumerically(): void { $addressBookId = $this->createAddressBookAtTokenEleven(); // From token 10 the earlier change at 9 must be out of range, the one at 10 in range $changes = $this->backend->getChangesForAddressBook((string) $addressBookId, '10', 1); $this->assertNotNull($changes); $this->assertSame([], $changes['added']); $this->assertSame(['changed.vcf'], $changes['modified']); } }