[CalendarServer-changes] [11569]

source_changes at macosforge.org source_changes at macosforge.org
Tue Jul 30 22:39:00 PDT 2013


Revision: 11569
          http://trac.calendarserver.org//changeset/11569
Author:   gaya at apple.com
Date:     2013-07-30 22:38:59 -0700 (Tue, 30 Jul 2013)
Log Message:
-----------
fix bulk add of groups with return-changed-data option.  Add CalDAVTester tests

Modified Paths:
--------------
    CalDAVTester/trunk/scripts/tests/CardDAV/bulk.xml
    CalendarServer/trunk/txdav/carddav/datastore/sql.py

Added Paths:
-----------
    CalDAVTester/trunk/Resource/CardDAV/bulk/simple/11.vcf
    CalDAVTester/trunk/Resource/CardDAV/bulk/simple/12.xml
    CalDAVTester/trunk/Resource/CardDAV/bulk/simple/13.vcf
    CalDAVTester/trunk/Resource/CardDAV/bulk/simple/14.vcf

Added: CalDAVTester/trunk/Resource/CardDAV/bulk/simple/11.vcf
===================================================================
--- CalDAVTester/trunk/Resource/CardDAV/bulk/simple/11.vcf	                        (rev 0)
+++ CalDAVTester/trunk/Resource/CardDAV/bulk/simple/11.vcf	2013-07-31 05:38:59 UTC (rev 11569)
@@ -0,0 +1,17 @@
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+UID:78b64b6b-80b9-4b8a-bd81-8f36645d8bbf
+FN:user02
+N:user02;;;;
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid02
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid02
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:44745975-AE6D-4FB0-80A6-A298427E047A
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid01
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:934731C6-1C95-4C40-BE1F-FA4215B2307B
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+END:VCARD

Added: CalDAVTester/trunk/Resource/CardDAV/bulk/simple/12.xml
===================================================================
--- CalDAVTester/trunk/Resource/CardDAV/bulk/simple/12.xml	                        (rev 0)
+++ CalDAVTester/trunk/Resource/CardDAV/bulk/simple/12.xml	2013-07-31 05:38:59 UTC (rev 11569)
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<multistatus xmlns='DAV:'>
+  <response>
+    <href>/addressbooks/__uids__/user01/addressbook/45aad6d69d91e1e6e37c9fd1d38b950d.vcf</href>
+    <propstat>
+      <prop>
+        <getetag>"c9c80708eda258e871b3e6f02e6383d8"</getetag>
+        <address-data xmlns='urn:ietf:params:xml:ns:carddav'><![CDATA[BEGIN:VCARD
+VERSION:3.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+UID:78b64b6b-80b9-4b8a-bd81-8f36645d8bbf
+FN:user02
+N:user02;;;;
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:44745975-AE6D-4FB0-80A6-A298427E047A
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:934731C6-1C95-4C40-BE1F-FA4215B2307B
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid01
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid02
+END:VCARD
+]]></address-data>
+      </prop>
+      <status>HTTP/1.1 200 OK</status>
+    </propstat>
+  </response>
+</multistatus>

Added: CalDAVTester/trunk/Resource/CardDAV/bulk/simple/13.vcf
===================================================================
--- CalDAVTester/trunk/Resource/CardDAV/bulk/simple/13.vcf	                        (rev 0)
+++ CalDAVTester/trunk/Resource/CardDAV/bulk/simple/13.vcf	2013-07-31 05:38:59 UTC (rev 11569)
@@ -0,0 +1,15 @@
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+UID:78b64b6b-80b9-4b8a-bd81-8f36645d8bbf
+FN:user02
+N:user02;;;;
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:44745975-AE6D-4FB0-80A6-A298427E047A
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:934731C6-1C95-4C40-BE1F-FA4215B2307B
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid01
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid02
+END:VCARD

Added: CalDAVTester/trunk/Resource/CardDAV/bulk/simple/14.vcf
===================================================================
--- CalDAVTester/trunk/Resource/CardDAV/bulk/simple/14.vcf	                        (rev 0)
+++ CalDAVTester/trunk/Resource/CardDAV/bulk/simple/14.vcf	2013-07-31 05:38:59 UTC (rev 11569)
@@ -0,0 +1,15 @@
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+UID:78b64b6b-80b9-4b8a-bd81-8f36645d8bbe
+FN:user02
+N:user02;;;;
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:44745975-AE6D-4FB0-80A6-A298427E047A
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:934731C6-1C95-4C40-BE1F-FA4215B2307B
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid01
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:user01-uid02
+END:VCARD

Modified: CalDAVTester/trunk/scripts/tests/CardDAV/bulk.xml
===================================================================
--- CalDAVTester/trunk/scripts/tests/CardDAV/bulk.xml	2013-07-30 23:28:52 UTC (rev 11568)
+++ CalDAVTester/trunk/scripts/tests/CardDAV/bulk.xml	2013-07-31 05:38:59 UTC (rev 11569)
@@ -28,7 +28,7 @@
 
 	<start/>
 	
-	<test-suite name='bulk-requests property'>
+	<test-suite name='bulk-requests property' ignore='yes'>
 		<test name='1'>
 			<description>PROPFIND on address book</description>
 			<request>
@@ -467,6 +467,138 @@
 		</test>
 	</test-suite>
 	
+	<test-suite name='Simple POST - group vcard with return data' ignore='no'>
+		<test name='1' ignore='no'>
+			<description>POST new group vcard with unordered and duplicate members</description>
+			<request print-response='no'>
+				<method>POST</method>
+				<ruri>$addressbookpath1:/</ruri>
+				<header>
+					<name>X-MobileMe-DAV-Options</name>
+					<value>return-changed-data</value>
+				</header>
+				<data substitutions='yes'>
+					<content-type>text/vcard; charset=utf-8</content-type>
+					<filepath>Resource/CardDAV/bulk/simple/11.vcf</filepath>
+				</data>
+				<verify>
+					<callback>xmlElementMatch</callback>
+					<arg>
+						<name>exists</name>
+						<value>$verify-property-prefix:/{DAV:}getetag</value>
+						<value>$verify-property-prefix:/{urn:ietf:params:xml:ns:carddav}address-data</value>
+					</arg>
+				</verify>
+				<verify>
+					<callback>xmlDataMatch</callback>
+					<arg>
+						<name>filepath</name>
+						<value>Resource/CardDAV/bulk/simple/12.xml</value>
+					</arg>
+					<arg>
+						<name>filter</name>
+						<value>{DAV:}href</value>
+						<value>{DAV:}getetag</value>
+					</arg>
+				</verify>
+				<grabelement>
+					<name>$multistatus-href-prefix:</name>
+					<variable>$href:</variable>
+				</grabelement>
+				<grabelement>
+					<name>$verify-property-prefix:/{DAV:}getetag</name>
+					<variable>$etag:</variable>
+				</grabelement>
+			</request>
+		</test>
+		<test name='2' ignore='no'>
+			<description>Check valid data</description>
+			<request>
+				<method>GET</method>
+				<ruri>$href:</ruri>
+				<verify>
+					<callback>addressDataMatch</callback>
+					<arg>
+						<name>filepath</name>
+						<value>Resource/CardDAV/bulk/simple/13.vcf</value>
+					</arg>
+				</verify>
+				<verify>
+					<callback>header</callback>
+					<arg>
+						<name>ETag</name>
+						<value>$etag:</value>
+					</arg>
+				</verify>
+			</request>
+		</test>
+		<test name='3' ignore='no'>
+			<description>POST new group vcard with ordered unique members</description>
+			<request print-response='no'>
+				<method>POST</method>
+				<ruri>$addressbookpath1:/</ruri>
+				<header>
+					<name>X-MobileMe-DAV-Options</name>
+					<value>return-changed-data</value>
+				</header>
+				<data substitutions='yes'>
+					<content-type>text/vcard; charset=utf-8</content-type>
+					<filepath>Resource/CardDAV/bulk/simple/14.vcf</filepath>
+				</data>
+				<verify>
+					<callback>xmlElementMatch</callback>
+					<arg>
+						<name>exists</name>
+						<value>$verify-property-prefix:/{DAV:}getetag</value>
+					</arg>
+					<arg>
+						<name>notexists</name>
+						<value>$verify-property-prefix:/{urn:ietf:params:xml:ns:carddav}address-data</value>
+					</arg>
+				</verify>
+				<grabelement>
+					<name>$multistatus-href-prefix:</name>
+					<variable>$href:</variable>
+				</grabelement>
+				<grabelement>
+					<name>$verify-property-prefix:/{DAV:}getetag</name>
+					<variable>$etag:</variable>
+				</grabelement>
+			</request>
+		</test>
+		<test name='4' ignore='no'>
+			<description>Check valid data</description>
+			<request>
+				<method>GET</method>
+				<ruri>$href:</ruri>
+				<verify>
+					<callback>addressDataMatch</callback>
+					<arg>
+						<name>filepath</name>
+						<value>Resource/CardDAV/bulk/simple/14.vcf</value>
+					</arg>
+				</verify>
+				<verify>
+					<callback>header</callback>
+					<arg>
+						<name>ETag</name>
+						<value>$etag:</value>
+					</arg>
+				</verify>
+			</request>
+		</test>
+		<test name='-1' ignore='no'>
+			<description>Clean up</description>
+			<request>
+				<method>DELETEALL</method>
+				<ruri>$addressbookpath1:/</ruri>
+				<verify>
+					<callback>statusCode</callback>
+				</verify>
+			</request>
+		</test>
+	</test-suite>
+	
 	<test-suite name='Simple POST - ctag condition' ignore='no'>
 		<test name='1'>
 			<description>PROPFIND on address book</description>

Modified: CalendarServer/trunk/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/carddav/datastore/sql.py	2013-07-30 23:28:52 UTC (rev 11568)
+++ CalendarServer/trunk/txdav/carddav/datastore/sql.py	2013-07-31 05:38:59 UTC (rev 11569)
@@ -63,6 +63,7 @@
 
 from zope.interface.declarations import implements
 
+import copy
 
 
 class AddressBookHome(CommonHome):
@@ -800,7 +801,8 @@
         if not rows:
             returnValue(None)
 
-        bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage, ownerAddressBookID, cachedBindStatus = rows[0]  #@UnusedVariable
+        row = rows[0]
+        bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage, ownerAddressBookID, cachedBindStatus = row[:cls.bindColumnCount + 2]  #@UnusedVariable
 
         # if wrong status, exit here.  Item is in queryCache
         if (cachedBindStatus == _BIND_STATUS_ACCEPTED) != bool(accepted):
@@ -835,7 +837,8 @@
         """
         bindRows = yield cls._bindForNameAndHomeID.on(home._txn, name=name, homeID=home._resourceID)
         if bindRows and (bindRows[0][4] == _BIND_STATUS_ACCEPTED) == bool(accepted):
-            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRows[0]  #@UnusedVariable
+            bindRow = bindRows[0]
+            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRow[:cls.bindColumnCount]  #@UnusedVariable
 
             # alt:
             # returnValue((yield cls.objectWithID(home, resourceID)))
@@ -849,7 +852,8 @@
             home._txn, name=name, homeID=home._resourceID
         )
         if groupBindRows and (groupBindRows[0][4] == _BIND_STATUS_ACCEPTED) == bool(accepted):
-            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0]  #@UnusedVariable
+            groupBindRow = groupBindRows[0]
+            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRow[:AddressBookObject.bindColumnCount]  #@UnusedVariable
 
             ownerAddressBookID = yield AddressBookObject.ownerAddressBookIDFromGroupID(home._txn, resourceID)
             # alt:
@@ -887,7 +891,8 @@
             home._txn, resourceID=resourceID, homeID=home._resourceID
         )
         if bindRows and (bindRows[0][4] == _BIND_STATUS_ACCEPTED) == bool(accepted):
-            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRows[0]  #@UnusedVariable
+            bindRow = bindRows[0]
+            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = bindRow[:cls.bindColumnCount]  #@UnusedVariable
 
             ownerHome = yield home.ownerHomeWithChildID(resourceID)
             if accepted:
@@ -899,7 +904,8 @@
                     home._txn, homeID=home._resourceID, addressbookID=resourceID
         )
         if groupBindRows and (groupBindRows[0][4] == _BIND_STATUS_ACCEPTED) == bool(accepted):
-            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRows[0]  #@UnusedVariable
+            groupBindRow = groupBindRows[0]
+            bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRow[:AddressBookObject.bindColumnCount]  #@UnusedVariable
 
             ownerAddressBookID = yield AddressBookObject.ownerAddressBookIDFromGroupID(home._txn, resourceID)
             ownerHome = yield home.ownerHomeWithChildID(ownerAddressBookID)
@@ -1719,7 +1725,6 @@
                 # update revisions table of shared group's containing address book
                 yield self._changeAddressBookRevision(self.ownerHome().addressbook(), inserting)
 
-        self._component = component
         returnValue(self._componentChanged)
 
 
@@ -1795,7 +1800,7 @@
             # get member ids
             memberUIDs = []
             foreignMemberAddrs = []
-            for memberAddr in component.resourceMemberAddresses():
+            for memberAddr in set(component.resourceMemberAddresses()):
                 if len(memberAddr) > len("urn:uuid:") and memberAddr.startswith("urn:uuid:"):
                     memberUIDs.append(memberAddr[len("urn:uuid:"):])
                 else:
@@ -1823,25 +1828,27 @@
 
             # don't store group members in object text
 
-            orginialComponent = str(component)
+            orginialComponentText = str(component)
             # sort addresses in component text
             memberAddresses = component.resourceMemberAddresses()
             component.removeProperties("X-ADDRESSBOOKSERVER-MEMBER")
-            for memberAddress in sorted(memberAddresses):
+            for memberAddress in sorted(list(set(memberAddresses))):
                 component.addProperty(Property("X-ADDRESSBOOKSERVER-MEMBER", memberAddress))
 
             # use sorted test to get size and md5
             componentText = str(component)
             self._md5 = hashlib.md5(componentText).hexdigest()
             self._size = len(componentText)
-            self._componentChanged = componentText != orginialComponent
+            self._componentChanged = orginialComponentText != componentText
 
             # remove members from component get new text
+            self._component = copy.deepcopy(component)
             component.removeProperties("X-ADDRESSBOOKSERVER-MEMBER")
             componentText = str(component)
             self._objectText = componentText
 
         else:
+            self._component = component
             componentText = str(component)
             self._md5 = hashlib.md5(componentText).hexdigest()
             self._size = len(componentText)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130730/6ef96121/attachment-0001.html>


More information about the calendarserver-changes mailing list