use of teammates.logic.api.EmailGenerator in project teammates by TEAMMATES.
the class EmailGeneratorTest method testGenerateStudentCourseJoinEmail_testSanitization.
@Test
public void testGenerateStudentCourseJoinEmail_testSanitization() throws IOException {
______TS("student course join email: sanitization required");
CourseAttributes course = coursesLogic.getCourse("idOfTestingSanitizationCourse");
StudentAttributes student1 = studentsLogic.getStudentForEmail(course.getId(), "normal@sanitization.tmt");
EmailWrapper email = new EmailGenerator().generateStudentCourseJoinEmail(course, student1);
String subject = String.format(EmailType.STUDENT_COURSE_JOIN.getSubject(), course.getName(), course.getId());
verifyEmail(email, student1.email, subject, "/studentCourseJoinEmailTestingSanitization.html");
______TS("student course join email after Google ID reset: sanitization required");
email = new EmailGenerator().generateStudentCourseRejoinEmailAfterGoogleIdReset(course, student1);
subject = String.format(EmailType.STUDENT_COURSE_REJOIN_AFTER_GOOGLE_ID_RESET.getSubject(), course.getName(), course.getId());
verifyEmail(email, student1.email, subject, "/studentCourseRejoinAfterGoogleIdResetEmailTestingSanitization.html");
}
use of teammates.logic.api.EmailGenerator in project teammates by TEAMMATES.
the class EmailGeneratorTest method testGenerateFeedbackSessionEmails.
@Test
public void testGenerateFeedbackSessionEmails() throws IOException {
FeedbackSessionAttributes session = fsLogic.getFeedbackSession("First feedback session", "idOfTypicalCourse1");
CourseAttributes course = coursesLogic.getCourse(session.getCourseId());
StudentAttributes student1 = studentsLogic.getStudentForEmail(course.getId(), "student1InCourse1@gmail.tmt");
InstructorAttributes instructor1 = instructorsLogic.getInstructorForEmail(course.getId(), "instructor1@course1.tmt");
List<StudentAttributes> students = studentsLogic.getStudentsForCourse(session.getCourseId());
List<InstructorAttributes> instructors = instructorsLogic.getInstructorsForCourse(session.getCourseId());
InstructorAttributes instructorToNotify = instructorsLogic.getInstructorForGoogleId(session.getCourseId(), instructor1.getGoogleId());
______TS("feedback session opening emails");
List<EmailWrapper> emails = new EmailGenerator().generateFeedbackSessionOpeningEmails(session);
assertEquals(10, emails.size());
String subject = String.format(EmailType.FEEDBACK_OPENING.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmailReceivedCorrectly(emails, student1.email, subject, "/sessionOpeningEmailForStudent.html");
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionOpeningEmailForInstructor.html");
______TS("feedback session reminders");
emails = new EmailGenerator().generateFeedbackSessionReminderEmails(session, students, instructors, instructorToNotify);
// (5 instructors, 5 students reminded) and (1 instructor to be notified)
assertEquals(11, emails.size());
subject = String.format(EmailType.FEEDBACK_SESSION_REMINDER.getSubject(), course.getName(), session.getFeedbackSessionName());
String lineInEmailCopyToInstructor = "The email below has been sent to students of course:";
// Verify the student reminder email
verifyEmailReceivedCorrectly(emails, student1.email, subject, "/sessionReminderEmailForStudent.html");
// Verify the Student email copy send to the instructor
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionReminderEmailCopyToInstructor.html", lineInEmailCopyToInstructor);
// Verify the instructor reminder email
String lineInEmailToInstructor = "/page/instructorFeedbackSubmissionEditPage?courseid=idOfTypicalCourse1&fsname=First+feedback+session";
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionReminderEmailForInstructor.html", lineInEmailToInstructor);
______TS("feedback session closing alerts");
emails = new EmailGenerator().generateFeedbackSessionClosingEmails(session);
assertEquals(8, emails.size());
subject = String.format(EmailType.FEEDBACK_CLOSING.getSubject(), course.getName(), session.getFeedbackSessionName());
// student1 has completed the feedback session and closing alert is only sent for those who are
// yet to complete, so we resort to student5
StudentAttributes student5 = studentsLogic.getStudentForEmail(course.getId(), "student5InCourse1@gmail.tmt");
for (EmailWrapper email : emails) {
if (email.getRecipient().equals(student1.email)) {
fail("student1 has completed the session and are not supposed to receive email");
}
}
verifyEmailReceivedCorrectly(emails, student5.email, subject, "/sessionClosingEmailForStudent.html");
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionClosingEmailForInstructor.html");
______TS("feedback session closed alerts");
emails = new EmailGenerator().generateFeedbackSessionClosedEmails(session);
assertEquals(10, emails.size());
subject = String.format(EmailType.FEEDBACK_CLOSED.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmailReceivedCorrectly(emails, student1.email, subject, "/sessionClosedEmailForStudent.html");
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionClosedEmailForInstructor.html");
______TS("feedback session published alerts");
emails = new EmailGenerator().generateFeedbackSessionPublishedEmails(session);
assertEquals(10, emails.size());
subject = String.format(EmailType.FEEDBACK_PUBLISHED.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmailReceivedCorrectly(emails, student1.email, subject, "/sessionPublishedEmailForStudent.html");
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionPublishedEmailForInstructor.html");
______TS("feedback session unpublished alerts");
emails = new EmailGenerator().generateFeedbackSessionUnpublishedEmails(session);
assertEquals(10, emails.size());
subject = String.format(EmailType.FEEDBACK_UNPUBLISHED.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmailReceivedCorrectly(emails, student1.email, subject, "/sessionUnpublishedEmailForStudent.html");
verifyEmailReceivedCorrectly(emails, instructor1.email, subject, "/sessionUnpublishedEmailForInstructor.html");
______TS("send summary of all feedback sessions of course email");
EmailWrapper email = new EmailGenerator().generateFeedbackSessionSummaryOfCourse(session.getCourseId(), student1);
subject = String.format(EmailType.STUDENT_EMAIL_CHANGED.getSubject(), course.getName(), course.getId());
verifyEmail(email, student1.email, subject, "/summaryOfFeedbackSessionsOfCourseEmailForStudent.html");
______TS("feedback session submission email");
Instant time = TimeHelper.parseInstant("2016-09-04 05:30 AM +0000");
email = new EmailGenerator().generateFeedbackSubmissionConfirmationEmailForStudent(session, student1, time);
subject = String.format(EmailType.FEEDBACK_SUBMISSION_CONFIRMATION.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmail(email, student1.email, subject, "/sessionSubmissionConfirmationEmailPositiveTimeZone.html");
setTimeZoneButMaintainLocalDate(session, ZoneId.of("Pacific/Marquesas"));
email = new EmailGenerator().generateFeedbackSubmissionConfirmationEmailForInstructor(session, instructor1, time);
subject = String.format(EmailType.FEEDBACK_SUBMISSION_CONFIRMATION.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmail(email, instructor1.email, subject, "/sessionSubmissionConfirmationEmailNegativeTimeZone.html");
setTimeZoneButMaintainLocalDate(session, ZoneId.of("UTC"));
email = new EmailGenerator().generateFeedbackSubmissionConfirmationEmailForInstructor(session, instructor1, time);
subject = String.format(EmailType.FEEDBACK_SUBMISSION_CONFIRMATION.getSubject(), course.getName(), session.getFeedbackSessionName());
verifyEmail(email, instructor1.email, subject, "/sessionSubmissionConfirmationEmailZeroTimeZone.html");
______TS("no email alerts sent for sessions not answerable/viewable for students");
FeedbackSessionAttributes privateSession = fsLogic.getFeedbackSession("Private feedback session", "idOfTypicalCourse2");
emails = new EmailGenerator().generateFeedbackSessionOpeningEmails(privateSession);
assertTrue(emails.isEmpty());
emails = new EmailGenerator().generateFeedbackSessionClosingEmails(privateSession);
assertTrue(emails.isEmpty());
emails = new EmailGenerator().generateFeedbackSessionClosedEmails(privateSession);
assertTrue(emails.isEmpty());
emails = new EmailGenerator().generateFeedbackSessionPublishedEmails(privateSession);
assertTrue(emails.isEmpty());
emails = new EmailGenerator().generateFeedbackSessionUnpublishedEmails(privateSession);
assertTrue(emails.isEmpty());
}
use of teammates.logic.api.EmailGenerator in project teammates by TEAMMATES.
the class EmailGeneratorTest method testGenerateUserCourseRegisterEmail.
@Test
public void testGenerateUserCourseRegisterEmail() throws IOException {
______TS("student course register email");
CourseAttributes course = CourseAttributes.builder("idOfTypicalCourse1", "Course Name", ZoneId.of("UTC")).build();
String name = "User Name";
String emailAddress = "user@email.tmt";
String googleId = "user.googleid";
EmailWrapper email = new EmailGenerator().generateUserCourseRegisteredEmail(name, emailAddress, googleId, false, course);
String subject = String.format(EmailType.USER_COURSE_REGISTER.getSubject(), course.getName(), course.getId());
verifyEmail(email, emailAddress, subject, "/studentCourseRegisterEmail.html");
______TS("instructor course register email");
email = new EmailGenerator().generateUserCourseRegisteredEmail(name, emailAddress, googleId, true, course);
subject = String.format(EmailType.USER_COURSE_REGISTER.getSubject(), course.getName(), course.getId());
verifyEmail(email, emailAddress, subject, "/instructorCourseRegisterEmail.html");
}
use of teammates.logic.api.EmailGenerator in project teammates by TEAMMATES.
the class InstructorCourseStudentDetailsEditSaveAction method execute.
@Override
public ActionResult execute() throws EntityDoesNotExistException {
String courseId = getRequestParamValue(Const.ParamsNames.COURSE_ID);
Assumption.assertPostParamNotNull(Const.ParamsNames.COURSE_ID, courseId);
String studentEmail = getRequestParamValue(Const.ParamsNames.STUDENT_EMAIL);
Assumption.assertPostParamNotNull(Const.ParamsNames.STUDENT_EMAIL, studentEmail);
InstructorAttributes instructor = logic.getInstructorForGoogleId(courseId, account.googleId);
gateKeeper.verifyAccessible(instructor, logic.getCourse(courseId), Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT);
StudentAttributes student = logic.getStudentForEmail(courseId, studentEmail);
if (student == null) {
return redirectWithError(Const.StatusMessages.STUDENT_NOT_FOUND_FOR_EDIT, "Student <span class=\"bold\">" + studentEmail + "</span> in " + "Course <span class=\"bold\">[" + courseId + "]</span> not found.", courseId);
}
student.name = getRequestParamValue(Const.ParamsNames.STUDENT_NAME);
student.email = getRequestParamValue(Const.ParamsNames.NEW_STUDENT_EMAIL);
student.team = getRequestParamValue(Const.ParamsNames.TEAM_NAME);
student.section = getRequestParamValue(Const.ParamsNames.SECTION_NAME);
student.comments = getRequestParamValue(Const.ParamsNames.COMMENTS);
boolean hasSection = logic.hasIndicatedSections(courseId);
student.name = SanitizationHelper.sanitizeName(student.name);
student.email = SanitizationHelper.sanitizeEmail(student.email);
student.team = SanitizationHelper.sanitizeName(student.team);
student.section = SanitizationHelper.sanitizeName(student.section);
student.comments = SanitizationHelper.sanitizeTextField(student.comments);
try {
StudentAttributes originalStudentAttribute = logic.getStudentForEmail(courseId, studentEmail);
student.updateWithExistingRecord(originalStudentAttribute);
boolean isSectionChanged = student.isSectionChanged(originalStudentAttribute);
boolean isTeamChanged = student.isTeamChanged(originalStudentAttribute);
boolean isEmailChanged = student.isEmailChanged(originalStudentAttribute);
if (isSectionChanged) {
logic.validateSectionsAndTeams(Arrays.asList(student), courseId);
} else if (isTeamChanged) {
logic.validateTeams(Arrays.asList(student), courseId);
}
logic.updateStudent(studentEmail, student);
boolean isSessionSummarySendEmail = getRequestParamAsBoolean(Const.ParamsNames.SESSION_SUMMARY_EMAIL_SEND_CHECK);
if (isEmailChanged) {
logic.resetStudentGoogleId(student.email, courseId);
if (isSessionSummarySendEmail) {
try {
EmailWrapper email = new EmailGenerator().generateFeedbackSessionSummaryOfCourse(courseId, student);
emailSender.sendEmail(email);
} catch (Exception e) {
log.severe("Error while sending session summary email" + TeammatesException.toStringWithStackTrace(e));
}
}
}
statusToUser.add(new StatusMessage(isSessionSummarySendEmail && isEmailChanged ? Const.StatusMessages.STUDENT_EDITED_AND_EMAIL_SENT : Const.StatusMessages.STUDENT_EDITED, StatusMessageColor.SUCCESS));
statusToAdmin = "Student <span class=\"bold\">" + studentEmail + "'s</span> details in " + "Course <span class=\"bold\">[" + courseId + "]</span> edited.<br>" + "New Email: " + student.email + "<br>New Team: " + student.team + "<br>" + "Comments: " + student.comments;
RedirectResult result = createRedirectResult(Const.ActionURIs.INSTRUCTOR_COURSE_DETAILS_PAGE);
result.addResponseParam(Const.ParamsNames.COURSE_ID, courseId);
return result;
} catch (InvalidParametersException | EnrollException e) {
setStatusForException(e);
String newEmail = student.email;
student.email = studentEmail;
boolean isOpenOrPublishedEmailSentForTheCourse = logic.isOpenOrPublishedEmailSentForTheCourse(courseId);
InstructorCourseStudentDetailsEditPageData data = new InstructorCourseStudentDetailsEditPageData(account, sessionToken, student, newEmail, hasSection, isOpenOrPublishedEmailSentForTheCourse);
return createShowPageResult(Const.ViewURIs.INSTRUCTOR_COURSE_STUDENT_EDIT, data);
}
}
use of teammates.logic.api.EmailGenerator in project teammates by TEAMMATES.
the class FeedbackSubmissionEditSaveAction method execute.
@Override
protected ActionResult execute() throws EntityDoesNotExistException {
courseId = getRequestParamValue(Const.ParamsNames.COURSE_ID);
feedbackSessionName = getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);
Assumption.assertPostParamNotNull(Const.ParamsNames.COURSE_ID, courseId);
Assumption.assertPostParamNotNull(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);
setAdditionalParameters();
verifyAccessibleForSpecificUser();
String userEmailForCourse = getUserEmailForCourse();
data = new FeedbackSubmissionEditPageData(account, student, sessionToken);
data.bundle = getDataBundle(userEmailForCourse);
Assumption.assertNotNull("Feedback session " + feedbackSessionName + " does not exist in " + courseId + ".", data.bundle);
checkAdditionalConstraints();
setStatusToAdmin();
if (!isSessionOpenForSpecificUser(data.bundle.feedbackSession)) {
isError = true;
statusToUser.add(new StatusMessage(Const.StatusMessages.FEEDBACK_SUBMISSIONS_NOT_OPEN, StatusMessageColor.WARNING));
return createSpecificRedirectResult();
}
String userTeamForCourse = getUserTeamForCourse();
String userSectionForCourse = getUserSectionForCourse();
int numOfQuestionsToGet = data.bundle.questionResponseBundle.size();
for (int questionIndx = 1; questionIndx <= numOfQuestionsToGet; questionIndx++) {
String totalResponsesForQuestion = getRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_RESPONSETOTAL + "-" + questionIndx);
if (totalResponsesForQuestion == null) {
// question has been skipped (not displayed).
continue;
}
List<FeedbackResponseAttributes> responsesForQuestion = new ArrayList<>();
String questionId = getRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID + "-" + questionIndx);
FeedbackQuestionAttributes questionAttributes = data.bundle.getQuestionAttributes(questionId);
if (questionAttributes == null) {
statusToUser.add(new StatusMessage("The feedback session or questions may have changed " + "while you were submitting. Please check your responses " + "to make sure they are saved correctly.", StatusMessageColor.WARNING));
isError = true;
log.warning("Question not found. (deleted or invalid id passed?) id: " + questionId + " index: " + questionIndx);
continue;
}
FeedbackQuestionDetails questionDetails = questionAttributes.getQuestionDetails();
int numOfResponsesToGet = Integer.parseInt(totalResponsesForQuestion);
Set<String> emailSet = data.bundle.getRecipientEmails(questionAttributes.getId());
emailSet.add("");
emailSet = SanitizationHelper.desanitizeFromHtml(emailSet);
ArrayList<String> responsesRecipients = new ArrayList<>();
List<String> errors = new ArrayList<>();
for (int responseIndx = 0; responseIndx < numOfResponsesToGet; responseIndx++) {
FeedbackResponseAttributes response = extractFeedbackResponseData(requestParameters, questionIndx, responseIndx, questionAttributes);
if (response.feedbackQuestionType != questionAttributes.questionType) {
errors.add(String.format(Const.StatusMessages.FEEDBACK_RESPONSES_WRONG_QUESTION_TYPE, questionIndx));
}
boolean isExistingResponse = response.getId() != null;
// came from the original set of existing responses loaded on the submission page
if (isExistingResponse && !isExistingResponseValid(response)) {
errors.add(String.format(Const.StatusMessages.FEEDBACK_RESPONSES_INVALID_ID, questionIndx));
continue;
}
responsesRecipients.add(response.recipient);
// if the answer is not empty but the recipient is empty
if (response.recipient.isEmpty() && !response.responseMetaData.getValue().isEmpty()) {
errors.add(String.format(Const.StatusMessages.FEEDBACK_RESPONSES_MISSING_RECIPIENT, questionIndx));
}
if (response.responseMetaData.getValue().isEmpty()) {
// deletes the response since answer is empty
addToPendingResponses(response);
} else {
response.giver = questionAttributes.giverType.isTeam() ? userTeamForCourse : userEmailForCourse;
response.giverSection = userSectionForCourse;
responsesForQuestion.add(response);
}
}
List<String> questionSpecificErrors = questionDetails.validateResponseAttributes(responsesForQuestion, data.bundle.recipientList.get(questionId).size());
errors.addAll(questionSpecificErrors);
if (!emailSet.containsAll(responsesRecipients)) {
errors.add(String.format(Const.StatusMessages.FEEDBACK_RESPONSE_INVALID_RECIPIENT, questionIndx));
}
if (errors.isEmpty()) {
for (FeedbackResponseAttributes response : responsesForQuestion) {
addToPendingResponses(response);
}
} else {
List<StatusMessage> errorMessages = new ArrayList<>();
for (String error : errors) {
errorMessages.add(new StatusMessage(error, StatusMessageColor.DANGER));
}
statusToUser.addAll(errorMessages);
isError = true;
}
}
saveNewReponses(responsesToSave);
deleteResponses(responsesToDelete);
updateResponses(responsesToUpdate);
if (!isError) {
statusToUser.add(new StatusMessage(Const.StatusMessages.FEEDBACK_RESPONSES_SAVED, StatusMessageColor.SUCCESS));
}
if (isUserRespondentOfSession()) {
appendRespondent();
} else {
removeRespondent();
}
boolean isSubmissionEmailRequested = "on".equals(getRequestParamValue(Const.ParamsNames.SEND_SUBMISSION_EMAIL));
if (!isError && isSendSubmissionEmail && isSubmissionEmailRequested) {
FeedbackSessionAttributes session = logic.getFeedbackSession(feedbackSessionName, courseId);
Assumption.assertNotNull(session);
String user = account == null ? null : account.googleId;
String unregisteredStudentEmail = student == null ? null : student.email;
String unregisteredStudentRegisterationKey = student == null ? null : student.key;
StudentAttributes student = null;
InstructorAttributes instructor = null;
if (user != null) {
student = logic.getStudentForGoogleId(courseId, user);
instructor = logic.getInstructorForGoogleId(courseId, user);
}
if (student == null && unregisteredStudentEmail != null) {
student = StudentAttributes.builder("", unregisteredStudentEmail, unregisteredStudentEmail).withKey(unregisteredStudentRegisterationKey).build();
}
Assumption.assertFalse(student == null && instructor == null);
try {
EmailWrapper email = instructor == null ? new EmailGenerator().generateFeedbackSubmissionConfirmationEmailForStudent(session, student, Instant.now()) : new EmailGenerator().generateFeedbackSubmissionConfirmationEmailForInstructor(session, instructor, Instant.now());
emailSender.sendEmail(email);
} catch (EmailSendingException e) {
log.severe("Submission confirmation email failed to send: " + TeammatesException.toStringWithStackTrace(e));
}
}
// TODO: Refactor to AjaxResult so status messages do not have to be passed by session
return createSpecificRedirectResult();
}
Aggregations