Files
provider_imap/tests/php/Unit/CollectionFetchTest.php
T
2026-10-05 20:34:02 -04:00

96 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
namespace KTXT\ProviderImap\Tests\Unit;
use KTXM\ProviderImap\Client\{Client, ConnectionConfig};
use KTXM\ProviderImap\Client\Transport\{ConnectionInterface, ConnectionFactoryInterface};
use KTXM\ProviderImap\Providers\Service;
use KTXM\ProviderImap\Service\Live\LiveMailService;
use PHPUnit\Framework\TestCase;
final class CollectionFetchTest extends TestCase
{
private array $commands = [];
public function testWithListStatusUsesOneRoundTrip(): void
{
$mailbox = $this->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;
}
};
}
}