Java tutorial
/** * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig 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 org.jasig.schedassist.impl.caldav.integration; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import net.fortuna.ical4j.model.Calendar; import net.fortuna.ical4j.model.ComponentList; import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Parameter; import net.fortuna.ical4j.model.Property; import net.fortuna.ical4j.model.PropertyList; import net.fortuna.ical4j.model.component.VEvent; import net.fortuna.ical4j.model.parameter.PartStat; import net.fortuna.ical4j.model.property.Attendee; import net.fortuna.ical4j.model.property.DtStart; import net.fortuna.ical4j.model.property.RDate; import net.fortuna.ical4j.model.property.Summary; import net.fortuna.ical4j.model.property.Transp; import org.apache.commons.lang.time.DateUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.schedassist.ICalendarDataDao; import org.jasig.schedassist.SchedulingException; import org.jasig.schedassist.impl.caldav.CaldavCalendarDataDaoImpl; import org.jasig.schedassist.impl.caldav.CalendarWithURI; import org.jasig.schedassist.model.AppointmentRole; import org.jasig.schedassist.model.AvailabilityReflection; import org.jasig.schedassist.model.AvailableBlock; import org.jasig.schedassist.model.AvailableBlockBuilder; import org.jasig.schedassist.model.AvailableSchedule; import org.jasig.schedassist.model.CommonDateOperations; import org.jasig.schedassist.model.IEventUtils; import org.jasig.schedassist.model.InputFormatException; import org.jasig.schedassist.model.Preferences; import org.jasig.schedassist.model.SchedulingAssistantAppointment; import org.jasig.schedassist.model.VisitorLimit; import org.jasig.schedassist.model.mock.MockCalendarAccount; import org.jasig.schedassist.model.mock.MockDelegateCalendarAccount; import org.jasig.schedassist.model.mock.MockScheduleOwner; import org.jasig.schedassist.model.mock.MockScheduleVisitor; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Integration test for {@link CaldavCalendarDataDaoImpl}. * Depends on Spring applicationContext configuration "integration-test.xml". * * Note this test is specifically excluded from the maven surefire configuration * as it is dependent on a CalDAV Server and test accounts being provided. * * @author Nicholas Blair, npblair@wisc.edu * @version $Id: CaldavIntegrationTest.java 50 2011-05-05 21:07:25Z nblair $ */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:integration-test.xml" }) public class CaldavIntegrationTest { @Autowired private CaldavCalendarDataDaoImpl calendarDataDao; @Autowired private IEventUtils eventUtils; @Autowired @Qualifier("owner1") private MockCalendarAccount ownerCalendarAccount1; @Autowired @Qualifier("visitor1") private MockCalendarAccount visitorCalendarAccount1; @Autowired @Qualifier("visitor2") private MockCalendarAccount visitorCalendarAccount2; @Autowired @Qualifier("resource1") private MockDelegateCalendarAccount resourceCalendarAccount1; @Value("${caldav.reflectionEnabled:false}") private String reflectionEnabled; private Log log = LogFactory.getLog(this.getClass()); /** * Simple integration test to see if {@link ICalendarDataDao#getCalendar(org.jasig.schedassist.model.ICalendarAccount, Date, Date)} * returns data. * * Before you run this test for the first time, import the event below into ownerCalendarAccount1's personal calendar: * <pre> * src/test/resources/vevent-examples/example-non-scheduling-assistant-conflict.ics * </pre> * * This test will fail until the aforementioned event is imported into the ownerCalendarAccount1 personal calendar. * * @throws InputFormatException */ @Test public void testGetCalendar() throws InputFormatException { Date start = CommonDateOperations.parseDateTimePhrase("20110504-1300"); Date end = DateUtils.addHours(start, 1); log.info("getCalendar test, " + start + " to " + end + " for account " + ownerCalendarAccount1); Calendar calendar = calendarDataDao.getCalendar(ownerCalendarAccount1, start, end); Assert.assertNotNull(calendar); ComponentList events = calendar.getComponents(VEvent.VEVENT); Assert.assertEquals(1, events.size()); VEvent event = (VEvent) events.get(0); Summary summary = event.getSummary(); Assert.assertNotNull(summary); Assert.assertEquals("dentist appointment", summary.getValue()); } /** * Basic workflow integration test: * <ol> * <li>Create an individual appointment using mock owner and visitor ("owner1" and "visitor1")</li> * <li>Verify event retrieved via {@link ICalendarDataDao#getExistingAppointment(org.jasig.schedassist.model.IScheduleOwner, AvailableBlock)}</li> * <li>Verify event contains expected properties and parameters</li> * <li>Cancel appointment, verify removed</li> * </ol> */ @Test public void testCreateAndCancelIndividualAppointment() { // starts now Date start = DateUtils.truncate(new Date(), java.util.Calendar.MINUTE); Date end = DateUtils.addHours(start, 1); final DateTime ical4jstart = new DateTime(start); final DateTime ical4jend = new DateTime(end); AvailableBlock block = AvailableBlockBuilder.createBlock(start, end, 1); MockScheduleOwner owner1 = new MockScheduleOwner(ownerCalendarAccount1, 1); owner1.setPreference(Preferences.MEETING_PREFIX, "test appointment"); owner1.setPreference(Preferences.LOCATION, "meeting room 1a"); MockScheduleVisitor visitor1 = new MockScheduleVisitor(visitorCalendarAccount1); VEvent event = this.calendarDataDao.createAppointment(visitor1, owner1, block, "testCreateAndCancelIndividualAppointment"); Assert.assertNotNull(event); VEvent lookupResult = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNotNull(lookupResult); Assert.assertEquals(ical4jstart, lookupResult.getStartDate().getDate()); Assert.assertEquals(ical4jend, lookupResult.getEndDate().getDate()); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookupResult.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(1, Integer.parseInt(lookupResult.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(2, lookupResult.getProperties(Attendee.ATTENDEE).size()); Property visitorAttendee = this.eventUtils.getAttendeeForUserFromEvent(event, visitorCalendarAccount1); Assert.assertNotNull(visitorAttendee); Assert.assertEquals(AppointmentRole.VISITOR, visitorAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); Property ownerAttendee = this.eventUtils.getAttendeeForUserFromEvent(event, ownerCalendarAccount1); Assert.assertNotNull(ownerAttendee); Assert.assertEquals(AppointmentRole.OWNER, ownerAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); this.calendarDataDao.cancelAppointment(visitor1, owner1, event); VEvent lookupResultAfterCancel = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNull(lookupResultAfterCancel); } /** * Basic workflow integration test: * <ol> * <li>Create an individual appointment using mock resource and visitor ("resource1" and "visitor1")</li> * <li>Verify event retrieved via {@link ICalendarDataDao#getExistingAppointment(org.jasig.schedassist.model.IScheduleOwner, AvailableBlock)}</li> * <li>Verify event contains expected properties and parameters</li> * <li>Cancel appointment, verify removed</li> * </ol> */ @Test public void testCreateAndCancelIndividualAppointmentDelegateOwner() { // starts now Date start = DateUtils.truncate(new Date(), java.util.Calendar.MINUTE); Date end = DateUtils.addHours(start, 1); final DateTime ical4jstart = new DateTime(start); final DateTime ical4jend = new DateTime(end); AvailableBlock block = AvailableBlockBuilder.createBlock(start, end, 1); MockScheduleOwner owner1 = new MockScheduleOwner(resourceCalendarAccount1, 1); owner1.setPreference(Preferences.MEETING_PREFIX, "test resource appointment"); owner1.setPreference(Preferences.LOCATION, "meeting room 1a"); MockScheduleVisitor visitor1 = new MockScheduleVisitor(visitorCalendarAccount1); VEvent event = this.calendarDataDao.createAppointment(visitor1, owner1, block, "testCreateAndCancelIndividualAppointmentDelegateOwner"); Assert.assertNotNull(event); VEvent lookupResult = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNotNull(lookupResult); Assert.assertEquals(ical4jstart, lookupResult.getStartDate().getDate()); Assert.assertEquals(ical4jend, lookupResult.getEndDate().getDate()); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookupResult.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(1, Integer.parseInt(lookupResult.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(2, lookupResult.getProperties(Attendee.ATTENDEE).size()); Property visitorAttendee = this.eventUtils.getAttendeeForUserFromEvent(event, visitorCalendarAccount1); Assert.assertNotNull(visitorAttendee); Assert.assertEquals(AppointmentRole.VISITOR, visitorAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); Property ownerAttendee = this.eventUtils.getAttendeeForUserFromEvent(event, resourceCalendarAccount1); Assert.assertNotNull(ownerAttendee); Assert.assertEquals(AppointmentRole.OWNER, ownerAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); this.calendarDataDao.cancelAppointment(visitor1, owner1, event); VEvent lookupResultAfterCancel = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNull(lookupResultAfterCancel); } /** * Integration test to create and manipulate a group appointment. * <ol> * <li>Visitor1 creates group appointment with Owner1</li> * <li>Visitor2 joins same appointment</li> * <li>Visitor1 leaves same appointment</li> * <li>Visitor2 cancels appointment</li> * </ol> * * @throws SchedulingException */ @Test public void testGroupAppointmentWorkflow() { // start an hour from now to avoid conflicts with individual apppointment Date startDate = DateUtils.truncate(DateUtils.addHours(new Date(), 1), java.util.Calendar.MINUTE); Date endDate = DateUtils.addHours(startDate, 1); final DateTime ical4jstart = new DateTime(startDate); final DateTime ical4jend = new DateTime(endDate); AvailableBlock block = AvailableBlockBuilder.createBlock(startDate, endDate, 2); MockScheduleOwner owner1 = new MockScheduleOwner(ownerCalendarAccount1, 1); owner1.setPreference(Preferences.MEETING_PREFIX, "group appointment"); owner1.setPreference(Preferences.LOCATION, "meeting room 1b"); MockScheduleVisitor visitor1 = new MockScheduleVisitor(visitorCalendarAccount1); VEvent original = this.calendarDataDao.createAppointment(visitor1, owner1, block, "testGroupAppointmentWorkflow"); Assert.assertNotNull(original); VEvent lookup1 = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNotNull(lookup1); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookup1.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(2, Integer.parseInt(lookup1.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(2, lookup1.getProperties(Attendee.ATTENDEE).size()); Property visitorAttendee = this.eventUtils.getAttendeeForUserFromEvent(lookup1, visitor1.getCalendarAccount()); Assert.assertNotNull(visitorAttendee); Assert.assertEquals(AppointmentRole.VISITOR, visitorAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); Property ownerAttendee = this.eventUtils.getAttendeeForUserFromEvent(lookup1, owner1.getCalendarAccount()); Assert.assertNotNull(ownerAttendee); Assert.assertEquals(AppointmentRole.OWNER, ownerAttendee.getParameter(AppointmentRole.APPOINTMENT_ROLE)); Assert.assertEquals(ical4jstart, lookup1.getStartDate().getDate()); Assert.assertEquals(ical4jend, lookup1.getEndDate().getDate()); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookup1.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(2, Integer.parseInt(lookup1.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(2, lookup1.getProperties(Attendee.ATTENDEE).size()); MockScheduleVisitor visitor2 = new MockScheduleVisitor(visitorCalendarAccount2); // make 2nd visitor join try { this.calendarDataDao.joinAppointment(visitor2, owner1, lookup1); } catch (SchedulingException e) { Assert.fail("caught SchedulingException when visitor2 attempts join: " + e); } VEvent lookup2 = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNotNull(lookup2); Assert.assertEquals(ical4jstart, lookup2.getStartDate().getDate()); Assert.assertEquals(ical4jend, lookup2.getEndDate().getDate()); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookup2.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(2, Integer.parseInt(lookup2.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(3, lookup2.getProperties(Attendee.ATTENDEE).size()); PropertyList attendeeList = lookup2.getProperties(Attendee.ATTENDEE); for (Object o : attendeeList) { Attendee attendee = (Attendee) o; Parameter participationStatus = attendee.getParameter(PartStat.PARTSTAT); Assert.assertEquals(PartStat.ACCEPTED, participationStatus); if (AppointmentRole.OWNER.equals(attendee.getParameter(AppointmentRole.APPOINTMENT_ROLE))) { Assert.assertEquals("mailto:" + owner1.getCalendarAccount().getEmailAddress(), attendee.getValue()); } else if (AppointmentRole.VISITOR.equals(attendee.getParameter(AppointmentRole.APPOINTMENT_ROLE))) { String value = attendee.getValue(); if (value.equals("mailto:" + visitor1.getCalendarAccount().getEmailAddress()) || value.equals("mailto:" + visitor2.getCalendarAccount().getEmailAddress())) { // success } else { Assert.fail("unexpected visitor attendee value: " + value); } } } // now make visitor1 leave the appointment try { this.calendarDataDao.leaveAppointment(visitor1, owner1, lookup2); } catch (SchedulingException e) { Assert.fail("caught SchedulingException when visitor1 attempts leave: " + e); } VEvent lookup3 = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNotNull(lookup3); Assert.assertEquals(ical4jstart, lookup3.getStartDate().getDate()); Assert.assertEquals(ical4jend, lookup3.getEndDate().getDate()); Assert.assertEquals(SchedulingAssistantAppointment.TRUE, lookup3.getProperty(SchedulingAssistantAppointment.AVAILABLE_APPOINTMENT)); Assert.assertEquals(2, Integer.parseInt(lookup3.getProperty(VisitorLimit.VISITOR_LIMIT).getValue())); Assert.assertEquals(2, lookup3.getProperties(Attendee.ATTENDEE).size()); attendeeList = lookup3.getProperties(Attendee.ATTENDEE); for (Object o : attendeeList) { Attendee attendee = (Attendee) o; Parameter participationStatus = attendee.getParameter(PartStat.PARTSTAT); Assert.assertEquals(PartStat.ACCEPTED, participationStatus); if (AppointmentRole.OWNER.equals(attendee.getParameter(AppointmentRole.APPOINTMENT_ROLE))) { Assert.assertEquals("mailto:" + owner1.getCalendarAccount().getEmailAddress(), attendee.getValue()); } else if (AppointmentRole.VISITOR.equals(attendee.getParameter(AppointmentRole.APPOINTMENT_ROLE))) { String value = attendee.getValue(); if (value.equals("mailto:" + visitor2.getCalendarAccount().getEmailAddress())) { // success } else { Assert.fail("unexpected visitor attendee value: " + value); } } } this.calendarDataDao.cancelAppointment(visitor2, owner1, lookup3); VEvent lookupResultAfterCancel = this.calendarDataDao.getExistingAppointment(owner1, block); Assert.assertNull(lookupResultAfterCancel); } /** * Reflect an {@link AvailableSchedule} into the owner's account and verify expected behavior. * * @throws InputFormatException */ @Test public void testReflectAvailabilitySchedule() throws InputFormatException { System.setProperty("org.jasig.schedassist.impl.caldav.reflectionEnabled", reflectionEnabled); if (Boolean.parseBoolean(reflectionEnabled)) { MockScheduleOwner owner1 = new MockScheduleOwner(ownerCalendarAccount1, 1); Date start = CommonDateOperations.parseDatePhrase("20110919"); Date end = DateUtils.addDays(start, 12); Set<AvailableBlock> availableBlocks = AvailableBlockBuilder.createBlocks("9:00 AM", "3:00 PM", "MWF", start, end); AvailableSchedule schedule = new AvailableSchedule(availableBlocks); this.calendarDataDao.reflectAvailableSchedule(owner1, schedule); List<CalendarWithURI> results = this.calendarDataDao.peekAtAvailableScheduleReflections(owner1, start, end); Assert.assertEquals(1, results.size()); CalendarWithURI calendar = results.get(0); VEvent event = (VEvent) calendar.getCalendar().getComponent(VEvent.VEVENT); Assert.assertTrue(event.getProperties().contains(AvailabilityReflection.TRUE)); Assert.assertEquals("Available 9:00 AM - 3:00 PM", event.getSummary().getValue()); Assert.assertTrue(event.getProperties().contains(Transp.TRANSPARENT)); DtStart dtstart = event.getStartDate(); Assert.assertEquals(net.fortuna.ical4j.model.parameter.Value.DATE, dtstart.getParameter(net.fortuna.ical4j.model.parameter.Value.VALUE)); Assert.assertEquals("20110919", dtstart.getValue()); PropertyList rdates = event.getProperties(RDate.RDATE); Assert.assertEquals(5, rdates.size()); Set<String> rdateValues = new HashSet<String>(); for (Object o : rdates) { Property rdate = (Property) o; Assert.assertEquals(net.fortuna.ical4j.model.parameter.Value.DATE, rdate.getParameter(net.fortuna.ical4j.model.parameter.Value.VALUE)); rdateValues.add(rdate.getValue()); } Assert.assertTrue(rdateValues.contains("20110921")); Assert.assertTrue(rdateValues.contains("20110923")); Assert.assertTrue(rdateValues.contains("20110926")); Assert.assertTrue(rdateValues.contains("20110928")); Assert.assertTrue(rdateValues.contains("20110930")); this.calendarDataDao.purgeAvailableScheduleReflections(owner1, start, end); results = this.calendarDataDao.peekAtAvailableScheduleReflections(owner1, start, end); Assert.assertEquals(0, results.size()); } else { log.debug("testReflectAvailabilitySchedule disabled"); } } }