newRepo(); $repo->save($this->makeEntry()); $found = $repo->findByDidAndDeviceId('did:plc:alice', 'dev-1'); $this->assertSame('dev-1', $found->getDeviceId()); } public function testFindByDidAndDeviceIdThrowsWhenMissing(): void { $repo = $this->newRepo(); $this->expectException(AccountDeviceNotFoundException::class); $repo->findByDidAndDeviceId('did:plc:alice', 'dev-1'); } public function testFindAllForDid(): void { $repo = $this->newRepo(); $repo->save($this->makeEntry('did:plc:alice', 'dev-1')); $repo->save($this->makeEntry('did:plc:alice', 'dev-2')); $repo->save($this->makeEntry('did:plc:bob', 'dev-3')); $this->assertCount(2, $repo->findAllForDid('did:plc:alice')); $this->assertCount(1, $repo->findAllForDid('did:plc:bob')); $this->assertCount(0, $repo->findAllForDid('did:plc:carol')); } public function testSaveInsertsNewAndUpdatesExisting(): void { $repo = $this->newRepo(); $repo->save($this->makeEntry()); $this->assertCount(1, $repo->findAllForDid('did:plc:alice')); $updated = new AccountDevice( did: 'did:plc:alice', deviceId: 'dev-1', createdAt: new DateTimeImmutable('2026-01-01T00:00:00Z'), updatedAt: new DateTimeImmutable('2026-02-01T00:00:00Z'), ); $repo->save($updated); $this->assertCount(1, $repo->findAllForDid('did:plc:alice')); $this->assertEquals( new DateTimeImmutable('2026-02-01T00:00:00Z'), $repo->findByDidAndDeviceId('did:plc:alice', 'dev-1')->getUpdatedAt(), ); } public function testDeleteByDidAndDeviceId(): void { $repo = $this->newRepo(); $repo->save($this->makeEntry('did:plc:alice', 'dev-1')); $repo->save($this->makeEntry('did:plc:alice', 'dev-2')); $repo->deleteByDidAndDeviceId('did:plc:alice', 'dev-1'); $this->assertCount(1, $repo->findAllForDid('did:plc:alice')); $this->expectException(AccountDeviceNotFoundException::class); $repo->findByDidAndDeviceId('did:plc:alice', 'dev-1'); } }