[CalendarServer-changes] [4365] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Jun 22 12:08:51 PDT 2009


Revision: 4365
          http://trac.macosforge.org/projects/calendarserver/changeset/4365
Author:   cdaboo at apple.com
Date:     2009-06-22 12:08:51 -0700 (Mon, 22 Jun 2009)
Log Message:
-----------
Be more tolerant of bad data in iTIP messages. SCHEDULE-STATUS value is only the status code not description.

Modified Paths:
--------------
    CalendarServer/trunk/run
    CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
    CalendarServer/trunk/twistedcaldav/scheduling/itip.py
    CalendarServer/trunk/twistedcaldav/scheduling/processing.py
    CalendarServer/trunk/twistedcaldav/scheduling/test/test_itip.py
    CalendarServer/trunk/twistedcaldav/test/test_icalendar.py

Modified: CalendarServer/trunk/run
===================================================================
--- CalendarServer/trunk/run	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/run	2009-06-22 19:08:51 UTC (rev 4365)
@@ -727,7 +727,7 @@
 
 caldavtester="${top}/CalDAVTester";
 
-svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 4358;
+svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 4364;
 
 #
 # PyFlakes

Modified: CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2009-06-22 19:08:51 UTC (rev 4365)
@@ -740,7 +740,7 @@
             # Now apply to each ATTENDEE/ORGANIZER in the original data
             self.calendar.setParameterToValueForPropertyWithValue(
                 "SCHEDULE-STATUS",
-                status,
+                status.split(";")[0],
                 "ATTENDEE" if is_organizer else "ORGANIZER",
                 recipient)
 

Modified: CalendarServer/trunk/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/itip.py	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/twistedcaldav/scheduling/itip.py	2009-06-22 19:08:51 UTC (rev 4365)
@@ -277,9 +277,10 @@
         rids = set()
         if new_master:
             attendee, partstat, private_comment = iTipProcessing.updateAttendeeData(new_master, old_master)
-            attendees.add(attendee)
-            if partstat or private_comment:
-                rids.add(("", partstat, private_comment,))
+            if attendee:
+                attendees.add(attendee)
+                if partstat or private_comment:
+                    rids.add(("", partstat, private_comment,))
 
         # Now do all overridden ones (sort by RECURRENCE-ID)
         sortedComponents = []
@@ -309,12 +310,20 @@
                     continue
 
             attendee, partstat, private_comment = iTipProcessing.updateAttendeeData(itip_component, match_component)
-            attendees.add(attendee)
-            if rids is not None and (partstat or private_comment):
-                rids.add((toString(rid), partstat, private_comment,))
+            if attendee:
+                attendees.add(attendee)
+                if rids is not None and (partstat or private_comment):
+                    rids.add((toString(rid), partstat, private_comment,))
 
-        assert len(attendees) == 1, "ATTENDEE property in a REPLY must be the same in all components\n%s" % (str(itip_message),)
-        return True, (attendees.pop(), rids)
+        # Check for an invalid instance by itself
+        len_attendees = len(attendees)
+        if len_attendees == 0:
+            return False, None
+        elif len_attendees == 1:
+            return True, (attendees.pop(), rids)
+        else:
+            log.error("ATTENDEE property in a REPLY must be the same in all components\n%s" % (str(itip_message),))
+            return False, None
 
     @staticmethod
     def updateAttendeeData(from_component, to_component):
@@ -334,15 +343,17 @@
 
         # Get REQUEST-STATUS as we need to write that into the saved ATTENDEE property
         reqstatus = tuple(from_component.properties("REQUEST-STATUS"))
-        assert len(reqstatus) <= 1, "There must be zero or REQUEST-STATUS properties in a REPLY\n%s" % (str(from_component),)
         if reqstatus:
-            reqstatus = ";".join(reqstatus[0].value()[0:2])
+            reqstatus = ",".join(status.value()[0] for status in reqstatus)
         else:
-            reqstatus = iTIPRequestStatus.SUCCESS
+            reqstatus = "2.0"
 
         # Get attendee in from_component - there MUST be only one
         attendees = tuple(from_component.properties("ATTENDEE"))
-        assert len(attendees) == 1, "There must be one and only one ATTENDEE property in a REPLY\n%s" % (str(from_component),)
+        if len(attendees) != 1:
+            log.error("There must be one and only one ATTENDEE property in a REPLY\n%s" % (str(from_component),))
+            return None, False, False
+
         attendee = attendees[0]
         partstat = attendee.params().get("PARTSTAT", ("NEEDS-ACTION",))[0]
         
@@ -372,7 +383,9 @@
                 private_comments = tuple(to_component.properties("X-CALENDARSERVER-ATTENDEE-COMMENT"))
                 for comment in private_comments:
                     params = comment.params()["X-CALENDARSERVER-ATTENDEE-REF"]
-                    assert len(params) == 1, "Must be one and only one X-CALENDARSERVER-ATTENDEE-REF parameter in X-CALENDARSERVER-ATTENDEE-COMMENT"
+                    if len(params) != 1:
+                        log.error("Must be one and only one X-CALENDARSERVER-ATTENDEE-REF parameter in X-CALENDARSERVER-ATTENDEE-COMMENT")
+                        params = (None,)
                     param = params[0]
                     if param == attendee.value():
                         private_comment = comment
@@ -656,9 +669,13 @@
     String constants for various iTIP status codes we use.
     """
     
-    MESSAGE_PENDING         = "1.0;Scheduling message send is pending"
-    MESSAGE_SENT            = "1.1;Scheduling message has been sent"
-    MESSAGE_DELIVERED       = "1.2;Scheduling message has been delivered"
+    MESSAGE_PENDING_CODE    = "1.0"
+    MESSAGE_SENT_CODE       = "1.1"
+    MESSAGE_DELIVERED_CODE  = "1.2"
+
+    MESSAGE_PENDING         = MESSAGE_PENDING_CODE + ";Scheduling message send is pending"
+    MESSAGE_SENT            = MESSAGE_SENT_CODE + ";Scheduling message has been sent"
+    MESSAGE_DELIVERED       = MESSAGE_DELIVERED_CODE + ";Scheduling message has been delivered"
     
     SUCCESS                 = "2.0;Success"
 

Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2009-06-22 19:08:51 UTC (rev 4365)
@@ -564,7 +564,7 @@
             
         # Fake a SCHEDULE-STATUS on the ORGANIZER property
         if made_changes:
-            calendar.setParameterToValueForPropertyWithValue("SCHEDULE-STATUS", iTIPRequestStatus.MESSAGE_DELIVERED, "ORGANIZER", None)
+            calendar.setParameterToValueForPropertyWithValue("SCHEDULE-STATUS", iTIPRequestStatus.MESSAGE_DELIVERED_CODE, "ORGANIZER", None)
         
         returnValue((made_changes, partstat,))
 

Modified: CalendarServer/trunk/twistedcaldav/scheduling/test/test_itip.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/test/test_itip.py	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/twistedcaldav/scheduling/test/test_itip.py	2009-06-22 19:08:51 UTC (rev 4365)
@@ -62,12 +62,13 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False),),
             ),
             (
                 "#1.2 Simple component, accepted",
@@ -102,12 +103,13 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False),),
             ),
             (
                 "#1.3 Simple component, no change",
@@ -142,12 +144,13 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (),
             ),
             (
                 "#2.1 Recurring component, change master/override",
@@ -198,7 +201,7 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 RRULE:FREQ=MONTHLY
@@ -208,12 +211,13 @@
 RECURRENCE-ID:20080801T120000Z
 DTSTART:20080801T123000Z
 DTEND:20080801T133000Z
-ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False), ("20080801T120000Z", True, False),),
             ),
             (
                 "#2.2 Recurring component, change master only",
@@ -258,7 +262,7 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 RRULE:FREQ=MONTHLY
@@ -274,6 +278,7 @@
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False),),
             ),
             (
                 "#2.3 Recurring component, change override only",
@@ -329,12 +334,13 @@
 RECURRENCE-ID:20080801T120000Z
 DTSTART:20080801T123000Z
 DTEND:20080801T133000Z
-ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("20080801T120000Z", True, False),),
             ),
             (
                 "#3.1 Recurring component, change master/override, new override",
@@ -391,7 +397,7 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 RRULE:FREQ=MONTHLY
@@ -401,7 +407,7 @@
 RECURRENCE-ID:20080801T120000Z
 DTSTART:20080801T123000Z
 DTEND:20080801T133000Z
-ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
@@ -410,12 +416,13 @@
 RECURRENCE-ID:20080901T120000Z
 DTSTART:20080901T120000Z
 DTEND:20080901T130000Z
-ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False), ("20080801T120000Z", True, False), ("20080901T120000Z", True, False),),
             ),
             (
                 "#3.2 Recurring component, change master, new override",
@@ -466,7 +473,7 @@
 UID:12345-67890
 DTSTART:20080601T120000Z
 DTEND:20080601T130000Z
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 RRULE:FREQ=MONTHLY
@@ -485,12 +492,13 @@
 RECURRENCE-ID:20080901T120000Z
 DTSTART:20080901T120000Z
 DTEND:20080901T130000Z
-ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("", True, False), ("20080901T120000Z", True, False),),
             ),
             (
                 "#3.3 Recurring component, change override, new override",
@@ -552,7 +560,7 @@
 RECURRENCE-ID:20080801T120000Z
 DTSTART:20080801T123000Z
 DTEND:20080801T133000Z
-ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
@@ -561,19 +569,260 @@
 RECURRENCE-ID:20080901T120000Z
 DTSTART:20080901T120000Z
 DTEND:20080901T130000Z
-ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS="2.0;Success":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=TENTATIVE;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
 ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
 ORGANIZER;CN=User 01:mailto:user1 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
+                True, "mailto:user1 at example.com", (("20080801T120000Z", True, False), ("20080901T120000Z", True, False),),
             ),
+            (
+                "#4.1 Recurring component, invalid override",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+RRULE:FREQ=MONTHLY
+EXDATE:20080801T120000Z
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+METHOD:REPLY
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080801T120000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+EXDATE:20080801T120000Z
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=MONTHLY
+END:VEVENT
+END:VCALENDAR
+""",
+                False, "", (),
+            ),
+            (
+                "#5.1 Invalid iTIP",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+METHOD:REPLY
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                False, "", (),
+            ),
+            (
+                "#5.2 Recurring component, different attendees in components",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+RRULE:FREQ=MONTHLY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080801T120000Z
+DTSTART:20080801T123000Z
+DTEND:20080801T133000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+METHOD:REPLY
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user1 at example.com
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080801T120000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+RRULE:FREQ=MONTHLY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080801T120000Z
+DTSTART:20080801T123000Z
+DTEND:20080801T133000Z
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                False, "", (),
+            ),
+            (
+                "#6.1 REQUEST-STATUS",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+METHOD:REPLY
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED:mailto:user1 at example.com
+REQUEST-STATUS:2.0;Success
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                True, "mailto:user1 at example.com", (("", True, False),),
+            ),
+            (
+                "#6.2 Multiple REQUEST-STATUS",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+METHOD:REPLY
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+ORGANIZER;CN="User 01":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED:mailto:user1 at example.com
+REQUEST-STATUS:2.1;Success but fallback taken on one or more property values
+REQUEST-STATUS:2.2;Success, invalid property ignored
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE;PARTSTAT=DECLINED;SCHEDULE-STATUS="2.1,2.2":mailto:user1 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+                True, "mailto:user1 at example.com", (("", True, False),),
+            ),
         )
 
-        for description, calendar_txt, itipmsg_txt, result in data:
+        for description, calendar_txt, itipmsg_txt, result, success, attendee, rids in data:
             calendar = Component.fromString(calendar_txt)
             itipmsg = Component.fromString(itipmsg_txt)
-            iTipProcessing.processReply(itipmsg, calendar)
+            reply_success, reply_processed = iTipProcessing.processReply(itipmsg, calendar)
 #            if not description.startswith("#3.1"):
 #                continue
 #            print description
@@ -584,6 +833,29 @@
                 str(result).replace("\n ", ""),
                 msg=description
             )
+            self.assertEqual(
+                reply_success,
+                success,
+                msg=description
+            )
+            if success:
+                reply_attendee, reply_rids, = reply_processed
+                self.assertEqual(
+                    reply_attendee,
+                    attendee,
+                    msg=description
+                )
+                self.assertEqual(
+                    tuple(sorted(list(reply_rids), key=lambda x:x[0])),
+                    rids,
+                    msg=description
+                )
+            else:
+                self.assertEqual(
+                    reply_processed,
+                    None,
+                    msg=description
+                )
 
 class iTIPGenerator (twistedcaldav.test.util.TestCase):
     """

Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2009-06-22 18:49:14 UTC (rev 4364)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py	2009-06-22 19:08:51 UTC (rev 4365)
@@ -523,14 +523,14 @@
 UID:12345-67890-1
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
-ATTENDEE;SCHEDULE-STATUS="2.0;OK":mailto:user02 at example.com
+ATTENDEE;SCHEDULE-STATUS=2.0:mailto:user02 at example.com
 ORGANIZER:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
                 (
                     "SCHEDULE-STATUS",
-                    "2.0;OK",
+                    "2.0",
                     "ATTENDEE",
                     "mailto:user02 at example.com",
                 ),
@@ -544,7 +544,7 @@
 UID:12345-67890-1
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
-ATTENDEE;SCHEDULE-STATUS="5.0;BAD":mailto:user02 at example.com
+ATTENDEE;SCHEDULE-STATUS=5.0:mailto:user02 at example.com
 ORGANIZER:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
@@ -556,14 +556,14 @@
 UID:12345-67890-1
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
-ATTENDEE;SCHEDULE-STATUS="2.0;OK":mailto:user02 at example.com
+ATTENDEE;SCHEDULE-STATUS=2.0:mailto:user02 at example.com
 ORGANIZER:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
                 (
                     "SCHEDULE-STATUS",
-                    "2.0;OK",
+                    "2.0",
                     "ATTENDEE",
                     "mailto:user02 at example.com",
                 ),
@@ -590,13 +590,13 @@
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
 ATTENDEE:mailto:user02 at example.com
-ORGANIZER;SCHEDULE-STATUS="2.0;OK":mailto:user01 at example.com
+ORGANIZER;SCHEDULE-STATUS=2.0:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
                 (
                     "SCHEDULE-STATUS",
-                    "2.0;OK",
+                    "2.0",
                     "ORGANIZER",
                     "mailto:user01 at example.com",
                 ),
@@ -611,7 +611,7 @@
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
 ATTENDEE:mailto:user02 at example.com
-ORGANIZER;SCHEDULE-STATUS="5.0;BAD":mailto:user01 at example.com
+ORGANIZER;SCHEDULE-STATUS=5.0:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
@@ -623,13 +623,13 @@
 DTSTART:20071114T000000Z
 ATTENDEE:mailto:user01 at example.com
 ATTENDEE:mailto:user02 at example.com
-ORGANIZER;SCHEDULE-STATUS="2.0;OK":mailto:user01 at example.com
+ORGANIZER;SCHEDULE-STATUS=2.0:mailto:user01 at example.com
 END:VEVENT
 END:VCALENDAR
 """,
                 (
                     "SCHEDULE-STATUS",
-                    "2.0;OK",
+                    "2.0",
                     "ORGANIZER",
                     "mailto:user01 at example.com",
                 ),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090622/3b75593f/attachment-0001.html>


More information about the calendarserver-changes mailing list