<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[15558] CalendarServer/trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/15558">15558</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2016-04-27 13:55:07 -0700 (Wed, 27 Apr 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Make sure push notifications can propagate from pod-to-pod to ensure sharees are notified properly.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunktwistedcaldavresourcepy">CalendarServer/trunk/twistedcaldav/resource.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavsharingpy">CalendarServer/trunk/twistedcaldav/sharing.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavstorebridgepy">CalendarServer/trunk/twistedcaldav/storebridge.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_sharingpy">CalendarServer/trunk/twistedcaldav/test/test_sharing.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoresqlpy">CalendarServer/trunk/txdav/caldav/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoretesttest_implicitpy">CalendarServer/trunk/txdav/caldav/datastore/test/test_implicit.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoretesttest_sql_externalpy">CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_external.py</a></li>
<li><a href="#CalendarServertrunktxdavcaldavdatastoretesttest_sql_sharingpy">CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_sharing.py</a></li>
<li><a href="#CalendarServertrunktxdavcarddavdatastoresqlpy">CalendarServer/trunk/txdav/carddav/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcarddavdatastoretesttest_sql_sharingpy">CalendarServer/trunk/txdav/carddav/datastore/test/test_sql_sharing.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastorepoddingsharing_invitespy">CalendarServer/trunk/txdav/common/datastore/podding/sharing_invites.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastorepoddingtestutilpy">CalendarServer/trunk/txdav/common/datastore/podding/test/util.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresqlpy">CalendarServer/trunk/txdav/common/datastore/sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresql_externalpy">CalendarServer/trunk/txdav/common/datastore/sql_external.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoresql_sharingpy">CalendarServer/trunk/txdav/common/datastore/sql_sharing.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoretesttest_sqlpy">CalendarServer/trunk/txdav/common/datastore/test/test_sql.py</a></li>
<li><a href="#CalendarServertrunktxdavcommondatastoretestutilpy">CalendarServer/trunk/txdav/common/datastore/test/util.py</a></li>
<li><a href="#CalendarServertrunktxdavwhotesttest_group_shareespy">CalendarServer/trunk/txdav/who/test/test_group_sharees.py</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunktwistedcaldavresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/resource.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/resource.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/twistedcaldav/resource.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -546,7 +546,7 @@
</span><span class="cx"> customxml.AllowedSharingModes.qname(),
</span><span class="cx"> customxml.SharedURL.qname(),
</span><span class="cx"> )
</span><del>- if self.isShared() or self.isShareeResource():
</del><ins>+ if self.isSharedByOwner() or self.isShareeResource():
</ins><span class="cx"> baseProperties += (
</span><span class="cx"> customxml.Invite.qname(),
</span><span class="cx"> )
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavsharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/sharing.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/sharing.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/twistedcaldav/sharing.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx"> # See if this property is on the shared calendar
</span><del>- if self.isShared():
</del><ins>+ if self.isSharedByOwner():
</ins><span class="cx"> invitations = yield self.validateInvites(request)
</span><span class="cx"> returnValue(customxml.Invite(
</span><span class="cx"> *[(yield invitePropertyElement(invitation)) for invitation in invitations]
</span><span class="lines">@@ -220,12 +220,12 @@
</span><span class="cx"> ))
</span><span class="cx">
</span><span class="cx">
</span><del>- def isShared(self):
</del><ins>+ def isSharedByOwner(self):
</ins><span class="cx"> """
</span><span class="cx"> Return True if this is an owner shared calendar collection.
</span><span class="cx"> """
</span><span class="cx"> try:
</span><del>- return self._newStoreObject.isShared() if self._newStoreObject else False
</del><ins>+ return self._newStoreObject.isSharedByOwner() if self._newStoreObject else False
</ins><span class="cx"> except AttributeError:
</span><span class="cx"> return False
</span><span class="cx">
</span><span class="lines">@@ -731,7 +731,7 @@
</span><span class="cx"> numRecords = len(invites)
</span><span class="cx">
</span><span class="cx"> # Set the sharing state on the collection
</span><del>- shared = self.isShared()
</del><ins>+ shared = self.isSharedByOwner()
</ins><span class="cx"> if shared and numRecords == 0:
</span><span class="cx"> yield self.downgradeFromShare(request)
</span><span class="cx"> elif not shared and numRecords != 0:
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavstorebridgepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/storebridge.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/storebridge.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -1195,7 +1195,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def resourceType(self):
</span><del>- if self.isShared():
</del><ins>+ if self.isSharedByOwner():
</ins><span class="cx"> return customxml.ResourceType.sharedownercalendar
</span><span class="cx"> elif self.isShareeResource():
</span><span class="cx"> return customxml.ResourceType.sharedcalendar
</span><span class="lines">@@ -3315,7 +3315,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def resourceType(self):
</span><del>- if self.isShared():
</del><ins>+ if self.isSharedByOwner():
</ins><span class="cx"> return customxml.ResourceType.sharedowneraddressbook
</span><span class="cx"> elif self.isShareeResource():
</span><span class="cx"> return customxml.ResourceType.sharedaddressbook
</span><span class="lines">@@ -3585,7 +3585,7 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def resourceType(self):
</span><del>- if self.isShared():
</del><ins>+ if self.isSharedByOwner():
</ins><span class="cx"> return customxml.ResourceType.sharedownergroup
</span><span class="cx"> elif self.isShareeResource():
</span><span class="cx"> return customxml.ResourceType.sharedgroup
</span><span class="lines">@@ -3610,7 +3610,7 @@
</span><span class="cx"> abCollectionResource = (yield request.locateResource(parentForURL(request.uri)))
</span><span class="cx"> returnValue((yield abCollectionResource.storeRemove(request)))
</span><span class="cx">
</span><del>- elif self.isShared():
</del><ins>+ elif self.isSharedByOwner():
</ins><span class="cx"> yield self.downgradeFromShare(request)
</span><span class="cx">
</span><span class="cx"> response = (
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_sharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_sharing.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_sharing.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/twistedcaldav/test/test_sharing.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -239,7 +239,7 @@
</span><span class="cx">
</span><span class="cx"> rtype = self.resource.resourceType()
</span><span class="cx"> self.assertEquals(rtype, regularCalendarType)
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx"> isShareeResource = self.resource.isShareeResource()
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -248,7 +248,7 @@
</span><span class="cx">
</span><span class="cx"> rtype = self.resource.resourceType()
</span><span class="cx"> self.assertEquals(rtype, sharedOwnerType)
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx"> isShareeResource = self.resource.isShareeResource()
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -261,7 +261,7 @@
</span><span class="cx">
</span><span class="cx"> rtype = self.resource.resourceType()
</span><span class="cx"> self.assertEquals(rtype, sharedOwnerType)
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx"> isShareeResource = self.resource.isShareeResource()
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -270,7 +270,7 @@
</span><span class="cx">
</span><span class="cx"> rtype = self.resource.resourceType()
</span><span class="cx"> self.assertEquals(rtype, regularCalendarType)
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx"> isShareeResource = self.resource.isShareeResource()
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -302,7 +302,7 @@
</span><span class="cx"> )
</span><span class="cx"> ))
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx"> isShareeResource = self.resource.isShareeResource()
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -332,7 +332,7 @@
</span><span class="cx"> )
</span><span class="cx"> ))
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx"> isShareeResource = (yield self.resource.isShareeResource())
</span><span class="cx"> self.assertFalse(isShareeResource)
</span><span class="lines">@@ -341,7 +341,7 @@
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_POSTupdateInvitee(self):
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx">
</span><span class="cx"> yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
</span><span class="lines">@@ -354,7 +354,7 @@
</span><span class="cx"> </CS:share>
</span><span class="cx"> """)
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx">
</span><span class="cx"> yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
</span><span class="lines">@@ -367,7 +367,7 @@
</span><span class="cx"> </CS:share>
</span><span class="cx"> """)
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx">
</span><span class="cx"> propInvite = (yield self.resource.readProperty(customxml.Invite, None))
</span><span class="lines">@@ -385,7 +385,7 @@
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_POSTremoveInvitee(self):
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx">
</span><span class="cx"> yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
</span><span class="lines">@@ -398,7 +398,7 @@
</span><span class="cx"> </CS:share>
</span><span class="cx"> """)
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertTrue(isShared)
</span><span class="cx">
</span><span class="cx"> yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
</span><span class="lines">@@ -409,7 +409,7 @@
</span><span class="cx"> </CS:share>
</span><span class="cx"> """)
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx">
</span><span class="cx"> propInvite = (yield self.resource.readProperty(customxml.Invite, None))
</span><span class="lines">@@ -868,7 +868,7 @@
</span><span class="cx"> </CS:share>
</span><span class="cx"> """)
</span><span class="cx">
</span><del>- isShared = self.resource.isShared()
</del><ins>+ isShared = self.resource.isSharedByOwner()
</ins><span class="cx"> self.assertFalse(isShared)
</span><span class="cx">
</span><span class="cx"> propInvite = (yield self.resource.readProperty(customxml.Invite, None))
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/sql.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -88,7 +88,8 @@
</span><span class="cx"> _ATTACHMENTS_MODE_READ, _ATTACHMENTS_MODE_WRITE, _BIND_MODE_DIRECT, \
</span><span class="cx"> _BIND_MODE_GROUP, _BIND_MODE_GROUP_READ, _BIND_MODE_GROUP_WRITE, \
</span><span class="cx"> _BIND_MODE_OWN, _BIND_MODE_READ, _BIND_MODE_WRITE, _BIND_STATUS_ACCEPTED, \
</span><del>- _TRANSP_OPAQUE, _TRANSP_TRANSPARENT, schema, _CHILD_TYPE_TRASH
</del><ins>+ _TRANSP_OPAQUE, _TRANSP_TRANSPARENT, schema, _CHILD_TYPE_TRASH, \
+ _HOME_STATUS_NORMAL
</ins><span class="cx"> from txdav.common.datastore.sql_sharing import SharingInvitation
</span><span class="cx"> from txdav.common.icommondatastore import IndexedSearchException, \
</span><span class="cx"> InternalDataStoreError, HomeChildNameAlreadyExistsError, \
</span><span class="lines">@@ -2588,6 +2589,7 @@
</span><span class="cx"> self.ownerHome().id(),
</span><span class="cx"> guid,
</span><span class="cx"> 0,
</span><ins>+ _HOME_STATUS_NORMAL,
</ins><span class="cx"> gmode,
</span><span class="cx"> _BIND_STATUS_ACCEPTED,
</span><span class="cx"> "",
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoretesttest_implicitpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_implicit.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/test/test_implicit.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_implicit.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -223,7 +223,7 @@
</span><span class="cx"> """
</span><span class="cx">
</span><span class="cx"> calendar_collection = (yield self.calendarUnderTest(home="user01"))
</span><del>- calendar_collection.setSupportedComponents("VTODO")
</del><ins>+ yield calendar_collection.setSupportedComponents("VTODO")
</ins><span class="cx"> calendar = Component.fromString(data1)
</span><span class="cx"> yield self.failUnlessFailure(calendar_collection.createCalendarObjectWithName("test.ics", calendar), InvalidComponentTypeError)
</span><span class="cx"> yield self.commit()
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoretesttest_sql_externalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_external.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_external.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_external.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -25,6 +25,8 @@
</span><span class="cx"> from txdav.common.datastore.podding.test.util import MultiStoreConduitTest
</span><span class="cx"> from txdav.common.datastore.podding.base import FailedCrossPodRequestError
</span><span class="cx"> from txdav.common.icommondatastore import ExternalShareFailed
</span><ins>+from twistedcaldav.ical import Component
+from operator import methodcaller, itemgetter
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> class BaseSharingTests(MultiStoreConduitTest):
</span><span class="lines">@@ -59,6 +61,21 @@
</span><span class="cx"> END:VCALENDAR
</span><span class="cx"> """
</span><span class="cx">
</span><ins>+ cal2 = """BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:uid2
+DTSTART:20131123T140000
+DURATION:PT1H
+CREATED:20060102T190000Z
+DTSTAMP:20051222T210507Z
+SUMMARY:event 2
+END:VEVENT
+END:VCALENDAR
+"""
+
</ins><span class="cx"> @classproperty(cache=False)
</span><span class="cx"> def requirements(cls): #@NoSelf
</span><span class="cx"> return {
</span><span class="lines">@@ -104,7 +121,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -117,7 +134,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("puser02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -132,7 +149,7 @@
</span><span class="cx"> inviteUID = shareeView.shareUID()
</span><span class="cx"> sharedName = shareeView.name()
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -153,7 +170,7 @@
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -163,9 +180,9 @@
</span><span class="cx"> yield self.commitTransaction(1)
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx"> yield calendar.setShared(False)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -178,7 +195,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("puser02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -187,7 +204,7 @@
</span><span class="cx"> inviteUID = shareeView.shareUID()
</span><span class="cx"> sharedName = shareeView.name()
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -213,7 +230,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -231,7 +248,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -244,7 +261,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("puser02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -253,7 +270,7 @@
</span><span class="cx"> inviteUID = shareeView.shareUID()
</span><span class="cx"> sharedName = shareeView.name()
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -280,7 +297,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -298,7 +315,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -312,7 +329,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("puser02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -321,7 +338,7 @@
</span><span class="cx">
</span><span class="cx"> sharedName = shareeView.name()
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -348,7 +365,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commitTransaction(0)
</span><span class="cx">
</span><span class="lines">@@ -366,7 +383,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -505,7 +522,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.directShareWithUser("puser02")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -591,7 +608,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(txn=self.theTransactionUnderTest(0), home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.assertFailure(calendar.inviteUIDToShare("puser02", _BIND_MODE_READ, "summary"), FailedCrossPodRequestError)
</span><span class="cx">
</span><span class="lines">@@ -738,7 +755,51 @@
</span><span class="cx"> yield self.commitTransaction(1)
</span><span class="cx">
</span><span class="cx">
</span><ins>+ @inlineCallbacks
+ def test_shared_notifications(self):
+ shared_name_puser02 = yield self.createShare()
+ shared_name_user02 = yield self.createShare(shareeGUID="user02", pod=0)
</ins><span class="cx">
</span><ins>+ map(methodcaller("reset"), self.theNotifiers)
+
+ # Change by owner
+ home = yield self.homeUnderTest(txn=self.theTransactionUnderTest(0), name="user01")
+ self.assertEquals(home.notifierID(), ("CalDAV", "user01",))
+ calendar = yield home.calendarWithName("calendar")
+ yield calendar.createObjectResourceWithName("2.ics", Component.fromString(self.cal2))
+ yield self.commitTransaction(0)
+
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[0].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[1].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ map(methodcaller("reset"), self.theNotifiers)
+
+ # Change by sharee on other pod
+ txn2 = self.theTransactionUnderTest(1)
+ home = yield self.homeUnderTest(txn=txn2, name="puser02")
+ self.assertEquals(home.notifierID(), ("CalDAV", "puser02",))
+ calendar = yield home.calendarWithName(shared_name_puser02)
+ cobj = yield calendar.calendarObjectWithName("2.ics")
+ yield cobj.remove()
+ yield self.commitTransaction(1)
+
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[0].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[1].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ map(methodcaller("reset"), self.theNotifiers)
+
+ # Change by sharee on same pod
+ txn2 = self.theTransactionUnderTest(0)
+ home = yield self.homeUnderTest(txn=txn2, name="user02")
+ self.assertEquals(home.notifierID(), ("CalDAV", "user02",))
+ calendar = yield home.calendarWithName(shared_name_user02)
+ yield calendar.createObjectResourceWithName("2_1.ics", Component.fromString(self.cal2))
+ yield self.commitTransaction(0)
+
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[0].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ self.assertEqual(set(map(itemgetter(0), self.theNotifiers[1].history)), set(["/CalDAV/example.com/user01/", "/CalDAV/example.com/user01/calendar/"]))
+ map(methodcaller("reset"), self.theNotifiers)
+
+
+
</ins><span class="cx"> class SharingRevisions(BaseSharingTests):
</span><span class="cx"> """
</span><span class="cx"> Test store-based sharing and interaction with revision table.
</span></span></pre></div>
<a id="CalendarServertrunktxdavcaldavdatastoretesttest_sql_sharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_sharing.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_sharing.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql_sharing.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -132,7 +132,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -145,7 +145,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx"> notifications = yield notifyHome.listNotificationObjects()
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + ".xml", ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -183,14 +183,14 @@
</span><span class="cx"> notifications = yield notifyHome.listNotificationObjects()
</span><span class="cx"> self.assertEqual(notifications, [])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx"> yield calendar.setShared(False)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -203,7 +203,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -218,7 +218,7 @@
</span><span class="cx"> notifications = yield notifyHome.listNotificationObjects()
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + ".xml", ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -234,7 +234,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -250,7 +250,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -263,7 +263,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -278,7 +278,7 @@
</span><span class="cx"> notifications = yield notifyHome.listNotificationObjects()
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + ".xml", ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -294,7 +294,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -310,7 +310,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -324,7 +324,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -339,7 +339,7 @@
</span><span class="cx"> notifications = yield notifyHome.listNotificationObjects()
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + ".xml", ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -355,7 +355,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -371,7 +371,7 @@
</span><span class="cx"> self.assertEqual(notifications, [inviteUID + "-reply.xml", ])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -450,7 +450,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.directShareWithUser("user02")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -498,7 +498,7 @@
</span><span class="cx"> )
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.directShareWithUser("user02")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="lines">@@ -735,7 +735,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group01", _BIND_MODE_READ, "summary")
</span><span class="lines">@@ -743,7 +743,7 @@
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -758,9 +758,9 @@
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx"> yield calendar.setShared(False)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -773,7 +773,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -790,7 +790,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -798,12 +798,12 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 3)
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield calendar.uninviteUIDFromShare("group02")
</span><span class="cx"> uninvites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(uninvites), 0)
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> for invite in invites:
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [])
</span><span class="lines">@@ -811,9 +811,9 @@
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx"> yield calendar.setShared(False)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -826,7 +826,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -843,7 +843,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -855,7 +855,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -867,7 +867,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -880,7 +880,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -897,7 +897,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -909,7 +909,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -921,7 +921,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -934,7 +934,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -951,7 +951,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -963,7 +963,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -975,7 +975,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -988,7 +988,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -1005,7 +1005,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1017,7 +1017,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1029,7 +1029,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -1042,7 +1042,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViews), 3)
</span><span class="lines">@@ -1059,7 +1059,7 @@
</span><span class="cx"> self.assertEqual(invite.summary, "summary")
</span><span class="cx"> yield self._check_notifications(invite.shareeUID, [invite.uid, ])
</span><span class="cx">
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1071,7 +1071,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1090,7 +1090,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -1103,7 +1103,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewsGroup02 = yield calendar.inviteUIDToShare("group02", _BIND_MODE_WRITE, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViewsGroup02), 3)
</span><span class="lines">@@ -1133,7 +1133,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1148,7 +1148,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewsGroup02 = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViewsGroup02), 3)
</span><span class="lines">@@ -1178,7 +1178,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1221,7 +1221,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewsGroup02 = yield calendar.inviteUIDToShare("group02", _BIND_MODE_WRITE, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViewsGroup02), 3)
</span><span class="lines">@@ -1251,7 +1251,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1300,7 +1300,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewUser07 = yield calendar.inviteUIDToShare("user07", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertNotEqual(shareeViewUser07, None)
</span><span class="lines">@@ -1331,7 +1331,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1372,7 +1372,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewUser07 = yield calendar.directShareWithUser("user07")
</span><span class="cx"> self.assertNotEqual(shareeViewUser07, None)
</span><span class="lines">@@ -1412,7 +1412,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites if invite.shareeUID != "user07"])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1452,7 +1452,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewsGroup02 = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertEqual(len(shareeViewsGroup02), 3)
</span><span class="lines">@@ -1484,7 +1484,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1527,7 +1527,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewsGroup02 = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ)
</span><span class="cx"> self.assertEqual(len(shareeViewsGroup02), 3)
</span><span class="lines">@@ -1559,7 +1559,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites if invite.shareeUID != "user07"])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1603,7 +1603,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewUser07 = yield calendar.inviteUIDToShare("user07", _BIND_MODE_READ, "summary")
</span><span class="cx"> self.assertNotEqual(shareeViewUser07, None)
</span><span class="lines">@@ -1637,7 +1637,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -1696,7 +1696,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViewUser07 = yield calendar.inviteUIDToShare("user07", _BIND_MODE_WRITE)
</span><span class="cx"> self.assertNotEqual(shareeViewUser07, None)
</span><span class="lines">@@ -1730,7 +1730,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [invite.uid + "-reply" for invite in invites])
</span><span class="cx">
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><del>- self.assertTrue(calendar.isShared())
</del><ins>+ self.assertTrue(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktxdavcarddavdatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/carddav/datastore/sql.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/carddav/datastore/sql.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/carddav/datastore/sql.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -1831,13 +1831,14 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> result = []
</span><del>- for homeUID, homeRID, resourceID, resourceName, bindMode, bindStatus, bindMessage in acceptedRows: #@UnusedVariable
</del><ins>+ for homeUID, homeRID, homeStatus, resourceID, resourceName, bindMode, bindStatus, bindMessage in acceptedRows: #@UnusedVariable
</ins><span class="cx"> invite = SharingInvitation(
</span><span class="cx"> resourceName,
</span><span class="cx"> self.addressbook()._home.name(),
</span><span class="cx"> self.addressbook()._home.id(),
</span><span class="cx"> homeUID,
</span><span class="cx"> homeRID,
</span><ins>+ homeStatus,
</ins><span class="cx"> bindMode,
</span><span class="cx"> bindStatus,
</span><span class="cx"> bindMessage,
</span></span></pre></div>
<a id="CalendarServertrunktxdavcarddavdatastoretesttest_sql_sharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/carddav/datastore/test/test_sql_sharing.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/carddav/datastore/test/test_sql_sharing.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/test_sql_sharing.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -249,7 +249,7 @@
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(addressbook.isShared())
</del><ins>+ self.assertFalse(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -262,7 +262,7 @@
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(addressbook.isShared())
</del><ins>+ self.assertFalse(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield addressbook.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="lines">@@ -281,7 +281,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -289,7 +289,7 @@
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 1)
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield addressbook.uninviteUIDFromShare("user02")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="lines">@@ -297,12 +297,12 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [])
</span><span class="cx">
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><del>- self.assertFalse(addressbook.isShared())
</del><ins>+ self.assertFalse(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -315,7 +315,7 @@
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(addressbook.isShared())
</del><ins>+ self.assertFalse(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield addressbook.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="lines">@@ -328,7 +328,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -343,7 +343,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -358,7 +358,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -371,7 +371,7 @@
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(addressbook.isShared())
</del><ins>+ self.assertFalse(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield addressbook.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield addressbook.sharingInvites()
</span><span class="lines">@@ -384,7 +384,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -398,7 +398,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -412,7 +412,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
</span><del>- self.assertTrue(addressbook.isShared())
</del><ins>+ self.assertTrue(addressbook.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -593,7 +593,7 @@
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(group.isShared())
</del><ins>+ self.assertFalse(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield group.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="lines">@@ -606,7 +606,7 @@
</span><span class="cx"> self.assertEqual(invites[0].summary, "summary")
</span><span class="cx"> inviteUID = shareeView.shareUID()
</span><span class="cx">
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -616,7 +616,7 @@
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -624,19 +624,19 @@
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 1)
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield group.uninviteUIDFromShare("user02")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [])
</span><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertFalse(group.isShared())
</del><ins>+ self.assertFalse(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -649,7 +649,7 @@
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(group.isShared())
</del><ins>+ self.assertFalse(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield group.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="lines">@@ -661,7 +661,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -673,7 +673,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -685,7 +685,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -698,7 +698,7 @@
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(group.isShared())
</del><ins>+ self.assertFalse(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield group.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="lines">@@ -710,7 +710,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -724,7 +724,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -738,7 +738,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -752,7 +752,7 @@
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(group.isShared())
</del><ins>+ self.assertFalse(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield group.inviteUIDToShare("user02", _BIND_MODE_READ, "summary")
</span><span class="cx"> invites = yield group.sharingInvites()
</span><span class="lines">@@ -764,7 +764,7 @@
</span><span class="cx">
</span><span class="cx"> yield self._check_notifications("user02", [inviteUID, ])
</span><span class="cx">
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -776,7 +776,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self.commit()
</span><span class="cx">
</span><span class="lines">@@ -790,7 +790,7 @@
</span><span class="cx"> yield self._check_notifications("user01", [inviteUID + "-reply", ])
</span><span class="cx">
</span><span class="cx"> group = yield self.addressbookObjectUnderTest(home="user01", addressbook_name="addressbook", name="group1.vcf")
</span><del>- self.assertTrue(group.isShared())
</del><ins>+ self.assertTrue(group.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastorepoddingsharing_invitespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/podding/sharing_invites.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/podding/sharing_invites.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/podding/sharing_invites.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -14,10 +14,13 @@
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><span class="cx">
</span><del>-from twisted.internet.defer import inlineCallbacks
</del><ins>+from twisted.internet.defer import inlineCallbacks, returnValue, DeferredList
</ins><span class="cx">
</span><span class="cx"> from txdav.common.datastore.podding.base import FailedCrossPodRequestError
</span><ins>+from txdav.common.datastore.sql_tables import _HOME_STATUS_EXTERNAL
+from twext.python.log import Logger
</ins><span class="cx">
</span><ins>+log = Logger()
</ins><span class="cx">
</span><span class="cx"> class SharingInvitesConduitMixin(object):
</span><span class="cx"> """
</span><span class="lines">@@ -239,3 +242,76 @@
</span><span class="cx"> request["status"],
</span><span class="cx"> summary=request.get("summary")
</span><span class="cx"> )
</span><ins>+
+
+ @inlineCallbacks
+ def send_sharenotification(
+ self, txn, homeType, ownerUID,
+ bindUID, shareeUIDs,
+ ):
+ """
+ Send a sharing notification cross-pod message for the specified sharees. Note that we
+ will aggregate sharees by their pod and send only one message to each pod. Will do this
+ using a DeferredList that ignores any errors.
+
+ @param homeType: Type of home being shared.
+ @type homeType: C{int}
+
+ @param ownerUID: UID of the sharer.
+ @type ownerUID: C{str}
+ @param bindUID: bind UID of the sharer calendar
+ @type bindUID: C{str}
+
+ @param shareeUIDs: UIDs of the sharees
+ @type shareeUIDs: C{str}
+ """
+
+ recipients = {}
+ for shareeUID in shareeUIDs:
+ _ignore_sender, recipient = yield self.validRequest(
+ ownerUID, shareeUID
+ )
+ recipients[recipient.server().id] = recipient.server()
+
+ request = {
+ "action": "sharenotification",
+ "type": homeType,
+ "ownerUID": ownerUID,
+ "bindUID": bindUID,
+ }
+
+ deferreds = []
+ for server in recipients.values():
+ deferreds.append(self.sendRequestToServer(txn, server, request))
+
+ # Always trap errors and ignore them as we want share notifications to be
+ # "fire and forget"
+ try:
+ yield DeferredList(deferreds, consumeErrors=True)
+ except Exception as ex:
+ log.error("Failed to send sharenotification: {exc}", exc=ex)
+
+
+ @inlineCallbacks
+ def recv_sharenotification(self, txn, request):
+ """
+ Process a sharing notification cross-pod request.
+ Request arguments as per L{send_sharenotification}.
+
+ @param request: request arguments
+ @type request: C{dict}
+ """
+
+ # Sharer home/calendar on this pod must already exist - however, we are going to ignore these
+ # failures as we want notifications to be "fire and forget". Plus we do get a notification
+ # when a share is removed, but AFTER the uninvite has been processed and the bind entries removed.
+ # We definitely do not want to treat that as a failure.
+ ownerHome = yield txn.homeWithUID(request["type"], request["ownerUID"], status=_HOME_STATUS_EXTERNAL)
+ if ownerHome is None:
+ returnValue(None)
+ ownerCalendar = yield ownerHome.childWithBindUID(request["bindUID"])
+ if ownerCalendar is None:
+ returnValue(None)
+
+ # Send the notification
+ yield ownerCalendar.notifyChanged()
</ins></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastorepoddingtestutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/podding/test/util.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/podding/test/util.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/podding/test/util.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -24,9 +24,7 @@
</span><span class="cx"> from txdav.common.datastore.podding.conduit import PoddingConduit
</span><span class="cx"> from txdav.common.datastore.podding.request import ConduitRequest
</span><span class="cx"> from txdav.common.datastore.sql_tables import _BIND_MODE_WRITE
</span><del>-from txdav.common.datastore.test.util import (
- CommonCommonTests, SQLStoreBuilder, buildTestDirectory
-)
</del><ins>+from txdav.common.datastore.test.util import CommonCommonTests, SQLStoreBuilder, buildTestDirectory, StubNotifierFactory
</ins><span class="cx">
</span><span class="cx"> import txweb2.dav.test.util
</span><span class="cx"> from txweb2 import responsecode
</span><span class="lines">@@ -150,6 +148,7 @@
</span><span class="cx">
</span><span class="cx"> theStoreBuilders = []
</span><span class="cx"> theStores = []
</span><ins>+ theNotifiers = []
</ins><span class="cx"> activeTransactions = []
</span><span class="cx"> accounts = None
</span><span class="cx"> augments = None
</span><span class="lines">@@ -161,6 +160,7 @@
</span><span class="cx"> SQLStoreBuilder(count=len(self.theStoreBuilders))
</span><span class="cx"> )
</span><span class="cx"> self.theStores = [None] * self.numberOfStores
</span><ins>+ self.theNotifiers = [None] * self.numberOfStores
</ins><span class="cx"> self.activeTransactions = [None] * self.numberOfStores
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -187,9 +187,12 @@
</span><span class="cx"> augments=self.augments,
</span><span class="cx"> )
</span><span class="cx"> self.theStores[i] = self.store
</span><ins>+ self.theNotifiers[i] = self.notifierFactory
</ins><span class="cx"> else:
</span><ins>+ self.theNotifiers[i] = StubNotifierFactory()
</ins><span class="cx"> self.theStores[i] = yield self.buildStore(
</span><del>- self.theStoreBuilders[i]
</del><ins>+ self.theStoreBuilders[i],
+ notifierFactory=self.theNotifiers[i],
</ins><span class="cx"> )
</span><span class="cx"> directory = buildTestDirectory(
</span><span class="cx"> self.theStores[i],
</span><span class="lines">@@ -272,7 +275,7 @@
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def createShare(
</span><del>- self, ownerGUID="user01", shareeGUID="puser02", name="calendar"
</del><ins>+ self, ownerGUID="user01", shareeGUID="puser02", name="calendar", pod=1
</ins><span class="cx"> ):
</span><span class="cx">
</span><span class="cx"> home = yield self.homeUnderTest(
</span><span class="lines">@@ -286,10 +289,10 @@
</span><span class="cx">
</span><span class="cx"> # ACK: home2 is None
</span><span class="cx"> home2 = yield self.homeUnderTest(
</span><del>- txn=self.theTransactionUnderTest(1), name=shareeGUID
</del><ins>+ txn=self.theTransactionUnderTest(pod), name=shareeGUID
</ins><span class="cx"> )
</span><span class="cx"> yield home2.acceptShare("shared-calendar")
</span><del>- yield self.commitTransaction(1)
</del><ins>+ yield self.commitTransaction(pod)
</ins><span class="cx">
</span><span class="cx"> returnValue("shared-calendar")
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -3690,7 +3690,7 @@
</span><span class="cx"> @return: a L{Deferred} which fires when the modification is complete.
</span><span class="cx"> """
</span><span class="cx">
</span><del>- if self.isShared() or self.external():
</del><ins>+ if not self.owned() or self.external():
</ins><span class="cx"> raise ShareNotAllowed("Cannot rename a shared collection")
</span><span class="cx">
</span><span class="cx"> oldName = self._name
</span><span class="lines">@@ -4507,7 +4507,10 @@
</span><span class="cx"> if notifier:
</span><span class="cx"> yield notifier.notify(self._txn, priority=category.value)
</span><span class="cx">
</span><ins>+ if not self.external():
+ yield self.notifyExternalShare()
</ins><span class="cx">
</span><ins>+
</ins><span class="cx"> @classproperty
</span><span class="cx"> def _lockLastModifiedQuery(cls):
</span><span class="cx"> schema = cls._homeChildMetaDataSchema
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresql_externalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql_external.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql_external.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/sql_external.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -70,8 +70,13 @@
</span><span class="cx">
</span><span class="cx"> def initFromStore(self):
</span><span class="cx"> """
</span><del>- NoOp for an external share as there is no metadata or properties.
</del><ins>+ External share does not have metadata or properties so we skip those by by-passing
+ the super method, but we do need to add notifiers.
</ins><span class="cx"> """
</span><ins>+
+ for factory_type, factory in self._txn._notifierFactories.items():
+ self.addNotifier(factory_type, factory.newNotifier(self))
+
</ins><span class="cx"> return succeed(self)
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoresql_sharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/sql_sharing.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/sql_sharing.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/sql_sharing.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -274,7 +274,7 @@
</span><span class="cx">
</span><span class="cx"> SharingInvitation = namedtuple(
</span><span class="cx"> "SharingInvitation",
</span><del>- ["uid", "ownerUID", "ownerHomeID", "shareeUID", "shareeHomeID", "mode", "status", "summary"]
</del><ins>+ ["uid", "ownerUID", "ownerHomeID", "shareeUID", "shareeHomeID", "shareeHomeStatus", "mode", "status", "summary"]
</ins><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -341,6 +341,7 @@
</span><span class="cx"> [
</span><span class="cx"> home.OWNER_UID,
</span><span class="cx"> bind.HOME_RESOURCE_ID,
</span><ins>+ home.STATUS,
</ins><span class="cx"> bind.RESOURCE_ID,
</span><span class="cx"> bind.RESOURCE_NAME,
</span><span class="cx"> bind.BIND_MODE,
</span><span class="lines">@@ -579,6 +580,38 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><ins>+ def notifyExternalShare(self):
+ """
+ Send a cross-pod message to all external shares to ensure change notifications are sent
+ to external sharees' clients subscribed to notifications on the other pods.
+ """
+
+ # We need to resolve the ownerView which may be this object, or if this is
+ # a shared object, may be something else. The ownerView is the one that
+ # knows about all the sharing invites and the bindUID (which is the identifier
+ # used to identify it on another pod).
+ if not self.owned():
+ ownerView = yield self.ownerView()
+ else:
+ ownerView = self
+
+ # Get all invites and figure out if any are external
+ externalUIDs = set()
+ for invitation in (yield ownerView.sharingInvites()):
+ if invitation.shareeHomeStatus == _HOME_STATUS_EXTERNAL:
+ externalUIDs.add(invitation.shareeUID)
+
+ if externalUIDs and ownerView.bindUID() is not None:
+ yield self._txn.store().conduit.send_sharenotification(
+ self._txn,
+ self.ownerHome()._homeType,
+ self.ownerHome().uid(),
+ ownerView.bindUID(),
+ externalUIDs,
+ )
+
+
+ @inlineCallbacks
</ins><span class="cx"> def allInvitations(self):
</span><span class="cx"> """
</span><span class="cx"> Get list of all invitations (non-direct) to this object.
</span><span class="lines">@@ -1033,13 +1066,14 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> result = []
</span><del>- for homeUID, homeRID, _ignore_resourceID, resourceName, bindMode, bindStatus, bindMessage in invitedRows:
</del><ins>+ for homeUID, homeRID, homeStatus, _ignore_resourceID, resourceName, bindMode, bindStatus, bindMessage in invitedRows:
</ins><span class="cx"> invite = SharingInvitation(
</span><span class="cx"> resourceName,
</span><span class="cx"> self.ownerHome().name(),
</span><span class="cx"> self.ownerHome().id(),
</span><span class="cx"> homeUID,
</span><span class="cx"> homeRID,
</span><ins>+ homeStatus,
</ins><span class="cx"> bindMode,
</span><span class="cx"> bindStatus,
</span><span class="cx"> bindMessage,
</span><span class="lines">@@ -1216,7 +1250,7 @@
</span><span class="cx"> return self._bindMode == _BIND_MODE_OWN
</span><span class="cx">
</span><span class="cx">
</span><del>- def isShared(self):
</del><ins>+ def isSharedByOwner(self):
</ins><span class="cx"> """
</span><span class="cx"> For an owned collection indicate whether it is shared.
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoretesttest_sqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/test/test_sql.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -310,6 +310,7 @@
</span><span class="cx"> pass
</span><span class="cx">
</span><span class="cx"> class TestCommonHomeChild(CommonHomeChild):
</span><ins>+ _homeSchema = schema.CALENDAR_HOME
</ins><span class="cx"> _homeChildSchema = schema.CALENDAR
</span><span class="cx"> _homeChildMetaDataSchema = schema.CALENDAR_METADATA
</span><span class="cx"> _bindSchema = schema.CALENDAR_BIND
</span></span></pre></div>
<a id="CalendarServertrunktxdavcommondatastoretestutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/common/datastore/test/util.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/common/datastore/test/util.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/common/datastore/test/util.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -856,14 +856,14 @@
</span><span class="cx"> self.config = config
</span><span class="cx">
</span><span class="cx">
</span><del>- def buildStore(self, storeBuilder=theStoreBuilder):
</del><ins>+ def buildStore(self, storeBuilder=theStoreBuilder, notifierFactory=None):
</ins><span class="cx"> """
</span><span class="cx"> Builds and returns a store
</span><span class="cx"> """
</span><span class="cx">
</span><span class="cx"> # Build the store before the directory; the directory will be assigned
</span><span class="cx"> # to the store via setDirectoryService()
</span><del>- return storeBuilder.buildStore(self, self.notifierFactory, None)
</del><ins>+ return storeBuilder.buildStore(self, notifierFactory if notifierFactory is not None else self.notifierFactory, None)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> def transactionUnderTest(self, txn=None):
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhotesttest_group_shareespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/test/test_group_sharees.py (15557 => 15558)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/test/test_group_sharees.py        2016-04-27 18:23:41 UTC (rev 15557)
+++ CalendarServer/trunk/txdav/who/test/test_group_sharees.py        2016-04-27 20:55:07 UTC (rev 15558)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group04", _BIND_MODE_READ)
</span><span class="lines">@@ -217,7 +217,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group04", _BIND_MODE_READ)
</span><span class="lines">@@ -301,7 +301,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ)
</span><span class="lines">@@ -384,7 +384,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group05", _BIND_MODE_READ)
</span><span class="lines">@@ -465,7 +465,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group06", _BIND_MODE_READ)
</span><span class="lines">@@ -549,7 +549,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="shared")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ)
</span><span class="lines">@@ -630,7 +630,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user01", name="shared")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> yield self._check_notifications("user01", [])
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group02", _BIND_MODE_READ)
</span><span class="lines">@@ -704,7 +704,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user03", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeViews = yield calendar.inviteUIDToShare("group05", _BIND_MODE_WRITE)
</span><span class="cx"> self.assertEqual(len(shareeViews), 2)
</span><span class="lines">@@ -787,7 +787,7 @@
</span><span class="cx"> calendar = yield self.calendarUnderTest(home="user03", name="calendar")
</span><span class="cx"> invites = yield calendar.sharingInvites()
</span><span class="cx"> self.assertEqual(len(invites), 0)
</span><del>- self.assertFalse(calendar.isShared())
</del><ins>+ self.assertFalse(calendar.isSharedByOwner())
</ins><span class="cx">
</span><span class="cx"> shareeView = yield calendar.inviteUIDToShare("user01", _BIND_MODE_READ)
</span><span class="cx"> self.assertTrue(shareeView is not None)
</span></span></pre>
</div>
</div>
</body>
</html>