service(listStatus: true)->collectionFetch('INBOX'); $this->assertCount(1, $this->commands); $this->assertStringContainsString('RETURN (STATUS', $this->commands[0]); $this->assertSame(3, $mailbox?->messages()); $this->assertSame(7, $mailbox?->uidValidity()); $this->assertSame(10, $mailbox?->uidNext()); } public function testWithoutListStatusFallsBackToStatus(): void { $mailbox = $this->service(listStatus: false)->collectionFetch('INBOX'); $this->assertCount(2, $this->commands); $this->assertStringNotContainsString('RETURN', $this->commands[0]); $this->assertStringStartsWith('STATUS', $this->commands[1]); $this->assertSame(3, $mailbox?->messages()); $this->assertSame(7, $mailbox?->uidValidity()); $this->assertSame(10, $mailbox?->uidNext()); } public function testUnknownMailboxIsNull(): void { $this->assertNull($this->service(listStatus: false, exists: false)->collectionFetch('Missing')); } private function service(bool $listStatus, bool $exists = true): 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, $listStatus, $exists): void { [$tag, $command] = explode(' ', trim($wire), 2); $operation = explode(' ', $command)[0]; if ($operation === 'CAPABILITY') { $lines[] = '* CAPABILITY IMAP4rev1' . ($listStatus ? ' LIST-STATUS' : '') . "\r\n"; } else { $this->commands[] = $command; } if ($operation === 'LIST') { if (!$listStatus && str_contains($command, 'RETURN')) { $lines[] = "$tag BAD Unknown RETURN option\r\n"; return; } if ($exists) { $lines[] = "* LIST (\\HasNoChildren) \"/\" \"INBOX\"\r\n"; if ($listStatus) { $lines[] = "* STATUS \"INBOX\" (MESSAGES 3 UNSEEN 1 UIDNEXT 10 UIDVALIDITY 7)\r\n"; } } } if ($operation === 'STATUS') { $lines[] = "* STATUS \"INBOX\" (MESSAGES 3 UNSEEN 1 UIDNEXT 10 UIDVALIDITY 7)\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; } }; } }