mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-11-15 12:50:15 +00:00
[Web] API: complete the OpenAPI docs, add route tests for json_api.php
This commit is contained in:
47 files changed
+18848
-7491
No files matched your search
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** App passwords of mailboxes */
|
||||
class AppPasswordRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testAddAppPassword(): void
|
||||
{
|
||||
$body = ['username' => 'john@example.org', 'app_name' => 'Thunderbird', 'app_passwd' => 'eiQu4ahz8iePh', 'app_passwd2' => 'eiQu4ahz8iePh', 'protocols' => ['imap_access']];
|
||||
|
||||
$this->assertCalled($this->post('add/app-passwd', $body), 'app_passwd', ['add', $body]);
|
||||
}
|
||||
|
||||
public function testListsOfAMailboxAndOfTheSessionUser(): void
|
||||
{
|
||||
$script = [
|
||||
self::answer('app_passwd', ['get'], [['id' => 23, 'name' => 'Thunderbird'], ['id' => 24, 'name' => 'Gone']]),
|
||||
self::answer('app_passwd', ['details', 23], ['id' => 23, 'mailbox' => 'john@example.org']),
|
||||
self::answer('app_passwd', ['details', 24], false),
|
||||
];
|
||||
|
||||
$mailbox = $this->get('get/app-passwd/all/john@example.org', ['script' => $script]);
|
||||
$this->assertSame([['get', ['username' => 'john@example.org']], ['details', 23], ['details', 24]], $mailbox->callsTo('app_passwd'));
|
||||
$this->assertSame([['id' => 23, 'mailbox' => 'john@example.org']], $mailbox->json());
|
||||
|
||||
$own = $this->get('get/app-passwd/all', ['session' => self::USER, 'script' => $script]);
|
||||
$this->assertSame(['get'], $own->callsTo('app_passwd')[0]);
|
||||
|
||||
$this->assertSame('{}', $this->get('get/app-passwd/all')->body);
|
||||
}
|
||||
|
||||
public function testSingleAppPasswordFails(): void
|
||||
{
|
||||
$result = $this->get('get/app-passwd/23', ['allow_error' => true]);
|
||||
|
||||
$this->assertStringContainsString('Cannot access offset of type string on string', (string)$result->error);
|
||||
$this->assertNotCalled($result, 'app_passwd');
|
||||
}
|
||||
|
||||
public function testEditAndDeleteAppPasswords(): void
|
||||
{
|
||||
$edit = $this->post('edit/app-passwd', ['items' => [23], 'attr' => ['username' => 'john@example.org', 'active' => '0']]);
|
||||
$this->assertCalled($edit, 'app_passwd', ['edit', ['id' => [23], 'username' => 'john@example.org', 'active' => '0']]);
|
||||
|
||||
$this->assertCalled($this->post('delete/app-passwd', [23, 24]), 'app_passwd', ['delete', ['id' => [23, 24]]]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** Sieve filters and the spam allow/deny lists of mailboxes */
|
||||
class FilterAndPolicyRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testAddEditDeleteFilters(): void
|
||||
{
|
||||
$body = ['username' => 'john@example.org', 'script_desc' => 'Move newsletters', 'script_data' => 'keep;', 'filter_type' => 'prefilter', 'active' => 1];
|
||||
$this->assertCalled($this->post('add/filter', $body), 'mailbox', ['add', 'filter', $body]);
|
||||
|
||||
$this->assertCalled($this->post('edit/filter', ['items' => [7], 'attr' => ['active' => 0]]), 'mailbox', ['edit', 'filter', ['id' => [7], 'active' => 0]]);
|
||||
$this->assertCalled($this->post('delete/filter', [7]), 'mailbox', ['delete', 'filter', ['id' => [7]]]);
|
||||
}
|
||||
|
||||
public function testAllFiltersOfAllMailboxes(): void
|
||||
{
|
||||
$result = $this->get('get/filters/all', ['script' => [
|
||||
self::answer('mailbox', ['get', 'domains'], ['example.org']),
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org'], ['john@example.org', 'jane@example.org']),
|
||||
self::answer('mailbox', ['get', 'filters', 'john@example.org'], [7, 8]),
|
||||
self::answer('mailbox', ['get', 'filter_details', 7], ['id' => 7]),
|
||||
self::answer('mailbox', ['get', 'filter_details', 8], false),
|
||||
]]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'filters', 'jane@example.org']);
|
||||
$this->assertSame([['id' => 7]], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/filters/all')->body);
|
||||
}
|
||||
|
||||
public function testFiltersOfAMailbox(): void
|
||||
{
|
||||
$result = $this->get('get/filters/john@example.org', ['script' => [
|
||||
self::answer('mailbox', ['get', 'filters'], [7]),
|
||||
self::answer('mailbox', ['get', 'filter_details', 7], ['id' => 7, 'username' => 'john@example.org']),
|
||||
]]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'filters', 'john@example.org']);
|
||||
$this->assertSame([['id' => 7, 'username' => 'john@example.org']], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/filters/jane@example.org')->body);
|
||||
}
|
||||
|
||||
public function testActiveUserSieveIsAListWithOneScript(): void
|
||||
{
|
||||
$result = $this->get('get/active-user-sieve/john@example.org', ['script' => [self::answer('mailbox', ['get', 'active_user_sieve'], "require \"fileinto\";\nkeep;")]]);
|
||||
|
||||
$this->assertSame([['get', 'active_user_sieve', 'john@example.org']], $result->callsTo('mailbox'));
|
||||
$this->assertSame(["require \"fileinto\";\nkeep;"], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/active-user-sieve/john@example.org', ['script' => [self::answer('mailbox', [], false)]])->body);
|
||||
|
||||
$none = $this->get('get/active-user-sieve');
|
||||
$this->assertNotCalled($none, 'mailbox');
|
||||
$this->assertSame('{}', $none->body);
|
||||
}
|
||||
|
||||
public function testAddAndDeleteMailboxPolicies(): void
|
||||
{
|
||||
$body = ['username' => 'john@example.org', 'object_list' => 'bl', 'object_from' => '*@spam.example.com'];
|
||||
$this->assertCalled($this->post('add/mailbox-policy', $body), 'policy', ['add', 'mailbox', $body]);
|
||||
|
||||
$this->assertCalled($this->post('delete/mailbox-policy', [13]), 'policy', ['delete', 'mailbox', ['prefid' => [13]]]);
|
||||
}
|
||||
|
||||
public function testAllowAndDenyListsArePartsOfThePolicy(): void
|
||||
{
|
||||
$policy = [
|
||||
'whitelist' => [['object' => 'john@example.org', 'value' => '*@partner.example.com', 'prefid' => 12]],
|
||||
'blacklist' => [['object' => 'example.org', 'value' => '*@spam.example.com', 'prefid' => 13]],
|
||||
];
|
||||
$script = [self::answer('policy', ['get', 'mailbox'], $policy)];
|
||||
|
||||
$allow = $this->get('get/policy_wl_mailbox/john@example.org', ['script' => $script]);
|
||||
$this->assertSame([['get', 'mailbox', 'john@example.org']], $allow->callsTo('policy'));
|
||||
$this->assertSame($policy['whitelist'], $allow->json());
|
||||
|
||||
$this->assertSame($policy['blacklist'], $this->get('get/policy_bl_mailbox/john@example.org', ['script' => $script])->json());
|
||||
$this->assertSame('{}', $this->get('get/policy_bl_mailbox/nobody@example.org')->body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** Mailboxes, their templates, tags, custom attributes, renaming, ACLs, logins and resets */
|
||||
class MailboxRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testAddMailbox(): void
|
||||
{
|
||||
$body = ['local_part' => 'john.doe', 'domain' => 'example.org', 'password' => 'Moo2Shoh5aiXu', 'password2' => 'Moo2Shoh5aiXu', 'tags' => ['sales']];
|
||||
|
||||
$this->assertCalled($this->post('add/mailbox', $body), 'mailbox', ['add', 'mailbox', $body]);
|
||||
// any other object is a mailbox as well
|
||||
$this->assertCalled($this->post('add/mailbox/something', $body), 'mailbox', ['add', 'mailbox', $body]);
|
||||
}
|
||||
|
||||
public function testAddMailboxTemplate(): void
|
||||
{
|
||||
$body = ['template' => 'Sales', 'quota' => 2048, 'acl' => ['spam_alias']];
|
||||
|
||||
$this->assertCalled($this->post('add/mailbox/template', $body), 'mailbox', ['add', 'mailbox_templates', $body]);
|
||||
}
|
||||
|
||||
public function testGetAllMailboxesWalksAllDomains(): void
|
||||
{
|
||||
$result = $this->get('get/mailbox/all', ['script' => [
|
||||
self::answer('mailbox', ['get', 'domains'], ['example.org', 'example.com']),
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org'], ['john@example.org', 'gone@example.org']),
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.com'], ['jane@example.com']),
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'john@example.org'], ['username' => 'john@example.org']),
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'gone@example.org'], false),
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'jane@example.com'], ['username' => 'jane@example.com']),
|
||||
]]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailboxes', 'example.org', null]);
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailbox_details', 'john@example.org', 'all']);
|
||||
$this->assertSame([['username' => 'john@example.org'], ['username' => 'jane@example.com']], $result->json());
|
||||
}
|
||||
|
||||
public function testReducedDetailsOfGivenDomainsWithTags(): void
|
||||
{
|
||||
$result = $this->get('get/mailbox/reduced/example.org,example.com', [
|
||||
'query' => ['tags' => 'sales,support'],
|
||||
'script' => [
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org'], ['john@example.org']),
|
||||
self::answer('mailbox', ['get', 'mailbox_details'], ['username' => 'john@example.org']),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertNotContains(['get', 'domains'], $result->callsTo('mailbox'));
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailboxes', 'example.org', ['sales', 'support']]);
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailboxes', 'example.com', ['sales', 'support']]);
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailbox_details', 'john@example.org', 'reduced']);
|
||||
$this->assertSame([['username' => 'john@example.org']], $result->json());
|
||||
}
|
||||
|
||||
public function testMailboxListsWithoutResults(): void
|
||||
{
|
||||
$this->assertSame('{}', $this->get('get/mailbox/all')->body);
|
||||
$this->assertSame('{}', $this->get('get/mailbox/all/example.org')->body);
|
||||
}
|
||||
|
||||
public function testGetOneMailbox(): void
|
||||
{
|
||||
$found = $this->get('get/mailbox/john@example.org', ['script' => [
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'john@example.org'], ['username' => 'john@example.org', 'quota' => 0]),
|
||||
]]);
|
||||
|
||||
$this->assertCalled($found, 'mailbox', ['get', 'mailbox_details', 'john@example.org']);
|
||||
$this->assertSame(['username' => 'john@example.org', 'quota' => 0], $found->json());
|
||||
$this->assertSame('{}', $this->get('get/mailbox/nobody@example.org')->body);
|
||||
}
|
||||
|
||||
public function testGetMailboxWithTagsSearchesByAddressPart(): void
|
||||
{
|
||||
$result = $this->get('get/mailbox/example.org', [
|
||||
'query' => ['tags' => 'sales'],
|
||||
'script' => [
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org', ['sales']], ['john@example.org']),
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'john@example.org'], ['username' => 'john@example.org']),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'mailbox_details', 'john@example.org']);
|
||||
$this->assertSame([['username' => 'john@example.org']], $result->json());
|
||||
$this->assertSame('[]', $this->get('get/mailbox/example.org', ['query' => ['tags' => 'sales']])->body);
|
||||
}
|
||||
|
||||
public function testGetMailboxTemplates(): void
|
||||
{
|
||||
$templates = [['id' => 2, 'template' => 'Default', 'type' => 'mailbox', 'attributes' => ['quota' => 0]]];
|
||||
$all = $this->get('get/mailbox/template/all', ['script' => [self::answer('mailbox', ['get', 'mailbox_templates'], $templates)]]);
|
||||
|
||||
$this->assertSame([['get', 'mailbox_templates']], $all->callsTo('mailbox'));
|
||||
$this->assertSame($templates, $all->json());
|
||||
$this->assertCalled($this->get('get/mailbox/template/2'), 'mailbox', ['get', 'mailbox_templates', '2']);
|
||||
}
|
||||
|
||||
public function testEditMailbox(): void
|
||||
{
|
||||
$result = $this->post('edit/mailbox', ['items' => 'john@example.org', 'attr' => ['quota' => 5120, 'sender_acl' => ['@example.com']]]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['edit', 'mailbox', ['username' => ['john@example.org'], 'quota' => 5120, 'sender_acl' => ['@example.com']]]);
|
||||
}
|
||||
|
||||
public function testEditMailboxTemplatesAndCustomAttributes(): void
|
||||
{
|
||||
$template = $this->post('edit/mailbox/template', ['items' => [3], 'attr' => ['template' => 'Sales', 'quarantine_category' => 'reject']]);
|
||||
$this->assertCalled($template, 'mailbox', ['edit', 'mailbox_templates', ['ids' => [3], 'template' => 'Sales', 'quarantine_category' => 'reject']]);
|
||||
|
||||
$custom = $this->post('edit/mailbox/custom-attribute', ['items' => ['john@example.org'], 'attr' => ['attribute' => ['department'], 'value' => ['Sales']]]);
|
||||
$this->assertCalled($custom, 'mailbox', ['edit', 'mailbox_custom_attribute', ['mailboxes' => ['john@example.org'], 'attribute' => ['department'], 'value' => ['Sales']]]);
|
||||
}
|
||||
|
||||
public function testRenameMailboxTakesTheNamesFromAttr(): void
|
||||
{
|
||||
$attr = ['domain' => 'example.org', 'old_local_part' => 'john.doe', 'new_local_part' => 'john', 'create_alias' => 1];
|
||||
|
||||
$result = $this->post('edit/rename-mbox', ['items' => [], 'attr' => $attr]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['edit', 'mailbox_rename', ['mailbox' => []] + $attr]);
|
||||
}
|
||||
|
||||
public function testEditUserAcl(): void
|
||||
{
|
||||
$result = $this->post('edit/user-acl', ['items' => ['john@example.org'], 'attr' => ['user_acl' => ['spam_alias', 'app_passwds']]]);
|
||||
|
||||
$this->assertCalled($result, 'acl', ['edit', 'user', ['username' => ['john@example.org'], 'user_acl' => ['spam_alias', 'app_passwds']]]);
|
||||
}
|
||||
|
||||
public function testDeleteMailboxesTagsAndTemplates(): void
|
||||
{
|
||||
$this->assertCalled($this->post('delete/mailbox', ['john@example.org']), 'mailbox', ['delete', 'mailbox', ['username' => ['john@example.org']]]);
|
||||
|
||||
$tags = $this->post('delete/mailbox/tag/john@example.org', ['sales', 'trainee']);
|
||||
$this->assertCalled($tags, 'mailbox', ['delete', 'tags_mailbox', ['tags' => ['sales', 'trainee'], 'username' => 'john@example.org']]);
|
||||
|
||||
$this->assertCalled($this->post('delete/mailbox/template', [3]), 'mailbox', ['delete', 'mailbox_templates', ['ids' => [3]]]);
|
||||
}
|
||||
|
||||
public function testResetEasCacheAndSogoProfile(): void
|
||||
{
|
||||
$this->assertCalled($this->post('delete/eas_cache', ['john@example.org']), 'mailbox', ['delete', 'eas_cache', ['username' => ['john@example.org']]]);
|
||||
$this->assertCalled($this->post('delete/sogo_profile', ['john@example.org']), 'mailbox', ['delete', 'sogo_profile', ['username' => ['john@example.org']]]);
|
||||
}
|
||||
|
||||
public function testLastLogin(): void
|
||||
{
|
||||
$logins = ['ui' => false, 'sasl' => [['real_rip' => '198.51.100.23', 'service' => 'imap']]];
|
||||
$default = $this->get('get/last-login/john@example.org', ['script' => [self::answer('last_login', [], $logins)]]);
|
||||
$this->assertSame([['get', 'john@example.org']], $default->callsTo('last_login'));
|
||||
$this->assertSame($logins, $default->json());
|
||||
|
||||
$this->assertSame([['get', 'john@example.org', 30]], $this->get('get/last-login/john@example.org/30')->callsTo('last_login'));
|
||||
$this->assertSame([['get', 'john@example.org']], $this->get('get/last-login/john@example.org/0')->callsTo('last_login'));
|
||||
|
||||
$none = $this->get('get/last-login');
|
||||
$this->assertSame('', $none->body);
|
||||
$this->assertNotCalled($none, 'last_login');
|
||||
}
|
||||
|
||||
public function testResetLastLoginIsAReadRoute(): void
|
||||
{
|
||||
$result = $this->get('get/reset-last-login/john@example.org', ['session' => self::API_RO, 'script' => [self::answer('last_login', ['reset'], true)]]);
|
||||
|
||||
$this->assertSame([['reset', 'john@example.org']], $result->callsTo('last_login'));
|
||||
$this->assertSame('true', $result->body);
|
||||
}
|
||||
|
||||
public function testBccDestinationOptions(): void
|
||||
{
|
||||
$result = $this->get('get/bcc-destination-options', ['script' => [
|
||||
self::answer('mailbox', ['get', 'domains'], ['example.org']),
|
||||
self::answer('mailbox', ['get', 'alias_domains'], ['example.net']),
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org'], ['john@example.org']),
|
||||
self::answer('user_get_alias_details', ['john@example.org'], [
|
||||
'direct_aliases' => ['sales@example.org' => ['public_comment' => ''], 'john@other.example' => ['public_comment' => '']],
|
||||
'shared_aliases' => ['team@example.org' => ['public_comment' => '']],
|
||||
]),
|
||||
self::answer('hasDomainAccess', ['API', 'admin', 'example.org'], true),
|
||||
]]);
|
||||
|
||||
$this->assertSame([
|
||||
'domains' => ['example.org'],
|
||||
'mailboxes' => ['john@example.org' => ['john@example.org', 'sales@example.org', 'team@example.org']],
|
||||
'alias_domains' => ['example.net'],
|
||||
], $result->json());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiResult;
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** search/mailbox: the DataTables server-side search of the mailbox table */
|
||||
class MailboxSearchTest extends ApiTestCase
|
||||
{
|
||||
private const REQUEST = [
|
||||
'draw' => 1,
|
||||
'start' => 0,
|
||||
'length' => 25,
|
||||
'search' => ['value' => 'john'],
|
||||
'order' => [['column' => 2, 'dir' => 'asc']],
|
||||
'columns' => [['data' => 'username', 'searchable' => true, 'orderable' => true]],
|
||||
];
|
||||
|
||||
private const KIND_FILTER = "(`m`.`kind` = '' OR `m`.`kind` = NULL)";
|
||||
|
||||
public function testAdminsSearchAllMailboxes(): void
|
||||
{
|
||||
$call = $this->searchCall($this->post('search/mailbox', self::REQUEST));
|
||||
|
||||
$this->assertSame([self::REQUEST, '@pdo', ['mailbox', 'm'], 'username'], array_slice($call, 0, 4));
|
||||
$this->assertSame([null, self::KIND_FILTER], array_slice($call, 5));
|
||||
$this->assertSame([2 => 'username', 3 => 'quota', 4 => 'last_mail_login', 5 => 'last_pw_change', 6 => 'in_use', 7 => 'name',
|
||||
20 => 'messages', 23 => 'tags', 24 => 'active'], array_column($call[4], 'db', 'dt'));
|
||||
}
|
||||
|
||||
public function testReadOnlyKeysMaySearch(): void
|
||||
{
|
||||
$this->searchCall($this->post('search/mailbox', self::REQUEST, ['session' => self::API_RO]));
|
||||
}
|
||||
|
||||
public function testDomainAdminsSearchTheirDomains(): void
|
||||
{
|
||||
$call = $this->searchCall($this->post('search/mailbox', self::REQUEST, ['session' => self::DOMAIN_ADMIN]));
|
||||
|
||||
$this->assertSame('INNER JOIN domain_admins as da ON da.domain = m.domain', $call[5]);
|
||||
$this->assertSame([
|
||||
'condition' => self::KIND_FILTER . ' AND `da`.`active` = 1 AND `da`.`username` = :username',
|
||||
'bindings' => ['username' => 'domainadmin'],
|
||||
], $call[6]);
|
||||
}
|
||||
|
||||
public function testOthersAreRefused(): void
|
||||
{
|
||||
foreach ([self::USER, self::NO_SESSION] as $session) {
|
||||
$result = $this->post('search/mailbox', self::REQUEST, ['session' => $session]);
|
||||
$this->assertApiError($result, 403, 'Insufficient permissions');
|
||||
$this->assertNotCalled($result, 'SSP::complex');
|
||||
}
|
||||
}
|
||||
|
||||
public function testRowsBecomeMailboxDetails(): void
|
||||
{
|
||||
$page = ['draw' => 1, 'recordsTotal' => 2, 'recordsFiltered' => 2, 'data' => [
|
||||
[2 => 'john@example.org', 3 => 0, 4 => '', 7 => 'John'],
|
||||
[2 => 'gone@example.org', 3 => 0, 4 => '', 7 => 'Gone'],
|
||||
]];
|
||||
$result = $this->post('search/mailbox', self::REQUEST, ['script' => [
|
||||
self::answer('SSP::complex', [], $page),
|
||||
self::answer('mailbox', ['get', 'mailbox_details', 'john@example.org'], ['username' => 'john@example.org']),
|
||||
]]);
|
||||
|
||||
$this->assertSame([['get', 'mailbox_details', 'john@example.org'], ['get', 'mailbox_details', 'gone@example.org']], $result->callsTo('mailbox'));
|
||||
$this->assertSame(['draw' => 1, 'recordsTotal' => 2, 'recordsFiltered' => 2, 'data' => [['username' => 'john@example.org']]], $result->json());
|
||||
}
|
||||
|
||||
public function testEmptyPageIsPassedOn(): void
|
||||
{
|
||||
$page = ['draw' => 4, 'recordsTotal' => 0, 'recordsFiltered' => 0, 'data' => []];
|
||||
|
||||
$result = $this->post('search/mailbox', self::REQUEST, ['script' => [self::answer('SSP::complex', [], $page)]]);
|
||||
|
||||
$this->assertNotCalled($result, 'mailbox');
|
||||
$this->assertSame($page, $result->json());
|
||||
}
|
||||
|
||||
private function searchCall(ApiResult $result): array
|
||||
{
|
||||
$calls = $result->callsTo('SSP::complex');
|
||||
$this->assertCount(1, $calls, $result->body);
|
||||
$this->assertNotCalled($result, 'SSP::simple');
|
||||
return $calls[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** Settings a mailbox user changes on its page: time-limited aliases, Pushover, tagged mail, TLS, quarantine, spam score */
|
||||
class MailboxSettingsRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testTimeLimitedAliases(): void
|
||||
{
|
||||
$body = ['username' => 'john@example.org', 'domain' => 'example.org', 'validity' => 720];
|
||||
$this->assertCalled($this->post('add/time_limited_alias', $body), 'mailbox', ['add', 'time_limited_alias', $body]);
|
||||
|
||||
$edit = $this->post('edit/time_limited_alias', ['items' => ['kahd.osuwe@example.org'], 'attr' => ['validity' => 24]]);
|
||||
$this->assertCalled($edit, 'mailbox', ['edit', 'time_limited_alias', ['address' => ['kahd.osuwe@example.org'], 'validity' => 24]]);
|
||||
|
||||
$delete = $this->post('delete/time_limited_alias', ['kahd.osuwe@example.org']);
|
||||
$this->assertCalled($delete, 'mailbox', ['delete', 'time_limited_alias', ['address' => ['kahd.osuwe@example.org']]]);
|
||||
}
|
||||
|
||||
public function testListTimeLimitedAliases(): void
|
||||
{
|
||||
$aliases = [['address' => 'kahd.osuwe@example.org', 'goto' => 'john@example.org', 'permanent' => 0]];
|
||||
|
||||
$result = $this->get('get/time_limited_aliases/john@example.org', ['script' => [self::answer('mailbox', ['get', 'time_limited_aliases'], $aliases)]]);
|
||||
|
||||
$this->assertSame([['get', 'time_limited_aliases', 'john@example.org']], $result->callsTo('mailbox'));
|
||||
$this->assertSame($aliases, $result->json());
|
||||
$this->assertSame('{}', $this->get('get/time_limited_aliases/jane@example.org')->body);
|
||||
}
|
||||
|
||||
public function testPushover(): void
|
||||
{
|
||||
$attr = ['key' => str_repeat('a', 30), 'token' => str_repeat('b', 30), 'active' => 1];
|
||||
$this->assertCalled($this->post('edit/pushover', ['items' => ['john@example.org'], 'attr' => $attr]), 'pushover', ['edit', ['username' => ['john@example.org']] + $attr]);
|
||||
|
||||
$this->assertCalled($this->post('edit/pushover-test', ['items' => ['john@example.org'], 'attr' => []]), 'pushover', ['test', ['username' => ['john@example.org']]]);
|
||||
}
|
||||
|
||||
public function testMailboxUserSettingsGetTheMailboxesAsUsername(): void
|
||||
{
|
||||
$routes = [
|
||||
'delimiter_action' => ['tagged_mail_handler' => 'subfolder'],
|
||||
'tls_policy' => ['tls_enforce_in' => 1],
|
||||
'quarantine_notification' => ['quarantine_notification' => 'daily'],
|
||||
'quarantine_category' => ['quarantine_category' => 'all'],
|
||||
'spam_score' => ['spam_score' => '6,12'],
|
||||
];
|
||||
foreach ($routes as $type => $attr) {
|
||||
$route = 'edit/' . ($type === 'spam_score' ? 'spam-score' : $type);
|
||||
$result = $this->post($route, ['items' => 'john@example.org', 'attr' => $attr]);
|
||||
$this->assertCalled($result, 'mailbox', ['edit', $type, ['username' => ['john@example.org']] + $attr]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testTheUiSendsItsOwnAddressAsItem(): void
|
||||
{
|
||||
$result = $this->postForm('edit/delimiter_action', ['items' => '["user@example.org"]', 'attr' => '{"tagged_mail_handler":"subject","csrf_token":"t"}'], ['session' => self::USER]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['edit', 'delimiter_action', ['username' => ['user@example.org'], 'tagged_mail_handler' => 'subject']]);
|
||||
}
|
||||
|
||||
public function testSpamScoreWithoutSpaces(): void
|
||||
{
|
||||
$mailbox = $this->get('get/spam-score/john@example.org', ['script' => [self::answer('mailbox', ['get', 'spam_score'], '6, 12')]]);
|
||||
$this->assertSame([['get', 'spam_score', 'john@example.org']], $mailbox->callsTo('mailbox'));
|
||||
$this->assertSame(['score' => '6,12'], $mailbox->json());
|
||||
|
||||
$default = $this->get('get/spam-score', ['script' => [self::answer('mailbox', ['get', 'spam_score'], '8, 15')]]);
|
||||
$this->assertSame([['get', 'spam_score', null]], $default->callsTo('mailbox'));
|
||||
$this->assertSame(['score' => '8,15'], $default->json());
|
||||
|
||||
$this->assertSame('{}', $this->get('get/spam-score/jane@example.org', ['script' => [self::answer('mailbox', [], false)]])->body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** Rate limits of mailboxes and the reset of rate limit counters */
|
||||
class RatelimitRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testRatelimitsOfAllMailboxesAddTheMailbox(): void
|
||||
{
|
||||
$result = $this->get('get/rl-mbox/all', ['script' => [
|
||||
self::answer('mailbox', ['get', 'domains'], ['example.org']),
|
||||
self::answer('mailbox', ['get', 'mailboxes', 'example.org'], ['john@example.org', 'jane@example.org']),
|
||||
self::answer('ratelimit', ['get', 'mailbox', 'john@example.org'], ['value' => '100', 'frame' => 'h']),
|
||||
self::answer('ratelimit', ['get', 'mailbox', 'jane@example.org'], false),
|
||||
]]);
|
||||
|
||||
$this->assertSame([['value' => '100', 'frame' => 'h', 'mailbox' => 'john@example.org']], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/rl-mbox/all')->body);
|
||||
}
|
||||
|
||||
public function testRatelimitOfAMailbox(): void
|
||||
{
|
||||
$result = $this->get('get/rl-mbox/john@example.org', ['script' => [self::answer('ratelimit', [], ['value' => '100', 'frame' => 'h'])]]);
|
||||
|
||||
$this->assertSame([['get', 'mailbox', 'john@example.org']], $result->callsTo('ratelimit'));
|
||||
$this->assertSame(['value' => '100', 'frame' => 'h'], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/rl-mbox/jane@example.org')->body);
|
||||
}
|
||||
|
||||
public function testEditRatelimit(): void
|
||||
{
|
||||
$result = $this->post('edit/rl-mbox', ['items' => ['john@example.org'], 'attr' => ['rl_value' => 100, 'rl_frame' => 'h']]);
|
||||
|
||||
$this->assertCalled($result, 'ratelimit', ['edit', 'mailbox', ['object' => ['john@example.org'], 'rl_value' => 100, 'rl_frame' => 'h']]);
|
||||
}
|
||||
|
||||
public function testDeleteRatelimitHashAnswersTheRawResult(): void
|
||||
{
|
||||
$deleted = $this->post('delete/rlhash', ['RLabc123'], ['script' => [self::answer('ratelimit', [], true, [self::message('success', 'hash_deleted')])]]);
|
||||
$this->assertSame([['delete', null, 'RLabc123']], $deleted->callsTo('ratelimit'));
|
||||
$this->assertSame('1', $deleted->body);
|
||||
|
||||
$missing = $this->post('delete/rlhash', ['RLabc123'], ['script' => [self::answer('ratelimit', [], false, [self::message('warning', 'hash_not_found')])]]);
|
||||
$this->assertSame('', $missing->body);
|
||||
|
||||
$this->assertSame([['delete', null, 'RLabcRLdef']], $this->post('delete/rlhash', ['RLabc', 'RLdef'])->callsTo('ratelimit'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mailcow\Tests\Api\Mailboxes;
|
||||
|
||||
use Mailcow\Tests\Api\ApiTestCase;
|
||||
|
||||
/** Resources (rooms, equipment, groups) */
|
||||
class ResourceRoutesTest extends ApiTestCase
|
||||
{
|
||||
public function testAddResource(): void
|
||||
{
|
||||
$body = ['domain' => 'example.org', 'description' => 'Meeting Room 1', 'kind' => 'location', 'multiple_bookings' => 0, 'active' => 1];
|
||||
|
||||
$this->assertCalled($this->post('add/resource', $body), 'mailbox', ['add', 'resource', $body]);
|
||||
}
|
||||
|
||||
public function testGetAllResourcesWalksAllDomains(): void
|
||||
{
|
||||
$result = $this->get('get/resource/all', ['script' => [
|
||||
self::answer('mailbox', ['get', 'domains'], ['example.org', 'example.com']),
|
||||
self::answer('mailbox', ['get', 'resources', 'example.org'], ['room1@example.org', 'gone@example.org']),
|
||||
self::answer('mailbox', ['get', 'resource_details', 'room1@example.org'], ['name' => 'room1@example.org']),
|
||||
self::answer('mailbox', ['get', 'resource_details', 'gone@example.org'], false),
|
||||
]]);
|
||||
|
||||
$this->assertCalled($result, 'mailbox', ['get', 'resources', 'example.com']);
|
||||
$this->assertSame([['name' => 'room1@example.org']], $result->json());
|
||||
$this->assertSame('{}', $this->get('get/resource/all')->body);
|
||||
}
|
||||
|
||||
public function testGetOneResource(): void
|
||||
{
|
||||
$result = $this->get('get/resource/room1@example.org', ['script' => [self::answer('mailbox', ['get', 'resource_details'], ['name' => 'room1@example.org'])]]);
|
||||
|
||||
$this->assertSame([['get', 'resource_details', 'room1@example.org']], $result->callsTo('mailbox'));
|
||||
$this->assertSame(['name' => 'room1@example.org'], $result->json());
|
||||
}
|
||||
|
||||
public function testEditAndDeleteResources(): void
|
||||
{
|
||||
$edit = $this->post('edit/resource', ['items' => ['room1@example.org'], 'attr' => ['multiple_bookings' => -1]]);
|
||||
$this->assertCalled($edit, 'mailbox', ['edit', 'resource', ['name' => ['room1@example.org'], 'multiple_bookings' => -1]]);
|
||||
|
||||
$delete = $this->post('delete/resource', ['room1@example.org']);
|
||||
$this->assertCalled($delete, 'mailbox', ['delete', 'resource', ['name' => ['room1@example.org']]]);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user