createStub(ServiceBase::class)); $service->appendUid = 202; $service->destroyResults = [[101 => true]]; $result = $service->entityReplace('Drafts', 101, 'raw message', ['\\Draft']); $this->assertSame(202, $result); $this->assertSame([ ['Drafts', 'raw message', ['\\Draft']], ], $service->createCalls); $this->assertSame([ ['Drafts', [101]], ], $service->destroyCalls); } public function testEntityReplaceRemovesReplacementWhenOldUidCannotBeDeleted(): void { $service = new LiveMailServiceStub($this->createStub(ServiceBase::class)); $service->appendUid = 202; $service->destroyResults = [ [101 => false], [202 => true], ]; try { $service->entityReplace('Drafts', 101, 'raw message', ['\\Draft']); $this->fail('Expected superseded message cleanup failure'); } catch (RuntimeException $exception) { $this->assertSame('Failed to delete the superseded IMAP entity', $exception->getMessage()); } $this->assertSame([ ['Drafts', [101]], ['Drafts', [202]], ], $service->destroyCalls); } } final class LiveMailServiceStub extends LiveMailService { public ?int $appendUid = null; public array $createCalls = []; public array $destroyCalls = []; public array $destroyResults = []; public function entityCreate(string $collection, string $rawMessage, array $flags = []): ?int { $this->createCalls[] = [$collection, $rawMessage, $flags]; return $this->appendUid; } public function entityDestroy(string $collection, int ...$uids): array { $this->destroyCalls[] = [$collection, $uids]; return array_shift($this->destroyResults) ?? []; } }