/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.jasig.portlet.calendar.adapter; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.microsoft.exchange.messages.GetUserAvailabilityResponse; import com.microsoft.exchange.types.CalendarEventDetails; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; import javax.portlet.PortletRequest; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import net.fortuna.ical4j.model.component.VEvent; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.portlet.calendar.CalendarConfiguration; import org.jasig.portlet.calendar.VEventStartComparator; import org.jasig.portlet.calendar.adapter.exchange.IExchangeCredentialsInitializationService; import org.jasig.portlet.calendar.caching.ICacheKeyGenerator; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Interval; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.ws.client.core.WebServiceMessageCallback; import org.springframework.ws.client.core.WebServiceOperations; /** * @author Jen Bourey, jbourey@unicon.net * @version $Revision$ */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/exchangeTestContext.xml") public class ExchangeCalendarAdapterTest { protected final Log log = LogFactory.getLog(getClass()); @Autowired(required = true) ApplicationContext applicationContext; @Autowired(required = true) Jaxb2Marshaller marshaller; @Autowired(required = true) Cache cache; @Mock CalendarConfiguration config; @Mock WebServiceOperations webService; @Mock PortletRequest request; @Mock ICacheKeyGenerator keyGenerator; @Mock IExchangeCredentialsInitializationService credentialsService; ExchangeCalendarAdapter adapter = new ExchangeCalendarAdapter(); String user = "user1"; Resource sampleExchangeResponse; Interval interval; @Before public void setUp() throws IOException { MockitoAnnotations.initMocks(this); adapter.setWebServiceOperations(webService); adapter.setCache(cache); adapter.setCredentialsService(credentialsService); adapter.setCacheKeyGenerator(keyGenerator); sampleExchangeResponse = applicationContext.getResource("classpath:/sampleExchangeResponse.xml"); when(keyGenerator.getKey( any(CalendarConfiguration.class), any(Interval.class), any(PortletRequest.class), anyString())) .thenReturn("key"); when(credentialsService.getNtlmDomain(request)).thenReturn("ed.ac.uk"); when(credentialsService.usesExchangeImpersonation(request)).thenReturn(false); when(credentialsService.getImpersonatedAccountId(request)).thenReturn(null); Map<String, String> userInfo = new HashMap<String, String>(); userInfo.put("user.login.id", user); userInfo.put("mail", "foo@mail.edu"); when(request.getAttribute(PortletRequest.USER_INFO)).thenReturn(userInfo); DateTime start = new DateTime(2010, 10, 1, 0, 0, DateTimeZone.UTC); interval = new Interval(start, start.plusMonths(1)); Source source = new StreamSource(sampleExchangeResponse.getInputStream()); GetUserAvailabilityResponse response = (GetUserAvailabilityResponse) marshaller.unmarshal(source); when(webService.marshalSendAndReceive(any(), any(WebServiceMessageCallback.class))) .thenReturn(response); } // Test commented out because it works, but it causes failures in whatever test runs after it for some reason. // @Test public void testCache() throws DatatypeConfigurationException { Cache cacheSpy = spy(cache); adapter.setCache(cacheSpy); adapter.getEvents(config, interval, request); Element cachedItem = cacheSpy.get("key"); adapter.getEvents(config, interval, request); verify(cacheSpy, times(3)).get("key"); verify(cacheSpy, times(1)).put(cachedItem); cacheSpy = null; adapter.setCache(cache); } @Test public void testRetrieveEvents() throws IOException, DatatypeConfigurationException { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); List<VEvent> events = new ArrayList<VEvent>(); events.addAll(adapter.getEvents(config, interval, request).getEvents()); Collections.sort(events, new VEventStartComparator()); assertEquals(2, events.size()); VEvent event = events.get(0); assertEquals("Eat Lunch", event.getSummary().getValue()); assertEquals("Somewhere Tasty", event.getLocation().getValue()); cal.setTimeInMillis(event.getStartDate().getDate().getTime()); assertEquals(cal.get(Calendar.YEAR), 2010); assertEquals(cal.get(Calendar.MONTH), 10); assertEquals(cal.get(Calendar.DATE), 16); assertEquals(cal.get(Calendar.HOUR_OF_DAY), 12); assertEquals(cal.get(Calendar.MINUTE), 0); cal.setTimeInMillis(event.getEndDate().getDate().getTime()); assertEquals(cal.get(Calendar.YEAR), 2010); assertEquals(cal.get(Calendar.MONTH), 10); assertEquals(cal.get(Calendar.DATE), 16); assertEquals(cal.get(Calendar.HOUR_OF_DAY), 13); assertEquals(cal.get(Calendar.MINUTE), 0); event = events.get(1); assertEquals("Wake Up", event.getSummary().getValue()); assertNull(event.getLocation()); cal.setTimeInMillis(event.getStartDate().getDate().getTime()); assertEquals(cal.get(Calendar.HOUR_OF_DAY), 7); cal.setTimeInMillis(event.getStartDate().getDate().getTime()); assertEquals(cal.get(Calendar.YEAR), 2010); assertEquals(cal.get(Calendar.MONTH), 10); assertEquals(cal.get(Calendar.DATE), 18); assertEquals(cal.get(Calendar.HOUR_OF_DAY), 7); assertEquals(cal.get(Calendar.MINUTE), 0); } @Test public void testGetInternalEvent() throws DatatypeConfigurationException { com.microsoft.exchange.types.CalendarEvent msEvent = new com.microsoft.exchange.types.CalendarEvent(); // set the test event start time to 4AM on November 1, 2010 DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); XMLGregorianCalendar start = datatypeFactory.newXMLGregorianCalendar(); start.setYear(2010); start.setMonth(11); start.setDay(1); start.setTime(4, 0, 0, 0); msEvent.setStartTime(start); // set the test event end time to 5AM on November 1, 2010 XMLGregorianCalendar end = datatypeFactory.newXMLGregorianCalendar(); end.setYear(2010); end.setMonth(12); end.setDay(1); end.setTime(5, 0, 0, 0); msEvent.setEndTime(end); // set the event tname and location CalendarEventDetails details = new CalendarEventDetails(); details.setSubject("Naptime"); details.setLocation("My house"); msEvent.setCalendarEventDetails(details); // transform the Microsoft calendar event into a calendar portlet event VEvent event = adapter.getInternalEvent(3, msEvent); // ensure the calendar id, summary, and location are all set correctly assertEquals("Naptime", event.getSummary().getValue()); assertEquals("My house", event.getLocation().getValue()); // check the start time Calendar cal = Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC")); cal.setTimeInMillis(event.getStartDate().getDate().getTime()); assertEquals(4, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(java.util.TimeZone.getTimeZone("UTC"), cal.getTimeZone()); assertTrue(event.getStartDate().isUtc()); assertNull(event.getStartDate().getTimeZone()); // check the end time cal.setTimeInMillis(event.getEndDate().getDate().getTime()); assertEquals(5, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(java.util.TimeZone.getTimeZone("UTC"), cal.getTimeZone()); assertTrue(event.getEndDate().isUtc()); assertNull(event.getEndDate().getTimeZone()); } @Test public void testGetXmlDate() throws DatatypeConfigurationException { // construct a calendar representing 4:30PM on June 4, 2010 DateTime date = new DateTime(2010, 6, 3, 16, 30, DateTimeZone.UTC); XMLGregorianCalendar xmlCal = adapter.getXmlDate(date); assertEquals(2010, xmlCal.getYear()); assertEquals(6, xmlCal.getMonth()); assertEquals(3, xmlCal.getDay()); assertEquals(16, xmlCal.getHour()); assertEquals(30, xmlCal.getMinute()); assertEquals(0, xmlCal.getSecond()); assertEquals(0, xmlCal.getFractionalSecond().intValue()); } }