[CalendarServer-changes] [14658] CalendarServer/trunk/txdav

source_changes at macosforge.org source_changes at macosforge.org
Fri Apr 3 15:47:43 PDT 2015


Revision: 14658
          http://trac.calendarserver.org//changeset/14658
Author:   sagen at apple.com
Date:     2015-04-03 15:47:43 -0700 (Fri, 03 Apr 2015)
Log Message:
-----------
When recovering an organizer's event with group attendees from the trash, re-link the event to the group reconciliation mechanism (since it's severed whilst in the trash)

Modified Paths:
--------------
    CalendarServer/trunk/txdav/caldav/datastore/sql.py
    CalendarServer/trunk/txdav/who/test/test_group_attendees.py

Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py	2015-04-03 18:57:04 UTC (rev 14657)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py	2015-04-03 22:47:43 UTC (rev 14658)
@@ -5120,11 +5120,19 @@
                     # original resource is the ongoing one,
                     # the new resource is the past one
 
-                    # Update the attendee's copy of the ongoing one
-                    yield ImplicitScheduler().refreshAllAttendeesExceptSome(
-                        self._txn,
-                        self,
-                    )
+                    caldata = yield self.componentForUser() # again, now that we've split
+                    if (yield self.reconcileGroupAttendees(caldata)):
+                        # changed
+                        yield self._setComponentInternal(
+                            caldata, inserting=True, updateSelf=True
+                        )
+
+                    else:
+                        # Update the attendee's copy of the ongoing one
+                        yield ImplicitScheduler().refreshAllAttendeesExceptSome(
+                            self._txn,
+                            self,
+                        )
                 else:
                     if fullyInFuture:
                         log.debug("Scheduled event being recovered by organizer from trash, fully in the future")

Modified: CalendarServer/trunk/txdav/who/test/test_group_attendees.py
===================================================================
--- CalendarServer/trunk/txdav/who/test/test_group_attendees.py	2015-04-03 18:57:04 UTC (rev 14657)
+++ CalendarServer/trunk/txdav/who/test/test_group_attendees.py	2015-04-03 22:47:43 UTC (rev 14658)
@@ -1755,3 +1755,211 @@
         comp = yield cobjs[0].componentForUser()
         self.assertTrue("STATUS:CANCELLED" in str(comp))
         yield self.commit()
+
+
+    @inlineCallbacks
+    def test_groupAttendeesWhenFullyInFutureEventInTrash(self):
+        """
+        Test that group attendee link is severed while an event is in the trash
+        and is relinked when recovered.  In this case, the event only has
+        instances in the future.
+        """
+
+        from twistedcaldav.stdconfig import config
+        self.patch(config, "EnableTrashCollection", True)
+
+        data_put_1 = """BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART:20240101T100000Z
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ORGANIZER:MAILTO:user02 at example.com
+ATTENDEE:mailto:user02 at example.com
+ATTENDEE:MAILTO:group01 at example.com
+END:VEVENT
+END:VCALENDAR"""
+
+        data_get_2 = """BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event1 at ninevah.local
+DTSTART:20240101T100000Z
+DURATION:PT1H
+ATTENDEE;CN=User 02;EMAIL=user02 at example.com;RSVP=TRUE:urn:x-uid:user02
+ATTENDEE;CN=Group 01;CUTYPE=X-SERVER-GROUP;EMAIL=group01 at example.com;SCHEDULE-STATUS=2.7:urn:x-uid:group01
+ATTENDEE;CN=User 01;EMAIL=user01 at example.com;MEMBER="urn:x-uid:group01";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:x-uid:user01
+CREATED:20060101T150000Z
+ORGANIZER;CN=User 02;EMAIL=user02 at example.com:urn:x-uid:user02
+SUMMARY:event 1
+END:VEVENT
+END:VCALENDAR
+"""
+
+        groupCacher = GroupCacher(self.transactionUnderTest().directoryService())
+
+        calendar = yield self.calendarUnderTest(name="calendar", home="user02")
+        vcalendar = Component.fromString(data_put_1)
+        yield calendar.createCalendarObjectWithName("data1.ics", vcalendar)
+
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        self.assertEqual(list(groupsToRefresh)[0], "group01")
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 1)
+        yield self.commit()
+
+        yield groupCacher.refreshGroup(self.transactionUnderTest(), "group01")
+        yield self.commit()
+        yield JobItem.waitEmpty(self._sqlCalendarStore.newTransaction, reactor, 60)
+
+        cobj = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user02")
+        vcalendar = yield cobj.component()
+        self.assertEqual(normalize_iCalStr(vcalendar), normalize_iCalStr(data_get_2))
+
+        yield self._verifyObjectResourceCount("user01", 1)
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        yield self.commit()
+
+        cobj = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user02")
+        yield cobj.remove()
+        yield self.commit()
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 0)
+        yield self.commit()
+
+        # With the event in the trash, the group will not be refreshed
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 0)
+        yield self.commit()
+
+        home = yield self.homeUnderTest(name="user02")
+        trash = yield home.getTrash()
+        names = yield trash.listObjectResources()
+        cobj = yield trash.calendarObjectWithName(names[0])
+        yield cobj.fromTrash()
+        yield self.commit()
+
+        # With the event recovered from the trash, the group will be refreshed
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        yield self.commit()
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 1)
+        yield self.commit()
+
+
+    @inlineCallbacks
+    def test_groupAttendeesWhenSplitEventInTrash(self):
+        """
+        Test that group attendee link is severed while an event is in the trash
+        and is relinked when recovered.  In this case, the event has instances
+        in the past and future.
+        """
+
+        from twistedcaldav.stdconfig import config
+        self.patch(config, "EnableTrashCollection", True)
+
+        data_put_1 = """BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART:20140101T100000Z
+RRULE:FREQ=DAILY
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ORGANIZER:MAILTO:user02 at example.com
+ATTENDEE:mailto:user02 at example.com
+ATTENDEE:MAILTO:group01 at example.com
+END:VEVENT
+END:VCALENDAR"""
+
+        data_get_2 = """BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event1 at ninevah.local
+DTSTART:20140101T100000Z
+DURATION:PT1H
+ATTENDEE;CN=User 02;EMAIL=user02 at example.com;RSVP=TRUE:urn:x-uid:user02
+ATTENDEE;CN=Group 01;CUTYPE=X-SERVER-GROUP;EMAIL=group01 at example.com;SCHEDULE-STATUS=2.7:urn:x-uid:group01
+ATTENDEE;CN=User 01;EMAIL=user01 at example.com;MEMBER="urn:x-uid:group01";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:x-uid:user01
+CREATED:20060101T150000Z
+ORGANIZER;CN=User 02;EMAIL=user02 at example.com:urn:x-uid:user02
+RRULE:FREQ=DAILY
+SUMMARY:event 1
+END:VEVENT
+END:VCALENDAR
+"""
+
+        groupCacher = GroupCacher(self.transactionUnderTest().directoryService())
+
+        calendar = yield self.calendarUnderTest(name="calendar", home="user02")
+        vcalendar = Component.fromString(data_put_1)
+        yield calendar.createCalendarObjectWithName("data1.ics", vcalendar)
+
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        self.assertEqual(list(groupsToRefresh)[0], "group01")
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 1)
+        yield self.commit()
+
+        yield groupCacher.refreshGroup(self.transactionUnderTest(), "group01")
+        yield self.commit()
+        yield JobItem.waitEmpty(self._sqlCalendarStore.newTransaction, reactor, 60)
+
+        cobj = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user02")
+        vcalendar = yield cobj.component()
+        self.assertEqual(normalize_iCalStr(vcalendar), normalize_iCalStr(data_get_2))
+
+        yield self._verifyObjectResourceCount("user01", 1)
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        yield self.commit()
+
+        cobj = yield self.calendarObjectUnderTest(name="data1.ics", calendar_name="calendar", home="user02")
+        yield cobj.remove()
+        yield self.commit()
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 0)
+        yield self.commit()
+
+        # With the event in the trash, the group will not be refreshed
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 0)
+        yield self.commit()
+
+        home = yield self.homeUnderTest(name="user02")
+        trash = yield home.getTrash()
+        names = yield trash.listObjectResources()
+        cobj = yield trash.calendarObjectWithName(names[0])
+        yield cobj.fromTrash()
+        yield self.commit()
+
+        # With the event recovered from the trash, the group will be refreshed
+        groupsToRefresh = yield groupCacher.groupsToRefresh(self.transactionUnderTest())
+        self.assertEqual(len(groupsToRefresh), 1)
+        yield self.commit()
+
+        rows = yield self.transactionUnderTest().execSQL("select * from group_attendee", [])
+        self.assertEquals(len(rows), 1)
+        yield self.commit()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150403/c3d17adb/attachment.html>


More information about the calendarserver-changes mailing list