From bd082026b942d522de3f67363e4885df8a9d5ee0 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 02:12:20 +0800 Subject: [PATCH 01/15] Create account request rejection endpoint --- .../java/teammates/common/util/Const.java | 3 + .../ui/constants/ResourceEndpoints.java | 1 + .../AccountRequestRejectionRequest.java | 36 ++++++++++++ .../teammates/ui/webapi/ActionFactory.java | 1 + .../ui/webapi/RejectAccountRequestAction.java | 55 +++++++++++++++++++ .../ui/webapi/UpdateAccountRequestAction.java | 4 +- 6 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java create mode 100644 src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java diff --git a/src/main/java/teammates/common/util/Const.java b/src/main/java/teammates/common/util/Const.java index 80369af91c4..2152278dd7e 100644 --- a/src/main/java/teammates/common/util/Const.java +++ b/src/main/java/teammates/common/util/Const.java @@ -45,6 +45,8 @@ public final class Const { public static final String MISSING_RESPONSE_TEXT = "No Response"; + public static final String ACCOUNT_REQUEST_NOT_FOUND = "Account request with id = %s not found"; + // These constants are used as variable values to mean that the variable is in a 'special' state. public static final int INT_UNINITIALIZED = -9999; @@ -337,6 +339,7 @@ public static class ResourceURIs { public static final String ACCOUNT_REQUEST = URI_PREFIX + "/account/request"; public static final String ACCOUNT_REQUESTS = URI_PREFIX + "/account/requests"; public static final String ACCOUNT_REQUEST_RESET = ACCOUNT_REQUEST + "/reset"; + public static final String ACCOUNT_REQUEST_REJECTION = ACCOUNT_REQUEST + "/rejection"; public static final String ACCOUNTS = URI_PREFIX + "/accounts"; public static final String RESPONSE_COMMENT = URI_PREFIX + "/responsecomment"; public static final String COURSE = URI_PREFIX + "/course"; diff --git a/src/main/java/teammates/ui/constants/ResourceEndpoints.java b/src/main/java/teammates/ui/constants/ResourceEndpoints.java index 8e288eb6264..3a7a3abe88c 100644 --- a/src/main/java/teammates/ui/constants/ResourceEndpoints.java +++ b/src/main/java/teammates/ui/constants/ResourceEndpoints.java @@ -17,6 +17,7 @@ public enum ResourceEndpoints { ACCOUNT_REQUEST(ResourceURIs.ACCOUNT_REQUEST), ACCOUNT_REQUESTS(ResourceURIs.ACCOUNT_REQUESTS), ACCOUNT_REQUEST_RESET(ResourceURIs.ACCOUNT_REQUEST_RESET), + ACCOUNT_REQUEST_REJECT(ResourceURIs.ACCOUNT_REQUEST_REJECTION), ACCOUNTS(ResourceURIs.ACCOUNTS), RESPONSE_COMMENT(ResourceURIs.RESPONSE_COMMENT), COURSE(ResourceURIs.COURSE), diff --git a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java new file mode 100644 index 00000000000..9a8298ec3a6 --- /dev/null +++ b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java @@ -0,0 +1,36 @@ +package teammates.ui.request; + +import javax.annotation.Nullable; + +import teammates.common.datatransfer.AccountRequestStatus; +import teammates.common.util.SanitizationHelper; + +/** + * The request reasonBody for rejecting an account request. + */ +public class AccountRequestRejectionRequest extends BasicRequest { + @Nullable + private String reasonTitle; + + @Nullable + private String reasonBody; + + public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) { + this.reasonTitle = SanitizationHelper.sanitizeTitle(reasonTitle); + this.reasonBody = SanitizationHelper.sanitizeForRichText(reasonBody); + } + + @Override + public void validate() throws InvalidHttpRequestBodyException { + // No validation + } + + public String getReasonTitle() { + return this.reasonTitle; + } + + public String getReasonBody() { + return this.reasonBody; + } + +} diff --git a/src/main/java/teammates/ui/webapi/ActionFactory.java b/src/main/java/teammates/ui/webapi/ActionFactory.java index 169d4ae5b07..8ac1bf854f0 100644 --- a/src/main/java/teammates/ui/webapi/ActionFactory.java +++ b/src/main/java/teammates/ui/webapi/ActionFactory.java @@ -53,6 +53,7 @@ public final class ActionFactory { map(ResourceURIs.ACCOUNT_REQUEST, PUT, UpdateAccountRequestAction.class); map(ResourceURIs.ACCOUNT_REQUESTS, GET, GetAccountRequestsAction.class); map(ResourceURIs.ACCOUNT_REQUEST_RESET, PUT, ResetAccountRequestAction.class); + map(ResourceURIs.ACCOUNT_REQUEST_REJECTION, PUT, RejectAccountRequestAction.class); map(ResourceURIs.ACCOUNTS, GET, GetAccountsAction.class); map(ResourceURIs.COURSE, GET, GetCourseAction.class); map(ResourceURIs.COURSE, DELETE, DeleteCourseAction.class); diff --git a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java new file mode 100644 index 00000000000..d11925d9fce --- /dev/null +++ b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java @@ -0,0 +1,55 @@ +package teammates.ui.webapi; + +import java.util.UUID; + +import teammates.common.datatransfer.AccountRequestStatus; +import teammates.common.exception.EntityDoesNotExistException; +import teammates.common.exception.InvalidParametersException; +import teammates.common.util.Const; +import teammates.storage.sqlentity.AccountRequest; +import teammates.ui.output.AccountRequestData; +import teammates.ui.request.AccountRequestRejectionRequest; +import teammates.ui.request.InvalidHttpRequestBodyException; + +/** + * Rejects an account request. + */ +public class RejectAccountRequestAction extends AdminOnlyAction { + + @Override + public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException { + String id = getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID); + UUID accountRequestId; + + try { + accountRequestId = UUID.fromString(id); + } catch (IllegalArgumentException e) { + throw new InvalidHttpParameterException(e.getMessage(), e); + } + + AccountRequest accountRequest = sqlLogic.getAccountRequest(accountRequestId); + + if (accountRequest == null) { + String errorMessage = String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString()); + throw new EntityNotFoundException(errorMessage); + } + + AccountRequestRejectionRequest accountRequestRejectionRequest = + getAndValidateRequestBody(AccountRequestRejectionRequest.class); + + try { + accountRequest.setStatus(AccountRequestStatus.REJECTED); + accountRequest = sqlLogic.updateAccountRequest(accountRequest); + } catch (InvalidParametersException e) { + throw new InvalidHttpRequestBodyException(e); + } catch (EntityDoesNotExistException e) { + throw new EntityNotFoundException(e); + } + + if (accountRequestRejectionRequest.getReasonBody() != null) { + // TODO: generate rejection email from reason title and reason body + } + + return new JsonResult(new AccountRequestData(accountRequest)); + } +} diff --git a/src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java b/src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java index 761a18abd8f..952b812afab 100644 --- a/src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java +++ b/src/main/java/teammates/ui/webapi/UpdateAccountRequestAction.java @@ -17,8 +17,6 @@ */ public class UpdateAccountRequestAction extends AdminOnlyAction { - static final String ACCOUNT_REQUEST_NOT_FOUND = "Account request with id = %s not found"; - @Override public JsonResult execute() throws InvalidOperationException, InvalidHttpRequestBodyException { String id = getNonNullRequestParamValue(Const.ParamsNames.ACCOUNT_REQUEST_ID); @@ -33,7 +31,7 @@ public JsonResult execute() throws InvalidOperationException, InvalidHttpRequest AccountRequest accountRequest = sqlLogic.getAccountRequest(accountRequestId); if (accountRequest == null) { - String errorMessage = String.format(ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString()); + String errorMessage = String.format(Const.ACCOUNT_REQUEST_NOT_FOUND, accountRequestId.toString()); throw new EntityNotFoundException(errorMessage); } From ce21b37d2e9e3e5c3a1d7ab4f60ccc9053f159d8 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 02:53:04 +0800 Subject: [PATCH 02/15] Add validation --- .../ui/request/AccountRequestRejectionRequest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java index 9a8298ec3a6..8b47cc707a1 100644 --- a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java +++ b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java @@ -2,7 +2,6 @@ import javax.annotation.Nullable; -import teammates.common.datatransfer.AccountRequestStatus; import teammates.common.util.SanitizationHelper; /** @@ -22,7 +21,12 @@ public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) { @Override public void validate() throws InvalidHttpRequestBodyException { - // No validation + if (reasonBody != null) { + assertTrue(reasonTitle != null, "If reason body is not null, reason title cannot be null"); + } + if (reasonTitle != null) { + assertTrue(reasonBody != null, "If reason title is not null, reason body cannot be null"); + } } public String getReasonTitle() { From 09ce7a3a55430f08c1d494ec01429d578009bb43 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 02:53:34 +0800 Subject: [PATCH 03/15] Add check for already rejected request when sending email --- .../java/teammates/ui/webapi/RejectAccountRequestAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java index d11925d9fce..54d1e165833 100644 --- a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java +++ b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java @@ -46,7 +46,8 @@ public JsonResult execute() throws InvalidOperationException, InvalidHttpRequest throw new EntityNotFoundException(e); } - if (accountRequestRejectionRequest.getReasonBody() != null) { + if (accountRequestRejectionRequest.getReasonBody() != null + && accountRequest.getStatus() != AccountRequestStatus.REJECTED) { // TODO: generate rejection email from reason title and reason body } From e58bb5beb28f777123da5c8914a5979bbcb368eb Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 02:53:52 +0800 Subject: [PATCH 04/15] Add integration test cases --- .../webapi/RejectAccountRequestActionIT.java | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java diff --git a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java new file mode 100644 index 00000000000..08833fe4651 --- /dev/null +++ b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java @@ -0,0 +1,183 @@ +package teammates.it.ui.webapi; + +import java.util.UUID; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import teammates.common.datatransfer.AccountRequestStatus; +import teammates.common.exception.EntityAlreadyExistsException; +import teammates.common.exception.InvalidParametersException; +import teammates.common.util.Const; +import teammates.common.util.HibernateUtil; +import teammates.storage.sqlentity.AccountRequest; +import teammates.storage.sqlentity.Course; +import teammates.ui.output.AccountRequestData; +import teammates.ui.request.AccountRequestRejectionRequest; +import teammates.ui.request.InvalidHttpRequestBodyException; +import teammates.ui.webapi.EntityNotFoundException; +import teammates.ui.webapi.InvalidHttpParameterException; +import teammates.ui.webapi.InvalidOperationException; +import teammates.ui.webapi.JsonResult; +import teammates.ui.webapi.RejectAccountRequestAction; + +/** + * SUT: {@link RejectAccountRequestAction}. + */ +public class RejectAccountRequestActionIT extends BaseActionIT { + + @Override + @BeforeMethod + protected void setUp() throws Exception { + super.setUp(); + persistDataBundle(typicalBundle); + HibernateUtil.flushSession(); + } + + @Override + protected String getActionUri() { + return Const.ResourceURIs.ACCOUNT_REQUEST_REJECTION; + } + + @Override + protected String getRequestMethod() { + return POST; + } + + @Override + public void testExecute() throws Exception { + // See individual test methods below + } + + @Test + protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail() + throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); + accountRequest.setStatus(AccountRequestStatus.PENDING); + UUID id = accountRequest.getId(); + + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", "body"); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; + + RejectAccountRequestAction action = getAction(requestBody, params); + JsonResult result = action.execute(); + + assertEquals(result.getStatusCode(), 200); + + AccountRequestData data = (AccountRequestData) result.getOutput(); + assertEquals(accountRequest.getName(), data.getName()); + assertEquals(accountRequest.getEmail(), data.getEmail()); + assertEquals(accountRequest.getInstitute(), data.getInstitute()); + assertEquals(AccountRequestStatus.REJECTED, data.getStatus()); + assertEquals(accountRequest.getComments(), data.getComments()); + + // TODO: test email number and contents + } + + @Test + protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail() + throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); + accountRequest.setStatus(AccountRequestStatus.PENDING); + UUID id = accountRequest.getId(); + + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, null); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; + + RejectAccountRequestAction action = getAction(requestBody, params); + JsonResult result = action.execute(); + + assertEquals(result.getStatusCode(), 200); + + AccountRequestData data = (AccountRequestData) result.getOutput(); + assertEquals(accountRequest.getName(), data.getName()); + assertEquals(accountRequest.getEmail(), data.getEmail()); + assertEquals(accountRequest.getInstitute(), data.getInstitute()); + assertEquals(AccountRequestStatus.REJECTED, data.getStatus()); + assertEquals(accountRequest.getComments(), data.getComments()); + + verifyNoEmailsSent(); + } + + @Test + protected void testExecute_withReasonBodyButNoTitle_shouldThrow() throws InvalidHttpParameterException { + AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); + UUID id = accountRequest.getId(); + + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, "body"); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; + + InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); + + assertEquals("If reason body is not null, reason title cannot be null", ihrbe.getMessage()); + verifyNoEmailsSent(); + } + + @Test + protected void testExecute_withReasonTitleButNoBody_shouldThrow() throws InvalidHttpParameterException { + AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); + UUID id = accountRequest.getId(); + + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", null); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; + + InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); + + assertEquals("If reason title is not null, reason body cannot be null", ihrbe.getMessage()); + verifyNoEmailsSent(); + } + + @Test + protected void testExecute_alreadyRejected_shouldNotSendEmail() + throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); + accountRequest.setStatus(AccountRequestStatus.REJECTED); + UUID id = accountRequest.getId(); + + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", "body"); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; + + RejectAccountRequestAction action = getAction(requestBody, params); + JsonResult result = action.execute(); + + assertEquals(result.getStatusCode(), 200); + + AccountRequestData data = (AccountRequestData) result.getOutput(); + assertEquals(accountRequest.getName(), data.getName()); + assertEquals(accountRequest.getEmail(), data.getEmail()); + assertEquals(accountRequest.getInstitute(), data.getInstitute()); + assertEquals(accountRequest.getStatus(), data.getStatus()); + assertEquals(accountRequest.getComments(), data.getComments()); + + verifyNoEmailsSent(); + } + + @Test + protected void testExecute_invalidUuid_shouldThrow() throws InvalidHttpParameterException { + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, null); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, "invalid"}; + + InvalidHttpParameterException ihpe = verifyHttpParameterFailure(requestBody, params); + assertEquals("Invalid UUID string: invalid", ihpe.getMessage()); + verifyNoEmailsSent(); + } + + + @Test + protected void testExecute_accountRequestNotFound_shouldThrow() throws InvalidHttpParameterException { + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, null); + String uuid = UUID.randomUUID().toString(); + String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, uuid}; + + EntityNotFoundException enfe = verifyEntityNotFound(requestBody, params); + assertEquals(String.format("Account request with id = %s not found", uuid), enfe.getMessage()); + verifyNoEmailsSent(); + } + + @Override + @Test + protected void testAccessControl() throws InvalidParametersException, EntityAlreadyExistsException { + Course course = typicalBundle.courses.get("course1"); + verifyOnlyAdminCanAccess(course); + } +} From a8cfdfc688e715279210de35a97f38d1ebb7a35f Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 12:40:11 +0800 Subject: [PATCH 05/15] Set request method to post --- src/main/java/teammates/ui/webapi/ActionFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/teammates/ui/webapi/ActionFactory.java b/src/main/java/teammates/ui/webapi/ActionFactory.java index 8ac1bf854f0..ae834448b7a 100644 --- a/src/main/java/teammates/ui/webapi/ActionFactory.java +++ b/src/main/java/teammates/ui/webapi/ActionFactory.java @@ -53,7 +53,7 @@ public final class ActionFactory { map(ResourceURIs.ACCOUNT_REQUEST, PUT, UpdateAccountRequestAction.class); map(ResourceURIs.ACCOUNT_REQUESTS, GET, GetAccountRequestsAction.class); map(ResourceURIs.ACCOUNT_REQUEST_RESET, PUT, ResetAccountRequestAction.class); - map(ResourceURIs.ACCOUNT_REQUEST_REJECTION, PUT, RejectAccountRequestAction.class); + map(ResourceURIs.ACCOUNT_REQUEST_REJECTION, POST, RejectAccountRequestAction.class); map(ResourceURIs.ACCOUNTS, GET, GetAccountsAction.class); map(ResourceURIs.COURSE, GET, GetCourseAction.class); map(ResourceURIs.COURSE, DELETE, DeleteCourseAction.class); From 5fb04f73aba606a94718c2797f8a7b937e99aea4 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 12:43:27 +0800 Subject: [PATCH 06/15] Fix lint errors --- .../webapi/RejectAccountRequestActionIT.java | 17 +++++------ .../ui/webapi/RejectAccountRequestAction.java | 30 ++++++++++++------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java index 08833fe4651..b3bc906fe12 100644 --- a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java +++ b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java @@ -51,7 +51,7 @@ public void testExecute() throws Exception { @Test protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail() - throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + throws InvalidOperationException, InvalidHttpRequestBodyException { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); accountRequest.setStatus(AccountRequestStatus.PENDING); UUID id = accountRequest.getId(); @@ -76,7 +76,7 @@ protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail() @Test protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail() - throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + throws InvalidOperationException, InvalidHttpRequestBodyException { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); accountRequest.setStatus(AccountRequestStatus.PENDING); UUID id = accountRequest.getId(); @@ -88,7 +88,7 @@ protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail() JsonResult result = action.execute(); assertEquals(result.getStatusCode(), 200); - + AccountRequestData data = (AccountRequestData) result.getOutput(); assertEquals(accountRequest.getName(), data.getName()); assertEquals(accountRequest.getEmail(), data.getEmail()); @@ -100,7 +100,7 @@ protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail() } @Test - protected void testExecute_withReasonBodyButNoTitle_shouldThrow() throws InvalidHttpParameterException { + protected void testExecute_withReasonBodyButNoTitle_shouldThrow() { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); UUID id = accountRequest.getId(); @@ -114,7 +114,7 @@ protected void testExecute_withReasonBodyButNoTitle_shouldThrow() throws Invalid } @Test - protected void testExecute_withReasonTitleButNoBody_shouldThrow() throws InvalidHttpParameterException { + protected void testExecute_withReasonTitleButNoBody_shouldThrow() { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); UUID id = accountRequest.getId(); @@ -129,7 +129,7 @@ protected void testExecute_withReasonTitleButNoBody_shouldThrow() throws Invalid @Test protected void testExecute_alreadyRejected_shouldNotSendEmail() - throws InvalidHttpParameterException, InvalidOperationException, InvalidHttpRequestBodyException { + throws InvalidOperationException, InvalidHttpRequestBodyException { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); accountRequest.setStatus(AccountRequestStatus.REJECTED); UUID id = accountRequest.getId(); @@ -153,7 +153,7 @@ protected void testExecute_alreadyRejected_shouldNotSendEmail() } @Test - protected void testExecute_invalidUuid_shouldThrow() throws InvalidHttpParameterException { + protected void testExecute_invalidUuid_shouldThrow() { AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, null); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, "invalid"}; @@ -162,9 +162,8 @@ protected void testExecute_invalidUuid_shouldThrow() throws InvalidHttpParameter verifyNoEmailsSent(); } - @Test - protected void testExecute_accountRequestNotFound_shouldThrow() throws InvalidHttpParameterException { + protected void testExecute_accountRequestNotFound_shouldThrow() { AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, null); String uuid = UUID.randomUUID().toString(); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, uuid}; diff --git a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java index 54d1e165833..3ef61d7fbb0 100644 --- a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java +++ b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java @@ -37,18 +37,28 @@ public JsonResult execute() throws InvalidOperationException, InvalidHttpRequest AccountRequestRejectionRequest accountRequestRejectionRequest = getAndValidateRequestBody(AccountRequestRejectionRequest.class); - try { - accountRequest.setStatus(AccountRequestStatus.REJECTED); - accountRequest = sqlLogic.updateAccountRequest(accountRequest); - } catch (InvalidParametersException e) { - throw new InvalidHttpRequestBodyException(e); - } catch (EntityDoesNotExistException e) { - throw new EntityNotFoundException(e); - } - if (accountRequestRejectionRequest.getReasonBody() != null && accountRequest.getStatus() != AccountRequestStatus.REJECTED) { - // TODO: generate rejection email from reason title and reason body + try { + accountRequest.setStatus(AccountRequestStatus.REJECTED); + accountRequest = sqlLogic.updateAccountRequest(accountRequest); + // TODO: generate and send rejection email from reason title and reason body + // EmailWrapper email = ... + // emailSender.sendEmail(email); + } catch (InvalidParametersException e) { + throw new InvalidHttpRequestBodyException(e); + } catch (EntityDoesNotExistException e) { + throw new EntityNotFoundException(e); + } + } else { + try { + accountRequest.setStatus(AccountRequestStatus.REJECTED); + accountRequest = sqlLogic.updateAccountRequest(accountRequest); + } catch (InvalidParametersException e) { + throw new InvalidHttpRequestBodyException(e); + } catch (EntityDoesNotExistException e) { + throw new EntityNotFoundException(e); + } } return new JsonResult(new AccountRequestData(accountRequest)); From 5d57d9b4189c5ef69081b541d2f12ea73e371a11 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Sat, 6 Apr 2024 12:51:42 +0800 Subject: [PATCH 07/15] Update tests list --- .../java/teammates/ui/webapi/GetActionClassesActionTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java b/src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java index 89ace4cdf78..fbcd4a0765c 100644 --- a/src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java +++ b/src/test/java/teammates/ui/webapi/GetActionClassesActionTest.java @@ -88,6 +88,7 @@ protected void testExecute() { DeleteAccountRequestAction.class, GetAccountRequestsAction.class, UpdateAccountRequestAction.class, + RejectAccountRequestAction.class, GetAccountAction.class, GetAccountsAction.class, FeedbackSessionPublishedRemindersAction.class, From 66e3acc5d340ac43949fd4037c122c7418994c35 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 11:39:18 +0800 Subject: [PATCH 08/15] Update validation check --- .../ui/request/AccountRequestRejectionRequest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java index 8b47cc707a1..b4318a879e7 100644 --- a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java +++ b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java @@ -21,11 +21,8 @@ public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) { @Override public void validate() throws InvalidHttpRequestBodyException { - if (reasonBody != null) { - assertTrue(reasonTitle != null, "If reason body is not null, reason title cannot be null"); - } - if (reasonTitle != null) { - assertTrue(reasonBody != null, "If reason title is not null, reason body cannot be null"); + if (reasonBody == null || reasonTitle == null) { + assertTrue(reasonTitle == reasonBody, "Both reason body and title need to be null to reject silently"); } } From 391dcb6829cf27f3387caedce8d1bedd43de67bc Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 11:39:24 +0800 Subject: [PATCH 09/15] Add test for validation --- .../AccountRequestRejectionRequestTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java diff --git a/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java b/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java new file mode 100644 index 00000000000..92181aefa0c --- /dev/null +++ b/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java @@ -0,0 +1,52 @@ +package teammates.ui.request; + +import org.testng.annotations.Test; + +import teammates.test.BaseTestCase; + +/** + * SUT: {@link AccountRequestRejectionRequest}. + */ +public class AccountRequestRejectionRequestTest extends BaseTestCase { + + private static final String typicalTitle = "We are Unable to Create an Account for you"; + private static final String typicalBody = new StringBuilder() + .append("

Hi, Example

\n") + .append("

Thanks for your interest in using TEAMMATES. ") + .append("We are unable to create a TEAMMATES instructor account for you.

\n\n") + .append("

\n") + .append(" Reason: The email address you provided ") + .append("is not an 'official' email address provided by your institution.
\n") + .append(" Remedy: ") + .append("Please re-submit an account request with your 'official' institution email address.\n") + .append("

\n\n") + .append("

If you need further clarification or would like to appeal this decision, ") + .append("please feel free to contact us at teammates@comp.nus.edu.sg.

\n") + .append("

Regards,
TEAMMATES Team.

\n") + .toString(); + + @Test + public void testValidate_withNonNullBodyAndNonNullTitle_shouldPass() throws Exception { + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(typicalTitle, typicalBody); + request.validate(); + } + + @Test + public void testValidate_withNullBodyAndNullTitle_shouldPass() throws Exception { + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(null, null); + request.validate(); + } + + @Test + public void testValidate_withNonNullBodyAndNullTitle_shouldFail() { + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(null, typicalBody); + assertThrows(InvalidHttpRequestBodyException.class, request::validate); + } + + + @Test + public void testValidate_withNullBodyAndNonNullTitle_shouldFail() { + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(typicalTitle, null); + assertThrows(InvalidHttpRequestBodyException.class, request::validate); + } +} From 4a6100246777847579fdfc9f3234100393d74430 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 11:48:02 +0800 Subject: [PATCH 10/15] Fix lint errors --- .../request/AccountRequestRejectionRequestTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java b/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java index 92181aefa0c..412bfcf1d87 100644 --- a/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java +++ b/src/test/java/teammates/ui/request/AccountRequestRejectionRequestTest.java @@ -9,8 +9,8 @@ */ public class AccountRequestRejectionRequestTest extends BaseTestCase { - private static final String typicalTitle = "We are Unable to Create an Account for you"; - private static final String typicalBody = new StringBuilder() + private static final String TYPICAL_TITLE = "We are Unable to Create an Account for you"; + private static final String TYPICAL_BODY = new StringBuilder() .append("

Hi, Example

\n") .append("

Thanks for your interest in using TEAMMATES. ") .append("We are unable to create a TEAMMATES instructor account for you.

\n\n") @@ -27,7 +27,7 @@ public class AccountRequestRejectionRequestTest extends BaseTestCase { @Test public void testValidate_withNonNullBodyAndNonNullTitle_shouldPass() throws Exception { - AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(typicalTitle, typicalBody); + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY); request.validate(); } @@ -39,14 +39,13 @@ public void testValidate_withNullBodyAndNullTitle_shouldPass() throws Exception @Test public void testValidate_withNonNullBodyAndNullTitle_shouldFail() { - AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(null, typicalBody); + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(null, TYPICAL_BODY); assertThrows(InvalidHttpRequestBodyException.class, request::validate); } - @Test public void testValidate_withNullBodyAndNonNullTitle_shouldFail() { - AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(typicalTitle, null); + AccountRequestRejectionRequest request = new AccountRequestRejectionRequest(TYPICAL_TITLE, null); assertThrows(InvalidHttpRequestBodyException.class, request::validate); } } From bb81cae7ea55f73ed948f3ce2db4a2a1b8f0e3d0 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 11:53:05 +0800 Subject: [PATCH 11/15] Fix validation comparison --- .../teammates/ui/request/AccountRequestRejectionRequest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java index b4318a879e7..8134786a19a 100644 --- a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java +++ b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java @@ -1,5 +1,7 @@ package teammates.ui.request; +import java.util.Objects; + import javax.annotation.Nullable; import teammates.common.util.SanitizationHelper; @@ -22,7 +24,8 @@ public AccountRequestRejectionRequest(String reasonTitle, String reasonBody) { @Override public void validate() throws InvalidHttpRequestBodyException { if (reasonBody == null || reasonTitle == null) { - assertTrue(reasonTitle == reasonBody, "Both reason body and title need to be null to reject silently"); + assertTrue(Objects.equals(reasonBody, reasonTitle), + "Both reason body and title need to be null to reject silently"); } } From 6f00d81d6bb4bf59a0e7545c325509c1be8ced54 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 12:08:02 +0800 Subject: [PATCH 12/15] Fix error message test --- .../teammates/it/ui/webapi/RejectAccountRequestActionIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java index b3bc906fe12..8b0b7b20618 100644 --- a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java +++ b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java @@ -109,7 +109,7 @@ protected void testExecute_withReasonBodyButNoTitle_shouldThrow() { InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); - assertEquals("If reason body is not null, reason title cannot be null", ihrbe.getMessage()); + assertEquals("Both reason body and title need to be null to reject silently", ihrbe.getMessage()); verifyNoEmailsSent(); } @@ -123,7 +123,7 @@ protected void testExecute_withReasonTitleButNoBody_shouldThrow() { InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); - assertEquals("If reason title is not null, reason body cannot be null", ihrbe.getMessage()); + assertEquals("Both reason body and title need to be null to reject silently", ihrbe.getMessage()); verifyNoEmailsSent(); } From a2ada587f38821a822aa1dcff2f84ddb1ef912a6 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 13:14:23 +0800 Subject: [PATCH 13/15] Add email sending --- .../teammates/ui/webapi/RejectAccountRequestAction.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java index 3ef61d7fbb0..e5657c14af5 100644 --- a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java +++ b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java @@ -6,6 +6,7 @@ import teammates.common.exception.EntityDoesNotExistException; import teammates.common.exception.InvalidParametersException; import teammates.common.util.Const; +import teammates.common.util.EmailWrapper; import teammates.storage.sqlentity.AccountRequest; import teammates.ui.output.AccountRequestData; import teammates.ui.request.AccountRequestRejectionRequest; @@ -42,9 +43,9 @@ public JsonResult execute() throws InvalidOperationException, InvalidHttpRequest try { accountRequest.setStatus(AccountRequestStatus.REJECTED); accountRequest = sqlLogic.updateAccountRequest(accountRequest); - // TODO: generate and send rejection email from reason title and reason body - // EmailWrapper email = ... - // emailSender.sendEmail(email); + EmailWrapper email = sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest, + accountRequestRejectionRequest.getReasonTitle(), accountRequestRejectionRequest.getReasonBody()); + emailSender.sendEmail(email); } catch (InvalidParametersException e) { throw new InvalidHttpRequestBodyException(e); } catch (EntityDoesNotExistException e) { From 0631604e81eb900569a77e971276ff10f6cf96fa Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 13:14:31 +0800 Subject: [PATCH 14/15] Update test cases --- .../webapi/RejectAccountRequestActionIT.java | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java index 8b0b7b20618..74aba31e1fb 100644 --- a/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java +++ b/src/it/java/teammates/it/ui/webapi/RejectAccountRequestActionIT.java @@ -8,8 +8,12 @@ import teammates.common.datatransfer.AccountRequestStatus; import teammates.common.exception.EntityAlreadyExistsException; import teammates.common.exception.InvalidParametersException; +import teammates.common.util.Config; import teammates.common.util.Const; +import teammates.common.util.EmailType; +import teammates.common.util.EmailWrapper; import teammates.common.util.HibernateUtil; +import teammates.common.util.SanitizationHelper; import teammates.storage.sqlentity.AccountRequest; import teammates.storage.sqlentity.Course; import teammates.ui.output.AccountRequestData; @@ -26,6 +30,22 @@ */ public class RejectAccountRequestActionIT extends BaseActionIT { + private static final String TYPICAL_TITLE = "We are Unable to Create an Account for you"; + private static final String TYPICAL_BODY = new StringBuilder() + .append("

Hi, Example

\n") + .append("

Thanks for your interest in using TEAMMATES. ") + .append("We are unable to create a TEAMMATES instructor account for you.

\n\n") + .append("

\n") + .append(" Reason: The email address you provided ") + .append("is not an 'official' email address provided by your institution.
\n") + .append(" Remedy: ") + .append("Please re-submit an account request with your 'official' institution email address.\n") + .append("

\n\n") + .append("

If you need further clarification or would like to appeal this decision, ") + .append("please feel free to contact us at teammates@comp.nus.edu.sg.

\n") + .append("

Regards,
TEAMMATES Team.

\n") + .toString(); + @Override @BeforeMethod protected void setUp() throws Exception { @@ -56,13 +76,13 @@ protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail() accountRequest.setStatus(AccountRequestStatus.PENDING); UUID id = accountRequest.getId(); - AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", "body"); + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; RejectAccountRequestAction action = getAction(requestBody, params); JsonResult result = action.execute(); - assertEquals(result.getStatusCode(), 200); + assertEquals(200, result.getStatusCode()); AccountRequestData data = (AccountRequestData) result.getOutput(); assertEquals(accountRequest.getName(), data.getName()); @@ -71,7 +91,13 @@ protected void testExecute_withReasonTitleAndBody_shouldRejectWithEmail() assertEquals(AccountRequestStatus.REJECTED, data.getStatus()); assertEquals(accountRequest.getComments(), data.getComments()); - // TODO: test email number and contents + verifyNumberOfEmailsSent(1); + EmailWrapper sentEmail = mockEmailSender.getEmailsSent().get(0); + assertEquals(EmailType.ACCOUNT_REQUEST_REJECTION, sentEmail.getType()); + assertEquals(Config.SUPPORT_EMAIL, sentEmail.getBcc()); + assertEquals(accountRequest.getEmail(), sentEmail.getRecipient()); + assertEquals(SanitizationHelper.sanitizeForRichText(TYPICAL_BODY), sentEmail.getContent()); + assertEquals("TEAMMATES: " + TYPICAL_TITLE, sentEmail.getSubject()); } @Test @@ -87,7 +113,7 @@ protected void testExecute_withoutReasonTitleAndBody_shouldRejectWithoutEmail() RejectAccountRequestAction action = getAction(requestBody, params); JsonResult result = action.execute(); - assertEquals(result.getStatusCode(), 200); + assertEquals(200, result.getStatusCode()); AccountRequestData data = (AccountRequestData) result.getOutput(); assertEquals(accountRequest.getName(), data.getName()); @@ -104,7 +130,7 @@ protected void testExecute_withReasonBodyButNoTitle_shouldThrow() { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); UUID id = accountRequest.getId(); - AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, "body"); + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(null, TYPICAL_BODY); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); @@ -118,7 +144,7 @@ protected void testExecute_withReasonTitleButNoBody_shouldThrow() { AccountRequest accountRequest = typicalBundle.accountRequests.get("unregisteredInstructor1"); UUID id = accountRequest.getId(); - AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", null); + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(TYPICAL_TITLE, null); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; InvalidHttpRequestBodyException ihrbe = verifyHttpRequestBodyFailure(requestBody, params); @@ -134,7 +160,7 @@ protected void testExecute_alreadyRejected_shouldNotSendEmail() accountRequest.setStatus(AccountRequestStatus.REJECTED); UUID id = accountRequest.getId(); - AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest("title", "body"); + AccountRequestRejectionRequest requestBody = new AccountRequestRejectionRequest(TYPICAL_TITLE, TYPICAL_BODY); String[] params = new String[] {Const.ParamsNames.ACCOUNT_REQUEST_ID, id.toString()}; RejectAccountRequestAction action = getAction(requestBody, params); From fe113ca10b1acdd014298ddfb4d17e7c597a3682 Mon Sep 17 00:00:00 2001 From: Xenos F Date: Mon, 8 Apr 2024 13:36:21 +0800 Subject: [PATCH 15/15] Refactor reason check code for clarity --- .../AccountRequestRejectionRequest.java | 6 ++++ .../ui/webapi/RejectAccountRequestAction.java | 28 +++++++------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java index 8134786a19a..89884e13b7d 100644 --- a/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java +++ b/src/main/java/teammates/ui/request/AccountRequestRejectionRequest.java @@ -37,4 +37,10 @@ public String getReasonBody() { return this.reasonBody; } + /** + * Returns true if both reason body and title are non-null. + */ + public boolean checkHasReason() { + return this.reasonBody != null && this.reasonTitle != null; + } } diff --git a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java index e5657c14af5..6b0b2534b44 100644 --- a/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java +++ b/src/main/java/teammates/ui/webapi/RejectAccountRequestAction.java @@ -37,29 +37,21 @@ public JsonResult execute() throws InvalidOperationException, InvalidHttpRequest AccountRequestRejectionRequest accountRequestRejectionRequest = getAndValidateRequestBody(AccountRequestRejectionRequest.class); + AccountRequestStatus initialStatus = accountRequest.getStatus(); - if (accountRequestRejectionRequest.getReasonBody() != null - && accountRequest.getStatus() != AccountRequestStatus.REJECTED) { - try { - accountRequest.setStatus(AccountRequestStatus.REJECTED); - accountRequest = sqlLogic.updateAccountRequest(accountRequest); + try { + accountRequest.setStatus(AccountRequestStatus.REJECTED); + accountRequest = sqlLogic.updateAccountRequest(accountRequest); + if (accountRequestRejectionRequest.checkHasReason() + && initialStatus != AccountRequestStatus.REJECTED) { EmailWrapper email = sqlEmailGenerator.generateAccountRequestRejectionEmail(accountRequest, accountRequestRejectionRequest.getReasonTitle(), accountRequestRejectionRequest.getReasonBody()); emailSender.sendEmail(email); - } catch (InvalidParametersException e) { - throw new InvalidHttpRequestBodyException(e); - } catch (EntityDoesNotExistException e) { - throw new EntityNotFoundException(e); - } - } else { - try { - accountRequest.setStatus(AccountRequestStatus.REJECTED); - accountRequest = sqlLogic.updateAccountRequest(accountRequest); - } catch (InvalidParametersException e) { - throw new InvalidHttpRequestBodyException(e); - } catch (EntityDoesNotExistException e) { - throw new EntityNotFoundException(e); } + } catch (InvalidParametersException e) { + throw new InvalidHttpRequestBodyException(e); + } catch (EntityDoesNotExistException e) { + throw new EntityNotFoundException(e); } return new JsonResult(new AccountRequestData(accountRequest));