service(); $service->entityExtant('INBOX', 1); $service->entityExtant('INBOX', 2); $this->assertSame(1, $this->sent('EXAMINE "INBOX"')); } public function testOtherMailboxIsSelected(): void { $service = $this->service(); $service->entityExtant('INBOX', 1); $service->entityExtant('Sent', 1); $service->entityExtant('INBOX', 1); $this->assertSame(2, $this->sent('EXAMINE "INBOX"')); $this->assertSame(1, $this->sent('EXAMINE "Sent"')); } public function testWriteAfterReadOnlySelectionSelectsReadWrite(): void { $service = $this->service(); $service->entityExtant('INBOX', 1); $service->entityPatch('INBOX', ['\\Seen'], [], 1); $service->entityExtant('INBOX', 1); $this->assertSame(1, $this->sent('EXAMINE "INBOX"')); $this->assertSame(1, $this->sent('SELECT "INBOX"')); } public function testFailedSelectionIsNotReused(): void { $service = $this->service(); $service->entityExtant('INBOX', 1); $this->failing = ['EXAMINE "Gone"']; try { $service->entityExtant('Gone', 1); $this->fail('Expected the selection to fail'); } catch (ImapException) { } $service->entityExtant('INBOX', 1); $this->assertSame(2, $this->sent('EXAMINE "INBOX"')); } private function sent(string $command): int { return count(array_filter($this->commands, static fn (string $sent): bool => $sent === $command)); } private function service(): LiveMailService { $lines = ["* PREAUTH Ready\r\n"]; $connection = $this->createStub(ConnectionInterface::class); $connection->method('readLine')->willReturnCallback(static function () use (&$lines): string { return array_shift($lines) ?? throw new \RuntimeException('Unexpected response read'); }); $connection->method('write')->willReturnCallback(function (string $wire) use (&$lines): void { [$tag, $command] = explode(' ', trim($wire), 2); $operation = explode(' ', $command)[0]; if ($operation === 'CAPABILITY') { $lines[] = "* CAPABILITY IMAP4rev1\r\n"; } else { $this->commands[] = $command; } if (in_array($command, $this->failing, true)) { $lines[] = "$tag NO Mailbox does not exist\r\n"; return; } if (in_array($operation, ['SELECT', 'EXAMINE'], true)) { $lines[] = "* 3 EXISTS\r\n"; } $lines[] = "$tag OK Completed\r\n"; }); $factory = $this->createStub(ConnectionFactoryInterface::class); $factory->method('create')->willReturn($connection); $client = new Client($factory); $client->connect(new ConnectionConfig('localhost')); return new class($this->createStub(Service::class), $client) extends LiveMailService { public function __construct(Service $service, private readonly Client $client) { parent::__construct($service); } public function imapClient(): Client { return $this->client; } }; } }