Java tutorial
/* ***** BEGIN LICENSE BLOCK ***** * * Copyright (C) 2011-2014 Linagora * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version, provided you comply * with the Additional Terms applicable for OBM connector by Linagora * pursuant to Section 7 of the GNU Affero General Public License, * subsections (b), (c), and (e), pursuant to which you must notably (i) retain * the Message sent thanks to OBM, Free Communication by Linagora? * signature notice appended to any and all outbound messages * (notably e-mail and meeting requests), (ii) retain all hypertext links between * OBM and obm.org, as well as between Linagora and linagora.com, and (iii) refrain * from infringing Linagora intellectual property rights over its trademarks * and commercial brands. Other Additional Terms apply, * see <http://www.linagora.com/licenses/> for more details. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License * for more details. * * You should have received a copy of the GNU Affero General Public License * and its applicable Additional Terms for OBM along with this program. If not, * see <http://www.gnu.org/licenses/> for the GNU Affero General Public License version 3 * and <http://www.linagora.com/licenses/> for the Additional Terms applicable to * OBM connectors. * * ***** END LICENSE BLOCK ***** */ package org.obm.sync.server.mailer; import static org.assertj.core.api.Assertions.assertThat; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.obm.DateUtils.date; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import java.util.TimeZone; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.util.SharedByteArrayInputStream; import org.apache.commons.io.IOUtils; import org.easymock.Capture; import org.jsoup.Jsoup; import org.junit.Before; import org.junit.Test; import org.obm.icalendar.Ical4jHelper; import org.obm.sync.auth.AccessToken; import org.obm.sync.calendar.Attendee; import org.obm.sync.calendar.Comment; import org.obm.sync.calendar.Event; import org.obm.sync.calendar.EventExtId; import org.obm.sync.calendar.EventObmId; import org.obm.sync.calendar.EventRecurrence; import org.obm.sync.calendar.Participation; import org.obm.sync.calendar.RecurrenceDay; import org.obm.sync.calendar.RecurrenceDays; import org.obm.sync.calendar.RecurrenceKind; import org.obm.sync.calendar.SimpleAttendeeService; import org.obm.sync.calendar.UserAttendee; import org.obm.sync.date.DateProvider; import org.obm.sync.server.template.ITemplateLoader; import org.obm.sync.server.template.TemplateLoaderFreeMarkerImpl; import org.obm.sync.services.AttendeeService; import org.slf4j.Logger; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import fr.aliacom.obm.ServicesToolBox; import fr.aliacom.obm.ToolBox; import fr.aliacom.obm.common.MailService; import fr.aliacom.obm.common.calendar.EventNotificationServiceTestTools; import fr.aliacom.obm.common.user.ObmUser; import fr.aliacom.obm.services.constant.ObmSyncConfigurationService; import freemarker.template.Configuration; import freemarker.template.Template; public abstract class EventChangeMailerTest { protected static final TimeZone TIMEZONE = TimeZone.getTimeZone("Europe/Paris"); private EventChangeMailer eventChangeMailer; protected abstract EventChangeMailer newEventChangeMailer(); protected abstract Locale getLocale(); protected abstract List<String> getInvitationPlainMessage(); protected abstract List<String> getInvitationHtmlMessage(); protected abstract List<String> getUpdatePlainMessage(); protected abstract List<String> getUpdateHtmlMessage(); protected abstract List<String> getCancelPlainMessage(); protected abstract List<String> getCancelHtmlMessage(); protected abstract List<String> getRecurrentInvitationPlainMessage(); protected abstract List<String> getRecurrentInvitationHtmlMessage(); protected abstract List<String> getRecurrentUpdatePlainMessage(); protected abstract List<String> getRecurrentUpdateHtmlMessage(); protected abstract List<String> getNonRecurrentToRecurrentUpdatePlainMessage(); protected abstract List<String> getNonRecurrentToRecurrentUpdateHtmlMessage(); protected abstract List<String> getRecurrentToNonRecurrentUpdatePlainMessage(); protected abstract List<String> getRecurrentToNonRecurrentUpdateHtmlMessage(); protected abstract List<String> getRecurrentCancelPlainMessage(); protected abstract List<String> getRecurrentCancelHtmlMessage(); protected abstract List<String> getChangeParticipationPlainMessage(); protected abstract List<String> getChangeParticipationHtmlMessage(); protected abstract String getNewEventSubject(); protected abstract String getNewRecurrentEventSubject(); protected abstract String getCancelEventSubject(); protected abstract String getCancelRecurrentEventSubject(); protected abstract String getUpdateEventSubject(); protected abstract String getUpdateRecurrentEventSubject(); protected abstract String getChangeParticipationSubject(); protected abstract String getNotice(); protected MailService mailService; protected DateProvider dateProvider; private AccessToken accessToken; private ObmUser obmUser; private Ical4jHelper ical4jHelper; private AttendeeService attendeeService; protected Logger logger; private Event event; private Event recurrentEvent; private List<String> icsToCheck; private final static String RECIPIENTS = "Ronan LANORE <rlanore@linagora.com>, " + "Guillaume ALAUX <galaux@linagora.com>, " + "Matthieu BAECHLER <mbaechler@linagora.com>, " + "Blandine DESCAMPS <blandine.descamps@linagora.com>"; protected EventChangeMailer getLocaleEventChangeMailer(Locale locale) { ITemplateLoader templateLoader = new ITemplateLoader() { @Override public Template getTemplate(String templateName, Locale locale, TimeZone timezone) throws IOException { Configuration cfg = new Configuration(); cfg.setClassForTemplateLoading(getClass(), TemplateLoaderFreeMarkerImpl.getTemplatePathPrefix(locale)); Template template = cfg.getTemplate(templateName, locale); template.setTimeZone(TIMEZONE); return cfg.getTemplate(templateName, locale); } }; ObmSyncConfigurationService constantService = createMock(ObmSyncConfigurationService.class); expect(dateProvider.getDate()).andReturn(new Date()).anyTimes(); expect(constantService.getObmUIBaseUrl()).andReturn("baseUrl").once(); expect(constantService.getResourceBundle(locale)).andReturn(ResourceBundle.getBundle("Messages", locale)) .atLeastOnce(); expect(constantService.getEmailCalendarEncoding()).andReturn(null).atLeastOnce(); replay(constantService, dateProvider); return new EventChangeMailer(mailService, constantService, templateLoader, logger); } private List<String> getRawMessageWithSubject(String subject) { return Lists.newArrayList("From: Obm User <user@test>", "To: Ronan LANORE <rlanore@linagora.com>, Guillaume", "Subject: " + subject); } private List<String> getCommonICSFields() { return Lists.newArrayList("BEGIN:VCALENDAR", "CALSCALE:GREGORIAN", "VERSION:2.0", "BEGIN:VEVENT", "SUMMARY:Sprint planning OBM", "ORGANIZER;CN=Raphael ROUGERON:mailto:rrougeron@linagora.com", "UID:f1514f44bf39311568d64072c1fec10f47fe", "X-OBM-DOMAIN:test.tlse.lng", "X-OBM-DOMAIN-UUID:ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6", "CREATED:20090608T142253Z", "LAST-MODIFIED:20090608T142315Z", "SEQUENCE:2", "DURATION:PT45M"); } private List<String> getNoAllowedTimeFormat() { return Lists.newArrayList("11:00:00", "11:45:00", "12:00:00", "13:00:00", "1:00:00"); } @Before public void setup() { dateProvider = createMock(DateProvider.class); mailService = createMock(MailService.class); logger = createNiceMock(Logger.class); attendeeService = new SimpleAttendeeService(); ical4jHelper = new Ical4jHelper(dateProvider, null, attendeeService); accessToken = new AccessToken(1, "unitTest"); obmUser = ServicesToolBox.getDefaultObmUser(); eventChangeMailer = newEventChangeMailer(); event = buildTestEvent(); recurrentEvent = buildTestRecurrentEvent(); icsToCheck = getCommonICSFields(); } private static Attendee createAttendee(String name, String email) { return UserAttendee.builder().email(email).displayName(name).build(); } private List<InternetAddress> createAddressList(String addresses) throws AddressException { return ImmutableList.copyOf(InternetAddress.parse(addresses)); } private static Event buildTestEvent() { Event event = new Event(); event.setSequence(2); event.setTimeCreate(date("2009-06-08T16:22:53")); event.setTimeUpdate(date("2009-06-08T16:23:15")); event.addAttendee(createAttendee("Ronan LANORE", "rlanore@linagora.com")); event.addAttendee(createAttendee("Guillaume ALAUX", "galaux@linagora.com")); event.addAttendee(createAttendee("Matthieu BAECHLER", "mbaechler@linagora.com")); event.addAttendee(createAttendee("Blandine DESCAMPS", "blandine.descamps@linagora.com")); event.setTitle("Sprint planning OBM"); event.setOwner("raphael"); event.setOwnerDisplayName("Raphael ROUGERON"); event.setOwnerEmail("rrougeron@linagora.com"); event.setCreatorDisplayName("Emmanuel SURLEAU"); event.setCreatorEmail("esurleau@linagora.com"); event.setStartDate(date("2010-11-08T11:00:00")); event.setExtId(new EventExtId("f1514f44bf39311568d64072c1fec10f47fe")); event.setDuration(2700); event.setLocation("A random location"); event.setUid(new EventObmId(1354)); EventRecurrence recurrence = new EventRecurrence(); recurrence.setKind(RecurrenceKind.none); event.setRecurrence(recurrence); return event; } private static Event buildTestRecurrentEvent() { Event event = buildTestEvent(); EventRecurrence recurrence = new EventRecurrence(); recurrence.setKind(RecurrenceKind.weekly); recurrence.setFrequence(2); recurrence .setDays(new RecurrenceDays(RecurrenceDay.Monday, RecurrenceDay.Wednesday, RecurrenceDay.Thursday)); recurrence.setEnd(date("2012-11-23T12:00:00")); event.setRecurrence(recurrence); return event; } private Capture<MimeMessage> expectMailServiceSendMessageWithRecipients(String expectedRecipients) throws AddressException, MessagingException { Capture<MimeMessage> capturedMessage = new Capture<MimeMessage>(); List<InternetAddress> addressList = createAddressList(expectedRecipients); mailService.sendMessage(EventNotificationServiceTestTools.compareCollections(addressList), capture(capturedMessage), anyObject(AccessToken.class)); expectLastCall().atLeastOnce(); replay(mailService); return capturedMessage; } private void checkStringContains(String text, List<String> expected) { for (String s : expected) { assertThat(text).contains(s); } } private void checkStringDoesNotContains(String text, List<String> expected) { for (String s : expected) { assertThat(text).doesNotContain(s); } } private void checkHtmlMessage(InvitationParts parts, List<String> expected) throws IOException, MessagingException { BodyPart htmlText = parts.htmlText; assertThat(htmlText.getContent()).isInstanceOf(String.class); String text = Jsoup.parse((String) htmlText.getContent()).text(); checkStringContains(text, expected); checkStringDoesNotContains(text, getNoAllowedTimeFormat()); } private void checkPlainMessage(InvitationParts parts, List<String> expected) throws IOException, MessagingException { BodyPart plainText = parts.plainText; assertThat(plainText.getContent()).isInstanceOf(String.class); String text = (String) plainText.getContent(); checkStringContains(text, expected); checkStringDoesNotContains(text, getNoAllowedTimeFormat()); } private void checkNotice(InvitationParts parts) throws IOException, MessagingException { String htmlText = Jsoup.parse((String) parts.htmlText.getContent()).text(); String plainText = (String) parts.plainText.getContent(); checkStringContains(htmlText, Lists.newArrayList(getNotice())); checkStringContains(plainText, Lists.newArrayList(getNotice())); } private void checkRawMessage(InvitationParts parts, List<String> expected) { String rawMessage = parts.rawMessage; checkStringContains(rawMessage, expected); } private void checkIcs(InvitationParts parts, List<String> expected) throws IOException, MessagingException { checkTextCalendar(parts.textCalendar, expected); checkApplicationIcs(parts.applicationIcs, expected); } private void checkTextCalendar(BodyPart textCalendar, List<String> expected) throws IOException, MessagingException { assertThat(textCalendar.getContent()).isInstanceOf(String.class); String text = (String) textCalendar.getContent(); checkStringContains(text, expected); } private void checkApplicationIcs(BodyPart applicationIcs, List<String> expected) throws IOException, MessagingException { assertThat(applicationIcs.getContent()).isInstanceOf(SharedByteArrayInputStream.class); SharedByteArrayInputStream stream = (SharedByteArrayInputStream) applicationIcs.getContent(); String decodedString = IOUtils.toString(stream, Charsets.US_ASCII.displayName()); checkStringContains(decodedString, expected); } private static String getRawMessage(MimeMessage actualMessage) throws IOException, MessagingException, UnsupportedEncodingException { ByteArrayOutputStream output = new ByteArrayOutputStream(); actualMessage.writeTo(output); String rawMessage = new String(output.toByteArray(), Charsets.UTF_8.displayName()); return rawMessage; } public static class InvitationParts { public String rawMessage; public BodyPart plainText; public BodyPart htmlText; public BodyPart textCalendar; public BodyPart applicationIcs; } protected InvitationParts checkNotificationStructure(MimeMessage mimeMessage) throws UnsupportedEncodingException, IOException, MessagingException { InvitationParts parts = new InvitationParts(); parts.rawMessage = getRawMessage(mimeMessage); assertThat(mimeMessage.getContentType()).startsWith("multipart/alternative"); assertThat(mimeMessage.getContent()).isInstanceOf(Multipart.class); Multipart alternative = (Multipart) mimeMessage.getContent(); assertThat(alternative.getCount()).isEqualTo(2); parts.plainText = alternative.getBodyPart(0); assertThat(parts.plainText.getContentType()).startsWith("text/plain; charset=UTF-8"); parts.htmlText = alternative.getBodyPart(1); assertThat(parts.htmlText.getContentType()).startsWith("text/html; charset=UTF-8"); return parts; } private InvitationParts checkInvitationStructure(MimeMessage mimeMessage) throws UnsupportedEncodingException, IOException, MessagingException { InvitationParts parts = new InvitationParts(); parts.rawMessage = getRawMessage(mimeMessage); assertThat(mimeMessage.getContentType()).startsWith("multipart/mixed"); assertThat(mimeMessage.getContent()).isInstanceOf(Multipart.class); Multipart mixed = (Multipart) mimeMessage.getContent(); assertThat(mixed.getCount()).isEqualTo(2); BodyPart firstPart = mixed.getBodyPart(0); assertThat(firstPart.getContentType()).startsWith("multipart/alternative"); assertThat(firstPart.getContent()).isInstanceOf(Multipart.class); Multipart alternative = (Multipart) firstPart.getContent(); assertThat(alternative.getCount()).isEqualTo(3); parts.plainText = alternative.getBodyPart(0); assertThat(parts.plainText.getContentType()).startsWith("text/plain; charset=UTF-8"); parts.htmlText = alternative.getBodyPart(1); assertThat(parts.htmlText.getContentType()).startsWith("text/html; charset=UTF-8"); parts.textCalendar = alternative.getBodyPart(2); parts.applicationIcs = mixed.getBodyPart(1); assertThat(parts.applicationIcs.getContentType()).isEqualTo("application/ics; name=meeting.ics"); return parts; } /* * Test against : * EventNoticeHtml_en.tpl, EventNoticePlain_en.tpl * EventNoticeHtml_fr.tpl, EventNoticePlain_fr.tpl */ @Test public void testAcceptedCreation() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); eventChangeMailer.notifyAcceptedNewUsers(obmUser, event.getAttendees(), event, getLocale(), TIMEZONE, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkNotificationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getNewEventSubject())); checkPlainMessage(parts, getInvitationPlainMessage()); checkHtmlMessage(parts, getInvitationHtmlMessage()); checkNotice(parts); } /* * Test against : * RecurrentEventNoticeHtml_en.tpl, RecurrentEventNoticePlain_en.tpl * RecurrentEventNoticeHtml_fr.tpl, RecurrentEventNoticePlain_fr.tpl */ @Test public void testAcceptedCreationRecurrentEvent() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); eventChangeMailer.notifyAcceptedNewUsers(obmUser, recurrentEvent.getAttendees(), recurrentEvent, getLocale(), TIMEZONE, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkNotificationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getNewRecurrentEventSubject())); checkPlainMessage(parts, getRecurrentInvitationPlainMessage()); checkHtmlMessage(parts, getRecurrentInvitationHtmlMessage()); checkNotice(parts); } /* * Test against : * ParticipationChangeHtml_en.tpl, ParticipationChangePlain_en.tpl * ParticipationChangeHtml_fr.tpl, ParticipationChangePlain_fr.tpl */ @Test public void testAcceptedParticipationChangeEvent() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients( "Raphael ROUGERON <rrougeron@linagora.com>"); List<Attendee> attendees = event.getAttendees(); Attendee updatedAttendee = attendees.get(2); updatedAttendee.setParticipation(Participation.accepted()); Participation updatedAttendeeStatus = updatedAttendee.getParticipation(); updatedAttendeeStatus.setComment(new Comment("This is a random comment")); event.addAttendee(createAttendee("Raphael ROUGERON", "rrougeron@linagora.com")); Attendee organizer = attendees.get(4); organizer.setOrganizer(true); String ics = ical4jHelper.buildIcsInvitationReply(event, ServicesToolBox.getIcal4jUserFrom("mbaechler@linagora.com"), accessToken); eventChangeMailer.notifyUpdateParticipation(event, event.findOrganizer(), ServicesToolBox.getSpecificObmUserFrom("mbaechler@linagora.com", "Matthieu", "BAECHLER"), updatedAttendeeStatus, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); List<String> rawMessage = getRawMessageWithSubject(getChangeParticipationSubject()); rawMessage.remove("From: Obm User <user@test>"); rawMessage.add("From: Matthieu BAECHLER <mbaechler@linagora.com>"); checkRawMessage(parts, rawMessage); checkPlainMessage(parts, getChangeParticipationPlainMessage()); checkHtmlMessage(parts, getChangeParticipationHtmlMessage()); assertThat(parts.textCalendar.getContentType()).isEqualTo("text/calendar; charset=UTF-8; method=REPLY;"); icsToCheck.add("METHOD:REPLY"); icsToCheck.add("DTSTART:20101108T100000Z"); icsToCheck.add("ATTENDEE;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED;RSVP=TRUE;CN=Matthieu BAECHLE\r\n R;ROLE=OPT-P" + "ARTICIPANT:mailto:mbaechler@linagora.com"); icsToCheck.add("COMMENT:This is a random comment"); checkIcs(parts, icsToCheck); } /* * Test against : * EventCancelHtml_en.tpl, EventCancelPlain_en.tpl * EventCancelHtml_fr.tpl, EventCancelPlain_fr.tpl */ @Test public void testCancelation() throws AddressException, MessagingException, UnsupportedEncodingException, IOException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); String ics = ical4jHelper.buildIcsInvitationCancel(ServicesToolBox.getIcal4jUser(), event, accessToken); eventChangeMailer.notifyRemovedUsers(ServicesToolBox.getDefaultObmUser(), event.getAttendees(), event, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getCancelEventSubject())); checkPlainMessage(parts, getCancelPlainMessage()); checkHtmlMessage(parts, getCancelHtmlMessage()); assertThat(parts.textCalendar.getContentType()).isEqualTo("text/calendar; charset=UTF-8; method=CANCEL;"); icsToCheck.add("METHOD:CANCEL"); icsToCheck.add("DTSTART:20101108T100000Z"); checkIcs(parts, icsToCheck); } /* * Test against : * RecurrentEventCancelHtml_en.tpl, RecurrentEventCancelPlain_en.tpl * RecurrentEventCancelHtml_fr.tpl, RecurrentEventCancelPlain_fr.tpl */ @Test public void testCancelationRecurrentEvent() throws AddressException, MessagingException, UnsupportedEncodingException, IOException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); String ics = ical4jHelper.buildIcsInvitationCancel(ServicesToolBox.getIcal4jUser(), recurrentEvent, accessToken); eventChangeMailer.notifyRemovedUsers(ServicesToolBox.getDefaultObmUser(), recurrentEvent.getAttendees(), recurrentEvent, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getCancelRecurrentEventSubject())); checkPlainMessage(parts, getRecurrentCancelPlainMessage()); checkHtmlMessage(parts, getRecurrentCancelHtmlMessage()); icsToCheck.add("METHOD:CANCEL"); icsToCheck.add("DTSTART:20101108T100000Z"); icsToCheck.add("RRULE:FREQ=WEEKLY;UNTIL=20121123T120000;INTERVAL=2;BYDAY=TH,MO,WE"); checkIcs(parts, icsToCheck); } /* * Test against : * EventInvitationHtml_en.tpl, EventInvitationPlain_en.tpl * EventInvitationHtml_fr.tpl, EventInvitationPlain_fr.tpl */ @Test public void testNeedActionCreation() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), event, accessToken); eventChangeMailer.notifyNeedActionNewUsers(ServicesToolBox.getDefaultObmUser(), event.getAttendees(), event, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); assertThat(parts.textCalendar.getContentType()).isEqualTo("text/calendar; charset=UTF-8; method=REQUEST;"); checkRawMessage(parts, getRawMessageWithSubject(getNewEventSubject())); checkPlainMessage(parts, getInvitationPlainMessage()); checkHtmlMessage(parts, getInvitationHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); checkIcs(parts, icsToCheck); } /* * Test against : * RecurrentEventInvitationHtml_en.tpl, RecurrentEventInvitationPlain_en.tpl * RecurrentEventInvitationHtml_fr.tpl, RecurrentEventInvitationPlain_fr.tpl */ @Test public void testNeedActionCreationRecurrentEvent() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), recurrentEvent, accessToken); eventChangeMailer.notifyNeedActionNewUsers(ServicesToolBox.getDefaultObmUser(), recurrentEvent.getAttendees(), recurrentEvent, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getNewRecurrentEventSubject())); checkPlainMessage(parts, getRecurrentInvitationPlainMessage()); checkHtmlMessage(parts, getRecurrentInvitationHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); icsToCheck.add("RRULE:FREQ=WEEKLY;UNTIL=20121123T120000;INTERVAL=2;BYDAY=TH,MO,WE"); checkIcs(parts, icsToCheck); } /* * Test against : * EventUpdateInvitationHtml_en.tpl, EventUpdateInvitationPlain_en.tpl * EventUpdateInvitationHtml_fr.tpl, EventUpdateInvitationPlain_fr.tpl */ @Test public void testNeedActionUpdate() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestEvent(); Event after = before.clone(); after.setStartDate(date("2010-11-08T12:00:00")); after.setDuration(3600); for (Attendee att : before.getAttendees()) { att.setParticipation(Participation.needsAction()); } after.setSequence(4); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyNeedActionUpdateUsers(ServicesToolBox.getDefaultObmUser(), before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); assertThat(parts.textCalendar.getContentType()).isEqualTo("text/calendar; charset=UTF-8; method=REQUEST;"); checkRawMessage(parts, getRawMessageWithSubject(getUpdateEventSubject())); checkPlainMessage(parts, getUpdatePlainMessage()); checkHtmlMessage(parts, getUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T110000Z"); icsToCheck.remove("SEQUENCE:2"); icsToCheck.add("SEQUENCE:4"); icsToCheck.remove("DURATION:PT45M"); icsToCheck.add("DURATION:PT1H"); checkIcs(parts, icsToCheck); } /* * Test against : * RecurrentEventUpdateInvitationHtml_en.tpl, RecurrentEventUpdateInvitationPlain_en.tpl * RecurrentEventUpdateInvitationHtml_fr.tpl, RecurrentEventUpdateInvitationPlain_fr.tpl */ @Test public void testNeedActionUpdateRecurrentEvent() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestRecurrentEvent(); Event after = before.clone(); before.getRecurrence().setEnd(null); after.setStartDate(date("2010-11-08T12:00:00")); after.setDuration(3600); for (Attendee att : before.getAttendees()) { att.setParticipation(Participation.needsAction()); } after.setSequence(4); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyNeedActionUpdateUsers(ServicesToolBox.getDefaultObmUser(), before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); assertThat(parts.textCalendar.getContentType()).isEqualTo("text/calendar; charset=UTF-8; method=REQUEST;"); checkRawMessage(parts, getRawMessageWithSubject(getUpdateRecurrentEventSubject())); checkPlainMessage(parts, getRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getRecurrentUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T110000Z"); icsToCheck.remove("SEQUENCE:2"); icsToCheck.add("SEQUENCE:4"); icsToCheck.add("RRULE:FREQ=WEEKLY;UNTIL=20121123T120000;INTERVAL=2;BYDAY=TH,MO,WE"); icsToCheck.remove("DURATION:PT45M"); icsToCheck.add("DURATION:PT1H"); checkIcs(parts, icsToCheck); } /* * Test against : * EventUpdateNoticeHtml_en.tpl, EventUpdateNoticePlain_en.tpl * EventUpdateNoticeHtml_fr.tpl, EventUpdateNoticePlain_fr.tpl */ @Test public void testNotifyAcceptedUpdateUsers() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestEvent(); Event after = before.clone(); after.setStartDate(date("2010-11-08T12:00:00")); after.setDuration(3600); for (Attendee att : before.getAttendees()) { att.setParticipation(Participation.accepted()); } eventChangeMailer.notifyAcceptedUpdateUsers(ServicesToolBox.getDefaultObmUser(), before.getAttendees(), before, after, getLocale(), TIMEZONE, "", accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateEventSubject())); checkPlainMessage(parts, getUpdatePlainMessage()); checkHtmlMessage(parts, getUpdateHtmlMessage()); checkNotice(parts); } /* * Test against : * RecurrentEventUpdateNoticeHtml_en.tpl, RecurrentEventUpdateNoticePlain_en.tpl * RecurrentEventUpdateNoticeHtml_fr.tpl, RecurrentEventUpdateNoticePlain_fr.tpl */ @Test public void testNotifyAcceptedUpdateUsersWithRecurrentEvent() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestRecurrentEvent(); Event after = before.clone(); before.getRecurrence().setEnd(null); after.setStartDate(date("2010-11-08T12:00:00")); after.setDuration(3600); for (Attendee att : before.getAttendees()) { att.setParticipation(Participation.accepted()); } eventChangeMailer.notifyAcceptedUpdateUsers(ServicesToolBox.getDefaultObmUser(), before.getAttendees(), before, after, getLocale(), TIMEZONE, "", accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateRecurrentEventSubject())); checkPlainMessage(parts, getRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getRecurrentUpdateHtmlMessage()); checkNotice(parts); } /* * Test against : * EventUpdateNoticeHtml_en.tpl, EventUpdateNoticePlain_en.tpl * EventUpdateNoticeHtml_fr.tpl, EventUpdateNoticePlain_fr.tpl */ @Test public void testNotifyAcceptedUpdateUsersCanWriteOnCalendar() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestEvent(); Event after = before.clone(); after.setStartDate(date("2010-11-08T12:00:00")); after.setDuration(3600); for (Attendee att : before.getAttendees()) { att.setParticipation(Participation.accepted()); } eventChangeMailer.notifyAcceptedUpdateUsersCanWriteOnCalendar(obmUser, before.getAttendees(), before, after, getLocale(), TIMEZONE, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkNotificationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateEventSubject())); checkPlainMessage(parts, getUpdatePlainMessage()); checkHtmlMessage(parts, getUpdateHtmlMessage()); checkNotice(parts); } @Test public void testBuildUpdateParticipationDatamodel() { Event event = new Event(); event.setStartDate(new Date()); ObmUser obmUser = ToolBox.getDefaultObmUser(); Participation status = Participation.accepted(); status.setComment(new Comment(null)); ObmSyncConfigurationService constantService = createMock(ObmSyncConfigurationService.class); expect(constantService.getObmUIBaseUrl()).andReturn("baseUrl").once(); expect(constantService.getResourceBundle(getLocale())) .andReturn(ResourceBundle.getBundle("Messages", getLocale())).atLeastOnce(); expect(constantService.getEmailCalendarEncoding()).andReturn(null).atLeastOnce(); replay(constantService); EventChangeMailer eventChangeMailer = new EventChangeMailer(null, constantService, null, logger); eventChangeMailer.buildUpdateParticipationDatamodel(event, obmUser, status, getLocale()); } @Test public void testNonRecurrentToRecurrentNotification() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event after = buildTestRecurrentEvent(); after.setSequence(4); Event before = after.clone(); before.setRecurrence(new EventRecurrence()); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyAcceptedUpdateUsers(obmUser, before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateRecurrentEventSubject())); checkPlainMessage(parts, getNonRecurrentToRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getNonRecurrentToRecurrentUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); icsToCheck.remove("SEQUENCE:2"); icsToCheck.add("SEQUENCE:4"); icsToCheck.add("RRULE:FREQ=WEEKLY;UNTIL=20121123T120000;INTERVAL=2;BYDAY=TH,MO,WE"); checkIcs(parts, icsToCheck); checkNotice(parts); } @Test public void testNonRecurrentToRecurrentNotifyNeedActionUpdateUsers() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event after = buildTestRecurrentEvent(); Event before = after.clone(); before.setRecurrence(new EventRecurrence()); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyNeedActionUpdateUsers(obmUser, before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateRecurrentEventSubject())); checkPlainMessage(parts, getNonRecurrentToRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getNonRecurrentToRecurrentUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); icsToCheck.add("RRULE:FREQ=WEEKLY;UNTIL=20121123T120000;INTERVAL=2;BYDAY=TH,MO,WE"); checkIcs(parts, icsToCheck); } @Test public void testRecurrentToNonRecurrentNotification() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestRecurrentEvent(); Event after = before.clone(); after.setRecurrence(new EventRecurrence()); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyAcceptedUpdateUsers(obmUser, before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateEventSubject())); checkPlainMessage(parts, getRecurrentToNonRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getRecurrentToNonRecurrentUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); checkIcs(parts, icsToCheck); checkNotice(parts); } @Test public void testRecurrentToNonRecurrentNotifyNeedActionUpdateUsers() throws UnsupportedEncodingException, IOException, MessagingException { Capture<MimeMessage> capturedMessage = expectMailServiceSendMessageWithRecipients(RECIPIENTS); Event before = buildTestRecurrentEvent(); Event after = before.clone(); after.setRecurrence(new EventRecurrence()); String ics = ical4jHelper.buildIcsInvitationRequest(ServicesToolBox.getIcal4jUser(), after, accessToken); eventChangeMailer.notifyNeedActionUpdateUsers(obmUser, before.getAttendees(), before, after, getLocale(), TIMEZONE, ics, accessToken); verify(mailService); MimeMessage mimeMessage = capturedMessage.getValue(); InvitationParts parts = checkInvitationStructure(mimeMessage); checkRawMessage(parts, getRawMessageWithSubject(getUpdateEventSubject())); checkPlainMessage(parts, getRecurrentToNonRecurrentUpdatePlainMessage()); checkHtmlMessage(parts, getRecurrentToNonRecurrentUpdateHtmlMessage()); icsToCheck.add("METHOD:REQUEST"); icsToCheck.add("DTSTART:20101108T100000Z"); checkIcs(parts, icsToCheck); } }