generated from Nodarx/template
4e12d41ee9
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
132 lines
5.3 KiB
PHP
132 lines
5.3 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\CollectionResource;
|
|
use KTXM\ProviderImap\Providers\ServiceBase;
|
|
use KTXM\ProviderImap\Providers\LiveService;
|
|
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)->mailboxFetch('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)->mailboxFetch('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)->mailboxFetch('Missing'));
|
|
}
|
|
|
|
public function testCollectionsAreResourcesKeyedByName(): void
|
|
{
|
|
$service = $this->service(listStatus: true);
|
|
|
|
$list = $service->collectionList();
|
|
$collection = $service->collectionFetch('INBOX');
|
|
|
|
$this->assertSame(['INBOX'], array_keys($list));
|
|
$this->assertInstanceOf(CollectionResource::class, $list['INBOX']);
|
|
$this->assertInstanceOf(CollectionResource::class, $collection);
|
|
$this->assertSame('INBOX', $collection?->identifier());
|
|
$this->assertNull($this->service(listStatus: true, exists: false)->collectionFetch('Missing'));
|
|
}
|
|
|
|
public function testDelimiterIsReadWithoutListingMailboxes(): void
|
|
{
|
|
$this->assertSame('/', $this->service(listStatus: false)->collectionDelimiter());
|
|
$this->assertSame(['LIST "" ""'], $this->commands);
|
|
}
|
|
|
|
public function testCollectionExtantReportsMissingMailboxes(): void
|
|
{
|
|
$service = new LiveService();
|
|
$live = $this->service(listStatus: true, exists: false);
|
|
(new \ReflectionProperty(LiveService::class, 'mailService'))->setValue($service, $live);
|
|
|
|
$this->assertSame(['Missing' => false], $service->collectionExtant('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' && $command === 'LIST "" ""') {
|
|
$lines[] = "* LIST (\\Noselect) \"/\" \"\"\r\n";
|
|
$lines[] = "$tag OK Completed\r\n";
|
|
return;
|
|
}
|
|
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(ServiceBase::class), $client) extends LiveMailService {
|
|
public function __construct(ServiceBase $service, private readonly Client $client)
|
|
{
|
|
parent::__construct($service);
|
|
}
|
|
|
|
public function imapClient(): Client
|
|
{
|
|
return $this->client;
|
|
}
|
|
};
|
|
}
|
|
}
|