[CalendarServer-changes] [11796]
source_changes at macosforge.org
source_changes at macosforge.org
Mon Oct 7 17:31:49 PDT 2013
Revision: 11796
http://trac.calendarserver.org//changeset/11796
Author: gaya at apple.com
Date: 2013-10-07 17:31:49 -0700 (Mon, 07 Oct 2013)
Log Message:
-----------
fix sync report for multiple shared groups - checkpoint
Modified Paths:
--------------
CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml
CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
Added Paths:
-----------
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/1.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/11.xml
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/12.xml
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/14.xml
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/15.xml
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/2.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/3.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/4.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/5.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/6.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/7.vcf
CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync-groups.xml
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/1.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/1.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/1.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,11 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Thompson;Default;;;
+FN:Default Thompson
+EMAIL;type=INTERNET;type=WORK;type=pref:lthompson at example.com
+TEL;type=WORK;type=pref:1-555-555-5555
+TEL;type=CELL:1-444-444-4444
+item1.ADR;type=WORK;type=pref:;;1245 Test;Sesame Street;California;11111;USA
+item1.X-ABADR:us
+UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/11.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/11.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/11.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>$cuaddrurn2:</D:href>
+ <CS:summary>Shared Group12</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+</CS:share>
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/12.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/12.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/12.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>$cuaddrurn1:</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>$addressbookpath1:/6.vcf</href>
+ </hosturl>
+ <in-reply-to>$inviteuid:</in-reply-to>
+ <summary>Shared Group12</summary>
+ <common-name>$username2:</common-name>
+ <first-name>$firstname2:</first-name>
+ <last-name>$lastname2:</last-name>
+</invite-reply>
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/14.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/14.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/14.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>$cuaddrurn2:</D:href>
+ <CS:summary>Shared Group45</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+</CS:share>
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/15.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/15.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/15.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>$cuaddrurn1:</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>$addressbookpath1:/7.vcf</href>
+ </hosturl>
+ <in-reply-to>$inviteuid:</in-reply-to>
+ <summary>Shared Group45</summary>
+ <common-name>$username2:</common-name>
+ <first-name>$firstname2:</first-name>
+ <last-name>$lastname2:</last-name>
+</invite-reply>
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/2.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/2.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/2.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,17 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Contact;Mulberry;;;
+FN:Mulberry Contact
+NICKNAME:mulberry
+ORG:Apple Inc.;
+EMAIL;type=INTERNET;type=WORK;type=pref:mulberry at example.com
+TEL;type=HOME;type=pref:777-777-7777
+TEL;type=WORK:8888888888
+TEL;type=WORK;type=FAX:5555555555
+item1.ADR;type=WORK;type=pref:;;1234 Infinite Circle;Exampletino\, CA 99999;USA;;
+item1.X-ABADR:us
+NOTE:This is a contact created in Mulberry.
+item2.URL;type=pref:http://www.example.com/~magic
+item2.X-ABLabel:_$!<HomePage>!$_
+UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/3.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/3.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/3.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Kawado;Saeko;;;
+FN:Snow Leopard
+ORG:Snow Leopard;
+EMAIL;type=INTERNET;type=WORK;type=pref:snowleopard at example.com
+TEL;type=WORK;type=pref:777-777-7777
+item1.ADR;type=WORK;type=pref:;;1 Fidel Ave. Suite 100;Mountain Top;CA;99999;USA
+item1.X-ABADR:us
+X-ABShowAs:COMPANY
+UID:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/4.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/4.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/4.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Mariotte;WithNote;;;
+FN:WithNote Mariotte
+EMAIL;type=INTERNET;type=WORK;type=pref:withnmariotte at example.com
+TEL;type=WORK;type=pref:1-777-777-7777
+TEL;type=CELL:1-8888888888
+item1.ADR;type=WORK;type=pref:;;1 North Blvd;Cupertino;CA;99999;United States
+item1.X-ABADR:us
+NOTE: Address book server test contact that hsa note field filled in.
+UID:44745975-AE6D-4FB0-80A6-A298427E047A
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/5.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/5.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/5.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,18 @@
+BEGIN:VCARD
+VERSION:3.0
+N:InfoIn;All;;;
+FN:All InfoIn
+ORG:allinfo Company;
+EMAIL;type=INTERNET;type=WORK;type=pref:allinfomationin at example.com
+TEL;type=WORK;type=pref:777-777-7777
+TEL;type=CELL:8888888888
+item1.ADR;type=WORK;type=pref:;;1 Gally Street Apt #2;Mountain Top;CA;99999;USA
+item1.X-ABADR:us
+X-YAHOO;type=WORK;type=pref:saeko.where at example.com
+X-YAHOO-ID;type=WORK;type=pref:saeko.where at example.com
+item2.X-ABRELATEDNAMES;type=pref:Mayumi Yan
+item2.X-ABLabel:_$!<Friend>!$_
+item3.X-ABRELATEDNAMES:Shane
+item3.X-ABLabel:_$!<Assistant>!$_
+UID:3765A955-1B96-41EA-994D-335192BEDCCD
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/6.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/6.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/6.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,11 @@
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Apple Inc.//AddressBook 6.1//EN
+UID:760d9b28-5a13-4880-b7eb-5769e6688fa3
+FN:Group 123
+N:Group123;;;;
+REV:20120503T194243Z
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/7.vcf
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/7.vcf (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/Resource/CardDAV/sharing/sync/group-two/7.vcf 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,11 @@
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Apple Inc.//AddressBook 6.1//EN
+UID:760d9b28-5a13-4880-b7eb-5769e6688fa4
+FN:Group 345
+N:Group345;;;;
+REV:20120503T194243Z
+X-ADDRESSBOOKSERVER-KIND:group
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:3765A955-1B96-41EA-994D-335192BEDCCD
+X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:44745975-AE6D-4FB0-80A6-A298427E047A
+END:VCARD
Added: CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync-groups.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync-groups.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync-groups.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -0,0 +1,1461 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd">
+
+<!--
+ Copyright (c) 2006-2013 Apple Inc. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<caldavtest>
+ <description>Test address book/group sharing and cached home sync tokens</description>
+
+ <require-feature>
+ <feature>carddav</feature>
+ <feature>shared-addressbooks</feature>
+ <feature>sync-report</feature>
+ </require-feature>
+
+ <start>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <ruri>$addressbookhome2:/</ruri>
+ <ruri>$notificationpath1:/</ruri>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ </start>
+
+
+ <!-- test suite below is similar to test suite in ../CalDAV/sharing-sync.xml -->
+ <test-suite name='two shared groups' ignore='no'>
+ <test name='0' ignore='no'>
+ <description>clean up old data</description>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <ruri>$addressbookhome2:/</ruri>
+ <ruri>$notificationpath1:/</ruri>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <description>create users groups</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/1.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/1.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/2.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/2.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/4.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/4.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/5.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/5.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/6.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/7.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='1a' ignore='no'>
+ <description>Initial sync tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>user1 POSTs invitation</description>
+ <request print-response="no">
+ <method>POST</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/11.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='3'>
+ <description>Check user2 notification collection and get invite uid</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$notificationpath2:/</ruri>
+ <grabelement>
+ <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name>
+ <variable>$inviteuid:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='4'>
+ <description>user2 replies ACCEPTED and deletes notification</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions="yes">
+ <content-type>application/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/12.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$notificationpath2:/$inviteuid:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='5a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ <value>$userguid1:/2.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ <value>2.vcf</value>
+ <value>6.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>user1 POSTs invitation</description>
+ <request print-response="no">
+ <method>POST</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/14.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='7'>
+ <description>Check user2 notification collection and get invite uid</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$notificationpath2:/</ruri>
+ <grabelement>
+ <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name>
+ <variable>$inviteuid:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='8'>
+ <description>user2 replies ACCEPTED and deletes notification</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions="yes">
+ <content-type>application/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/15.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$notificationpath2:/$inviteuid:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='9a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ <value>$userguid1:/2.vcf</value>
+ <value>$userguid1:/4.vcf</value>
+ <value>$userguid1:/5.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ <value>2.vcf</value>
+ <value>4.vcf</value>
+ <value>5.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+
+ <test name='10'>
+ <description>Sharee creates vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookhome2:/$userguid1:/3.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/3.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='11a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/3.vcf</value>
+ <value>$addressbook:/6.vcf</value>
+ <value>$addressbook:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/3.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='12'>
+ <description>Sharer changes vcard</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/3.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/3.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='13a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13'>
+ <description>Sharee deletes vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$addressbookhome2:/$userguid1:/3.vcf</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='14a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/6.vcf</value>
+ <value>$addressbook:/7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$addressbook:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='15'>
+ <description>Sharer unshares first group</description>
+ <request print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/POST/sharingremove2.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='16a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/4.vcf</value>
+ <value>$userguid1:/5.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>4.vcf</value>
+ <value>5.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='17'>
+ <description>Sharer unshares 2nd group</description>
+ <request print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/POST/sharingremove2.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='18a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>404</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ </test-suite>
+
+ <end>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <ruri>$addressbookhome2:/</ruri>
+ <ruri>$addressbookhome3:/</ruri>
+ <ruri>$addressbookhome4:/</ruri>
+ <ruri>$notificationpath1:/</ruri>
+ <ruri>$notificationpath2:/</ruri>
+ <ruri>$notificationpath3:/</ruri>
+ <ruri>$notificationpath4:/</ruri>
+ </request>
+ </end>
+
+</caldavtest>
Modified: CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml 2013-10-08 00:03:58 UTC (rev 11795)
+++ CalDAVTester/branches/users/gaya/sharedgroupfixestester/scripts/tests/CardDAV/sharing-sync.xml 2013-10-08 00:31:49 UTC (rev 11796)
@@ -256,7 +256,7 @@
</grabelement>
</request>
</test>
- <test name='5d' ignore='no'>
+ <test name='5d-' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
@@ -265,9 +265,27 @@
<filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
</data>
<verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
<callback>multistatusItems</callback>
<arg>
<name>okhrefs</name>
+ <value>$addressbook:/</value>
<value>$sharedaddressbook:/</value>
</arg>
</verify>
@@ -277,6 +295,23 @@
</grabelement>
</request>
</test>
+ <test name='5e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='5e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
@@ -299,6 +334,23 @@
</grabelement>
</request>
</test>
+ <test name='5f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='5f' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
@@ -1031,9 +1083,12 @@
<callback>statusCode</callback>
</verify>
</request>
- <request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>DELETE</method>
<ruri>$notificationpath2:/$inviteuid:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
</request>
</test>
<test name='5a' ignore='no'>
@@ -1099,18 +1154,36 @@
</grabelement>
</request>
</test>
+ <test name='5d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='5d' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
<ruri>$addressbookhome2:/</ruri>
<data substitutions='yes'>
<content-type>text/xml; charset=utf-8</content-type>
- <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
</data>
<verify>
<callback>multistatusItems</callback>
<arg>
<name>okhrefs</name>
+ <value>$addressbook:/</value>
<value>$userguid1:/</value>
</arg>
</verify>
@@ -1120,6 +1193,23 @@
</grabelement>
</request>
</test>
+ <test name='5e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='5e' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
@@ -1143,6 +1233,23 @@
</grabelement>
</request>
</test>
+ <test name='5f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='5f' ignore='no'>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>REPORT</method>
@@ -1152,7 +1259,11 @@
<filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
</data>
<verify>
- <callback>statusCode</callback>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ </arg>
</verify>
<grabelement>
<name>/{DAV:}multistatus/{DAV:}sync-token</name>
@@ -2156,6 +2267,1412 @@
</test>
</test-suite>
+ <!-- test suite below is similar to test suite in ../CalDAV/sharing-sync.xml -->
+ <test-suite name='two shared groups' ignore='no'>
+ <test name='0' ignore='no'>
+ <description>clean up old data</description>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <ruri>$addressbookhome2:/</ruri>
+ <ruri>$notificationpath1:/</ruri>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <description>create users groups</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/1.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/1.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/2.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/2.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/4.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/4.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/5.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/5.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/6.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/7.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='1a' ignore='no'>
+ <description>Initial sync tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='1e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>user1 POSTs invitation</description>
+ <request print-response="no">
+ <method>POST</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/11.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='3'>
+ <description>Check user2 notification collection and get invite uid</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$notificationpath2:/</ruri>
+ <grabelement>
+ <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name>
+ <variable>$inviteuid:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='4'>
+ <description>user2 replies ACCEPTED and deletes notification</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions="yes">
+ <content-type>application/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/12.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$notificationpath2:/$inviteuid:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='5a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ <value>$userguid1:/2.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='5f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ <value>2.vcf</value>
+ <value>6.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>user1 POSTs invitation</description>
+ <request print-response="no">
+ <method>POST</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/14.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='7'>
+ <description>Check user2 notification collection and get invite uid</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$notificationpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$notificationpath2:/</ruri>
+ <grabelement>
+ <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name>
+ <variable>$inviteuid:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='8'>
+ <description>user2 replies ACCEPTED and deletes notification</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions="yes">
+ <content-type>application/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/15.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$notificationpath2:/$inviteuid:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='9a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/1.vcf</value>
+ <value>$userguid1:/2.vcf</value>
+ <value>$userguid1:/4.vcf</value>
+ <value>$userguid1:/5.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='9f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>1.vcf</value>
+ <value>2.vcf</value>
+ <value>4.vcf</value>
+ <value>5.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+
+ <test name='10'>
+ <description>Sharee creates vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookhome2:/$userguid1:/3.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/3.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='11a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/3.vcf</value>
+ <value>$addressbook:/6.vcf</value>
+ <value>$addressbook:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/3.vcf</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='11f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='12'>
+ <description>Sharer changes vcard</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$addressbookpath1:/3.vcf</ruri>
+ <data>
+ <content-type>text/vcard; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/sync/group-two/3.vcf</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='13a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='13'>
+ <description>Sharee deletes vcard</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$addressbookhome2:/$userguid1:/3.vcf</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='14a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$addressbook:/6.vcf</value>
+ <value>$addressbook:/7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$addressbook:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/6.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='14f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>6.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ <arg>
+ <name>badhrefs</name>
+ <value>3.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='15'>
+ <description>Sharer unshares first group</description>
+ <request print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookpath1:/6.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/POST/sharingremove2.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='16a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16d-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16e-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ <value>$userguid1:/</value>
+ <value>$userguid1:/4.vcf</value>
+ <value>$userguid1:/5.vcf</value>
+ <value>$userguid1:/7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='16f-' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>403</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-init-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>4.vcf</value>
+ <value>5.vcf</value>
+ <value>7.vcf</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken6:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='17'>
+ <description>Sharer unshares 2nd group</description>
+ <request print-response='no'>
+ <method>POST</method>
+ <ruri>$addressbookpath1:/7.vcf</ruri>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/POST/sharingremove2.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='18a' ignore='no'>
+ <description>Updated tokens</description>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token1-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken1:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18b' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token2-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>okhrefs</name>
+ <value>$addressbook:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken2:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18c' ignore='no'>
+ <request print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookpath1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token3-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken3:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18d' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token4-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken4:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18e' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token5-level-infinite.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>badhrefs</name>
+ <value>$userguid1:/</value>
+ </arg>
+ </verify>
+ <grabelement>
+ <name>/{DAV:}multistatus/{DAV:}sync-token</name>
+ <variable>$synctoken5:</variable>
+ </grabelement>
+ </request>
+ </test>
+ <test name='18f' ignore='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>REPORT</method>
+ <ruri>$addressbookhome2:/$userguid1:/</ruri>
+ <data substitutions='yes'>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/REPORT/sync-token6-level-1.xml</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>404</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ </test-suite>
+
<!-- test suites below are similar to those in ../CalDAV/sync-report.xml but
use shared address books instead of calendars -->
@@ -4253,7 +5770,7 @@
</test>
</test-suite>
- <test-suite name='simple reports - diff token - delete/create addressbook - home depth:infinity' ignore='no'>
+ <test-suite name='simple reports - diff token - delete/create addressbook - home depth:infinity' ignore='yes'>
<require-feature>
<feature>sync-report-home</feature>
</require-feature>
Modified: CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-10-08 00:03:58 UTC (rev 11795)
+++ CalendarServer/branches/users/gaya/sharedgroupfixes/txdav/carddav/datastore/sql.py 2013-10-08 00:31:49 UTC (rev 11796)
@@ -595,11 +595,8 @@
bindRevisions += [groupBindRow[5] for groupBindRow in groupBindRows]
if revision != 0 and revision < max(bindRevisions):
- if depth == "1":
- revision = 0
- else:
- # perhaps we could return a multistatus result of 403 instead: TODO: Check RFC
- raise SyncTokenValidException
+ # perhaps we could return a multistatus result of 403 instead: TODO: Check RFC
+ raise SyncTokenValidException
path = self.name()
@@ -1305,42 +1302,42 @@
@inlineCallbacks
- def _objectAccessSets(self):
+ def _groupIDAccessSets(self):
if self.owned():
- returnValue(([], []))
+ returnValue((set(), set()))
else:
groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
self._txn, homeID=self._home._resourceID, addressbookID=self._resourceID
)
- readWriteObjectIDs = []
- readOnlyObjectIDs = []
+ readWriteGroupIDs = set()
+ readOnlyGroupIDs = set()
for groupBindRow in groupBindRows:
bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRow[:AddressBookObject.bindColumnCount] #@UnusedVariable
if bindMode == _BIND_MODE_WRITE:
- readWriteObjectIDs.append(resourceID)
+ readWriteGroupIDs.add(resourceID)
else:
- readOnlyObjectIDs.append(resourceID)
+ readOnlyGroupIDs.add(resourceID)
- if readOnlyObjectIDs and readWriteObjectIDs:
+ if readOnlyGroupIDs and readWriteGroupIDs:
# expand read-write groups and remove any subgroups from read-only group list
- allWriteableIDs = yield self.expandGroupIDs(self._txn, readWriteObjectIDs)
- adjustedReadOnlyGroupIDs = set(readOnlyObjectIDs) - set(allWriteableIDs)
- adjustedReadWriteGroupIDs = set(readWriteObjectIDs) | (set(readOnlyObjectIDs) - adjustedReadOnlyGroupIDs)
+ allWriteableIDs = yield self.expandGroupIDs(self._txn, readWriteGroupIDs)
+ adjustedReadOnlyGroupIDs = set(readOnlyGroupIDs) - set(allWriteableIDs)
+ adjustedReadWriteGroupIDs = set(readWriteGroupIDs) | (set(readOnlyGroupIDs) - adjustedReadOnlyGroupIDs)
else:
- adjustedReadOnlyGroupIDs = readOnlyObjectIDs
- adjustedReadWriteGroupIDs = readWriteObjectIDs
- returnValue((tuple(adjustedReadOnlyGroupIDs), tuple(adjustedReadWriteGroupIDs)))
+ adjustedReadOnlyGroupIDs = readOnlyGroupIDs
+ adjustedReadWriteGroupIDs = readWriteGroupIDs
+ returnValue((adjustedReadOnlyGroupIDs, adjustedReadWriteGroupIDs))
# FIXME: Unused
@inlineCallbacks
- def readOnlyObjectIDs(self):
- returnValue((yield self._objectAccessSets())[0])
+ def readOnlyGroupIDs(self):
+ returnValue((yield self._groupIDAccessSets())[0])
@inlineCallbacks
- def readWriteObjectIDs(self):
- returnValue((yield self._objectAccessSets())[1])
+ def readWriteGroupIDs(self):
+ returnValue((yield self._groupIDAccessSets())[1])
'''
# FIXME: Unused: Use for caching access
@@ -1360,32 +1357,32 @@
groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
self._txn, homeID=self._home._resourceID, addressbookID=self._resourceID
)
- readWriteObjectIDs = []
- readOnlyObjectIDs = []
+ readWriteGroupIDs = []
+ readOnlyGroupIDs = []
for groupBindRow in groupBindRows:
bindMode, homeID, resourceID, bindName, bindStatus, bindRevision, bindMessage = groupBindRow[:AddressBookObject.bindColumnCount] #@UnusedVariable
if bindMode == _BIND_MODE_WRITE:
- readWriteObjectIDs.append(resourceID)
+ readWriteGroupIDs.append(resourceID)
else:
- readOnlyObjectIDs.append(resourceID)
+ readOnlyGroupIDs.append(resourceID)
- if readOnlyObjectIDs:
- readOnlyIDs |= set((yield self.expandGroupIDs(self._txn, readOnlyObjectIDs)))
- if readWriteObjectIDs:
- readWriteIDs |= set((yield self.expandGroupIDs(self._txn, readWriteObjectIDs)))
+ if readOnlyGroupIDs:
+ readOnlyIDs |= set((yield self.expandGroupIDs(self._txn, readOnlyGroupIDs)))
+ if readWriteGroupIDs:
+ readWriteIDs |= set((yield self.expandGroupIDs(self._txn, readWriteGroupIDs)))
readOnlyIDs -= readWriteIDs
returnValue(tuple(readOnlyIDs), tuple(readWriteIDs))
# FIXME: Unused: Use for caching access
@inlineCallbacks
- def readOnlyObjectIDs(self):
+ def readOnlyGroupIDs(self):
returnValue((yield self.accessControlObjectIDs())[1])
# FIXME: Unused: Use for caching access
@inlineCallbacks
- def readWriteObjectIDs(self):
+ def readWriteGroupIDs(self):
returnValue((yield self.accessControlObjectIDs())[1])
@@ -1439,9 +1436,10 @@
# count accepted
if bind.BIND_STATUS in columnMap:
previouslyAcceptedBindCount = 1 if shareeView.fullyShared() else 0
- previouslyAcceptedBindCount += len((yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=shareeView._resourceID
- )))
+ )
+ previouslyAcceptedBindCount += len(groupBindRows)
bindNameRows = yield self._updateBindColumnsQuery(columnMap).on(
self._txn,
@@ -1466,6 +1464,12 @@
yield shareeView._deletedSyncToken(sharedRemoval=True)
shareeView.viewerHome()._children.pop(self.shareeName(), None)
shareeView.viewerHome()._children.pop(shareeView._resourceID, None)
+ else:
+ #update all bind revisions
+ yield shareeView.notifyPropertyChanged()
+ for groupBindRow in groupBindRows:
+ groupObject = yield shareeView.objectResourceWithID(groupBindRow[2])
+ yield groupObject._initBindRevision()
if bind.MESSAGE in columnMap:
shareeView._bindMessage = columnMap[bind.MESSAGE]
@@ -1489,6 +1493,9 @@
"""
call super and set isShared = True
"""
+
+ # Note: super always calls shareView._initSyncToken():
+ # even when shareView is previously shared via group sharing
bindName = yield super(AddressBook, self).shareWith(shareeHome, mode, status, message)
queryCacher = self._txn._queryCacher
@@ -1517,16 +1524,20 @@
if shareeAddressBook:
acceptedBindCount = 1 if shareeAddressBook.fullyShared() else 0
- acceptedBindCount += len((yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
self._txn, homeID=shareeHome._resourceID, addressbookID=shareeAddressBook._resourceID
- )))
+ )
+ acceptedBindCount += len(groupBindRows)
if acceptedBindCount == 1:
yield shareeAddressBook._deletedSyncToken(sharedRemoval=True)
shareeHome._children.pop(self.shareeName(), None)
shareeHome._children.pop(shareeAddressBook._resourceID, None)
- elif not shareeAddressBook.fullyShared():
- # FIXME: remove objects for this group only using self.removeObjectResource()
- self._objectNames = None
+ else:
+ yield shareeAddressBook.notifyPropertyChanged()
+ #update all bind revisions
+ for groupBindRow in groupBindRows:
+ groupObject = yield shareeAddressBook.objectResourceWithID(groupBindRow[2])
+ yield groupObject._initBindRevision()
# Must send notification to ensure cache invalidation occurs
yield self.notifyPropertyChanged()
@@ -1611,36 +1622,25 @@
if self.isGroupForSharedAddressBook() or self.shareUID():
raise HTTPError(FORBIDDEN)
- if not self.owned() and not self.addressbook().fullyShared():
- readWriteObjectIDs = yield self.addressbook().readWriteObjectIDs()
+ partiallyShared = not self.owned() and not self.addressbook().fullyShared()
+ if partiallyShared:
+ readWriteGroupIDs = yield self.addressbook().readWriteGroupIDs()
readWriteObjectIDs = (
- set((yield self.addressbook().expandGroupIDs(self._txn, readWriteObjectIDs)))
- if readWriteObjectIDs else set()
+ set((yield self.addressbook().expandGroupIDs(self._txn, readWriteGroupIDs)))
+ if readWriteGroupIDs else set()
)
-
# can't delete item in read-only shared group, even if user has addressbook unbind
if self._resourceID not in readWriteObjectIDs:
raise HTTPError(FORBIDDEN)
- # get sync token for delete now
- yield self.addressbook()._deleteRevision(self.name(), self._resourceID)
+ # get sync token for delete now
+ yield self.addressbook()._deleteRevision(self.name(), self._resourceID)
- readWriteGroupIDs = set()
- for readWriteObjectID in readWriteObjectIDs:
- abObject = yield self.addressbook().objectResourceWithID(readWriteObjectID)
- if abObject.kind() == _ABO_KIND_GROUP:
- readWriteGroupIDs.add(readWriteObjectID)
- yield self.addressbook()._updateRevision(abObject.name())
-
- else:
- # get sync token for delete now
- yield self.addressbook()._deleteRevision(self.name(), self._resourceID)
-
# get groups where this object was once a member and version info
aboMembers = schema.ABO_MEMBERS
groupRows = yield Select([aboMembers.GROUP_ID, aboMembers.MEMBER_ID, aboMembers.REMOVED, aboMembers.REVISION],
From=aboMembers,
- Where=aboMembers.MEMBER_ID == self._resourceID,
+ Where=(aboMembers.MEMBER_ID == self._resourceID)
).on(self._txn)
# combine by groupID
@@ -1656,9 +1656,9 @@
if self._resourceID in AddressBook._currentMemberIDsFromMemberIDRemovedRevisionRows(memberRows)
])
- if not self.owned() and not self.addressbook().fullyShared():
- groupIDsToRemoveFrom = readWriteGroupIDs | groupIDs
- groupIDs -= readWriteGroupIDs
+ if partiallyShared:
+ groupIDsToRemoveFrom = groupIDs & readWriteObjectIDs
+ groupIDs -= readWriteObjectIDs
else:
groupIDsToRemoveFrom = groupIDs
@@ -1671,6 +1671,9 @@
revision=self._syncTokenRevision,
removed=True,
)
+ if partiallyShared:
+ groupObject = yield self.addressbook().objectResourceWithID(groupIDToRemoveFrom)
+ yield self.addressbook()._updateRevision(groupObject.name())
# add to foreign member table row by UID (aboForeignMembers on address books)
memberAddress = "urn:uuid:" + self._uid
@@ -1683,10 +1686,8 @@
).on(self._txn)
if self.kind() == _ABO_KIND_GROUP:
-
# mark members as deleted
memberIDsToRemove = yield AddressBook.memberIDsWithGroupIDs(self._txn, [self._resourceID])
-
for memberIDToRemove in memberIDsToRemove:
yield self._insertMemberIDQuery.on(
self._txn,
@@ -1717,9 +1718,9 @@
returnValue(True)
#otherwise, must be in a read-write group
- readWriteObjectIDs = yield self.addressbook().readWriteObjectIDs()
- readWriteIDs = yield self.addressbook().expandGroupIDs(self._txn, readWriteObjectIDs)
- returnValue(self._resourceID in readWriteIDs)
+ readWriteGroupIDs = yield self.addressbook().readWriteGroupIDs()
+ readWriteObjectIDs = yield self.addressbook().expandGroupIDs(self._txn, readWriteGroupIDs)
+ returnValue(self._resourceID in readWriteObjectIDs)
@classmethod
@@ -2207,15 +2208,15 @@
).on(self._txn)
groupIDs = set([groupIDRow[0] for groupIDRow in groupIDRows])
+ # add this object to shared groups
if not self.owned() and not self.addressbook().fullyShared():
- readWriteObjectIDs = yield self.addressbook().readWriteObjectIDs()
- assert readWriteObjectIDs, "no access"
+ readWriteGroupIDs = yield self.addressbook().readWriteGroupIDs()
+ assert readWriteGroupIDs, "no access"
+ groupIDs |= readWriteGroupIDs
- for readWriteObjectID in readWriteObjectIDs:
- abObject = yield self.addressbook().objectResourceWithID(readWriteObjectID)
- if abObject.kind() == _ABO_KIND_GROUP:
- groupIDs.add(readWriteObjectID)
- yield self.addressbook()._updateRevision(abObject.name())
+ for readWriteGroupID in readWriteGroupIDs:
+ groupObject = yield self.addressbook().objectResourceWithID(readWriteGroupID)
+ yield self.addressbook()._updateRevision(groupObject.name())
# add to member table rows
for groupID in groupIDs:
@@ -2509,16 +2510,23 @@
if shareeAddressBook and shareeAddressBook._bindStatus == _BIND_STATUS_ACCEPTED:
acceptedBindCount = 1 if shareeAddressBook.fullyShared() else 0
- acceptedBindCount += len((
- yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
- self._txn, homeID=shareeHome._resourceID, addressbookID=shareeAddressBook._resourceID
- )
- ))
+ groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeHome._resourceID, addressbookID=shareeAddressBook._resourceID
+ )
+ acceptedBindCount += len(groupBindRows)
if acceptedBindCount == 1:
yield shareeAddressBook._deletedSyncToken(sharedRemoval=True)
shareeHome._children.pop(self.addressbook().shareeName(), None)
shareeHome._children.pop(self.addressbook()._resourceID, None)
+ else:
+ shareeAddressBook.notifyPropertyChanged()
+ #update all bind revisions
+ for groupBindRow in groupBindRows:
+ groupObject = yield shareeAddressBook.objectResourceWithID(groupBindRow[2])
+ yield groupObject._initBindRevision()
+ if shareeAddressBook.fullyShared():
+ yield shareeAddressBook._initBindRevision()
# Must send notification to ensure cache invalidation occurs
yield self.addressbook().notifyPropertyChanged()
@@ -2598,17 +2606,14 @@
else:
if status == _BIND_STATUS_ACCEPTED:
shareeView = yield shareeHome.objectWithShareUID(bindName)
+ groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=shareeView.addressbook()._resourceID
+ )
+ currentAcceptedBindCount = len(groupBindRows)
if not shareeView.addressbook().fullyShared():
- currentAcceptedBindCount = len((
- yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
- self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=shareeView.addressbook()._resourceID
- )
- ))
if currentAcceptedBindCount == 1:
yield shareeView.addressbook()._initSyncToken()
- yield shareeView._initBindRevision()
-
queryCacher = self._txn._queryCacher
if queryCacher:
cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self.addressbook().shareeName())
@@ -2673,12 +2678,11 @@
# count accepted
if bind.BIND_STATUS in columnMap:
- previouslyAcceptedBindCount = 1 if self.addressbook().fullyShared() else 0
- previouslyAcceptedBindCount += len((
- yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
- self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=self.addressbook()._resourceID
- )
- ))
+ previouslyAcceptedBindCount = 1 if shareeView.addressbook().fullyShared() else 0
+ groupBindRows = yield AddressBookObject._acceptedBindForHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeView.viewerHome()._resourceID, addressbookID=self.addressbook()._resourceID
+ )
+ previouslyAcceptedBindCount += len(groupBindRows)
bindNameRows = yield self._updateBindColumnsQuery(columnMap).on(
self._txn,
@@ -2698,11 +2702,20 @@
shareeView.viewerHome()._children[self.addressbook().shareeName()] = shareeView.addressbook()
shareeView.viewerHome()._children[shareeView._resourceID] = shareeView.addressbook()
yield shareeView._initBindRevision()
- elif shareeView._bindStatus != _BIND_STATUS_INVITED:
+ elif shareeView._bindStatus == _BIND_STATUS_DECLINED:
if 1 == previouslyAcceptedBindCount:
yield shareeView.addressbook()._deletedSyncToken(sharedRemoval=True)
shareeView.viewerHome()._children.pop(self.addressbook().shareeName(), None)
shareeView.viewerHome()._children.pop(shareeView._resourceID, None)
+ else:
+ # update all bind revisions
+ yield shareeView.addressbook().notifyPropertyChanged()
+ for groupBindRow in groupBindRows:
+ if groupBindRow[2] != shareeView._resourceID:
+ groupObject = yield shareeView.addressbook().objectResourceWithID(groupBindRow[2])
+ yield groupObject._initBindRevision()
+ if shareeView.addressbook().fullyShared():
+ yield shareeView.addressbook()._initBindRevision()
if bind.MESSAGE in columnMap:
shareeView._bindMessage = columnMap[bind.MESSAGE]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20131007/ae882bb6/attachment-0001.html>
More information about the calendarserver-changes
mailing list