[Web][Tests] Add archive module tests

This commit is contained in:
FreddleSpl0it committed 2026-11-07 00:18:58 +01:00
1 parent 2ac2edf0ad
commit fc56d53029
14 files changed
+1403

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
namespace Mailcow\Tests\Support;
use Mailcow\Archive\Model\Mailbox;
use Mailcow\Archive\Repository\LookupRepository;
/**
* Address tables in memory, with the conditions of the SQL already applied: only active rows are listed,
* $mailboxes holds the mailboxes that receive mail as username => [archive setting, domain archive].
*/
class FakeArchiveLookup extends LookupRepository
{
public array $recipientMaps = [];
public array $aliases = [];
public array $resources = [];
public array $spamAliases = [];
/** alias domain => target domain */
public array $aliasDomains = [];
public array $mailboxes = [];
/** ['rcpt' => [key => dest], 'sender' => [key => dest]] */
public array $bcc = ['rcpt' => [], 'sender' => []];
/** @var string[] domains and alias domains of the mailcow */
public array $domains = [];
/** @var string[] every lookup as "<method>:<key>" */
public array $queries = [];
public function __construct()
{
}
public function recipientMap(string $key): ?string
{
$this->queries[] = 'recipientMap:' . $key;
return $this->recipientMaps[$key] ?? null;
}
public function aliasGoto(string $key): ?string
{
$this->queries[] = 'aliasGoto:' . $key;
return $this->aliases[$key] ?? null;
}
public function isResource(string $username): bool
{
return in_array($username, $this->resources, true);
}
public function spamAliasGoto(string $key): ?string
{
return $this->spamAliases[$key] ?? null;
}
public function aliasDomainMailbox(string $local, string $domain): ?string
{
$target = $this->aliasDomains[$domain] ?? null;
return ($target !== null && isset($this->mailboxes[$local . '@' . $target])) ? $local . '@' . $target : null;
}
public function bccDestination(string $key, string $type): ?string
{
return $this->bcc[$type][$key] ?? null;
}
public function isMailcowDomain(string $domain): bool
{
return in_array($domain, $this->domains, true);
}
public function mailbox(string $username): ?Mailbox
{
if (!isset($this->mailboxes[$username])) {
return null;
}
[$archive, $domainArchive] = $this->mailboxes[$username];
return Mailbox::fromRow(['username' => $username, 'domain' => substr($username, strrpos($username, '@') + 1),
'archive' => $archive, 'domain_archive' => $domainArchive, 'name' => '', 'active' => 1]);
}
public function archivedMailboxes(): array
{
return array_values(array_filter(array_map(fn(string $username): Mailbox => $this->mailbox($username), array_keys($this->mailboxes)),
fn(Mailbox $mailbox): bool => $mailbox->archived()));
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace Mailcow\Tests\Support;
/**
* The few Redis commands of the archive state, in memory (the test image has no redis extension).
*/
class FakeRedis
{
public array $lists = [];
public array $strings = [];
public function set(string $key, string $value): bool
{
$this->strings[$key] = $value;
return true;
}
public function get(string $key): string|false
{
return $this->strings[$key] ?? false;
}
public function incr(string $key): int
{
$this->strings[$key] = (string)((int)($this->strings[$key] ?? 0) + 1);
return (int)$this->strings[$key];
}
public function lPush(string $key, string $value): int
{
$this->lists[$key] ??= [];
array_unshift($this->lists[$key], $value);
return count($this->lists[$key]);
}
public function lTrim(string $key, int $start, int $stop): bool
{
$this->lists[$key] = array_slice($this->lists[$key] ?? [], $start, $stop - $start + 1);
return true;
}
/** Like Redis, a negative stop counts from the end (-1 is the last element) */
public function lRange(string $key, int $start, int $stop): array
{
$list = $this->lists[$key] ?? [];
if ($stop < 0) {
$stop += count($list);
}
return array_slice($list, $start, max(0, $stop - $start + 1));
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Mailcow\Tests\Support;
use Mailcow\Archive\Smtp\SmtpClient;
use Mailcow\Archive\Smtp\SmtpException;
/**
* SmtpClient without network: records submit() and probe() calls, answers with the configured results.
*/
class FakeSmtpClient extends SmtpClient
{
/** @var array[] submit() calls: host, port, from, rcpt, data */
public array $submitted = [];
/** @var array[] probe() calls */
public array $probed = [];
public ?SmtpException $error = null;
/** @var string[] extensions probe() reports */
public array $extensions = ['PIPELINING', 'SIZE', 'STARTTLS', '8BITMIME', 'SMTPUTF8'];
public array $mx = [];
public function submit(string $host, int $port, string $from, string $rcpt, string $data): string
{
if ($this->error !== null) {
throw $this->error;
}
$this->submitted[] = compact('host', 'port', 'from', 'rcpt', 'data');
return 'Q' . count($this->submitted);
}
public function probe(string $host, int $port, string $tls, string $username, string $password, string $from, string $rcpt): array
{
$this->probed[] = compact('host', 'port', 'tls', 'username', 'password', 'from', 'rcpt');
if ($this->error !== null) {
throw $this->error;
}
return $this->extensions;
}
public function mailHost(string $domain): string
{
return $this->mx[$domain] ?? $domain;
}
}