/** * See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Board of Regents of the University of Wisconsin System * 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: * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 com.microsoft.exchange.integration; import static org.junit.Assert.*; import java.util.GregorianCalendar; import java.util.Set; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.XMLGregorianCalendar; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.support.DataAccessUtils; import com.ibm.icu.util.TimeZone; import com.microsoft.exchange.DateHelp; import com.microsoft.exchange.ExchangeWebServices; import com.microsoft.exchange.exception.ExchangeWebServicesRuntimeException; import com.microsoft.exchange.impl.BaseExchangeCalendarDataDao; import com.microsoft.exchange.impl.RequestServerTimeZoneInterceptor; import com.microsoft.exchange.types.CalendarItemType; import com.microsoft.exchange.types.ItemIdType; import edu.emory.mathcs.backport.java.util.Collections; public class TimeZoneIntegrationTest { String upn = "ctcudd@wisctest.wisc.edu"; String badTimeZoneID ="Asia/Gaza"; protected final Log log = LogFactory.getLog(this.getClass()); /** * A timezone with no Windows equivalant is set before initalization. * This causes {@link RequestServerTimeZoneInterceptor} to set the default {@link TimeZone} to UTC * AND sets {@link RequestServerTimeZoneInterceptor}.windowsID to UTC */ @Test public void unmappableTimeZoneTest(){ TimeZone badTimeZone = TimeZone.getTimeZone(badTimeZoneID); TimeZone.setDefault(badTimeZone); assertEquals(TimeZone.getDefault(), badTimeZone); ApplicationContext context = new ClassPathXmlApplicationContext("classpath:test-contexts/exchangeContext.xml"); RequestServerTimeZoneInterceptor timeZoneInterceptor = context.getBean(RequestServerTimeZoneInterceptor.class); assertEquals(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID, TimeZone.getDefault().getID()); assertEquals(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID, timeZoneInterceptor.getWindowsTimeZoneID()); } @Test public void badTimeZoneContextTest() throws DatatypeConfigurationException{ TimeZone badTimeZone = TimeZone.getTimeZone(badTimeZoneID); TimeZone.setDefault(badTimeZone); assertEquals(TimeZone.getDefault(), badTimeZone); ApplicationContext context = new ClassPathXmlApplicationContext("classpath:test-contexts/exchangeContext.xml"); RequestServerTimeZoneInterceptor timeZoneInterceptor = context.getBean(RequestServerTimeZoneInterceptor.class); assertEquals(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID, TimeZone.getDefault().getID()); assertEquals(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID, timeZoneInterceptor.getWindowsTimeZoneID()); //time zone currently set to utc, create a date using default time zone XMLGregorianCalendar now = DateHelp.getXMLGregorianCalendarNow(); //change the default time zone, so the RequestServerTimeZoneInterceptor is out of sync with default time zone. TimeZone.setDefault(badTimeZone); ExchangeWebServices ews = context.getBean(ExchangeWebServices.class); BaseExchangeCalendarDataDao exchangeCalendarDao = context.getBean(BaseExchangeCalendarDataDao.class); exchangeCalendarDao.setWebServices(ews); //attempt an ews call, which should fail... try{ exchangeCalendarDao.getCalendarFolderMap("ctcudd@wisctest.wisc.edu"); fail("exchangeCalendarDao should have thrown exception..."); }catch(ExchangeWebServicesRuntimeException e){} //change timezone back and call should now succed TimeZone.setDefault(TimeZone.getTimeZone(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID)); exchangeCalendarDao.getCalendarFolderMap(upn); } @Test public void createGetDeleteCalendarItem() throws DatatypeConfigurationException{ TimeZone utcTimeZone = TimeZone.getTimeZone(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID); TimeZone.setDefault(utcTimeZone); ApplicationContext context = new ClassPathXmlApplicationContext("classpath:test-contexts/exchangeContext.xml"); RequestServerTimeZoneInterceptor timeZoneInterceptor = context.getBean(RequestServerTimeZoneInterceptor.class); ExchangeWebServices ews = context.getBean(ExchangeWebServices.class); BaseExchangeCalendarDataDao exchangeCalendarDao = context.getBean(BaseExchangeCalendarDataDao.class); exchangeCalendarDao.setWebServices(ews); assertEquals(TimeZone.getDefault(), utcTimeZone); //XMLGregorianCalendar is sortof backed by a gregorian calendar, date/times should reflect default jvm timezone XMLGregorianCalendar xmlStart = DateHelp.getXMLGregorianCalendarNow(); CalendarItemType calendarItem = new CalendarItemType(); calendarItem.setStart(xmlStart); ItemIdType itemId = exchangeCalendarDao.createCalendarItem(upn, calendarItem); assertNotNull(itemId); Set<ItemIdType> itemIds = Collections.singleton(itemId); Set<CalendarItemType> calendarItems = exchangeCalendarDao.getCalendarItems(upn, itemIds); assertNotNull(calendarItems); CalendarItemType createdCalendarItem = DataAccessUtils.singleResult(calendarItems); assertNotNull(createdCalendarItem); XMLGregorianCalendar createdCalendarItemStart = createdCalendarItem.getStart(); assertNotNull(createdCalendarItemStart); assertEquals(xmlStart.getTimezone(), createdCalendarItemStart.getTimezone()); //nope! tzDisplayName = createdCalendarItem.getTimeZone() //assertEquals(RequestServerTimeZoneInterceptor.FALLBACK_TIMEZONE_ID, createdCalendarItem.getTimeZone()); assertEquals(xmlStart.getEon(), createdCalendarItemStart.getEon()); assertEquals(xmlStart.getEonAndYear(), createdCalendarItemStart.getEonAndYear()); assertEquals(xmlStart.getYear(), createdCalendarItemStart.getYear()); assertEquals(xmlStart.getMonth(), createdCalendarItemStart.getMonth()); assertEquals(xmlStart.getDay(), createdCalendarItemStart.getDay()); assertEquals(xmlStart.getHour(), createdCalendarItemStart.getHour()); assertEquals(xmlStart.getMinute(), createdCalendarItemStart.getMinute()); assertEquals(xmlStart.getSecond(), createdCalendarItemStart.getSecond()); //nope! always seems to be a slight variation //assertEquals(xmlStart.toGregorianCalendar().getTimeInMillis(), createdCalendarItemStart.toGregorianCalendar().getTimeInMillis()); //assertEquals(xmlStart.getMillisecond(), createdCalendarItemStart.getMillisecond()); //assertEquals(xmlStart.getFractionalSecond(), createdCalendarItemStart.getFractionalSecond()); assertTrue(DateHelp.withinOneSecond(xmlStart, createdCalendarItemStart)); assertTrue(exchangeCalendarDao.deleteCalendarItems(upn, itemIds)); } @Test public void createGetDeleteCalendarItemBadTimeZone() throws DatatypeConfigurationException{ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:test-contexts/exchangeContext.xml"); RequestServerTimeZoneInterceptor timeZoneInterceptor = context.getBean(RequestServerTimeZoneInterceptor.class); ExchangeWebServices ews = context.getBean(ExchangeWebServices.class); BaseExchangeCalendarDataDao exchangeCalendarDao = context.getBean(BaseExchangeCalendarDataDao.class); exchangeCalendarDao.setWebServices(ews); //XMLGregorianCalendar is sortof backed by a gregorian calendar, date/times should reflect default jvm timezone XMLGregorianCalendar xmlStart = DateHelp.getXMLGregorianCalendarNow(java.util.TimeZone.getTimeZone("Pacific/Palau")); CalendarItemType calendarItem = new CalendarItemType(); calendarItem.setStart(xmlStart); ItemIdType itemId = exchangeCalendarDao.createCalendarItem(upn, calendarItem); assertNotNull(itemId); Set<ItemIdType> itemIds = Collections.singleton(itemId); Set<CalendarItemType> calendarItems = exchangeCalendarDao.getCalendarItems(upn, itemIds); assertNotNull(calendarItems); CalendarItemType createdCalendarItem = DataAccessUtils.singleResult(calendarItems); assertNotNull(createdCalendarItem); XMLGregorianCalendar createdCalendarItemStart = createdCalendarItem.getStart(); assertNotNull(createdCalendarItemStart); //because the XMLGregorian calnedar was created with a time zone other than system default assertFalse(xmlStart.getTimezone() == createdCalendarItemStart.getTimezone()); assertTrue(DateHelp.withinOneSecond(xmlStart, createdCalendarItemStart)); assertTrue(exchangeCalendarDao.deleteCalendarItems(upn, itemIds)); } }