This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 997bb5776ce445da47bda4c3af7f99c5d95d636f Author: Tung TRAN <[email protected]> AuthorDate: Mon Aug 2 17:40:26 2021 +0700 JAMES-3621 Mailbox webadmin routes - unseenMessageCount --- .../james/webadmin/routes/UserMailboxesRoutes.java | 43 ++++++- .../webadmin/service/UserMailboxesService.java | 8 ++ .../webadmin/routes/UserMailboxesRoutesTest.java | 136 +++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java index ec25b8f..a20ae30 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java @@ -91,6 +91,7 @@ public class UserMailboxesRoutes implements Routes { public static final String USER_MAILBOXES_BASE = USERS_BASE + Constants.SEPARATOR + USER_NAME + Constants.SEPARATOR + MAILBOXES; public static final String SPECIFIC_MAILBOX = USER_MAILBOXES_BASE + Constants.SEPARATOR + MAILBOX_NAME; public static final String MESSAGE_COUNT_PATH = SPECIFIC_MAILBOX + "/messageCount"; + public static final String UNSEEN_MESSAGE_COUNT_PATH = SPECIFIC_MAILBOX + "/unseenMessageCount"; private final UserMailboxesService userMailboxesService; private final JsonTransformer jsonTransformer; @@ -132,6 +133,8 @@ public class UserMailboxesRoutes implements Routes { reIndexMailboxesRoute() .ifPresent(route -> service.post(USER_MAILBOXES_BASE, route, jsonTransformer)); + + unseenMessageCount(); } @GET @@ -355,7 +358,7 @@ public class UserMailboxesRoutes implements Routes { }) @ApiOperation(value = "Counting emails in a given mailbox.") @ApiResponses(value = { - @ApiResponse(code = HttpStatus.OK_200, message = "The number emails in a given mailbox", response = String.class), + @ApiResponse(code = HttpStatus.OK_200, message = "The number emails in a given mailbox", response = Long.class), @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid mailbox name"), @ApiResponse(code = HttpStatus.UNAUTHORIZED_401, message = "Unauthorized. The user is not authenticated on the platform"), @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "Invalid get on user mailboxes"), @@ -384,4 +387,42 @@ public class UserMailboxesRoutes implements Routes { } }); } + + @GET + @Path("/{mailboxName}/unseenMessageCount") + @ApiImplicitParams({ + @ApiImplicitParam(required = true, dataType = "string", name = "username", paramType = "path"), + @ApiImplicitParam(required = true, dataType = "string", name = "mailboxName", paramType = "path") + }) + @ApiOperation(value = "Counting unseen emails in a given mailbox.") + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.OK_200, message = "The number unseen emails in a given mailbox", response = Long.class), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid mailbox name"), + @ApiResponse(code = HttpStatus.UNAUTHORIZED_401, message = "Unauthorized. The user is not authenticated on the platform"), + @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "Invalid get on user mailboxes"), + @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side.") + }) + public void unseenMessageCount() { + service.get(UNSEEN_MESSAGE_COUNT_PATH, (request, response) -> { + try { + return userMailboxesService.unseenMessageCount(getUsernameParam(request), new MailboxName(request.params(MAILBOX_NAME))); + } catch (IllegalStateException | MailboxNotFoundException e) { + LOGGER.info("Invalid get on user mailbox", e); + throw ErrorResponder.builder() + .statusCode(HttpStatus.NOT_FOUND_404) + .type(ErrorType.NOT_FOUND) + .message("Invalid get on user mailboxes") + .cause(e) + .haltError(); + } catch (IllegalArgumentException | MailboxNameException e) { + LOGGER.info("Attempt to test existence of an invalid mailbox", e); + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorType.INVALID_ARGUMENT) + .message("Attempt to test existence of an invalid mailbox") + .cause(e) + .haltError(); + } + }); + } } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java index 395bf71..4a839d4 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java @@ -114,6 +114,14 @@ public class UserMailboxesService { return mailboxManager.getMailbox(MailboxPath.forUser(username, mailboxName.asString()), mailboxSession).getMessageCount(mailboxSession); } + public long unseenMessageCount(Username username, MailboxName mailboxName) throws UsersRepositoryException, MailboxException { + usernamePreconditions(username); + MailboxSession mailboxSession = mailboxManager.createSystemSession(username); + return mailboxManager.getMailbox(MailboxPath.forUser(username, mailboxName.asString()), mailboxSession) + .getMailboxCounters(mailboxSession) + .getUnseen(); + } + private Stream<MailboxPath> listChildren(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException { return listUserMailboxes(mailboxSession) .map(MailboxMetaData::getPath) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java index 0ecaefc..4fc7201 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java @@ -23,6 +23,7 @@ import static io.restassured.RestAssured.given; import static io.restassured.RestAssured.when; import static io.restassured.RestAssured.with; import static io.restassured.http.ContentType.JSON; +import static javax.mail.Flags.Flag.SEEN; import static org.apache.james.webadmin.Constants.SEPARATOR; import static org.apache.james.webadmin.routes.UserMailboxesRoutes.USERS_BASE; import static org.assertj.core.api.Assertions.assertThat; @@ -978,6 +979,141 @@ class UserMailboxesRoutesTest { .containsEntry("message", "Invalid get on user mailboxes") .containsEntry("details", String.format("#private:%s:%s can not be found", USERNAME.asString(), MAILBOX_NAME)); } + + @Test + void getUnseenMessageCountShouldReturnZeroWhenMailBoxEmpty() { + with() + .put(MAILBOX_NAME); + + String response = when() + .get(MAILBOX_NAME + "/unseenMessageCount") + .then() + .statusCode(OK_200) + .extract() + .body().asString(); + + assertThat(response) + .isEqualTo("0"); + } + + @Test + void getUnseenMessageCountShouldReturnZeroWhenMailBoxDoNotHaveAnyUnSeenEmail() { + with() + .put(MAILBOX_NAME); + + MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, MAILBOX_NAME); + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + + IntStream.range(0, 10) + .forEach(index -> { + try { + mailboxManager.getMailbox(mailboxPath, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder() + .withFlags(new Flags(SEEN)) + .build("header: value\r\n\r\nbody"), + systemSession); + } catch (MailboxException e) { + LOGGER.warn("Error when append message " + e); + } + }); + + String response = when() + .get(MAILBOX_NAME + "/unseenMessageCount") + .then() + .statusCode(OK_200) + .extract() + .body().asString(); + + assertThat(response) + .isEqualTo("0"); + } + + @Test + void getUnseenMessageCountShouldReturnNumberOfUnSeenEmails() { + with() + .put(MAILBOX_NAME); + + MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, MAILBOX_NAME); + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + + IntStream.range(0, 5) + .forEach(index -> { + try { + mailboxManager.getMailbox(mailboxPath, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder() + .withFlags(new Flags(SEEN)) + .build("header: value\r\n\r\nbody"), + systemSession); + } catch (MailboxException e) { + LOGGER.warn("Error when append message " + e); + } + }); + + IntStream.range(0, 10) + .forEach(index -> { + try { + mailboxManager.getMailbox(mailboxPath, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder() + .build("header: value\r\n\r\nbody"), + systemSession); + } catch (MailboxException e) { + LOGGER.warn("Error when append message " + e); + } + }); + + String response = when() + .get(MAILBOX_NAME + "/unseenMessageCount") + .then() + .statusCode(OK_200) + .extract() + .body().asString(); + + assertThat(response) + .isEqualTo("10"); + } + + @Test + void getUnseenMessageCountShouldReturnErrorWhenUserIsNotFound() throws UsersRepositoryException { + when(usersRepository.contains(USERNAME)).thenReturn(false); + + Map<String, Object> errors = when() + .get(MAILBOX_NAME + "/unseenMessageCount") + .then() + .statusCode(NOT_FOUND_404) + .contentType(JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", NOT_FOUND_404) + .containsEntry("type", ERROR_TYPE_NOTFOUND) + .containsEntry("message", "Invalid get on user mailboxes") + .containsEntry("details", "User does not exist"); + } + + @Test + void getUnseenMessageCountShouldReturnErrorWhenMailboxDoesNotExist() { + Map<String, Object> errors = when() + .get(MAILBOX_NAME + "/unseenMessageCount") + .then() + .statusCode(NOT_FOUND_404) + .contentType(JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", NOT_FOUND_404) + .containsEntry("type", ERROR_TYPE_NOTFOUND) + .containsEntry("message", "Invalid get on user mailboxes") + .containsEntry("details", String.format("#private:%s:%s can not be found", USERNAME.asString(), MAILBOX_NAME)); + } } @Nested --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
