Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

First pass at who extensions

  • Loading branch information
wsanchez committed Jan 31, 2014
1 parent 3f03e39 commit cde50c999c7a468c36e7d24287bdc302e7c0dc6f
Showing with 204 additions and 34 deletions.
  1. +15 −6 txdav/who/idirectory.py
  2. +19 −0 txdav/who/test/__init__.py
  3. +121 −0 txdav/who/test/test_xml.py
  4. +49 −28 txdav/who/xml.py
@@ -15,6 +15,9 @@
# limitations under the License.
##

from __future__ import print_function
from __future__ import absolute_import

"""
Calendar and contacts directory extentions to L{twext.who.idirectory}.
"""
@@ -115,20 +118,25 @@ class AutoScheduleMode(Names):
"""
Constants for automatic scheduling modes.
@cvar none: Invitations are not automatically handled.
@cvar accept: Accept all invitations.
@cvar decline: Decline all invitations.
@cvar acceptIfFree: Accept invitations that do not conflict with a busy
time slot. Other invitations are left to be handled manually.
time slot. Other invitations are not automatically handled.
@cvar declineIfBusy: Decline invitations that conflict with a busy time
slot. Other invitations are left to be handled manually.
"""
slot. Other invitations are not automatically handled.
# default -> ?
@cvar acceptIfFreeDeclineIfBusy: Accept invitations that do not conflict
with a busy time slot. Decline invitations that conflict with a busy
time slot. Other invitations are not automatically handled.
"""

# none -> ?
none = NamedConstant()
none.description = u"no action"

accept = NamedConstant()
accept.description = u"accept"
@@ -142,4 +150,5 @@ class AutoScheduleMode(Names):
declineIfBusy = NamedConstant()
declineIfBusy.description = u"decline if busy"

# automatic -> ?
acceptIfFreeDeclineIfBusy = NamedConstant()
acceptIfFreeDeclineIfBusy.description = u"accept if free, decline if busy"
@@ -0,0 +1,19 @@
##
# Copyright (c) 2014 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##

"""
Tests for L{txdav.who}.
"""
@@ -0,0 +1,121 @@
##
# Copyright (c) 2014 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##

from __future__ import print_function
from __future__ import absolute_import

"""
Tests for L{txdav.who.xml}.
"""

from textwrap import dedent

from twisted.internet.defer import inlineCallbacks
from twisted.trial import unittest

from twext.who.test.test_xml import xmlService

from ..idirectory import (
RecordType, FieldName, AutoScheduleMode
)
from ..xml import DirectoryService



class ExtendedSchemaTest(unittest.TestCase):
"""
Tests for calendar and contacts schema extensions.
"""

def makeRecord(self, fieldName, elementName, value):
uid = u"THE ONLY RECORD"

xmlData = dedent(
b"""
<?xml version="1.0" encoding="utf-8"?>
<directory realm="Test Realm">
<record type="user">
<uid>{uid}</uid>
<short-name>wsanchez</short-name>
<{element}>{value}</{element}>
</record>
</directory>
"""[1:]
.format(
uid=uid.encode("utf-8"),
element=elementName.encode("utf-8"),
value=value.encode("utf-8"),
)
)

service = xmlService(
self.mktemp(), xmlData=xmlData, serviceClass=DirectoryService
)

# print("Unknown record types:", service.unknownRecordTypes)
# print("Unknown fields:", service.unknownFieldElements)

return service.recordWithUID(uid)


@inlineCallbacks
def test_unicodeElements(self):
for field, element in (
(FieldName.serviceNodeUID, u"service-node"),
(FieldName.autoAcceptGroup, u"auto-accept-group"),
):
record = yield self.makeRecord(field, element, u"xyzzy")
self.assertEquals(record.fields[field], u"xyzzy")


@inlineCallbacks
def test_booleanElements(self):
for field, element in (
(FieldName.loginAllowed, u"login-allowed"),
(FieldName.hasCalendars, u"has-calendars"),
(FieldName.hasContacts, u"has-contacts"),
):
record = yield self.makeRecord(field, element, u"<true />")
self.assertIdentical(record.fields[field], True, field)

test_booleanElements.todo = "WTF?"


@inlineCallbacks
def test_autoScheduleMode(self):
for mode, value in (
(AutoScheduleMode.none, u"none"),
(AutoScheduleMode.accept, u"accept"),
(AutoScheduleMode.decline, u"decline"),
(AutoScheduleMode.acceptIfFree, u"accept-if-free"),
(AutoScheduleMode.declineIfBusy, u"decline-if-busy"),
(
AutoScheduleMode.acceptIfFreeDeclineIfBusy,
u"accept-if-free-decline-if-busy"
),
):
field = FieldName.autoScheduleMode
record = yield self.makeRecord(field, u"auto-schedule-mode", value)
self.assertIdentical(record.fields[field], mode)

test_autoScheduleMode.todo = "constants unhandled"


def test_recordTypes(self):
raise NotImplementedError(RecordType)

test_recordTypes.todo = "unimplemented"
@@ -1,4 +1,4 @@
# -*- test-case-name: txdav.who -*-
# -*- test-case-name: txdav.who.test.test_xml -*-
##
# Copyright (c) 2014 Apple Inc. All rights reserved.
#
@@ -31,26 +31,7 @@
from twext.who.xml import DirectoryService as BaseDirectoryService
from twext.who.util import ConstantsContainer

from .idirectory import RecordType, FieldName



#
# Directory Service
#

class DirectoryService(BaseDirectoryService):
"""
XML directory service with calendar and contacts attributes.
"""

recordType = ConstantsContainer(
(BaseDirectoryService.recordType, RecordType)
)

fieldName = ConstantsContainer(
(BaseDirectoryService.fieldName, FieldName)
)
from .idirectory import RecordType, FieldName, AutoScheduleMode



@@ -98,30 +79,70 @@ class RecordTypeValue(Values):
"""

location = ValueConstant(u"location")
location.fieldName = FieldName.location
location.recordType = RecordType.location

resource = ValueConstant(u"resource")
resource.fieldName = FieldName.resource
resource.recordType = RecordType.resource

address = ValueConstant(u"address")
address.fieldName = FieldName.address
address.recordType = RecordType.address



class AutoScheduleValue(Values):
"""
XML attribute values for auto-schedule modes.
XML element values for auto-schedule modes.
"""
# default -> ?

# none -> ?
none = ValueConstant(u"none")
none.mode = AutoScheduleMode.none

accept = ValueConstant(u"accept")
accept.mode = AutoScheduleMode.accept

decline = ValueConstant(u"decline")
decline.mode = AutoScheduleMode.decline

acceptIfFree = ValueConstant(u"accept-if-free")
acceptIfFree.mode = AutoScheduleMode.acceptIfFree

declineIfBusy = ValueConstant(u"decline-if-busy")
declineIfBusy.mode = AutoScheduleMode.declineIfBusy

acceptIfFreeDeclineIfBusy = ValueConstant(
u"accept-if-free-decline-if-busy"
)
acceptIfFreeDeclineIfBusy.mode = AutoScheduleMode.acceptIfFreeDeclineIfBusy



# automatic -> ?
#
# Directory Service
#

class DirectoryService(BaseDirectoryService):
"""
XML directory service with calendar and contacts data.
"""

recordType = ConstantsContainer(
(BaseDirectoryService.recordType, RecordType)
)

fieldName = ConstantsContainer(
(BaseDirectoryService.fieldName, FieldName)
)

# XML schema constants

element = ConstantsContainer(
(BaseDirectoryService.element, Element)
)

attribute = ConstantsContainer(
(BaseDirectoryService.attribute, Attribute)
)

recordTypeValue = ConstantsContainer(
(BaseDirectoryService.recordTypeValue, RecordTypeValue)
)

0 comments on commit cde50c9

Please sign in to comment.
You can’t perform that action at this time.