diff --git a/src/main/java/com/wcc/platform/configuration/GlobalExceptionHandler.java b/src/main/java/com/wcc/platform/configuration/GlobalExceptionHandler.java index d841238f..1cc88798 100644 --- a/src/main/java/com/wcc/platform/configuration/GlobalExceptionHandler.java +++ b/src/main/java/com/wcc/platform/configuration/GlobalExceptionHandler.java @@ -15,6 +15,7 @@ import com.wcc.platform.domain.exceptions.ErrorDetails; import com.wcc.platform.domain.exceptions.ForbiddenException; import com.wcc.platform.domain.exceptions.InvalidCycleStatusTransitionException; +import com.wcc.platform.domain.exceptions.InvalidMentorshipTypeException; import com.wcc.platform.domain.exceptions.InvalidProgramTypeException; import com.wcc.platform.domain.exceptions.InvalidTokenException; import com.wcc.platform.domain.exceptions.MemberNotFoundException; @@ -89,6 +90,7 @@ public ResponseEntity handleInternalError( */ @ExceptionHandler({ InvalidProgramTypeException.class, + InvalidMentorshipTypeException.class, IllegalArgumentException.class, TemplateValidationException.class }) diff --git a/src/main/java/com/wcc/platform/domain/template/TemplateType.java b/src/main/java/com/wcc/platform/domain/template/TemplateType.java index df48aff8..890ce0bd 100644 --- a/src/main/java/com/wcc/platform/domain/template/TemplateType.java +++ b/src/main/java/com/wcc/platform/domain/template/TemplateType.java @@ -22,7 +22,8 @@ public enum TemplateType { REMINDER_MENTEE_LONG("reminder_long_term_mentorship_mentee.yml"), MENTEES_MENTOR_LONG("list_potential_mentees_mentor_long.yml"), FOLLOWUP_MENTEES_LONG("list_potential_mentees_follow_up_mentor_long.yml"), - NEW_MENTEES_REVIEW("alert_new_mentees_applications_mentor.yml"), + NEW_MENTEES_REVIEW_LONG_TERM("alert_new_mentees_long_term_applications_mentor.yml"), + NEW_MENTEES_REVIEW_ADHOC("alert_new_mentees_adhoc_applications_mentor.yml"), STUDY_GROUP_AVAIL("confirm_availability_study_group_mentor.yml"), STUDY_GROUPS_MENTEE("mentor_led_study_groups_mentee.yml"), STUDY_GROUP_INTRO("study_group_introduction_email_mentee.yml"), diff --git a/src/main/java/com/wcc/platform/service/MentorshipNotificationService.java b/src/main/java/com/wcc/platform/service/MentorshipNotificationService.java index 0a855819..a4bcf23e 100644 --- a/src/main/java/com/wcc/platform/service/MentorshipNotificationService.java +++ b/src/main/java/com/wcc/platform/service/MentorshipNotificationService.java @@ -143,7 +143,8 @@ public void sendPairingConfirmation( } /** - * Sends a NEW_MENTEES_REVIEW notification email to a mentor when manually assigned a mentee. + * Sends a new mentees review notification email to a mentor when a mentee applies for the mentor, + * or manually assigned by Admin * * @param mentor the mentor to notify * @param cycle the mentorship cycle @@ -153,8 +154,12 @@ public void sendNewMenteesNotification(final Mentor mentor, final MentorshipCycl cycle.getCycleYear() != null ? cycle.getCycleYear().getValue() : LocalDate.now(ZONE_ID).getYear(); + final TemplateType emailTemplateType = + cycle.getMentorshipType() == MentorshipType.LONG_TERM + ? TemplateType.NEW_MENTEES_REVIEW_LONG_TERM + : TemplateType.NEW_MENTEES_REVIEW_ADHOC; sendNotification( - TemplateType.NEW_MENTEES_REVIEW, + emailTemplateType, Map.of( "mentorName", mentor.getFullName(), "year", year, diff --git a/src/main/resources/email-templates/alert_new_mentees_adhoc_applications_mentor.yml b/src/main/resources/email-templates/alert_new_mentees_adhoc_applications_mentor.yml new file mode 100644 index 00000000..ae57619a --- /dev/null +++ b/src/main/resources/email-templates/alert_new_mentees_adhoc_applications_mentor.yml @@ -0,0 +1,39 @@ +NEW_MENTEES_REVIEW_ADHOC: + subject: "[Action Required] Pending Mentee Application(s) for {{year}} {{cycleType}} WCC Mentorship Programme" + body: | +

Dear {{mentorName}},

+

+ Thank you for being part of the Women Coding Community {{year}} {{cycleType}} Mentorship Programme! +

+ +

+ You have new mentee applications currently pending your review. + Could you please log into your Mentor Dashboard today to check? +

+ +

+ In an {{cycleType}} cycle, a mentee can apply to more than one mentor. Once any mentor accepts, the application is no longer available to others. + If you cannot find an application in your dashboard, it may have already been accepted by another mentor. +

+ +

+ As an action point, please approve the mentee(s) you'd like to accept, or reject so that their application(s) can be forwarded to other mentors. +

+ +

+ Please note: If you have not logged into the dashboard before, please reply to this email, so we can send a password reset email from {{mentorshipEmail}}. +

+ +

+ If you do not see the application(s) or have any other trouble accessing your account, please feel free to reply to this email. +

+ +

+ Thank you for your continued support of the mentorship programme, and we hope to get your response soon. +

+ +

+ {{teamEmailSignature}} +

+ +

[Automated Message]

\ No newline at end of file diff --git a/src/main/resources/email-templates/alert_new_mentees_applications_mentor.yml b/src/main/resources/email-templates/alert_new_mentees_long_term_applications_mentor.yml similarity index 96% rename from src/main/resources/email-templates/alert_new_mentees_applications_mentor.yml rename to src/main/resources/email-templates/alert_new_mentees_long_term_applications_mentor.yml index e28de2cc..d512abaa 100644 --- a/src/main/resources/email-templates/alert_new_mentees_applications_mentor.yml +++ b/src/main/resources/email-templates/alert_new_mentees_long_term_applications_mentor.yml @@ -1,4 +1,4 @@ -NEW_MENTEES_REVIEW: +NEW_MENTEES_REVIEW_LONG_TERM: subject: "[Action Required] Pending Mentee Application(s) for {{year}} {{cycleType}} WCC Mentorship Programme" body: |

Dear {{mentorName}},

@@ -7,10 +7,10 @@ NEW_MENTEES_REVIEW:

- You have new mentee applications currently pending your review. - Could you please log into your Mentor Dashboard today to check? + You have new mentee applications currently pending your review. + Could you please log into your Mentor Dashboard today to check?

- +

As an action point, please approve the mentee(s) you'd like to accept, or reject so that their application(s) can be forwarded to other mentors.

diff --git a/src/test/java/com/wcc/platform/configuration/GlobalExceptionHandlerTest.java b/src/test/java/com/wcc/platform/configuration/GlobalExceptionHandlerTest.java index f6755ee4..e1b0c329 100644 --- a/src/test/java/com/wcc/platform/configuration/GlobalExceptionHandlerTest.java +++ b/src/test/java/com/wcc/platform/configuration/GlobalExceptionHandlerTest.java @@ -13,6 +13,7 @@ import com.wcc.platform.domain.exceptions.DuplicatedMemberException; import com.wcc.platform.domain.exceptions.ErrorDetails; import com.wcc.platform.domain.exceptions.ForbiddenException; +import com.wcc.platform.domain.exceptions.InvalidMentorshipTypeException; import com.wcc.platform.domain.platform.mentorship.TechnicalAreaProficiency; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -100,6 +101,19 @@ void shouldReturnConflictForDataAccessException() { assertEquals(expectation, response.getBody()); } + @Test + @DisplayName( + "Given InvalidMentorshipTypeException, when handling, then return BAD_REQUEST") + void shouldReturnBadRequestForInvalidMentorshipTypeException() { + var exception = new InvalidMentorshipTypeException("Cycle type mismatch"); + + var response = globalExceptionHandler.handleProgramTypeError(exception, webRequest); + + var expectation = new ErrorDetails(BAD_REQUEST.value(), "Cycle type mismatch", DETAILS); + assertEquals(BAD_REQUEST, response.getStatusCode()); + assertEquals(expectation, response.getBody()); + } + @Test @DisplayName( "Given malformed JSON with unknown field, " diff --git a/src/test/java/com/wcc/platform/service/MentorshipNotificationServiceTest.java b/src/test/java/com/wcc/platform/service/MentorshipNotificationServiceTest.java index 6215c556..36c1749b 100644 --- a/src/test/java/com/wcc/platform/service/MentorshipNotificationServiceTest.java +++ b/src/test/java/com/wcc/platform/service/MentorshipNotificationServiceTest.java @@ -16,7 +16,9 @@ import com.wcc.platform.domain.platform.mentorship.ApplicationStatus; import com.wcc.platform.domain.platform.mentorship.MatchStatus; import com.wcc.platform.domain.platform.mentorship.Mentor; +import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.mentorship.MentorshipMatch; +import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.domain.template.RenderedTemplate; import com.wcc.platform.domain.template.TemplateType; import com.wcc.platform.repository.MemberRepository; @@ -181,6 +183,42 @@ void shouldSendNotificationByMemberId() { assertThat(emailRequest.getRecipients()).contains("team@test.com"); } + @Test + @DisplayName( + "Given an Ad-Hoc cycle, when sendNewMenteesNotification, then NEW_MENTEES_REVIEW_ADHOC template is used") + void shouldUseAdhocReviewTemplateForAdhocCycle() { + var cycle = MentorshipCycleEntity.builder().mentorshipType(MentorshipType.AD_HOC).build(); + + when(notificationConfig.getMentorshipEmail()).thenReturn("team@test.com"); + when(emailTemplateService.renderTemplate(any(), any())) + .thenReturn(new RenderedTemplate("Subject", "Body")); + + notificationService.sendNewMenteesNotification(mentor, cycle); + + @SuppressWarnings("unchecked") + ArgumentCaptor> paramsCaptor = ArgumentCaptor.forClass(Map.class); + verify(emailTemplateService) + .renderTemplate(eq(TemplateType.NEW_MENTEES_REVIEW_ADHOC), paramsCaptor.capture()); + } + + @Test + @DisplayName( + "Given a Long-Term cycle, when sendNewMenteesNotification, then NEW_MENTEES_REVIEW_LONG_TERM is used") + void shouldUseLongTermReviewTemplateForLongTermCycle() { + var cycle = MentorshipCycleEntity.builder().mentorshipType(MentorshipType.LONG_TERM).build(); + + when(notificationConfig.getMentorshipEmail()).thenReturn("team@test.com"); + when(emailTemplateService.renderTemplate(any(), any())) + .thenReturn(new RenderedTemplate("Subject", "Body")); + + notificationService.sendNewMenteesNotification(mentor, cycle); + + @SuppressWarnings("unchecked") + ArgumentCaptor> paramsCaptor = ArgumentCaptor.forClass(Map.class); + verify(emailTemplateService) + .renderTemplate(eq(TemplateType.NEW_MENTEES_REVIEW_LONG_TERM), paramsCaptor.capture()); + } + @Test @DisplayName( "Given member IDs and no team email, when sendNotificationByMemberId, then sends only to members")