Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Recurrent events only one event is displayed on exchange agenda- EXO-68948 #99

Merged
merged 2 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.time.format.TextStyle;
import java.util.*;

import microsoft.exchange.webservices.data.core.enumeration.property.time.DayOfTheWeek;
import microsoft.exchange.webservices.data.core.enumeration.property.time.Month;
import microsoft.exchange.webservices.data.core.exception.misc.ArgumentOutOfRangeException;
import microsoft.exchange.webservices.data.property.complex.recurrence.pattern.Recurrence;
import org.apache.commons.lang3.StringUtils;
import org.exoplatform.agenda.model.Event;
import org.exoplatform.agenda.model.EventRecurrence;
import org.exoplatform.agenda.model.RemoteEvent;
import org.exoplatform.agenda.rest.model.EventEntity;
import org.exoplatform.agenda.service.AgendaEventService;
import org.exoplatform.agenda.service.AgendaRemoteEventService;
import org.exoplatform.agenda.util.AgendaDateUtils;
import org.exoplatform.agendaconnector.model.ExchangeUserSetting;
Expand Down Expand Up @@ -58,13 +63,17 @@ public class ExchangeConnectorServiceImpl implements ExchangeConnectorService {

private AgendaRemoteEventService agendaRemoteEventService;

private AgendaEventService agendaEventService;

private static final Log LOG = ExoLogger.getLogger(ExchangeConnectorServiceImpl.class);


public ExchangeConnectorServiceImpl(ExchangeConnectorStorage exchangeConnectorStorage,
AgendaRemoteEventService agendaRemoteEventService) {
AgendaRemoteEventService agendaRemoteEventService,
AgendaEventService agendaEventService) {
this.exchangeConnectorStorage = exchangeConnectorStorage;
this.agendaRemoteEventService = agendaRemoteEventService;
this.agendaEventService = agendaEventService;
}

@Override
Expand Down Expand Up @@ -179,6 +188,7 @@ public void pushEventToExchange(long userIdentityId, EventEntity event, ZoneId u
ZonedDateTime endDate = AgendaDateUtils.parseRFC3339ToZonedDateTime(event.getEnd(), userTimeZone);
appointment.setStart(AgendaDateUtils.toDate(startDate));
appointment.setEnd(AgendaDateUtils.toDate(endDate));
appointment.setRecurrence(getEventRecurrence(event.getId()));
appointment.save(new FolderId(WellKnownFolderName.Calendar), SendInvitationsMode.SendToAllAndSaveCopy);
remoteEvent = new RemoteEvent();
remoteEvent.setIdentityId(userIdentityId);
Expand All @@ -195,6 +205,7 @@ public void pushEventToExchange(long userIdentityId, EventEntity event, ZoneId u
ZonedDateTime endDate = AgendaDateUtils.parseRFC3339ToZonedDateTime(event.getEnd(), userTimeZone);
appointment.setStart(AgendaDateUtils.toDate(startDate));
appointment.setEnd(AgendaDateUtils.toDate(endDate));
appointment.setRecurrence(getEventRecurrence(event.getId()));
appointment.update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy);
}
} catch (ServiceLocalException e) {
Expand Down Expand Up @@ -224,4 +235,91 @@ public void deleteExchangeEvent(long userIdentityId, long eventId) throws Illega
throw new IllegalAccessException("User '" + userIdentityId + "' is not allowed to connect to exchange server");
}
}

private Recurrence getEventRecurrence(long eventId) throws ArgumentOutOfRangeException {
Event event = agendaEventService.getEventById(eventId);
EventRecurrence eventRecurrence = event.getRecurrence();
if (eventRecurrence == null) {
return null;
}
ZonedDateTime startDate = eventRecurrence.getOverallStart();
Recurrence recurrence;
switch (eventRecurrence.getType()) {
case DAILY:
recurrence = new Recurrence.DailyPattern();
recurrence.setStartDate(AgendaDateUtils.toDate(startDate));
break;
case WEEKLY:
DayOfTheWeek day =
DayOfTheWeek.valueOf(StringUtils.capitalize(AgendaDateUtils.getDayNameFromDayAbbreviation(eventRecurrence.getByDay())));
recurrence = new Recurrence.WeeklyPattern(AgendaDateUtils.toDate(startDate), 1, day);
break;
case WEEK_DAYS:
recurrence = new Recurrence.WeeklyPattern(AgendaDateUtils.toDate(startDate),
1,
DayOfTheWeek.Monday,
DayOfTheWeek.Tuesday,
DayOfTheWeek.Wednesday,
DayOfTheWeek.Thursday,
DayOfTheWeek.Friday);
break;
case MONTHLY:
recurrence = new Recurrence.MonthlyPattern(AgendaDateUtils.toDate(startDate),
eventRecurrence.getInterval(),
Integer.valueOf(eventRecurrence.getByMonthDay().get(0)));
break;
case YEARLY:
recurrence = new Recurrence.YearlyPattern(AgendaDateUtils.toDate(startDate),
Month.valueOf(java.time.Month.of(Integer.parseInt(eventRecurrence.getByMonth()
.get(0)))
.getDisplayName(TextStyle.FULL, Locale.ENGLISH)),
Integer.valueOf(eventRecurrence.getByMonthDay().get(0)));
break;
case CUSTOM:
recurrence = getCustomEventRecurrence(eventRecurrence);
break;
default:
throw new IllegalStateException("Can't handle type: " + eventRecurrence.getType());
}
return recurrence;
}

private Recurrence getCustomEventRecurrence(EventRecurrence eventRecurrence) throws ArgumentOutOfRangeException {
Recurrence recurrence;
ZonedDateTime startDate = eventRecurrence.getOverallStart();
ZonedDateTime endDate = eventRecurrence.getOverallEnd();
switch (eventRecurrence.getFrequency()) {
case YEARLY:
recurrence = new Recurrence.YearlyPattern(AgendaDateUtils.toDate(startDate),
Month.valueOf(java.time.Month.of(Integer.parseInt(eventRecurrence.getByMonth()
.get(0)))
.getDisplayName(TextStyle.FULL, Locale.ENGLISH)),
Integer.valueOf(eventRecurrence.getByMonthDay().get(0)));
break;
case MONTHLY:
recurrence = new Recurrence.MonthlyPattern(AgendaDateUtils.toDate(startDate),
eventRecurrence.getInterval(),
Integer.valueOf(eventRecurrence.getByMonthDay().get(0)));
break;
case WEEKLY:
List<DayOfTheWeek> weekDays =
eventRecurrence.getByDay()
.stream()
.map(day -> DayOfTheWeek.valueOf(StringUtils.capitalize(AgendaDateUtils.getDayNameFromDayAbbreviation(Collections.singletonList(day)))))
.toList();
recurrence = new Recurrence.WeeklyPattern(AgendaDateUtils.toDate(startDate),
eventRecurrence.getInterval(),
weekDays.toArray(new DayOfTheWeek[weekDays.size()]));
recurrence.setStartDate(AgendaDateUtils.toDate(startDate));
recurrence.setEndDate(AgendaDateUtils.toDate(endDate));
break;
case DAILY:
recurrence = new Recurrence.DailyPattern();
recurrence.setStartDate(AgendaDateUtils.toDate(startDate));
break;
default:
throw new IllegalStateException("Can't handle type: " + eventRecurrence.getType());
}
return recurrence;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;

import org.apache.ecs.html.Col;
import org.exoplatform.agenda.constant.EventRecurrenceFrequency;
import org.exoplatform.agenda.constant.EventRecurrenceType;
import org.exoplatform.agenda.model.Event;
import org.exoplatform.agenda.model.EventRecurrence;
import org.exoplatform.agenda.service.AgendaEventService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -49,13 +56,18 @@ public class ExchangeConnectorServiceImplTest {

private ExchangeConnectorStorage exchangeConnectorStorage;

private AgendaEventService agendaEventService;

@Before
public void setUp() throws Exception {
agendaRemoteEventService = mock(AgendaRemoteEventService.class);
exchangeConnectorStorage = mock(ExchangeConnectorStorage.class);
agendaEventService = mock(AgendaEventService.class);
exchangeService = PowerMockito.mock(ExchangeService.class);
PowerMockito.whenNew(ExchangeService.class).withArguments(any()).thenReturn(exchangeService);
exchangeConnectorService = new ExchangeConnectorServiceImpl(exchangeConnectorStorage, agendaRemoteEventService);
exchangeConnectorService = new ExchangeConnectorServiceImpl(exchangeConnectorStorage,
agendaRemoteEventService,
agendaEventService);
}

@Test
Expand Down Expand Up @@ -104,10 +116,71 @@ public void testCreateExchangeEvent() throws Exception {
eventEntity.setEnd(AgendaDateUtils.toRFC3339Date(endDate));
eventEntity.setRemoteProviderId(1);
eventEntity.setRemoteProviderName("agenda.exchangeCalendar");
Event event = new Event();
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);

// Then
verify(agendaRemoteEventService, times(1)).saveRemoteEvent(any());
EventRecurrence eventRecurrence = new EventRecurrence();
eventRecurrence.setType(EventRecurrenceType.DAILY);
eventRecurrence.setOverallStart(ZonedDateTime.now());
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(2)).saveRemoteEvent(any());

eventRecurrence.setType(EventRecurrenceType.WEEK_DAYS);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(3)).saveRemoteEvent(any());

eventRecurrence.setType(EventRecurrenceType.WEEKLY);
eventRecurrence.setByDay(Collections.singletonList("WE"));
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(4)).saveRemoteEvent(any());

eventRecurrence.setType(EventRecurrenceType.MONTHLY);
eventRecurrence.setByMonth(Collections.singletonList("1"));
eventRecurrence.setByMonthDay(Collections.singletonList("1"));
eventRecurrence.setInterval(1);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(5)).saveRemoteEvent(any());

eventRecurrence.setType(EventRecurrenceType.YEARLY);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(6)).saveRemoteEvent(any());

eventRecurrence.setType(EventRecurrenceType.CUSTOM);

eventRecurrence.setFrequency(EventRecurrenceFrequency.YEARLY);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(7)).saveRemoteEvent(any());

eventRecurrence.setFrequency(EventRecurrenceFrequency.MONTHLY);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(8)).saveRemoteEvent(any());

eventRecurrence.setFrequency(EventRecurrenceFrequency.WEEKLY);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(9)).saveRemoteEvent(any());

eventRecurrence.setFrequency(EventRecurrenceFrequency.DAILY);
event.setRecurrence(eventRecurrence);
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);
verify(agendaRemoteEventService, times(10)).saveRemoteEvent(any());
}

@Test
Expand Down Expand Up @@ -140,8 +213,9 @@ public void testUpdateExchangeEvent() throws Exception {
eventEntity.setEnd(AgendaDateUtils.toRFC3339Date(endDate));
eventEntity.setRemoteProviderId(1);
eventEntity.setRemoteProviderName("agenda.exchangeCalendar");
Event event = new Event();
when(agendaEventService.getEventById(eventEntity.getId())).thenReturn(event);
exchangeConnectorService.pushEventToExchange(1, eventEntity, dstTimeZone);

// Then
verify(appointment, times(1)).update(any(), any());
}
Expand Down
Loading