Рассылки, папки по +метке, ловушка только для чужих адресов, служебное API для Jambotron
continuous-integration/drone/pr Build is passing
continuous-integration/drone/pr Build is passing
- V6 mail_lists + mail_list_members: письмо на alerts-prod@ → каждому участнику своя копия в папку рассылки; закрытая рассылка — только от вошедших отправителей (550 снаружи) - bob+prod@ → ящик bob@, папка prod (создаётся сама; системные папки нельзя) - TRAP: чужие адреса → одна копия в INBOX отправителя; наши ящики и рассылки доставляются - /api/service/** (SERVICE_TOKEN из secrets-init): аккаунты (пароль один раз, выключение → вон из рассылок), рассылки - MailDirectory: одно пространство адресов для ящиков и рассылок, без «+» в именах - Настройки → LISTS для администраторов - 86 тестов; живой прогон на Postgres 17: миграции V1–V6, API, SMTP (рассылка/метка/ловушка) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,13 +34,22 @@ class MailboxAdminControllerTest {
|
||||
private final MailDomains domains = new MailDomains("jambocheck.com", "");
|
||||
private final MailAdmins admins = new MailAdmins("", "", domains);
|
||||
private final com.mailserver.util.JwtUtils jwt = mock(com.mailserver.util.JwtUtils.class);
|
||||
private final MailboxAdminController controller = new MailboxAdminController(users, mail, domains, admins, jwt);
|
||||
private final com.mailserver.service.MailLists lists = mock(com.mailserver.service.MailLists.class);
|
||||
private final com.mailserver.service.MailDirectory directory = new com.mailserver.service.MailDirectory(users, lists, domains);
|
||||
private final MailboxAdminController controller = new MailboxAdminController(users, mail, domains, admins, jwt, directory, lists);
|
||||
|
||||
private final User admin = user(1L, "admin@jambocheck.com");
|
||||
private final User alice = user(2L, "alice@jambocheck.com");
|
||||
|
||||
MailboxAdminControllerTest() {
|
||||
when(mail.usedBytes(anyLong())).thenReturn(Mono.just(0L));
|
||||
when(lists.exists(anyString())).thenReturn(Mono.just(false));
|
||||
when(lists.exists("alerts@jambocheck.com")).thenReturn(Mono.just(true));
|
||||
when(users.findOptional(anyString())).thenReturn(Mono.empty());
|
||||
when(users.findOptional("alice@jambocheck.com")).thenReturn(Mono.just(alice));
|
||||
when(lists.save(anyString(), any(), any(), any(Boolean.class), any())).thenAnswer(i ->
|
||||
Mono.just(new com.mailserver.service.MailLists.MailList(5L, i.getArgument(0), i.getArgument(1), i.getArgument(2),
|
||||
i.getArgument(3), List.of("alice@jambocheck.com"))));
|
||||
when(users.all()).thenReturn(Flux.just(alice, admin));
|
||||
when(users.byId(1L)).thenReturn(Mono.just(admin));
|
||||
when(users.byId(2L)).thenReturn(Mono.just(alice));
|
||||
@@ -59,6 +68,27 @@ class MailboxAdminControllerTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void mailboxAndListShareOneAddressSpaceNoPlusInNames() {
|
||||
assertThat(status(() -> create("admin@jambocheck.com", "alerts@jambocheck.com", ""))).isEqualTo(HttpStatus.CONFLICT);
|
||||
assertThat(status(() -> create("admin@jambocheck.com", "bob+x@jambocheck.com", ""))).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
assertThat(create("admin@jambocheck.com", "jambotron_prod@jambocheck.com", "").mailbox().email()).isEqualTo("jambotron_prod@jambocheck.com");
|
||||
|
||||
var request = new MailboxAdminController.ListRequest("prod", "alerts", false, List.of("Alice@jambocheck.com"));
|
||||
assertThat(controller.saveList(as("admin@jambocheck.com"), "alerts-prod@jambocheck.com", Mono.just(request)).block().members())
|
||||
.containsExactly("alice@jambocheck.com");
|
||||
assertThat(status(() -> controller.saveList(as("admin@jambocheck.com"), "alice@jambocheck.com", Mono.just(request)).block()))
|
||||
.isEqualTo(HttpStatus.CONFLICT);
|
||||
var unknown = new MailboxAdminController.ListRequest("prod", null, false, List.of("ghost@jambocheck.com"));
|
||||
assertThat(status(() -> controller.saveList(as("admin@jambocheck.com"), "alerts-prod@jambocheck.com", Mono.just(unknown)).block()))
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
var badFolder = new MailboxAdminController.ListRequest("Trash", null, false, List.of());
|
||||
assertThat(status(() -> controller.saveList(as("admin@jambocheck.com"), "alerts-prod@jambocheck.com", Mono.just(badFolder)).block()))
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
assertThat(status(() -> controller.saveList(as("alice@jambocheck.com"), "alerts-prod@jambocheck.com", Mono.just(request)).block()))
|
||||
.isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void administratorSwitchesTrapOthersCanNot() {
|
||||
assertThat(controller.trap(as("admin@jambocheck.com"), 2L, Mono.just(new MailboxAdminController.TrapRequest(true))).block().trap()).isTrue();
|
||||
|
||||
Reference in New Issue
Block a user