[CalendarServer-changes] [5668] CalendarServer/branches/new-store/txcaldav/calendarstore

source_changes at macosforge.org source_changes at macosforge.org
Tue Jun 1 15:24:05 PDT 2010


Revision: 5668
          http://trac.macosforge.org/projects/calendarserver/changeset/5668
Author:   glyph at apple.com
Date:     2010-06-01 15:24:00 -0700 (Tue, 01 Jun 2010)
Log Message:
-----------
simplify

Modified Paths:
--------------
    CalendarServer/branches/new-store/txcaldav/calendarstore/file.py
    CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py
    CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py
    CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_file.py
    CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_scheduling.py

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/file.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/file.py	2010-06-01 17:23:05 UTC (rev 5667)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/file.py	2010-06-01 22:24:00 UTC (rev 5668)
@@ -29,6 +29,8 @@
 
 from zope.interface import implements
 
+from twisted.python.util import FancyEqMixin
+
 from twisted.internet.defer import inlineCallbacks
 
 from twext.python.log import LoggingMixIn
@@ -372,12 +374,14 @@
 
 
 
-class Calendar(LoggingMixIn):
+class Calendar(LoggingMixIn, FancyEqMixin):
     """
     File-based implementation of L{ICalendar}.
     """
     implements(ICalendar)
 
+    compareAttributes = '_path _calendarHome _transaction'.split()
+
     def __init__(self, path, calendarHome):
         self._path = path
         self._calendarHome = calendarHome
@@ -520,15 +524,15 @@
 
 class CalendarObject(LoggingMixIn):
     """
-    @ivar path: The path of the .ics file on disk
+    @ivar _path: The path of the .ics file on disk
 
-    @type path: L{FilePath}
+    @type _path: L{FilePath}
     """
     implements(ICalendarObject)
 
     def __init__(self, path, calendar):
         self._path = path
-        self.calendar = calendar
+        self._calendar = calendar
         self._component = None
 
 
@@ -580,7 +584,7 @@
                 else:
                     self._path.remove()
             return undo
-        self.calendar._transaction.addOperation(do)
+        self._calendar._transaction.addOperation(do)
 
 
     def component(self):

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py	2010-06-01 17:23:05 UTC (rev 5667)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/scheduling.py	2010-06-01 22:24:00 UTC (rev 5668)
@@ -17,86 +17,80 @@
 from zope.interface.declarations import implements
 from txcaldav.icalendarstore import ICalendarStore, ICalendarStoreTransaction, \
     ICalendarHome, ICalendar, ICalendarObject
+from twisted.python.util import FancyEqMixin
+from twisted.python.components import proxyForInterface
 
 
 
-class ImplicitSchedulingTransaction(object):
+class ImplicitTransaction(
+        proxyForInterface(ICalendarStoreTransaction,
+                          originalAttribute="_transaction")):
     """
     Wrapper around an L{ICalendarStoreTransaction}.
     """
-    implements(ICalendarStoreTransaction)
 
     def __init__(self, transaction):
         """
-        Initialize an L{ImplicitSchedulingTransaction}.
+        Initialize an L{ImplicitTransaction}.
 
         @type transaction: L{ICalendarStoreTransaction}
         """
         self._transaction = transaction
 
 
-    def abort(self):
-        """
-        Abort the underlying transaction.
-        """
-        return self._transaction.abort()
-
-
-    def commit(self):
-        """
-        Commit the underlying transaction.
-        """
-        return self._transaction.commit()
-
-
     def calendarHomeWithUID(self, uid, create=False):
         # FIXME: 'create' flag
-        newHome = self._transaction.calendarHomeWithUID(uid)
-#        return ImplicitSchedulingCalendarHome(newHome, self)
+        newHome = super(ImplicitTransaction, self
+            ).calendarHomeWithUID(uid, create)
+#        return ImplicitCalendarHome(newHome, self)
         if newHome is None:
             return None
         else:
             # FIXME: relay transaction
-            return ImplicitSchedulingCalendarHome(newHome, None)
+            return ImplicitCalendarHome(newHome, None)
 
 
 
-class ImplicitSchedulingCalendarHome(object):
+class ImplicitCalendarHome(
+        proxyForInterface(ICalendarHome, "_calendarHome")
+    ):
+
     implements(ICalendarHome)
 
     def __init__(self, calendarHome, transaction):
         """
-        L{ImplicitSchedulingCalendarHome}
+        Initialize L{ImplicitCalendarHome} with an underlying
+        calendar home and L{ImplicitTransaction}.
         """
         self._calendarHome = calendarHome
         self._transaction = transaction
 
 
-    def uid(self):
-        return self._calendarHome.uid()
+#    def properties(self):
+#        # FIXME: wrap?
+#        return self._calendarHome.properties()
 
-    def properties(self): ""
-        # FIXME: implement
-        # return self._calendarHome.properties()
+    def calendars(self):
+        for calendar in super(ImplicitCalendarHome, self).calendars():
+            yield ImplicitCalendar(self, calendar)
 
-    def calendars(self): ""
-        # FIXME: implement
     def createCalendarWithName(self, name):
         self._calendarHome.createCalendarWithName(name)
-    def removeCalendarWithName(self, name): ""
-        # FIXME: implement
 
+    def removeCalendarWithName(self, name):
+        self._calendarHome.removeCalendarWithName(name)
 
+
     def calendarWithName(self, name):
         calendar = self._calendarHome.calendarWithName(name)
         if calendar is not None:
-            return ImplicitSchedulingCalendar(self, calendar)
+            return ImplicitCalendar(self, calendar)
         else:
             return None
 
 
 
-class ImplicitSchedulingCalendarObject(object):
+class ImplicitCalendarObject(object):
     implements(ICalendarObject)
     def setComponent(self, component): ""
     def component(self): ""
@@ -108,43 +102,41 @@
 
 
 
-class ImplicitSchedulingCalendar(object):
-    implements(ICalendar)
+class ImplicitCalendar(FancyEqMixin,
+                       proxyForInterface(ICalendar, "_subCalendar")):
 
+    compareAttributes = ['_subCalendar', '_parentHome']
+
     def __init__(self, parentHome, subCalendar):
         self._parentHome = parentHome
         self._subCalendar = subCalendar
 
-    def name(self):
-        return self._subCalendar.name()
+#    def ownerCalendarHome(self):
+#        return self._parentHome
+#    def calendarObjects(self):
+#        # FIXME: wrap
+#        return self._subCalendar.calendarObjects()
+#    def calendarObjectWithUID(self, uid): ""
+#    def createCalendarObjectWithName(self, name, component):
+#        # FIXME: implement most of StoreCalendarObjectResource here!
+#        self._subCalendar.createCalendarObjectWithName(name, component)
+#    def removeCalendarObjectWithName(self, name):
+#        # FIXME: implement deletion logic here!
+#        return self._subCalendar.removeCalendarObjectWithName(name)
+#    def removeCalendarObjectWithUID(self, uid): ""
+#    def syncToken(self): ""
+#    def calendarObjectsInTimeRange(self, start, end, timeZone): ""
+#    def calendarObjectsSinceToken(self, token): ""
+#    def properties(self):
+#        # FIXME: probably need to wrap this as well
+#        return self._subCalendar.properties()
+#
+#    def calendarObjectWithName(self, name):
+#        #FIXME: wrap
+#        return self._subCalendar.calendarObjectWithName(name)
 
-    def ownerCalendarHome(self):
-        return self._parentHome
-    def calendarObjects(self):
-        # FIXME: wrap
-        return self._subCalendar.calendarObjects()
-    def calendarObjectWithUID(self, uid): ""
-    def createCalendarObjectWithName(self, name, component):
-        # FIXME: implement most of StoreCalendarObjectResource here!
-        self._subCalendar.createCalendarObjectWithName(name, component)
-    def removeCalendarObjectWithName(self, name):
-        # FIXME: implement deletion logic here!
-        return self._subCalendar.removeCalendarObjectWithName(name)
-    def removeCalendarObjectWithUID(self, uid): ""
-    def syncToken(self): ""
-    def calendarObjectsInTimeRange(self, start, end, timeZone): ""
-    def calendarObjectsSinceToken(self, token): ""
-    def properties(self):
-        # FIXME: probably need to wrap this as well
-        return self._subCalendar.properties()
 
-
-    def calendarObjectWithName(self, name):
-        #FIXME: wrap
-        return self._subCalendar.calendarObjectWithName(name)
-
-
-class ImplicitSchedulingStore(object):
+class ImplicitStore(object):
     """
     This is a wrapper around an L{ICalendarStore} that implements implicit
     scheduling.
@@ -154,7 +146,7 @@
 
     def __init__(self, calendarStore):
         """
-        Create an L{ImplicitSchedulingStore} wrapped around another
+        Create an L{ImplicitStore} wrapped around another
         L{ICalendarStore} provider.
         """
         self._calendarStore = calendarStore
@@ -164,5 +156,5 @@
         """
         Wrap an underlying L{ITransaction}.
         """
-        return ImplicitSchedulingTransaction(
+        return ImplicitTransaction(
                     self._calendarStore.newTransaction())

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py	2010-06-01 17:23:05 UTC (rev 5667)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/test/common.py	2010-06-01 22:24:00 UTC (rev 5668)
@@ -18,12 +18,20 @@
 Tests for common calendar store API functions.
 """
 
-from txcaldav.icalendarstore import ICalendarStore, ICalendarStoreTransaction, \
-    ICalendarObject, ICalendarHome, ICalendar, InvalidCalendarComponentError
-from twext.python.filepath import CachingFilePath as FilePath
 from zope.interface.verify import verifyObject
-from zope.interface.exceptions import BrokenMethodImplementation
+from zope.interface.exceptions import (
+    BrokenMethodImplementation, DoesNotImplement)
+
+from txdav.idav import IPropertyStore
 from txdav.propertystore.base import PropertyName
+
+from txcaldav.icalendarstore import (
+    ICalendarStore, ICalendarStoreTransaction, ICalendarObject, ICalendarHome,
+    ICalendar, InvalidCalendarComponentError,
+    CalendarObjectNameAlreadyExistsError, CalendarAlreadyExistsError,
+    NoSuchCalendarError, NoSuchCalendarObjectError)
+
+from twext.python.filepath import CachingFilePath as FilePath
 from twext.web2.dav import davxml
 from twext.python.vcomponent import VComponent
 
@@ -34,13 +42,20 @@
 
 cal1Root = homeRoot.child("calendar_1")
 
-calendar1_objectNames = (
+calendar1_objectNames = [
     "1.ics",
     "2.ics",
     "3.ics",
-)
+]
 
 
+home1_calendarNames = [
+    "calendar_1",
+    "calendar_2",
+    "calendar_empty",
+]
+
+
 event4_text = (
     "BEGIN:VCALENDAR\r\n"
       "VERSION:2.0\r\n"
@@ -82,6 +97,41 @@
     "END:VCALENDAR\r\n"
 )
 
+
+
+event4notCalDAV_text = (
+    "BEGIN:VCALENDAR\r\n"
+      "VERSION:2.0\r\n"
+      "PRODID:-//Apple Inc.//iCal 4.0.1//EN\r\n"
+      "CALSCALE:GREGORIAN\r\n"
+      "BEGIN:VEVENT\r\n"
+        "CREATED:20100203T013849Z\r\n"
+        "UID:4\r\n"
+        "DTEND;TZID=US/Pacific:20100207T173000\r\n" # TZID without VTIMEZONE
+        "TRANSP:OPAQUE\r\n"
+        "SUMMARY:New Event\r\n"
+        "DTSTART;TZID=US/Pacific:20100207T170000\r\n"
+        "DTSTAMP:20100203T013909Z\r\n"
+        "SEQUENCE:3\r\n"
+        "BEGIN:VALARM\r\n"
+          "X-WR-ALARMUID:1377CCC7-F85C-4610-8583-9513D4B364E1\r\n"
+          "TRIGGER:-PT20M\r\n"
+          "ATTACH;VALUE=URI:Basso\r\n"
+          "ACTION:AUDIO\r\n"
+        "END:VALARM\r\n"
+      "END:VEVENT\r\n"
+    "END:VCALENDAR\r\n"
+)
+
+
+
+event1modified_text = event4_text.replace(
+    "\r\nUID:uid4\r\n",
+    "\r\nUID:uid1\r\n"
+)
+
+
+
 class CommonTests(object):
     """
     Tests for common functionality of interfaces defined in
@@ -182,6 +232,9 @@
             verifyObject(interface, provider)
         except BrokenMethodImplementation, e:
             self.fail(e)
+        except DoesNotImplement, e:
+            self.fail("%r does not provide %s.%s" %
+                (provider, interface.__module__, interface.getName()))
 
 
     def test_calendarStoreProvides(self):
@@ -251,6 +304,27 @@
         )
 
 
+    def test_calendarWithName_exists(self):
+        """
+        L{ICalendarHome.calendarWithName} returns an L{ICalendar} provider,
+        whose name matches the one passed in.
+        """
+        home = self.homeUnderTest()
+        for name in home1_calendarNames:
+            calendar = home.calendarWithName(name)
+            self.assertProvides(ICalendar, calendar)
+            self.assertEquals(calendar.name(), name)
+
+
+    def test_calendarWithName_absent(self):
+        """
+        L{ICalendarHome.calendarWithName} returns C{None} for calendars which
+        do not exist.
+        """
+        self.assertEquals(self.homeUnderTest().calendarWithName("xyzzy"),
+                          None)
+
+
     def test_createCalendarWithName_absent(self):
         """
         L{ICalendarHome.createCalendarWithName} creates a new L{ICalendar} that
@@ -281,26 +355,65 @@
         checkProperties()
 
 
+    def test_createCalendarWithName_exists(self):
+        """
+        L{ICalendarHome.createCalendarWithName} raises
+        L{CalendarAlreadyExistsError} when the name conflicts with an already-
+        existing 
+        """
+        for name in home1_calendarNames:
+            self.assertRaises(
+                CalendarAlreadyExistsError,
+                self.homeUnderTest().createCalendarWithName, name
+            )
+
+
+    def test_removeCalendarWithName_exists(self):
+        """
+        L{ICalendarHome.removeCalendarWithName} removes a calendar that already
+        exists.
+        """
+        home = self.homeUnderTest()
+        # FIXME: test transactions
+        for name in home1_calendarNames:
+            self.assertNotIdentical(home.calendarWithName(name), None)
+            home.removeCalendarWithName(name)
+            self.assertEquals(home.calendarWithName(name), None)
+
+
+    def test_removeCalendarWithName_absent(self):
+        """
+        Attempt to remove an non-existing calendar should raise.
+        """
+        home = self.homeUnderTest()
+        self.assertRaises(NoSuchCalendarError,
+                          home.removeCalendarWithName, "xyzzy")
+
+
     def test_calendarObjects(self):
         """
         L{ICalendar.calendarObjects} will enumerate the calendar objects present
         in the filesystem, in name order, but skip those with hidden names.
         """
         calendar1 = self.calendarUnderTest()
-        calendarObjects = tuple(calendar1.calendarObjects())
+        calendarObjects = list(calendar1.calendarObjects())
 
         for calendarObject in calendarObjects:
             self.assertProvides(ICalendarObject, calendarObject)
+            self.assertEquals(
+                calendar1.calendarObjectWithName(calendarObject.name()),
+                calendarObject
+            )
 
         self.assertEquals(
-            tuple(o.name() for o in calendarObjects),
+            list(o.name() for o in calendarObjects),
             calendar1_objectNames
         )
 
 
     def test_calendarObjectsWithRemovedObject(self):
         """
-        L{ICalendar.calendarObjects} will skip those objects which have been
+        L{ICalendar.calendarObjects} skips those objects which have been
         removed by L{Calendar.removeCalendarObjectWithName} in the same
         transaction, even if it has not yet been committed.
         """
@@ -321,6 +434,19 @@
         )
 
 
+    def test_calendarObjectWithName_exists(self):
+        """
+        L{ICalendar.calendarObjectWithName} returns an L{ICalendarObject}
+        provider for calendars which already exist.
+        """
+        calendar1 = self.calendarUnderTest()
+        for name in calendar1_objectNames:
+            calendarObject = calendar1.calendarObjectWithName(name)
+            self.assertProvides(ICalendarObject, calendarObject)
+            self.assertEquals(calendarObject.name(), name)
+            # FIXME: add more tests based on CommonTests.requirements
+
+
     def test_calendarObjectWithName_absent(self):
         """
         L{ICalendar.calendarObjectWithName} returns C{None} for calendars which
@@ -330,13 +456,115 @@
         self.assertEquals(calendar1.calendarObjectWithName("xyzzy"), None)
 
 
-    def test_name(self):
+    def test_removeCalendarObjectWithUID_exists(self):
         """
+        Remove an existing calendar object.
+        """
+        calendar = self.calendarUnderTest()
+        for name in calendar1_objectNames:
+            uid = (u'uid' + name.rstrip(".ics"))
+            self.assertNotIdentical(calendar.calendarObjectWithUID(uid),
+                                    None)
+            calendar.removeCalendarObjectWithUID(uid)
+            self.assertEquals(
+                calendar.calendarObjectWithUID(uid),
+                None
+            )
+            self.assertEquals(
+                calendar.calendarObjectWithName(name),
+                None
+            )
+
+
+    def test_removeCalendarObjectWithName_exists(self):
+        """
+        Remove an existing calendar object.
+        """
+        calendar = self.calendarUnderTest()
+        for name in calendar1_objectNames:
+            self.assertNotIdentical(
+                calendar.calendarObjectWithName(name), None
+            )
+            calendar.removeCalendarObjectWithName(name)
+            self.assertIdentical(
+                calendar.calendarObjectWithName(name), None
+            )
+
+
+    def test_removeCalendarObjectWithName_absent(self):
+        """
+        Attempt to remove an non-existing calendar object should raise.
+        """
+        calendar = self.calendarUnderTest()
+        self.assertRaises(
+            NoSuchCalendarObjectError,
+            calendar.removeCalendarObjectWithName, "xyzzy"
+        )
+
+
+    def test_calendarName(self):
+        """
         L{Calendar.name} reflects the name of the calendar.
         """
         self.assertEquals(self.calendarUnderTest().name(), "calendar_1")
 
 
+    def test_calendarObjectName(self):
+        """
+        L{ICalendarObject.name} reflects the name of the calendar object.
+        """
+        self.assertEquals(self.calendarObjectUnderTest().name(), "1.ics")
+
+
+    def test_component(self):
+        """
+        L{ICalendarObject.component} returns a L{VComponent} describing the
+        calendar data underlying that calendar object.
+        """
+        component = self.calendarObjectUnderTest().component()
+
+        self.failUnless(
+            isinstance(component, VComponent),
+            component
+        )
+
+        self.assertEquals(component.name(), "VCALENDAR")
+        self.assertEquals(component.mainType(), "VEVENT")
+        self.assertEquals(component.resourceUID(), "uid1")
+
+
+    def test_iCalendarText(self):
+        """
+        L{ICalendarObject.iCalendarText} returns a C{str} describing the same
+        data provided by L{ICalendarObject.component}.
+        """
+        text = self.calendarObjectUnderTest().iCalendarText()
+        self.assertIsInstance(text, str)
+        self.failUnless(text.startswith("BEGIN:VCALENDAR\r\n"))
+        self.assertIn("\r\nUID:uid1\r\n", text)
+        self.failUnless(text.endswith("\r\nEND:VCALENDAR\r\n"))
+
+
+    def test_calendarObjectUID(self):
+        """
+        L{ICalendarObject.uid} returns a C{str} describing the C{UID} property
+        of the calendar object's component.
+        """
+        self.assertEquals(self.calendarObjectUnderTest().uid(), "uid1")
+
+
+    def test_organizer(self):
+        """
+        L{ICalendarObject.organizer} returns a C{str} describing the calendar
+        user address of the C{ORGANIZER} property of the calendar object's
+        component.
+        """
+        self.assertEquals(
+            self.calendarObjectUnderTest().organizer(),
+            "mailto:wsanchez at apple.com"
+        )
+
+
     def test_calendarObjectWithUID_absent(self):
         """
         L{ICalendar.calendarObjectWithUID} returns C{None} for calendars which
@@ -346,9 +574,31 @@
         self.assertEquals(calendar1.calendarObjectWithUID("xyzzy"), None)
 
 
+    def test_calendars(self):
+        """
+        L{ICalendarHome.calendars} returns an iterable of L{ICalendar}
+        providers, which are consistent with the results from
+        L{ICalendar.calendarWithName}.
+        """
+        # Add a dot directory to make sure we don't find it
+        # self.home1._path.child(".foo").createDirectory()
+        home = self.homeUnderTest()
+        calendars = list(home.calendars())
+
+        for calendar in calendars:
+            self.assertProvides(ICalendar, calendar)
+            self.assertEquals(calendar,
+                              home.calendarWithName(calendar.name()))
+
+        self.assertEquals(
+            list(c.name() for c in calendars),
+            home1_calendarNames
+        )
+
+
     def test_createCalendarObjectWithName_absent(self):
         """
-        L{ICalendar.createCalendarObjectWithName} will create a new
+        L{ICalendar.createCalendarObjectWithName} creates a new
         L{ICalendarObject}.
         """
         calendar1 = self.calendarUnderTest()
@@ -361,6 +611,45 @@
         self.assertEquals(calendarObject.component(), component)
 
 
+    def test_createCalendarObjectWithName_exists(self):
+        """
+        L{ICalendar.createCalendarObjectWithName} raises
+        L{CalendarObjectNameAlreadyExistsError} if a calendar object with the
+        given name already exists in that calendar.
+        """
+        self.assertRaises(
+            CalendarObjectNameAlreadyExistsError,
+            self.calendarUnderTest().createCalendarObjectWithName,
+            "1.ics", VComponent.fromString(event4_text)
+        )
+
+
+    def test_createCalendarObjectWithName_invalid(self):
+        """
+        L{ICalendar.createCalendarObjectWithName} raises
+        L{InvalidCalendarComponentError} if presented with invalid iCalendar
+        text.
+        """
+        self.assertRaises(
+            InvalidCalendarComponentError,
+            self.calendarUnderTest().createCalendarObjectWithName,
+            "new", VComponent.fromString(event4notCalDAV_text)
+        )
+
+
+    def test_setComponent_invalid(self):
+        """
+        L{ICalendarObject.setComponent} raises L{InvalidICalendarDataError} if
+        presented with invalid iCalendar text.
+        """
+        calendarObject = self.calendarObjectUnderTest()
+        self.assertRaises(
+            InvalidCalendarComponentError,
+            calendarObject.setComponent,
+            VComponent.fromString(event4notCalDAV_text)
+        )
+
+
     def test_setComponent_uidchanged(self):
         """
         L{ICalendarObject.setComponent} raises L{InvalidCalendarComponentError}
@@ -375,3 +664,72 @@
         )
 
 
+    def test_calendarHomeWithUID_create(self):
+        """
+        L{ICalendarStoreTransaction.calendarHomeWithUID} with C{create=True}
+        will create a calendar home that doesn't exist yet.
+        """
+        txn = self.transactionUnderTest()
+        noHomeUID = "xyzzy"
+        calendarHome = txn.calendarHomeWithUID(
+            noHomeUID,
+            create=True
+        )
+        def readOtherTxn():
+            return self.savedStore.newTransaction().calendarHomeWithUID(
+                noHomeUID)
+        self.assertProvides(ICalendarHome, calendarHome)
+        # A concurrent transaction shouldn't be able to read it yet:
+        self.assertIdentical(readOtherTxn(), None)
+        txn.commit()
+        # But once it's committed, other transactions should see it.
+        self.assertProvides(ICalendarHome, readOtherTxn())
+
+
+    def test_setComponent(self):
+        """
+        L{CalendarObject.setComponent} changes the result of
+        L{CalendarObject.component} within the same transaction.
+        """
+        component = VComponent.fromString(event1modified_text)
+
+        calendar1 = self.calendarUnderTest()
+        calendarObject = calendar1.calendarObjectWithName("1.ics")
+        oldComponent = calendarObject.component()
+        self.assertNotEqual(component, oldComponent)
+        calendarObject.setComponent(component)
+        self.assertEquals(calendarObject.component(), component)
+
+        # Also check a new instance
+        calendarObject = calendar1.calendarObjectWithName("1.ics")
+        self.assertEquals(calendarObject.component(), component)
+
+
+    def checkPropertiesMethod(self, thunk):
+        """
+        Verify that the given object has a properties method that returns an
+        L{IPropertyStore}.
+        """
+        properties = thunk.properties()
+        self.assertProvides(IPropertyStore, properties)
+
+
+    def test_homeProperties(self):
+        """
+        L{ICalendarHome.properties} returns a property store.
+        """
+        self.checkPropertiesMethod(self.homeUnderTest())
+
+
+    def test_calendarProperties(self):
+        """
+        L{ICalendar.properties} returns a property store.
+        """
+        self.checkPropertiesMethod(self.calendarUnderTest())
+
+
+    def test_calendarObjectProperties(self):
+        """
+        L{ICalendarObject.properties} returns a proprety store.
+        """
+        self.checkPropertiesMethod(self.calendarObjectUnderTest())

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_file.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_file.py	2010-06-01 17:23:05 UTC (rev 5667)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_file.py	2010-06-01 22:24:00 UTC (rev 5668)
@@ -23,63 +23,22 @@
 
 from twext.python.vcomponent import VComponent
 
-from txdav.idav import IPropertyStore
-
 from txcaldav.icalendarstore import CalendarNameNotAllowedError
 from txcaldav.icalendarstore import CalendarObjectNameNotAllowedError
 from txcaldav.icalendarstore import CalendarAlreadyExistsError
-from txcaldav.icalendarstore import CalendarObjectNameAlreadyExistsError
 from txcaldav.icalendarstore import CalendarObjectUIDAlreadyExistsError
 from txcaldav.icalendarstore import NoSuchCalendarError
 from txcaldav.icalendarstore import NoSuchCalendarObjectError
-from txcaldav.icalendarstore import InvalidCalendarComponentError
 
 from txcaldav.calendarstore.file import CalendarStore, CalendarHome
 from txcaldav.calendarstore.file import Calendar, CalendarObject
 
 from txcaldav.calendarstore.test.common import (
-    CommonTests, calendar1_objectNames, event4_text)
+    CommonTests, calendar1_objectNames, event4_text, event1modified_text,
+    home1_calendarNames)
 
 storePath = FilePath(__file__).parent().child("calendar_store")
 
-home1_calendarNames = (
-    "calendar_1",
-    "calendar_2",
-    "calendar_empty",
-)
-
-
-event1modified_text = event4_text.replace(
-    "\r\nUID:uid4\r\n",
-    "\r\nUID:uid1\r\n"
-)
-
-event4notCalDAV_text = (
-    "BEGIN:VCALENDAR\r\n"
-      "VERSION:2.0\r\n"
-      "PRODID:-//Apple Inc.//iCal 4.0.1//EN\r\n"
-      "CALSCALE:GREGORIAN\r\n"
-      "BEGIN:VEVENT\r\n"
-        "CREATED:20100203T013849Z\r\n"
-        "UID:4\r\n"
-        "DTEND;TZID=US/Pacific:20100207T173000\r\n" # TZID without VTIMEZONE
-        "TRANSP:OPAQUE\r\n"
-        "SUMMARY:New Event\r\n"
-        "DTSTART;TZID=US/Pacific:20100207T170000\r\n"
-        "DTSTAMP:20100203T013909Z\r\n"
-        "SEQUENCE:3\r\n"
-        "BEGIN:VALARM\r\n"
-          "X-WR-ALARMUID:1377CCC7-F85C-4610-8583-9513D4B364E1\r\n"
-          "TRIGGER:-PT20M\r\n"
-          "ATTACH;VALUE=URI:Basso\r\n"
-          "ACTION:AUDIO\r\n"
-        "END:VALARM\r\n"
-      "END:VEVENT\r\n"
-    "END:VCALENDAR\r\n"
-)
-
-
-
 def _todo(f, why):
     f.todo = why
     return f
@@ -91,23 +50,11 @@
 todo = lambda why: lambda f: _todo(f, why)
 
 
-class PropertiesTestMixin(object):
-
-    def test_properties(self):
-        properties = self.home1.properties()
-
-        self.failUnless(
-            IPropertyStore.providedBy(properties),
-            properties
-        )
-
-
-
 def setUpCalendarStore(test):
     test.root = FilePath(test.mktemp())
     test.root.createDirectory()
 
-    calendarPath = test.root.child("store")
+    calendarPath = test.calendarPath = test.root.child("store")
     storePath.copyTo(calendarPath)
 
 
@@ -140,41 +87,6 @@
         setUpCalendarStore(self)
 
 
-    def test_init(self):
-        """
-        Ivars are correctly initialized.
-        """
-        self.failUnless(
-            isinstance(self.calendarStore._path, FilePath),
-            self.calendarStore._path
-        )
-
-
-    def test_calendarHomeWithUID_create(self):
-        """
-        Create missing calendar home.
-        """
-        txn = self.calendarStore.newTransaction()
-        calendarHome = txn.calendarHomeWithUID(
-            "xyzzy",
-            create=True
-        )
-
-        self.failUnless(isinstance(calendarHome, CalendarHome))
-        self.failIf(calendarHome._path.isdir())
-        txn.commit()
-        self.failUnless(calendarHome._path.isdir())
-
-
-    def test_calendarHomeWithUID_create_exists(self):
-        """
-        Create missing calendar home.
-        """
-        calendarHome = self.calendarStore.newTransaction().calendarHomeWithUID("home1")
-
-        self.failUnless(isinstance(calendarHome, CalendarHome))
-
-
     def test_calendarHomeWithUID_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -187,7 +99,7 @@
 
 
 
-class CalendarHomeTest(unittest.TestCase, PropertiesTestMixin):
+class CalendarHomeTest(unittest.TestCase):
 
     def setUp(self):
         setUpHome1(self)
@@ -195,7 +107,8 @@
 
     def test_init(self):
         """
-        Ivars are correctly initialized.
+        L{CalendarHome} has C{_path} and L{_calendarStore} attributes,
+        indicating its location on disk and parent store, respectively.
         """
         self.failUnless(
             isinstance(self.home1._path, FilePath),
@@ -207,41 +120,6 @@
         )
 
 
-    def test_calendars(self):
-        """
-        Find all of the calendars.
-        """
-        # Add a dot directory to make sure we don't find it
-        self.home1._path.child(".foo").createDirectory()
-
-        calendars = tuple(self.home1.calendars())
-
-        for calendar in calendars:
-            self.failUnless(isinstance(calendar, Calendar), calendar)
-
-        self.assertEquals(
-            tuple(c.name() for c in calendars),
-            home1_calendarNames
-        )
-
-
-    def test_calendarWithName_exists(self):
-        """
-        Find existing calendar by name.
-        """
-        for name in home1_calendarNames:
-            calendar = self.home1.calendarWithName(name)
-            self.failUnless(isinstance(calendar, Calendar), calendar)
-            self.assertEquals(calendar.name(), name)
-
-
-    def test_calendarWithName_absent(self):
-        """
-        Missing calendar.
-        """
-        self.assertEquals(self.home1.calendarWithName("xyzzy"), None)
-
-
     def test_calendarWithName_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -252,17 +130,6 @@
         self.assertEquals(self.home1.calendarWithName(name), None)
 
 
-    def test_createCalendarWithName_exists(self):
-        """
-        Attempt to create an existing calendar should raise.
-        """
-        for name in home1_calendarNames:
-            self.assertRaises(
-                CalendarAlreadyExistsError,
-                self.home1.createCalendarWithName, name
-            )
-
-
     def test_createCalendarWithName_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -274,27 +141,6 @@
         )
 
 
-    def test_removeCalendarWithName_exists(self):
-        """
-        Remove an existing calendar.
-        """
-        for name in home1_calendarNames:
-            self.assertNotIdentical(self.home1.calendarWithName(name),
-                                    None)
-            self.home1.removeCalendarWithName(name)
-            self.assertEquals(self.home1.calendarWithName(name), None)
-
-
-    def test_removeCalendarWithName_absent(self):
-        """
-        Attempt to remove an non-existing calendar should raise.
-        """
-        self.assertRaises(
-            NoSuchCalendarError,
-            self.home1.removeCalendarWithName, "xyzzy"
-        )
-
-
     def test_removeCalendarWithName_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -309,7 +155,7 @@
 
 
 
-class CalendarTest(unittest.TestCase, PropertiesTestMixin):
+class CalendarTest(unittest.TestCase):
 
     def setUp(self):
         setUpCalendar1(self)
@@ -330,19 +176,6 @@
         )
 
 
-    def test_calendarObjectWithName_exists(self):
-        """
-        Find existing calendar object by name.
-        """
-        for name in calendar1_objectNames:
-            calendarObject = self.calendar1.calendarObjectWithName(name)
-            self.failUnless(
-                isinstance(calendarObject, CalendarObject),
-                calendarObject
-            )
-            self.assertEquals(calendarObject.name(), name)
-
-
     def test_calendarObjectWithName_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -370,17 +203,6 @@
         )
 
 
-    def test_createCalendarObjectWithName_exists(self):
-        """
-        Attempt to create an existing calendar object should raise.
-        """
-        self.assertRaises(
-            CalendarObjectNameAlreadyExistsError,
-            self.calendar1.createCalendarObjectWithName,
-            "1.ics", VComponent.fromString(event4_text)
-        )
-
-
     def test_createCalendarObjectWithName_dot(self):
         """
         Filenames starting with "." are reserved by this
@@ -410,42 +232,6 @@
         )
 
 
-    def test_createCalendarObjectWithName_invalid(self):
-        """
-        Attempt to create a calendar object with a invalid iCalendar text
-        should raise.
-        """
-        self.assertRaises(
-            InvalidCalendarComponentError,
-            self.calendar1.createCalendarObjectWithName,
-            "new", VComponent.fromString(event4notCalDAV_text)
-        )
-
-
-    def test_removeCalendarObjectWithName_exists(self):
-        """
-        Remove an existing calendar object.
-        """
-        for name in calendar1_objectNames:
-            self.assertNotIdentical(
-                self.calendar1.calendarObjectWithName(name), None
-            )
-            self.calendar1.removeCalendarObjectWithName(name)
-            self.assertIdentical(
-                self.calendar1.calendarObjectWithName(name), None
-            )
-
-
-    def test_removeCalendarObjectWithName_absent(self):
-        """
-        Attempt to remove an non-existing calendar object should raise.
-        """
-        self.assertRaises(
-            NoSuchCalendarObjectError,
-            self.calendar1.removeCalendarObjectWithName, "xyzzy"
-        )
-
-
     def test_removeCalendarObject_delayedEffect(self):
         """
         Removing a calendar object should not immediately remove the underlying
@@ -471,25 +257,6 @@
         )
 
 
-    def test_removeCalendarObjectWithUID_exists(self):
-        """
-        Remove an existing calendar object.
-        """
-        for name in calendar1_objectNames:
-            uid = (u'uid' + name.rstrip(".ics"))
-            self.assertNotIdentical(self.calendar1.calendarObjectWithUID(uid),
-                                    None)
-            self.calendar1.removeCalendarObjectWithUID(uid)
-            self.assertEquals(
-                self.calendar1.calendarObjectWithUID(uid),
-                None
-            )
-            self.assertEquals(
-                self.calendar1.calendarObjectWithName(name),
-                None
-            )
-
-
     def _refresh(self):
         """
         Re-read the (committed) home1 and calendar1 objects in a new
@@ -608,7 +375,7 @@
 
 
 
-class CalendarObjectTest(unittest.TestCase, PropertiesTestMixin):
+class CalendarObjectTest(unittest.TestCase):
     def setUp(self):
         setUpCalendar1(self)
         self.object1 = self.calendar1.calendarObjectWithName("1.ics")
@@ -616,86 +383,20 @@
 
     def test_init(self):
         """
-        Ivars are correctly initialized.
-        """
+        L{CalendarObject} has instance attributes, C{_path} and C{_calendar},
+        which refer to its position in the filesystem and the calendar in which
+        it is contained, respectively.
+        """ 
         self.failUnless(
             isinstance(self.object1._path, FilePath),
             self.object1._path
         )
         self.failUnless(
-            isinstance(self.object1.calendar, Calendar),
-            self.object1.calendar
+            isinstance(self.object1._calendar, Calendar),
+            self.object1._calendar
         )
 
 
-    def test_name(self):
-        """
-        Name is correct.
-        """
-        self.assertEquals(self.object1.name(), "1.ics")
-
-
-    def test_setComponent(self):
-        """
-        L{CalendarObject.setComponent} changes the result of
-        L{CalendarObject.component} within the same transaction.
-        """
-        component = VComponent.fromString(event1modified_text)
-
-        calendarObject = self.calendar1.calendarObjectWithName("1.ics")
-        oldComponent = calendarObject.component()
-        self.assertNotEqual(component, oldComponent)
-        calendarObject.setComponent(component)
-        self.assertEquals(calendarObject.component(), component)
-
-        # Also check a new instance
-        calendarObject = self.calendar1.calendarObjectWithName("1.ics")
-        self.assertEquals(calendarObject.component(), component)
-
-
-    def test_setComponent_invalid(self):
-        calendarObject = self.calendar1.calendarObjectWithName("1.ics")
-        self.assertRaises(
-            InvalidCalendarComponentError,
-            calendarObject.setComponent,
-            VComponent.fromString(event4notCalDAV_text)
-        )
-
-
-    def test_component(self):
-        """
-        Component is correct.
-        """
-        component = self.object1.component()
-
-        self.failUnless(
-            isinstance(component, VComponent),
-            component
-        )
-
-        self.assertEquals(component.name(), "VCALENDAR")
-        self.assertEquals(component.mainType(), "VEVENT")
-        self.assertEquals(component.resourceUID(), "uid1")
-
-
-    def text_iCalendarText(self):
-        """
-        iCalendar text is correct.
-        """
-        text = self.object1.iCalendarText()
-
-        self.failUnless(text.startswith("BEGIN:VCALENDAR\r\n"))
-        self.failUnless("\r\nUID:uid-1\r\n" in text)
-        self.failUnless(text.endswith("\r\nEND:VCALENDAR\r\n"))
-
-
-    def test_uid(self):
-        """
-        UID is correct.
-        """
-        self.assertEquals(self.object1.uid(), "uid1")
-
-
     def test_componentType(self):
         """
         Component type is correct.
@@ -703,17 +404,7 @@
         self.assertEquals(self.object1.componentType(), "VEVENT")
 
 
-    def test_organizer(self):
-        """
-        Organizer is correct.
-        """
-        self.assertEquals(
-            self.object1.organizer(),
-            "mailto:wsanchez at apple.com"
-        )
 
-
-
 class FileStorageTests(unittest.TestCase, CommonTests):
     """
     File storage tests.
@@ -727,6 +418,15 @@
         return self.calendarStore
 
 
+    def test_init(self):
+        """
+        L{CalendarStore} has a C{_path} attribute which refers to its
+        constructor argument.
+        """
+        self.assertEquals(self.storeUnderTest()._path,
+                          self.calendarPath)
+
+
     def test_calendarObjectsWithDotFile(self):
         """
         Adding a dotfile to the calendar home should not increase

Modified: CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_scheduling.py
===================================================================
--- CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_scheduling.py	2010-06-01 17:23:05 UTC (rev 5667)
+++ CalendarServer/branches/new-store/txcaldav/calendarstore/test/test_scheduling.py	2010-06-01 22:24:00 UTC (rev 5668)
@@ -21,15 +21,28 @@
 from twisted.trial.unittest import TestCase
 from txcaldav.calendarstore.test.common import CommonTests
 from txcaldav.calendarstore.test.test_file import setUpCalendarStore
-from txcaldav.calendarstore.scheduling import ImplicitSchedulingStore
+from txcaldav.calendarstore.scheduling import ImplicitStore
 
+simpleEvent = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ORGANIZER:mailto:user1 at example.com
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+END:VEVENT
+END:VCALENDAR
+"""
 
-class ImplicitSchedulingStoreTests(TestCase, CommonTests):
+class ImplicitStoreTests(TestCase, CommonTests):
     """
     Tests for L{ImplicitSchedulingStore}.
     """
 
     def storeUnderTest(self):
         setUpCalendarStore(self)
-        self.implicitStore = ImplicitSchedulingStore(self.calendarStore)
+        self.implicitStore = ImplicitStore(self.calendarStore)
         return self.implicitStore
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100601/c9760c3b/attachment-0001.html>


More information about the calendarserver-changes mailing list