diff --git a/server/build.gradle b/server/build.gradle
index 62d6854d5..601c5657c 100755
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -115,6 +115,8 @@ dependencies {
implementation("io.micronaut.reactor:micronaut-reactor")
implementation("io.micrometer:context-propagation")
+ implementation 'ch.digitalfondue.mjml4j:mjml4j:1.0.3'
+
testRuntimeOnly "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
testRuntimeOnly "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
@@ -213,3 +215,5 @@ java {
}
run.jvmArgs('-Dcom.sun.management.jmxremote', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000')
+
+
diff --git a/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetFactory.java b/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetFactory.java
index 55419e4d4..6e755a229 100644
--- a/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetFactory.java
+++ b/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetFactory.java
@@ -14,6 +14,7 @@
public class MailJetFactory {
public static final String HTML_FORMAT = "html";
+ public static final String MJML_FORMAT = "mjml";
public static final String TEXT_FORMAT = "text";
@Bean
@@ -34,6 +35,13 @@ EmailSender getHtmlSender(MailJetSender sender) {
return sender;
}
+ @Singleton
+ @Named(MJML_FORMAT)
+ EmailSender getMjmlSender(MailJetSender sender) {
+ sender.setEmailFormat(MailJetSender.MJMLPART);
+ return sender;
+ }
+
@Singleton
@Named(TEXT_FORMAT)
EmailSender getTextSender(MailJetSender sender) {
diff --git a/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetSender.java b/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetSender.java
index f6b7e98f5..05bbdc4ce 100644
--- a/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetSender.java
+++ b/server/src/main/java/com/objectcomputing/checkins/notifications/email/MailJetSender.java
@@ -5,6 +5,7 @@
import com.mailjet.client.MailjetResponse;
import com.mailjet.client.errors.MailjetException;
import com.mailjet.client.resource.Emailv31;
+import ch.digitalfondue.mjml4j.Mjml4j;
import com.objectcomputing.checkins.exceptions.BadArgException;
import io.micronaut.context.annotation.Prototype;
import io.micronaut.context.annotation.Requires;
@@ -20,6 +21,7 @@
@Prototype
@Requires(bean = MailJetConfiguration.class)
public class MailJetSender implements EmailSender {
+ public static final String MJMLPART = "MJMLPART";
private static final Logger LOG = LoggerFactory.getLogger(MailJetSender.class);
private final MailjetClient client;
@@ -94,6 +96,16 @@ public void sendEmail(String fromName, String fromAddress, String subject, Strin
.put("Email", fromAddress)
.put("Name", fromName);
+ String modifiedEmailFormat = emailFormat;
+ if (modifiedEmailFormat.equals(MJMLPART)) {
+ // Convert the MJML to HTML and update the local email format.
+ var configuration = new Mjml4j.Configuration("en");
+ content = Mjml4j.render(content, configuration);
+ modifiedEmailFormat = Emailv31.Message.HTMLPART;
+ }
+ final String localEmailFormat = modifiedEmailFormat;
+ final String localContent = content;
+
emailBatches.forEach((recipientList) -> {
MailjetRequest request = new MailjetRequest(Emailv31.resource)
.property(Emailv31.MESSAGES, new JSONArray()
@@ -102,7 +114,7 @@ public void sendEmail(String fromName, String fromAddress, String subject, Strin
.put(Emailv31.Message.TO, new JSONArray().put(sender))
.put(Emailv31.Message.BCC, recipientList)
.put(Emailv31.Message.SUBJECT, subject)
- .put(emailFormat, content)));
+ .put(localEmailFormat, localContent)));
try {
MailjetResponse response = client.post(request);
LOG.info("Mailjet response status: {}", response.getStatus());
@@ -134,10 +146,12 @@ public boolean sendEmailReceivesStatus(String fromName, String fromAddress, Stri
@Override
public void setEmailFormat(String format) {
- if (format.equals(Emailv31.Message.HTMLPART) || format.equals(Emailv31.Message.TEXTPART)) {
+ if (format.equals(MJMLPART) ||
+ format.equals(Emailv31.Message.HTMLPART) ||
+ format.equals(Emailv31.Message.TEXTPART)) {
this.emailFormat = format;
} else {
- throw new BadArgException(String.format("Email format must be either HTMLPART or TEXTPART, got %s", format));
+ throw new BadArgException(String.format("Email format must be either HTMLPART, MJMLPART or TEXTPART, got %s", format));
}
}
}
diff --git a/server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServicesImpl.java b/server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServicesImpl.java
index 908ac8093..180d8fef3 100644
--- a/server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServicesImpl.java
+++ b/server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServicesImpl.java
@@ -6,7 +6,9 @@
import com.objectcomputing.checkins.exceptions.PermissionException;
import com.objectcomputing.checkins.notifications.email.EmailSender;
import com.objectcomputing.checkins.notifications.email.MailJetFactory;
+import com.objectcomputing.checkins.services.email.Email;
import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
+import com.objectcomputing.checkins.services.memberprofile.MemberProfileUtils;
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices;
import com.objectcomputing.checkins.services.memberprofile.currentuser.CurrentUserServices;
import com.objectcomputing.checkins.services.reviews.ReviewAssignment;
@@ -14,11 +16,16 @@
import com.objectcomputing.checkins.services.reviews.ReviewPeriod;
import com.objectcomputing.checkins.services.reviews.ReviewPeriodRepository;
import com.objectcomputing.checkins.util.Util;
+import io.micronaut.context.annotation.Value;
+import io.micronaut.core.io.Readable;
+import io.micronaut.core.io.IOUtils;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.BufferedReader;
+import java.time.format.DateTimeFormatter;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
@@ -44,11 +51,23 @@ public class FeedbackRequestServicesImpl implements FeedbackRequestServices {
private final String notificationSubject;
private final String webURL;
+ private enum CompletionEmailType { REVIEWERS, SUPERVISOR }
+ private record ReviewPeriodInfo(String subject, LocalDate closeDate) {}
+ @Value("classpath:mjml/feedback_request.mjml")
+ private Readable feedbackRequestTemplate;
+ @Value("classpath:mjml/update_request.mjml")
+ private Readable updateRequestTemplate;
+ @Value("classpath:mjml/reviewer_email.mjml")
+ private Readable reviewerTemplate;
+ @Value("classpath:mjml/supervisor_email.mjml")
+ private Readable supervisorTemplate;
+
public FeedbackRequestServicesImpl(FeedbackRequestRepository feedbackReqRepository,
CurrentUserServices currentUserServices,
MemberProfileServices memberProfileServices,
- ReviewPeriodRepository reviewPeriodRepository, ReviewAssignmentRepository reviewAssignmentRepository,
- @Named(MailJetFactory.HTML_FORMAT) EmailSender emailSender,
+ ReviewPeriodRepository reviewPeriodRepository,
+ ReviewAssignmentRepository reviewAssignmentRepository,
+ @Named(MailJetFactory.MJML_FORMAT) EmailSender emailSender,
CheckInsConfiguration checkInsConfiguration
) {
this.feedbackReqRepository = feedbackReqRepository;
@@ -107,19 +126,29 @@ public FeedbackRequest save(FeedbackRequest feedbackRequest) {
public void sendNewRequestEmail(FeedbackRequest storedRequest) {
MemberProfile creator = memberProfileServices.getById(storedRequest.getCreatorId());
+ MemberProfile reviewer = memberProfileServices.getById(storedRequest.getRecipientId());
MemberProfile requestee = memberProfileServices.getById(storedRequest.getRequesteeId());
- String senderName = creator.getFirstName() + " " + creator.getLastName();
- String newContent = "
You have received a feedback request.
" +
- "" + senderName + " is requesting feedback on " + requestee.getFirstName() + " " + requestee.getLastName() + " from you.
";
- if (storedRequest.getDueDate() != null) {
- newContent += "This request is due on " + storedRequest.getDueDate().getMonth() + " " + storedRequest.getDueDate().getDayOfMonth() + ", " + storedRequest.getDueDate().getYear() + ".";
- }
- newContent += "
Please go to your unique link at " + webURL + "/feedback/submit?request=" + storedRequest.getId() + " to complete this request.
";
-
-// LOG.warn("Pretending to send an email about the new request to "+memberProfileServices.getById(storedRequest.getRecipientId()).getFirstName());
- if (!storedRequest.getRecipientId().equals(storedRequest.getRequesteeId())) {
- emailSender.sendEmail(senderName, creator.getWorkEmail(), notificationSubject, newContent, memberProfileServices.getById(storedRequest.getRecipientId()).getWorkEmail());
- }
+ String senderName = MemberProfileUtils.getFullName(creator);
+
+ String newContent = String.format(
+ templateToString(feedbackRequestTemplate),
+ reviewer.getFirstName(), senderName,
+ storedRequest.getRecipientId().equals(storedRequest.getRequesteeId()) ?
+ "" :
+ String.format("on %s ",
+ MemberProfileUtils.getFullName(requestee)),
+ storedRequest.getDueDate() == null ?
+ "This request does not have a due date." :
+ String.format("This request is due on %s %d, %d.",
+ storedRequest.getDueDate().getMonth(),
+ storedRequest.getDueDate().getDayOfMonth(),
+ storedRequest.getDueDate().getYear()),
+ String.format("%s/feedback/submit?request=%s",
+ webURL, storedRequest.getId().toString()));
+
+ emailSender.sendEmail(senderName, creator.getWorkEmail(),
+ notificationSubject, newContent,
+ reviewer.getWorkEmail());
}
@Override
@@ -187,20 +216,20 @@ public FeedbackRequest update(FeedbackRequestUpdateDTO feedbackRequestUpdateDTO)
}
FeedbackRequest storedRequest = feedbackReqRepository.update(feedbackRequest);
+ MemberProfile reviewer = memberProfileServices.getById(storedRequest.getRecipientId());
MemberProfile requestee = memberProfileServices.getById(storedRequest.getRequesteeId());
// Send email if the feedback request has been reopened for edits
if (originalFeedback.getStatus().equals("submitted") && feedbackRequest.getStatus().equals("sent")) {
MemberProfile creator = memberProfileServices.getById(storedRequest.getCreatorId());
+ String senderName = MemberProfileUtils.getFullName(creator);
+ String newContent = String.format(
+ templateToString(updateRequestTemplate),
+ reviewer.getFirstName(), senderName,
+ MemberProfileUtils.getFullName(requestee),
+ String.format("%s/feedback/submit?request=%s",
+ webURL, storedRequest.getId().toString()));
- String senderName = creator.getFirstName() + " " + creator.getLastName();
- String newContent = "You have received edit access to a feedback request.
" +
- "" + senderName +
- " has reopened the feedback request on " +
- requestee.getFirstName() + " " + requestee.getLastName() + " from you." +
- "You may make changes to your answers, but you will need to submit the form again when finished.
";
- newContent += "Please go to your unique link at " + webURL + "/feedback/submit?request=" + storedRequest.getId() + " to complete this request.
";
-// LOG.warn("Pretending to send an email about the reopened request to "+memberProfileServices.getById(storedRequest.getRecipientId()).getFirstName());
- emailSender.sendEmail(senderName, creator.getWorkEmail(), notificationSubject, newContent, memberProfileServices.getById(storedRequest.getRecipientId()).getWorkEmail());
+ emailSender.sendEmail(senderName, creator.getWorkEmail(), notificationSubject, newContent, reviewer.getWorkEmail());
}
// Send email if the feedback request has been reassigned
@@ -210,12 +239,14 @@ public FeedbackRequest update(FeedbackRequestUpdateDTO feedbackRequestUpdateDTO)
// Send self-review completion email to supervisor and pdl if appropriate
if (currentUserServices.getCurrentUser().getId().equals(requestee.getId())) {
- sendSelfReviewCompletionEmailToPdlAndSupervisor(feedbackRequest);
+ sendSelfReviewCompletionEmailToSupervisor(feedbackRequest);
}
- // Send email to reviewers
- if (reviewAssignmentsSet != null && reviewAssignmentsSet.size() > 0) {
- this.sendSelfReviewCompletionEmailToReviewers(feedbackRequest, reviewAssignmentsSet);
+ // Send email to reviewers. But, only when the requestee is the
+ // recipient (i.e., a self-review).
+ if (reviewAssignmentsSet != null && reviewAssignmentsSet.size() > 0 &&
+ feedbackRequest.getRequesteeId().equals(feedbackRequest.getRecipientId())) {
+ sendSelfReviewCompletionEmailToReviewers(feedbackRequest, reviewAssignmentsSet);
}
return storedRequest;
@@ -345,120 +376,128 @@ private FeedbackRequest getFromDTO(FeedbackRequestUpdateDTO dto) {
}
public void sendSelfReviewCompletionEmailToReviewers(FeedbackRequest feedbackRequest, Set reviewAssignmentSet) {
- MemberProfile currentUserProfile = currentUserServices.getCurrentUser();
- MemberProfile pdlProfile = null;
- MemberProfile supervisorProfile = null;
-
- try {
- if (currentUserProfile.getPdlId() != null) {
- pdlProfile = memberProfileServices.getById(currentUserProfile.getPdlId());
- }
- } catch (NullPointerException e) {
- LOG.error("PDL could not be found for self-review completion email");
- }
-
- try {
- if (currentUserProfile.getSupervisorid() != null) {
- supervisorProfile = memberProfileServices.getById(currentUserProfile.getSupervisorid());
- }
- } catch (NullPointerException e) {
- LOG.error("Supervisor could not be found for self-review completion email");
- }
-
- String reviewPeriodString = "";
- if (feedbackRequest.getReviewPeriodId() != null) {
- Optional reviewPeriodOpt = reviewPeriodRepository.findById(feedbackRequest.getReviewPeriodId());
- if (reviewPeriodOpt.isPresent()) {
- ReviewPeriod reviewPeriod = reviewPeriodOpt.get();
- reviewPeriodString = String.format(" for %s", reviewPeriod.getName());
- }
- }
-
- String subject = String.format("%s %s has finished their self-review%s.", currentUserProfile.getFirstName(), currentUserProfile.getLastName(), reviewPeriodString);
- StringBuilder bodyBuilder = new StringBuilder(String.format("Self-review has been completed by %s %s%s.
", currentUserProfile.getFirstName(), currentUserProfile.getLastName(), reviewPeriodString));
-
- if (pdlProfile != null) {
- bodyBuilder.append(String.format("PDL: %s %s
", pdlProfile.getFirstName(), pdlProfile.getLastName()));
- }
-
- if (supervisorProfile != null) {
- bodyBuilder.append(String.format("Supervisor: %s %s
", supervisorProfile.getFirstName(), supervisorProfile.getLastName()));
- }
-
- Set recipients = new HashSet<>();
+ // Send an email to each reviewer.
reviewAssignmentSet.forEach(reviewAssignment -> {
MemberProfile memberProfileReviewer = memberProfileServices.getById(reviewAssignment.getReviewerId());
- if (memberProfileReviewer != null && memberProfileReviewer.getWorkEmail() != null) {
- recipients.add(memberProfileReviewer.getWorkEmail());
+ if (memberProfileReviewer != null &&
+ memberProfileReviewer.getWorkEmail() != null) {
+ sendSelfReviewCompletionEmail(feedbackRequest,
+ memberProfileReviewer,
+ CompletionEmailType.REVIEWERS);
}
});
-
- bodyBuilder.append("
It is now your turn in their review process. Please complete your portion in a timely manner.");
-
- String body = bodyBuilder.toString();
-
- if (recipients.size() > 0) {
- try {
- emailSender.sendEmail(null, null, subject, body, recipients.toArray(new String[0]));
- } catch (Exception e) {
- LOG.error("Unable to send self-review completion email to reviewers", e);
- }
- }
}
- public void sendSelfReviewCompletionEmailToPdlAndSupervisor(FeedbackRequest feedbackRequest) {
+ public void sendSelfReviewCompletionEmailToSupervisor(FeedbackRequest feedbackRequest) {
MemberProfile currentUserProfile = currentUserServices.getCurrentUser();
- MemberProfile pdlProfile = null;
- MemberProfile supervisorProfile = null;
-
try {
- if (currentUserProfile.getPdlId() != null) {
- pdlProfile = memberProfileServices.getById(currentUserProfile.getPdlId());
+ if (currentUserProfile.getSupervisorid() != null) {
+ MemberProfile supervisorProfile =
+ memberProfileServices.getById(
+ currentUserProfile.getSupervisorid());
+ sendSelfReviewCompletionEmail(feedbackRequest,
+ supervisorProfile,
+ CompletionEmailType.SUPERVISOR);
}
- } catch (NullPointerException e) {
- LOG.error("PDL could not be found for self-review completion email");
+ } catch (NotFoundException e) {
+ LOG.error("Supervisor could not be found for completion email");
}
+ }
+ private void sendSelfReviewCompletionEmail(FeedbackRequest feedbackRequest,
+ MemberProfile reviewer,
+ CompletionEmailType emailType) {
+ // Build the email contents.
+ Email email;
+ MemberProfile currentUserProfile = currentUserServices.getCurrentUser();
+ switch(emailType) {
+ case CompletionEmailType.REVIEWERS:
+ email = buildReviewerEmail(feedbackRequest, reviewer,
+ currentUserProfile);
+ break;
+ default:
+ case CompletionEmailType.SUPERVISOR:
+ email = buildSupervisorEmail(feedbackRequest, reviewer,
+ currentUserProfile);
+ break;
+ }
+
+ // Send the email.
try {
- if (currentUserProfile.getSupervisorid() != null) {
- supervisorProfile = memberProfileServices.getById(currentUserProfile.getSupervisorid());
- }
- } catch (NullPointerException e) {
- LOG.error("Supervisor could not be found for self-review completion email");
+ emailSender.sendEmail(null, null, email.getSubject(),
+ email.getContents(),
+ reviewer.getWorkEmail());
+ } catch (Exception e) {
+ LOG.error("Unable to send the self-review completion email.", e);
}
+ }
+ private ReviewPeriodInfo getSelfReviewInfo(
+ FeedbackRequest feedbackRequest, String name) {
String reviewPeriodString = "";
+ LocalDate closeDate = null;
if (feedbackRequest.getReviewPeriodId() != null) {
Optional reviewPeriodOpt = reviewPeriodRepository.findById(feedbackRequest.getReviewPeriodId());
if (reviewPeriodOpt.isPresent()) {
ReviewPeriod reviewPeriod = reviewPeriodOpt.get();
+ if (reviewPeriod.getCloseDate() != null) {
+ closeDate = reviewPeriod.getCloseDate().toLocalDate();
+ }
reviewPeriodString = String.format(" for %s", reviewPeriod.getName());
}
}
+ return new ReviewPeriodInfo(
+ String.format("%s has finished their self-review%s.",
+ name, reviewPeriodString), closeDate);
+ }
- String subject = String.format("%s %s has finished their self-review%s.", currentUserProfile.getFirstName(), currentUserProfile.getLastName(), reviewPeriodString);
- StringBuilder bodyBuilder = new StringBuilder(String.format("Self-review has been completed by %s %s%s.
", currentUserProfile.getFirstName(), currentUserProfile.getLastName(), reviewPeriodString));
-
- Set recipients = new HashSet<>();
- if (pdlProfile != null) {
- bodyBuilder.append(String.format("PDL: %s %s
", pdlProfile.getFirstName(), pdlProfile.getLastName()));
- recipients.add(pdlProfile.getWorkEmail());
- }
-
- if (supervisorProfile != null) {
- bodyBuilder.append(String.format("Supervisor: %s %s
", supervisorProfile.getFirstName(), supervisorProfile.getLastName()));
- recipients.add(supervisorProfile.getWorkEmail());
- }
+ private Email buildReviewerEmail(FeedbackRequest feedbackRequest,
+ MemberProfile reviewerProfile,
+ MemberProfile currentUserProfile) {
+ String reviewerName = reviewerProfile.getFirstName();
+ String revieweeName = MemberProfileUtils.getFullName(currentUserProfile);
+ UUID requestId = feedbackRequest.getId();
+ String selfReviewURL = String.format("%s/feedback/view/responses/?request=%s", webURL, requestId == null ? "none" : requestId.toString());
+ ReviewPeriodInfo info = getSelfReviewInfo(feedbackRequest, revieweeName);
+ LocalDate closeDate = info.closeDate();
+ String ending = closeDate == null ? "the review period closes" :
+ closeDate.format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
+
+ String body = String.format(templateToString(reviewerTemplate),
+ revieweeName, reviewerName, revieweeName,
+ selfReviewURL, ending);
+ Email email = new Email();
+ email.setSubject(info.subject());
+ email.setContents(body);
+ return email;
+ }
- String body = bodyBuilder.toString();
+ private Email buildSupervisorEmail(FeedbackRequest feedbackRequest,
+ MemberProfile supervisorProfile,
+ MemberProfile currentUserProfile) {
+ String supervisorName = supervisorProfile == null ? "Supervisor" :
+ supervisorProfile.getFirstName();
+ String revieweeName = MemberProfileUtils.getFullName(currentUserProfile);
+ UUID requestId = feedbackRequest.getId();
+ String selfReviewURL = String.format("%s/feedback/view/responses/?request=%s", webURL, requestId == null ? "none" : requestId.toString());
+ ReviewPeriodInfo info = getSelfReviewInfo(feedbackRequest, revieweeName);
+
+ String body = String.format(templateToString(supervisorTemplate),
+ supervisorName, revieweeName,
+ selfReviewURL);
+
+ Email email = new Email();
+ email.setSubject(info.subject());
+ email.setContents(body);
+ return email;
+ }
- if (pdlProfile != null || supervisorProfile != null) {
- try {
- emailSender.sendEmail(null, null, subject, body, recipients.toArray(new String[0]));
- } catch (Exception e) {
- LOG.error("Unable to send self-review completion email to PDL/Supervisor", e);
- }
+ private String templateToString(Readable template) {
+ try {
+ return IOUtils.readText(new BufferedReader(template.asReader()));
+ } catch (Exception ex) {
+ LOG.error(ex.toString());
+ return "";
}
}
-
}
diff --git a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseEmail.java b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseEmail.java
index bac3a3f40..2b22eb0e0 100644
--- a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseEmail.java
+++ b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseEmail.java
@@ -5,18 +5,32 @@
import com.objectcomputing.checkins.notifications.email.MailJetFactory;
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices;
+import jakarta.inject.Singleton;
import jakarta.inject.Named;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.micronaut.context.annotation.Value;
+import io.micronaut.core.io.Readable;
+import io.micronaut.core.io.IOUtils;
+
+import java.io.BufferedReader;
import java.util.List;
+@Singleton
class PulseEmail {
+ private static final Logger LOG = LoggerFactory.getLogger(PulseEmail.class);
private final EmailSender emailSender;
private final CheckInsConfiguration checkInsConfiguration;
private final MemberProfileServices memberProfileServices;
private final String SUBJECT = "Check Out the Pulse Survey!";
+
+ @Value("classpath:mjml/pulse_email.mjml")
+ private Readable pulseEmailTemplate;
- public PulseEmail(@Named(MailJetFactory.HTML_FORMAT) EmailSender emailSender,
+ public PulseEmail(@Named(MailJetFactory.MJML_FORMAT) EmailSender emailSender,
CheckInsConfiguration checkInsConfiguration,
MemberProfileServices memberProfileServices) {
this.emailSender = emailSender;
@@ -25,43 +39,22 @@ public PulseEmail(@Named(MailJetFactory.HTML_FORMAT) EmailSender emailSender,
}
private List getActiveTeamMembers() {
- List profiles = memberProfileServices.findAll().stream()
+ List addresses = memberProfileServices.findAll().stream()
.filter(p -> p.getTerminationDate() == null)
.map(p -> p.getWorkEmail())
.toList();
- return profiles;
+ return addresses;
}
private String getEmailContent() {
-/*
-
-
-
-
-
- Please fill out your Pulse survey, if you haven't already done so. We want to know how you're doing!
- Click here to begin.
-
-
-
-
-*/
- return String.format("""
-
-
-
-
-
-
- Please fill out your Pulse survey, if you haven't already done so. We want to know how you're doing!
-
-
-
-
-
-
-""", checkInsConfiguration.getWebAddress());
+ try {
+ return String.format(IOUtils.readText(
+ new BufferedReader(pulseEmailTemplate.asReader())),
+ checkInsConfiguration.getWebAddress());
+ } catch(Exception ex) {
+ LOG.error(ex.toString());
+ return "";
+ }
}
public void send() {
diff --git a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java
index 3731950de..9743134ad 100644
--- a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java
+++ b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java
@@ -11,6 +11,7 @@
import lombok.Getter;
import lombok.AllArgsConstructor;
+import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
@@ -40,6 +41,9 @@ private class Frequency {
private final SettingsServices settingsServices;
private final Map sent = new HashMap();
+ @Inject
+ private PulseEmail email;
+
private final DayOfWeek emailDay = DayOfWeek.MONDAY;
private String setting = "bi-weekly";
@@ -50,7 +54,7 @@ private class Frequency {
);
public PulseServicesImpl(
- @Named(MailJetFactory.HTML_FORMAT) EmailSender emailSender,
+ @Named(MailJetFactory.MJML_FORMAT) EmailSender emailSender,
CheckInsConfiguration checkInsConfiguration,
MemberProfileServices memberProfileServices,
SettingsServices settingsServices) {
@@ -93,7 +97,7 @@ public void sendPendingEmail(LocalDate check) {
LOG.info("The Pulse Email has already been sent today");
} else {
LOG.info("Sending Pulse Email");
- send();
+ email.send();
sent.put(key, true);
}
break;
@@ -110,10 +114,4 @@ public void sendPendingEmail(LocalDate check) {
} while(start.isBefore(check) || start.isEqual(check));
}
}
-
- private void send() {
- PulseEmail email = new PulseEmail(emailSender, checkInsConfiguration,
- memberProfileServices);
- email.send();
- }
}
diff --git a/server/src/main/resources/mjml/README.md b/server/src/main/resources/mjml/README.md
new file mode 100644
index 000000000..f4977fb7c
--- /dev/null
+++ b/server/src/main/resources/mjml/README.md
@@ -0,0 +1,10 @@
+# Templates
+
+Place MJML templates here. If they are going to be used within a call to `String.format()`, be sure to double up on any percent signs (i.e., `width="100%%"`).
+
+### Micronaut Usage
+
+```java
+@Value("classpath:mjml/feedback_request.mjml")
+private Readable feedbackRequestTemplate;
+```
diff --git a/server/src/main/resources/mjml/feedback_request.mjml b/server/src/main/resources/mjml/feedback_request.mjml
new file mode 100644
index 000000000..596b8ade9
--- /dev/null
+++ b/server/src/main/resources/mjml/feedback_request.mjml
@@ -0,0 +1,36 @@
+
+
+ Feedback Request
+ Feedback Request
+
+
+
+
+
+
+
+
+
+
+
+ Give Your Feedback!
+
+
+
+
+
+ You have received a feedback request.
+
+ Hello, %s!
+ %s is requesting feedback %sfrom you.
+ %s
+ Please go to your unique link to complete this request.
+
+
+
+
+ Thank you for everything you do!
+
+
+
+
diff --git a/server/src/main/resources/mjml/pulse_email.mjml b/server/src/main/resources/mjml/pulse_email.mjml
new file mode 100644
index 000000000..769cb9a0e
--- /dev/null
+++ b/server/src/main/resources/mjml/pulse_email.mjml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Please fill out your Pulse survey, if you haven't already done so. We want to know how you're doing!
+ Click here to begin.
+
+
+
+
diff --git a/server/src/main/resources/mjml/reviewer_email.mjml b/server/src/main/resources/mjml/reviewer_email.mjml
new file mode 100644
index 000000000..c50aa4b42
--- /dev/null
+++ b/server/src/main/resources/mjml/reviewer_email.mjml
@@ -0,0 +1,35 @@
+
+
+ Self-Review Completion
+ Self-Reviews Completion for Reviewer
+
+
+
+
+
+
+
+
+
+
+
+ It's Your Turn!
+
+
+
+
+
+ It's time to begin your review of %s
+
+ Hello, %s!
+ %s has completed their self-review and it can be viewed here. It's your turn to share your thoughts and complete your review. Please complete your review before %s.
+
+
+
+
+
+ Thank you for everything you do!
+
+
+
+
diff --git a/server/src/main/resources/mjml/supervisor_email.mjml b/server/src/main/resources/mjml/supervisor_email.mjml
new file mode 100644
index 000000000..b9ad37b00
--- /dev/null
+++ b/server/src/main/resources/mjml/supervisor_email.mjml
@@ -0,0 +1,35 @@
+
+
+ Self-Review Completion
+ Self-Reviews Completion for Supervisor
+
+
+
+
+
+
+
+
+
+
+
+ Self-Review Completion
+
+
+
+
+
+ Your team member has completed their self-review!
+
+ Hello, %s!
+ %s has completed their self-review. You can view it here.
+
+
+
+
+
+ Thank you for everything you do!
+
+
+
+
diff --git a/server/src/main/resources/mjml/update_request.mjml b/server/src/main/resources/mjml/update_request.mjml
new file mode 100644
index 000000000..db7588e61
--- /dev/null
+++ b/server/src/main/resources/mjml/update_request.mjml
@@ -0,0 +1,36 @@
+
+
+ Feedback Request Reopened
+ Feedback Request Reopened
+
+
+
+
+
+
+
+
+
+
+
+ Edit Your Feedback!
+
+
+
+
+
+ You have received edit access to a feedback request.
+
+ Hello, %s!
+ %s has reopened the feedback request on %s from you.
+ You may make changes to your answers, but you will need to submit the form again when finished.
+ Please go to your unique link to complete this request.
+
+
+
+
+ Thank you for everything you do!
+
+
+
+
diff --git a/server/src/test/java/com/objectcomputing/checkins/services/MailJetFactoryReplacement.java b/server/src/test/java/com/objectcomputing/checkins/services/MailJetFactoryReplacement.java
index eb4781035..3c96c47ed 100644
--- a/server/src/test/java/com/objectcomputing/checkins/services/MailJetFactoryReplacement.java
+++ b/server/src/test/java/com/objectcomputing/checkins/services/MailJetFactoryReplacement.java
@@ -28,6 +28,13 @@
@Requires(property = "replace.mailjet.factory", value = StringUtils.TRUE)
public class MailJetFactoryReplacement {
+ @Singleton
+ @Named(MailJetFactory.MJML_FORMAT)
+ @Replaces(value = EmailSender.class, named = MailJetFactory.MJML_FORMAT)
+ MockEmailSender getMjmlSender() {
+ return new MockEmailSender();
+ }
+
@Singleton
@Named(MailJetFactory.HTML_FORMAT)
@Replaces(value = EmailSender.class, named = MailJetFactory.HTML_FORMAT)
diff --git a/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestControllerTest.java
index 92b7afc82..53e08739d 100644
--- a/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestControllerTest.java
+++ b/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestControllerTest.java
@@ -54,7 +54,7 @@ class FeedbackRequestControllerTest extends TestContainersSuite implements Membe
CheckInsConfiguration checkInsConfiguration;
@Inject
- @Named(MailJetFactory.HTML_FORMAT)
+ @Named(MailJetFactory.MJML_FORMAT)
private MailJetFactoryReplacement.MockEmailSender emailSender;
@BeforeEach
@@ -63,26 +63,6 @@ void resetMocks() {
emailSender.reset();
}
- private String createEmailContent(FeedbackRequest storedRequest, UUID requestId, MemberProfile creator, MemberProfile requestee) {
- String newContent = "You have received a feedback request.
" +
- "" + creator.getFirstName() + " " + creator.getLastName() + " is requesting feedback on " + requestee.getFirstName() + " " + requestee.getLastName() + " from you.
";
- if (storedRequest.getDueDate() != null) {
- newContent += "This request is due on " + storedRequest.getDueDate().getMonth() + " " + storedRequest.getDueDate().getDayOfMonth() + ", " + storedRequest.getDueDate().getYear() + ".";
- }
- newContent += "
Please go to your unique link at " + checkInsConfiguration.getWebAddress() + "/feedback/submit?request=" + requestId + " to complete this request.
";
- return newContent;
- }
-
- private String updateEmailContent(UUID requestId, MemberProfile creator, MemberProfile requestee) {
- String newContent = "You have received edit access to a feedback request.
" +
- "" + creator.getFirstName() + " " + creator.getLastName() +
- " has reopened the feedback request on " +
- requestee.getFirstName() + " " + requestee.getLastName() + " from you." +
- "You may make changes to your answers, but you will need to submit the form again when finished.
";
- newContent += "Please go to your unique link at " + checkInsConfiguration.getWebAddress() + "/feedback/submit?request=" + requestId + " to complete this request.
";
- return newContent;
- }
-
/**
* Converts a {@link FeedbackRequest} to a {@link FeedbackRequestCreateDTO}
*
@@ -206,16 +186,14 @@ void testCreateFeedbackRequestSendsEmailNow() {
String fromName = pdlMemberProfile.getFirstName() + " " + pdlMemberProfile.getLastName();
//verify appropriate email was sent
assertTrue(response.getBody().isPresent());
- String correctContent = createEmailContent(feedbackRequest, response.getBody().get().getId(), pdlMemberProfile, employeeMemberProfile);
- assertEquals(List.of(
- "SEND_EMAIL",
- fromName,
- pdlMemberProfile.getWorkEmail(),
- checkInsConfiguration.getApplication().getFeedback().getRequestSubject(),
- correctContent,
- recipient.getWorkEmail()
- ),
- emailSender.events.getFirst()
+ assertEquals(1, emailSender.events.size());
+ validateEmail("SEND_EMAIL",
+ fromName,
+ pdlMemberProfile.getWorkEmail(),
+ checkInsConfiguration.getApplication().getFeedback().getRequestSubject(),
+ "You have received a feedback request",
+ recipient.getWorkEmail(),
+ emailSender.events.getFirst()
);
}
@@ -1070,16 +1048,14 @@ void testFeedbackRequestEnableEditsSendsEmail() {
String fromName = pdl.getFirstName() + " " + pdl.getLastName();
// Verify appropriate email was sent
assertTrue(response.getBody().isPresent());
- String correctContent = updateEmailContent(response.getBody().get().getId(), pdl, requestee);
- assertEquals(List.of(
- "SEND_EMAIL",
- fromName,
- pdl.getWorkEmail(),
- checkInsConfiguration.getApplication().getFeedback().getRequestSubject(),
- correctContent,
- recipient.getWorkEmail()
- ),
- emailSender.events.getFirst()
+ assertEquals(1, emailSender.events.size());
+ validateEmail("SEND_EMAIL",
+ fromName,
+ pdl.getWorkEmail(),
+ checkInsConfiguration.getApplication().getFeedback().getRequestSubject(),
+ "You have received edit access to a feedback request",
+ recipient.getWorkEmail(),
+ emailSender.events.getFirst()
);
}
@@ -1438,4 +1414,18 @@ void testGetMultipleRequesteesBySupervisor() {
assertResponseEqualsEntity(feedbackReq, response.getBody().get().get(0));
assertResponseEqualsEntity(feedbackReqTwo, response.getBody().get().get(1));
}
+
+ private void validateEmail(String action, String fromName,
+ String fromAddress, String subject,
+ String partial, String toAddress,
+ List event) {
+ assertEquals(action, event.get(0));
+ assertEquals(fromName, event.get(1));
+ assertEquals(fromAddress, event.get(2));
+ assertEquals(subject, event.get(3));
+ if (partial != null && !partial.isEmpty()) {
+ assertTrue(event.get(4).contains(partial));
+ }
+ assertEquals(toAddress, event.get(5));
+ }
}
diff --git a/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestTest.java b/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestTest.java
index f67bbfa41..e6f095e6c 100644
--- a/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestTest.java
+++ b/server/src/test/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestTest.java
@@ -15,12 +15,16 @@
import com.objectcomputing.checkins.services.reviews.ReviewPeriodRepository;
import io.micronaut.context.annotation.Property;
import io.micronaut.core.util.StringUtils;
+import io.micronaut.runtime.server.EmbeddedServer;
import jakarta.inject.Inject;
import jakarta.inject.Named;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledInNativeImage;
+import org.mockito.Mock;
import org.mockito.Mockito;
import java.time.LocalDate;
@@ -30,12 +34,13 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.openMocks;
@Property(name = "replace.mailjet.factory", value = StringUtils.TRUE)
// Disabled in nativeTest, as we get an exception from Mockito
@@ -43,36 +48,56 @@
@DisabledInNativeImage
class FeedbackRequestTest extends TestContainersSuite {
+ @Mock
private FeedbackRequestRepository feedbackReqRepository;
+ @Mock
private CurrentUserServices currentUserServices;
+ @Mock
private MemberProfileServices memberProfileServices;
+ @Mock
private ReviewPeriodRepository reviewPeriodRepository;
+ @Mock
private ReviewAssignmentRepository reviewAssignmentRepository;
private FeedbackRequestServicesImpl feedbackRequestServices;
@Inject
- @Named(MailJetFactory.HTML_FORMAT)
+ @Named(MailJetFactory.MJML_FORMAT)
private MailJetFactoryReplacement.MockEmailSender emailSender;
+ @Inject
+ private EmbeddedServer server;
+
+ private AutoCloseable mockFinalizer;
+
@Inject
CheckInsConfiguration checkInsConfiguration;
+ @BeforeAll
+ void initMocks() {
+ mockFinalizer = openMocks(this);
+ feedbackRequestServices = new FeedbackRequestServicesImpl(feedbackReqRepository, currentUserServices, memberProfileServices, reviewPeriodRepository, reviewAssignmentRepository, emailSender, checkInsConfiguration);
+ server.getApplicationContext().inject(feedbackRequestServices);
+ }
+
@BeforeEach
@Tag("mocked")
void setUp() {
+ Mockito.reset(feedbackReqRepository);
+ Mockito.reset(currentUserServices);
+ Mockito.reset(memberProfileServices);
+ Mockito.reset(reviewPeriodRepository);
+ Mockito.reset(reviewAssignmentRepository);
emailSender.reset();
+ }
- feedbackReqRepository = Mockito.mock(FeedbackRequestRepository.class);
- currentUserServices = Mockito.mock(CurrentUserServices.class);
- memberProfileServices = Mockito.mock(MemberProfileServices.class);
- reviewPeriodRepository = Mockito.mock(ReviewPeriodRepository.class);
- reviewAssignmentRepository = Mockito.mock(ReviewAssignmentRepository.class);
- feedbackRequestServices = new FeedbackRequestServicesImpl(feedbackReqRepository, currentUserServices, memberProfileServices, reviewPeriodRepository, reviewAssignmentRepository, emailSender, checkInsConfiguration);
+ @AfterAll
+ void cleanupMocks() throws Exception {
+ mockFinalizer.close();
}
@Test
@@ -250,16 +275,16 @@ void testSendSelfReviewCompletionEmailToReviewers() {
feedbackRequestServices.sendSelfReviewCompletionEmailToReviewers(feedbackRequest, reviewAssignmentsSet);
- assertEquals(1, emailSender.events.size());
- assertEquals(
- List.of("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review for Self-Review Test.", "Self-review has been completed by firstName lastName for Self-Review Test.
PDL: PDL Profile
Supervisor: Supervisor Profile
It is now your turn in their review process. Please complete your portion in a timely manner.", reviewer01.getWorkEmail() + "," + reviewer02.getWorkEmail()),
+ // This should equal the number of review assignments.
+ assertEquals(2, emailSender.events.size());
+ validateEmail("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review for Self-Review Test.", "firstName lastName has completed their self-review",
emailSender.events.getFirst()
);
}
@Test
@Tag("mocked")
- void testSendSelfReviewCompletionEmailToPdlAndSupervisor() {
+ void testSendSelfReviewCompletionEmailToSupervisor() {
UUID creatorId = UUID.randomUUID();
MemberProfile currentUser = new MemberProfile();
currentUser.setId(creatorId);
@@ -297,50 +322,16 @@ void testSendSelfReviewCompletionEmailToPdlAndSupervisor() {
when(memberProfileServices.getById(supervisorProfile.getId())).thenReturn(supervisorProfile);
when(reviewPeriodRepository.findById(reviewPeriodId)).thenReturn(Optional.of(reviewPeriod));
- feedbackRequestServices.sendSelfReviewCompletionEmailToPdlAndSupervisor(feedbackRequest);
-
- assertEquals(1, emailSender.events.size());
- assertEquals(
- List.of("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review for Self-Review Test.", "Self-review has been completed by firstName lastName for Self-Review Test.
PDL: PDL Profile
Supervisor: Supervisor Profile
", supervisorProfile.getWorkEmail() + "," + pdlProfile.getWorkEmail()),
- emailSender.events.getFirst()
- );
- }
-
- @Test
- @Tag("mocked")
- void testSendSelfReviewCompletionEmailToPdlAndSupervisor_MissingPdl() {
- UUID creatorId = UUID.randomUUID();
- MemberProfile currentUser = new MemberProfile();
- currentUser.setId(creatorId);
-
- MemberProfile supervisorProfile = new MemberProfile();
- supervisorProfile.setId(UUID.randomUUID());
- supervisorProfile.setFirstName("Supervisor");
- supervisorProfile.setLastName("Profile");
- supervisorProfile.setWorkEmail("supervisor@example.com");
-
- currentUser.setSupervisorid(supervisorProfile.getId());
-
- String firstName = "firstName";
- String lastName = "lastName";
-
- currentUser.setFirstName(firstName);
- currentUser.setLastName(lastName);
-
- when(currentUserServices.getCurrentUser()).thenReturn(currentUser);
- when(memberProfileServices.getById(supervisorProfile.getId())).thenReturn(supervisorProfile);
+ feedbackRequestServices.sendSelfReviewCompletionEmailToSupervisor(feedbackRequest);
- feedbackRequestServices.sendSelfReviewCompletionEmailToPdlAndSupervisor(new FeedbackRequest());
assertEquals(1, emailSender.events.size());
- assertEquals(
- List.of("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review.", "Self-review has been completed by firstName lastName.
Supervisor: Supervisor Profile
", supervisorProfile.getWorkEmail()),
- emailSender.events.getFirst()
+ validateEmail("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review for Self-Review Test.", "firstName lastName has completed their self-review", emailSender.events.getFirst()
);
}
@Test
@Tag("mocked")
- void testSendSelfReviewCompletionEmailToPdlAndSupervisor_MissingSupervisor() {
+ void testSendSelfReviewCompletionEmailToSupervisor_MissingSupervisor() {
UUID creatorId = UUID.randomUUID();
MemberProfile currentUser = new MemberProfile();
currentUser.setId(creatorId);
@@ -362,37 +353,13 @@ void testSendSelfReviewCompletionEmailToPdlAndSupervisor_MissingSupervisor() {
when(currentUserServices.getCurrentUser()).thenReturn(currentUser);
when(memberProfileServices.getById(pdlProfile.getId())).thenReturn(pdlProfile);
- feedbackRequestServices.sendSelfReviewCompletionEmailToPdlAndSupervisor(new FeedbackRequest());
- assertEquals(1, emailSender.events.size());
- assertEquals(
- List.of("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review.", "Self-review has been completed by firstName lastName.
PDL: PDL Profile
", pdlProfile.getWorkEmail()),
- emailSender.events.getFirst()
- );
- }
-
- @Test
- @Tag("mocked")
- void testSendSelfReviewCompletionEmailToPdlAndSupervisor_MissingPdlAndSupervisor() {
- UUID creatorId = UUID.randomUUID();
- MemberProfile currentUser = new MemberProfile();
- currentUser.setId(creatorId);
-
- String firstName = "firstName";
- String lastName = "lastName";
-
- currentUser.setFirstName(firstName);
- currentUser.setLastName(lastName);
-
- when(currentUserServices.getCurrentUser()).thenReturn(currentUser);
-
- feedbackRequestServices.sendSelfReviewCompletionEmailToPdlAndSupervisor(new FeedbackRequest());
-
+ feedbackRequestServices.sendSelfReviewCompletionEmailToSupervisor(new FeedbackRequest());
assertEquals(0, emailSender.events.size());
}
@Test
@Tag("mocked")
- void testSendSelfReviewCompletionEmailToPdlAndSupervisor_EmailSenderException() {
+ void testSendSelfReviewCompletionEmailToSupervisor_EmailSenderException() {
UUID creatorId = UUID.randomUUID();
MemberProfile currentUser = new MemberProfile();
currentUser.setId(creatorId);
@@ -424,11 +391,21 @@ void testSendSelfReviewCompletionEmailToPdlAndSupervisor_EmailSenderException()
emailSender.setException(new RuntimeException("Email sending failed"));
- assertDoesNotThrow(() -> feedbackRequestServices.sendSelfReviewCompletionEmailToPdlAndSupervisor(new FeedbackRequest()));
+ assertDoesNotThrow(() -> feedbackRequestServices.sendSelfReviewCompletionEmailToSupervisor(new FeedbackRequest()));
assertEquals(1, emailSender.events.size());
- assertEquals(
- List.of("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review.", "Self-review has been completed by firstName lastName.
PDL: PDL Profile
Supervisor: Supervisor Profile
", supervisorProfile.getWorkEmail() + "," + pdlProfile.getWorkEmail()),
- emailSender.events.getFirst()
+ validateEmail("SEND_EMAIL", "null", "null", "firstName lastName has finished their self-review.", "firstName lastName has completed their self-review", emailSender.events.getFirst()
);
}
+
+ private void validateEmail(String action, String fromName,
+ String fromAddress, String subject,
+ String partial, List event) {
+ assertEquals(action, event.get(0));
+ assertEquals(fromName, event.get(1));
+ assertEquals(fromAddress, event.get(2));
+ assertEquals(subject, event.get(3));
+ if (partial != null && !partial.isEmpty()) {
+ assertTrue(event.get(4).contains(partial));
+ }
+ }
}
diff --git a/server/src/test/java/com/objectcomputing/checkins/services/pulse/PulseServicesTest.java b/server/src/test/java/com/objectcomputing/checkins/services/pulse/PulseServicesTest.java
index 03f606bce..f6d861c7f 100644
--- a/server/src/test/java/com/objectcomputing/checkins/services/pulse/PulseServicesTest.java
+++ b/server/src/test/java/com/objectcomputing/checkins/services/pulse/PulseServicesTest.java
@@ -30,11 +30,12 @@
import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE;
import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
@Property(name = "replace.mailjet.factory", value = StringUtils.TRUE)
class PulseServicesTest extends TestContainersSuite implements TeamFixture, RoleFixture {
@Inject
- @Named(MailJetFactory.HTML_FORMAT)
+ @Named(MailJetFactory.MJML_FORMAT)
private MailJetFactoryReplacement.MockEmailSender emailSender;
@Inject
@@ -98,9 +99,11 @@ void testBiWeeklySendEmail() {
pulseServices.sendPendingEmail(biWeeklyDate);
assertEquals(1, emailSender.events.size());
- final List event = emailSender.events.get(0);
- assertEquals(6, event.size());
- assertEquals(recipients, event.get(5));
+ validateEmail("SEND_EMAIL", "null", "null",
+ "Check Out the Pulse Survey!",
+ "Please fill out your Pulse survey, if you haven't already done so.",
+ recipients,
+ emailSender.events.getFirst());
}
@Test
@@ -111,9 +114,11 @@ void testWeeklySendEmail() {
pulseServices.sendPendingEmail(weeklyDate);
assertEquals(1, emailSender.events.size());
- final List event = emailSender.events.get(0);
- assertEquals(6, event.size());
- assertEquals(recipients, event.get(5));
+ validateEmail("SEND_EMAIL", "null", "null",
+ "Check Out the Pulse Survey!",
+ "Please fill out your Pulse survey, if you haven't already done so.",
+ recipients,
+ emailSender.events.getFirst());
}
@Test
@@ -124,9 +129,11 @@ void testMonthlySendEmail() {
pulseServices.sendPendingEmail(monthlyDate);
assertEquals(1, emailSender.events.size());
- final List event = emailSender.events.get(0);
- assertEquals(6, event.size());
- assertEquals(recipients, event.get(5));
+ validateEmail("SEND_EMAIL", "null", "null",
+ "Check Out the Pulse Survey!",
+ "Please fill out your Pulse survey, if you haven't already done so.",
+ recipients,
+ emailSender.events.getFirst());
}
@Test
@@ -154,4 +161,18 @@ void testNoSendEmail() {
// This should be zero because the date is not a Monday.
assertEquals(0, emailSender.events.size());
}
+
+ private void validateEmail(String action, String fromName,
+ String fromAddress, String subject,
+ String partial, String recipients,
+ List event) {
+ assertEquals(action, event.get(0));
+ assertEquals(fromName, event.get(1));
+ assertEquals(fromAddress, event.get(2));
+ assertEquals(subject, event.get(3));
+ if (partial != null && !partial.isEmpty()) {
+ assertTrue(event.get(4).contains(partial));
+ }
+ assertEquals(recipients, event.get(5));
+ }
}