feat: add cache harmonize command

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-10-07 21:03:52 -04:00
parent 65fdb23fa4
commit c20dde6633
4 changed files with 263 additions and 1 deletions
+39 -1
View File
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace KTXT\ProviderImap\Tests\Unit;
use Generator;
use KTXF\Resource\Filter\IFilter;
use KTXF\Resource\Sort\ISort;
use KTXC\Db\DataStore;
use KTXM\ProviderImap\Client\Mailbox;
use KTXM\ProviderImap\Client\Protocol\Command\Argument\FetchOptions;
@@ -138,6 +140,25 @@ final class MessageHarmonizationTest extends TestCase
$this->assertSame(1, $this->live->fetchBatches[2][49]);
}
public function testHarmonizeAllSkipsUnselectableAndIsolatesFailures(): void
{
$this->live->flags = [1 => []];
$this->live->mailboxList = [
new Mailbox('INBOX', '/', []),
new Mailbox('Archive', '/', ['\\Noselect']),
new Mailbox('Broken', '/', []),
];
$this->live->failing = ['Broken'];
$result = $this->harmonizer->harmonizeAll();
$this->assertSame(['Archive', 'Broken'], $result['mailboxes']['added']);
$this->assertSame(['INBOX', 'Broken'], array_keys($result['messages']));
$this->assertSame('harmonized', $result['messages']['INBOX']['status']);
$this->assertSame('Mailbox not found on server: Broken', $result['messages']['Broken']);
$this->assertNull($this->mailboxes->lockOwner);
}
public function testLockIsReleasedWhenTheRunFails(): void
{
$this->live->uidValidity = null;
@@ -163,9 +184,23 @@ final class MessageHarmonizationLiveStub extends LiveMailService
public array $fetchBatches = [];
public int $selects = 0;
public ?int $bodyTextLimit = null;
/** @var Mailbox[] */
public array $mailboxList = [];
/** @var string[] */
public array $failing = [];
public function collectionList(?string $location = null, IFilter|null $filter = null, ISort|null $sort = null, string $depth = '*'): Generator
{
foreach ($this->mailboxList as $mailbox) {
yield $mailbox->name() => $mailbox;
}
}
public function collectionFetch(string $identifier): ?Mailbox
{
if (in_array($identifier, $this->failing, true)) {
return null;
}
$this->selects++;
return new Mailbox($identifier, '/', [], count($this->flags), 0, $this->uidValidity, 0, [], true, $this->uidNext);
}
@@ -201,7 +236,10 @@ final class FakeMailboxStore extends MailboxStore
public function upsert(string $tenantId, string $serviceId, CollectionResource $collection): void
{
$name = (string) $collection->identifier();
$this->documents[$name] = ($this->documents[$name] ?? self::STATE_DEFAULTS) + ['name' => $name];
$this->documents[$name] = [
...($this->documents[$name] ?? self::STATE_DEFAULTS),
...$collection->toCacheMeta(),
];
}
public function fetch(string $serviceId, string $name): ?array