newRepo(); $t = $this->makeToken(); $repo->save($t); $result = $repo->findByPurposeAndDid(EmailToken::PURPOSE_CONFIRM_EMAIL, 'did:plc:alice'); $this->assertSame('abc123', $result->getToken()); } public function testFindByPurposeAndToken(): void { $repo = $this->newRepo(); $t = $this->makeToken(); $repo->save($t); $result = $repo->findByPurposeAndToken(EmailToken::PURPOSE_CONFIRM_EMAIL, 'abc123'); $this->assertSame('did:plc:alice', $result->getDid()); } public function testFindThrowsWhenMissing(): void { $repo = $this->newRepo(); $this->expectException(EmailTokenNotFoundException::class); $repo->findByPurposeAndDid(EmailToken::PURPOSE_RESET_PASSWORD, 'did:plc:alice'); } public function testSaveOverwritesPreviousForSamePurposeAndDid(): void { $repo = $this->newRepo(); $repo->save($this->makeToken(token: 'old')); $repo->save($this->makeToken(token: 'new')); $result = $repo->findByPurposeAndDid(EmailToken::PURPOSE_CONFIRM_EMAIL, 'did:plc:alice'); $this->assertSame('new', $result->getToken()); } public function testDeleteByPurposeAndDid(): void { $repo = $this->newRepo(); $repo->save($this->makeToken()); $repo->deleteByPurposeAndDid(EmailToken::PURPOSE_CONFIRM_EMAIL, 'did:plc:alice'); $this->expectException(EmailTokenNotFoundException::class); $repo->findByPurposeAndDid(EmailToken::PURPOSE_CONFIRM_EMAIL, 'did:plc:alice'); } }