move doctests from cyberapps.tum to cybertools.organize

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@4147 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2011-01-15 16:13:48 +00:00
parent 7e2150f81c
commit 42565dc685
5 changed files with 823 additions and 5 deletions

View file

@ -57,10 +57,8 @@ Tasks
>>> from cybertools.organize.task import Task
Service Management
==================
Service and Form Management
===========================
>>> from cybertools.organize.service import Service
(See cyberapps.tumsm for comprehensive description and tests.)
See servicemanager.txt and formmanager.txt.

38
organize/formmanager.txt Normal file
View file

@ -0,0 +1,38 @@
============
Form Manager
============
($Id$)
This package does not provide functionality on its own but shows only
how to integrate other packages into an application package.
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True)
>>> from cybertools.organize.tests import setUp
>>> setUp(site)
>>> from zope import component
>>> from cybertools.composer import schema
>>> from cybertools.composer.schema import client
Setting up a Form Manager
=========================
>>> fm = client.ClientManager()
Form Manager Views
==================
>>> from cybertools.composer.schema.browser.schema import FormManagerView
Fin de partie
=============
>>> placefulTearDown()

View file

@ -346,6 +346,20 @@ class IScheduledService(IService):
duration = Attribute('Time delta between start and end date/time.')
class ICompoundService(IService):
""" A service that consists of a set of sub-services, e.g. a conference,
a course or a multi-day seminar.
Sub-services may be other compound services or simple services;
in addition there may be service parts additional strucure elements.
"""
class IServicePart(IService):
""" A service that provides a substructure element of a compound service,
e.g. a conference track or a conference day.
"""
class IClient(Interface):
""" An fairly abstract interface for objects to be used as clients
for services.

752
organize/servicemanager.txt Normal file
View file

@ -0,0 +1,752 @@
===============
Service Manager
================
($Id$)
This package does not provide functionality on its own but shows only
how to integrate other packages into an application package.
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True)
>>> from cybertools.organize.tests import setUp
>>> setUp(site)
>>> from zope import component
>>> from cybertools.composer import schema
>>> from cybertools.composer.interfaces import IInstance
>>> from cybertools.composer.schema.interfaces import IClientFactory
>>> from cybertools.organize import service
Setting up a Service Manager
============================
A service manager is a collection of individual services; in our
example the service manager represents a workshop with two
parts (events, lectures, ...).
>>> workshop = site['workshop'] = service.ServiceManager()
>>> workshop.__parent__ = site
>>> workshop.__name__ = 'workshop'
>>> event1 = service.ScheduledService('event1', category='event', manager=workshop,
... title=u'Event 1', capacity=5)
>>> event2 = service.ScheduledService('event2', category='event', manager=workshop,
... title=u'Event 2')
>>> workshop.services.append(event1)
>>> workshop.services.append(event2)
In order to be able to registrate participants for the workshop we
have to provide data structures for the participants (the service
clients. This is done via to form descriptions (schemas), one for the
personal data (first name, last name), and one for the address.
>>> workshop.clientSchemas.append(schema.Schema(
... schema.Field('lastName', u'Last Name', required=True,
... standardFieldName='lastName'),
... schema.Field('firstName', u'First Name'),
... schema.Field('email', u'Email Address', required=True,
... fieldType='email', standardFieldName='email'),
... schema.Field('age', u'Age', fieldType='number'),
... schema.Field('addr', u'Personal Address', required=True,
... fieldtype='radiobuttons',
... vocabulary=u'Mrs\nMr'),
... schema.Field('acadTitles', u'Academic Titles',
... fieldtype='checkboxes',
... vocabulary=u'Prof.\nDr.'),
... name='person',
... manager=workshop,
... ))
>>> workshop.clientSchemas.append(schema.Schema(
... schema.Field('street', u'Street'),
... schema.Field('city', u'City', required=True),
... schema.Field('country', u'Country', required=True,
... fieldType='dropdown', vocabulary=u'USA\nGermany'),
... name='address',
... manager=workshop,
... ))
Registration of Clients
=======================
So we are now ready to register participants.
>>> client1 = IClientFactory(workshop)()
>>> client1Name = workshop.addClient(client1)
>>> data = dict(addr=u'Mr', lastName=u'Skywalker', email='luke@skywalker.universe')
>>> inst = component.getAdapter(client1, IInstance, name='editor')
>>> inst.template = workshop.clientSchemas['person']
>>> state = inst.applyTemplate(data=data)
>>> list(client1.__schema_attributes__)
['schema.client.__standard__', 'schema.client.person']
>>> client1.__schema_attributes__['schema.client.person']['lastName']
u'Skywalker'
Instead of directly peeking into the attributes we can also use a
suitable instance adapter.
>>> inst = IInstance(client1)
>>> inst.template = workshop.clientSchemas['person']
>>> inst.applyTemplate()
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
'email': u'luke@skywalker.universe',
'standard.email': u'luke@skywalker.universe'}
Note that the ``standardFieldName`` setting for the ``lastName`` field
results in a 'standard.lastName' entry; this technique may be used to
retrieve certain standard informations from a client without having to
use a template.
Using schema views for displaying and editing data
--------------------------------------------------
We need some additional setup for working with schema views - so we have to
supply some session handling stuff in order to work with client names.
>>> from zope.interface import implements
>>> from zope.app.session.interfaces import IClientIdManager, ISessionDataContainer
>>> from zope.app.session import session
>>> component.provideAdapter(session.ClientId)
>>> component.provideAdapter(session.Session)
>>> component.provideUtility(session.RAMSessionDataContainer(), ISessionDataContainer)
>>> class ClientIdManager(object):
... implements(IClientIdManager)
... def getClientId(self, request): return 'dummy'
>>> component.provideUtility(ClientIdManager())
>>> from zope.publisher.browser import TestRequest
>>> from cybertools.composer.schema.browser.schema import SchemaView
>>> request = TestRequest()
>>> schema = workshop.clientSchemas['person']
>>> view = SchemaView(schema, request)
Let's have a closer look at some of the view's attributes.
>>> [f.name for f in view.fields]
['lastName', 'firstName', 'email', 'age', 'addr', 'acadTitles']
>>> view.data
{}
Providing an id will enable the view to return the data of
the corresponding client.
>>> input = dict(id=client1Name)
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.data
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
'email': u'luke@skywalker.universe',
'standard.email': u'luke@skywalker.universe'}
When we provide data and an 'update' action a new client object will
be created - if we clear the client name in the session first via
``view.setClientName('')``.
>>> input = dict(lastName='Solo', firstName='Han', email='han.solo@space.net',
... addr=u'Mr', action='update')
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.setClientName('')
>>> view.update()
False
>>> client2Name = view.clientName
>>> client2Name != client1Name
True
>>> input = dict(id=client2Name)
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.data
{'acadTitles': u'', 'standard.lastName': u'Solo', 'addr': u'Mr',
'firstName': u'Han', 'lastName': u'Solo',
'age': '', '__name__': '...', 'email': u'han.solo@space.net',
'standard.email': u'han.solo@space.net'}
If we provide an id parameter we may also change an existing client.
>>> input = dict(lastName=u'Skywalker', firstName=u'Luke', id=client1Name,
... email='luke@skywalker.universe', addr=u'Mr', action='update')
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.update()
False
>>> input = dict(id=client1Name)
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.data
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
'firstName': u'Luke', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
'email': u'luke@skywalker.universe',
'standard.email': u'luke@skywalker.universe'}
If we do not provide a value for a required attribute we get a validation
error and the form will be displayed again.
>>> input = dict(firstName=u'Anakin', action='update')
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.update()
True
The same happens if we provide a number field with a string that cannot
be converted to an integer.
>>> input = dict(firstName=u'Anakin', lastName=u'Skywalker', age='foo',
... action='update')
>>> request = TestRequest(form=input)
>>> view = SchemaView(schema, request)
>>> view.update()
True
More on special field types
---------------------------
>>> schema2 = workshop.clientSchemas['address']
>>> countryField = schema2.fields.country
>>> countryField.getVocabularyItems()
[{'token': u'USA', 'title': u'USA'}, {'token': u'Germany', 'title': u'Germany'}]
Registering for Services Using a Registration Template
======================================================
>>> from cybertools.organize.service import RegistrationTemplate
>>> workshop.clientSchemas.append(RegistrationTemplate(
... name='regform',
... manager=workshop))
>>> regForm = workshop.clientSchemas['regform']
>>> list(regForm.services)
[<...ScheduledService object...>, <...ScheduledService object...>]
The registration action itself is performed using an IClientRegistrations
adapter for a client object.
>>> from cybertools.organize.interfaces import IClientRegistrations
>>> from cybertools.organize.service import ClientRegistrations
>>> component.provideAdapter(ClientRegistrations)
>>> regs = IClientRegistrations(client1)
>>> regs.template = regForm
>>> regs.register([regForm.services[0]])
>>> regs = list(regs.getRegistrations())
>>> regs
[<...Registration object...>]
>>> regs[0].client is client1
True
Using a registration template view for displaying and editing registration data
-------------------------------------------------------------------------------
(Note: after creating a view we usually clear the client name in the session
using ``view.setClientName('')`` in order to create a new client object.)
>>> from cybertools.organize.browser.service import RegistrationTemplateView
>>> request = TestRequest()
>>> regForm = workshop.clientSchemas['regform']
>>> view = RegistrationTemplateView(regForm, request)
>>> view.setClientName('')
>>> len(view.services)
2
>>> view.getRegistrations()
[]
Providing an id will enable the view to return the data of
the corresponding client.
>>> input = dict(id=client1Name)
>>> request = TestRequest(form=input)
>>> view = RegistrationTemplateView(regForm, request)
>>> regs = list(view.getRegistrations())
>>> regs
[<...Registration object...>]
>>> regs[0].client is client1
True
When we provide registration data and an 'update' action a new client object will
be created.
>>> input = dict(service_tokens=['event2'], action='update')
>>> request = TestRequest(form=input)
>>> view = RegistrationTemplateView(regForm, request)
>>> view.setClientName('')
>>> view.update()
False
>>> client3Name = view.clientName
>>> input = dict(id=client3Name)
>>> request = TestRequest(form=input)
>>> view = RegistrationTemplateView(regForm, request)
>>> regs = list(view.getRegistrations())
>>> regs
[<...Registration object...>]
>>> regs[0].client.__name__ == client3Name
True
>>> regs[0].service.token
'event2'
If we provide an id parameter we may also change an existing client.
>>> input = dict(service_tokens=['event1'], id=client1Name, action='update')
>>> request = TestRequest(form=input)
>>> view = RegistrationTemplateView(regForm, request)
>>> view.update()
False
>>> input = dict(id=client1Name)
>>> request = TestRequest(form=input)
>>> view = RegistrationTemplateView(regForm, request)
>>> regs = list(view.getRegistrations())
>>> len(regs)
1
>>> regs[0].service.token
'event1'
Let's finally look at the services and what they know about the clients
registered for them.
>>> clientNames = [client1Name, client2Name, client3Name]
>>> for service in workshop.getServices():
... for cn, reg in sorted(service.registrations.items()):
... print 'client-%i: ' % (clientNames.index(cn)+1), reg.service.name
client-1: event1
client-3: event2
More on Schema-based Forms and Template Views
=============================================
Navigation
----------
If a service provides more than one template (schema or registration
template) the form may show buttons to navigate to the next or previous
template together with saving the data entered.
>>> schema = workshop.clientSchemas['person']
>>> view = SchemaView(schema, TestRequest())
>>> view.getPreviousTemplate()
''
>>> view.getNextTemplate()
'http://127.0.0.1/workshop/address'
>>> schema = workshop.clientSchemas['address']
>>> view = SchemaView(schema, TestRequest())
>>> view.getPreviousTemplate()
'http://127.0.0.1/workshop/person'
>>> view.getNextTemplate()
'http://127.0.0.1/workshop/regform'
>>> schema = workshop.clientSchemas['regform']
>>> view = SchemaView(schema, TestRequest())
>>> view.previousTemplate
'http://127.0.0.1/workshop/address'
>>> view.getNextTemplate()
''
>>> view.getCheckoutView()
'http://127.0.0.1/workshop/checkout.html'
Message Definition and Rule Handling
====================================
Setting up a message manager with messages
------------------------------------------
>>> messageText = '''Dear $person.firstName $person.lastName,
... You have been registered for the following $services.
... $@@list_registrations_text
... $footer
... '''
>>> from cybertools.composer.message.interfaces import IMessageManager
>>> from cybertools.organize.service import MessageManagerAdapter
>>> component.provideAdapter(MessageManagerAdapter)
>>> messageManager = IMessageManager(workshop)
>>> messageManager.addMessage('feedback_text', messageText,
... subjectLine='Workshop Registration')
>>> messageManager.addMessage('footer', 'Best regards, $sender')
>>> messageManager.addMessage('sender', 'Jack')
>>> messageManager.addMessage('services', text='events')
Controlling actions with rules
------------------------------
Let's first set up a rule with two actions.
>>> from cybertools.composer.rule.base import Rule, Action, Event
>>> from cybertools.organize.service import eventTypes
>>> checkoutEvent = eventTypes['service.checkout']
>>> checkoutRule = Rule('checkout')
>>> checkoutRule.events.append(checkoutEvent)
>>> checkoutRule.actions.append(Action('sendmail',
... parameters=dict(sender='manager@workshops.com',
... messageName='feedback_text')))
We also have to provide rule instance and action handler adapters that
will do the real work.
>>> from cybertools.composer.rule.instance import RuleInstance
>>> from cybertools.composer.rule.interfaces import IRuleInstance
>>> component.provideAdapter(RuleInstance, provides=IRuleInstance)
>>> from cybertools.composer.rule.mail import MailActionHandler
>>> from cybertools.composer.rule.message import MessageActionHandler
>>> component.provideAdapter(MessageActionHandler, name='message')
>>> component.provideAdapter(MailActionHandler, name='sendmail')
We can now get a rule manager for our workshop and add the rule to it.
>>> from cybertools.composer.rule.interfaces import IRuleManager
>>> from cybertools.organize.service import RuleManagerAdapter
>>> component.provideAdapter(RuleManagerAdapter)
>>> ruleManager = IRuleManager(workshop)
>>> ruleManager.addRule(checkoutRule)
For testing purposes we also have to register a TestMailer that
just prints the message and other parameters.
>>> from cybertools.composer.rule.tests import TestMailer
>>> from zope.sendmail.interfaces import IMailDelivery
>>> component.provideUtility(TestMailer(), provides=IMailDelivery, name='Mail')
We are now ready to trigger a registration checkout.
>>> result = ruleManager.handleEvent(Event(checkoutEvent, client1))
sender: manager@workshops.com
recipients: [u'luke@skywalker.universe']
subject: Workshop Registration
message:
Dear Luke Skywalker,
You have been registered for the following events.
@@list_registrations_text
Best regards, Jack
<BLANKLINE>
In addition to sending mails we can also control the redirection to a
feedback or thankyou page with a rule.
>>> messageHtml = '''<p>Dear $person.firstName $person.lastName,</p>
... <p>You have been registered for the following $services.</p>
... <div>$@@list_registrations_html</div>
... <div>$footer</div>
... '''
>>> messageManager.addMessage('feedback_html', messageHtml)
>>> checkoutRule.actions.append(Action('redirect',
... parameters=dict(viewName='message_view.html',
... messageName='feedback_html')))
>>> from cybertools.composer.rule.web import RedirectActionHandler
>>> component.provideAdapter(RedirectActionHandler, name='redirect')
>>> request = TestRequest()
>>> request._app_names = ['workshop', 'checkout.html']
>>> result = ruleManager.handleEvent(Event(checkoutEvent, client1, request))
sender: ...
This redirects to a special message view that will deliver the
rendered message.
>>> from cybertools.composer.rule.web import MessageView
>>> input = dict(message='feedback_html')
>>> view = MessageView(workshop, TestRequest(form=input))
>>> view.getMessage()
u'<p>Dear Luke Skywalker...'
Service Manager and Service Views
=================================
>>> from cybertools.organize.browser.service import ServiceManagerView
>>> wsView = ServiceManagerView(workshop, TestRequest())
Service manager view
--------------------
The service manager view provides an ``overview()`` method that
allows a hierarchical presentation.
>>> overview = wsView.overview()
>>> for line in overview:
... print line['title'], line['isHeadline'], line['level']
Event True 0
Event 1 False 1
Event 2 False 1
Service view
------------
>>> from cybertools.organize.browser.service import ServiceView
>>> srvView = ServiceView(event1, TestRequest(form=dict(with_temporary='yes')))
The service view allows us to retrieve the registrations of a service, e.g.
to list them on a page template.
>>> regs = srvView.listRegistrations()
>>> len(list(regs))
1
>>> reg = regs.keys()[0]
There are also convenience methods for retrieving and formatting client
and registration data.
>>> regInfo = srvView.getRegistrationInfo(reg)
>>> clientInfo = srvView.getDataForClient(reg)
>>> print srvView.formatClientInfo(clientInfo)
Skywalker
>>> print regInfo['number'], regInfo['stateTitle']
1 temporary
The service view also provides fields that sum up the numbers of all
(non-temporary) registrations. (The number of waiting participants is empty
because the ``waitingList`` flag has not been set.)
>>> srvView.registeredTotalSubmitted
0
>>> srvView.registeredTotalsSubmitted
{'numberWaiting': '', 'number': 0}
Checkout
--------
After finishing registrating for services the user may check out (submit)
her registrations.
>>> from cybertools.organize.browser.service import CheckoutView
>>> checkout = CheckoutView(workshop, TestRequest())
>>> data = checkout.getClientData()
>>> list(sorted(data))
['__name__', 'errors', 'info_messages', 'service_registrations',
'standard.email', 'standard.lastName']
>>> checkout.getRegistrationsInfo()
[...]
>>> checkout.listRegistrationsText()
u'Event 1\nDatum: -\nUhrzeit: -\n\n'
When the user clicks the "Confirm Registration" button the corresponding
actions will be carried out.
>>> input = dict(action='update')
>>> request = TestRequest(form=input)
>>> request._app_names = ['workshop', 'checkout.html']
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: unknown@sender.com
recipients: [u'luke@skywalker.universe']
subject: Workshop Registration
message: ...
False
The checkout procedure has set the registrations' state to 'submitted'.
>>> srvView = ServiceView(event1, TestRequest())
>>> srvView.getRegistrationInfo(reg)['state']
'submitted'
>>> srvView.registeredTotalSubmitted
1
What happens if we submit a registration again?
(We supply the clientName because this may have been cleared on checkout
for security reasons.)
>>> input = dict(action='update', id=client1Name)
>>> request = TestRequest(form=input)
>>> request._app_names = ['workshop', 'checkout.html']
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: unknown@sender.com
recipients: [u'luke@skywalker.universe']
subject: Workshop Registration
message: ...
False
>>> srvView.getRegistrationInfo(reg)['state']
'submitted'
Waiting List
============
The use of the waiting list is controlled by the ``waitingList`` flag.
>>> event1.waitingList
False
>>> len(event1.registrations)
1
>>> event1.availableCapacity
4
We now limit the capacity of the event to 1 so that there is no place available
any more.
>>> event1.capacity = 1
>>> event1.availableCapacity
0
>>> regView = RegistrationTemplateView(regForm, TestRequest())
>>> regView.setClientName('')
>>> regView.allowRegistration(event1)
False
If we now set the ``waitingList`` flag to True further registration is
possible.
>>> event1.waitingList = True
>>> regView.allowRegistration(event1)
True
>>> input = dict(lastName='Walker', firstName='John', email='john@walker.tv',
... addr=u'Mr', action='update')
>>> request = TestRequest(form=input)
>>> schema = workshop.clientSchemas['person']
>>> view = SchemaView(schema, request)
>>> view.setClientName('')
>>> view.update()
False
>>> client4Name = view.clientName
>>> input = {'action': 'update', 'service.event1': 3, 'id': client4Name}
>>> regView = RegistrationTemplateView(regForm, TestRequest(form=input))
>>> regView.update()
False
>>> for reg in sorted(event1.registrations.values(), key=lambda x: x.number):
... print reg.number, reg.numberWaiting
0 3
1 0
Let's fix the last registration by running the checkout process.
>>> input = dict(action='update', id=client4Name)
>>> request = TestRequest(form=input)
>>> request._app_names = ['workshop', 'checkout.html']
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: ...
Taking over free places
-----------------------
What happens if one of the participants cancels her registration?
>>> input = {'action': 'update', 'service.event1': 0, 'id': client1Name}
>>> regView = RegistrationTemplateView(regForm, TestRequest(form=input))
>>> regView.update()
False
>>> for reg in sorted(event1.registrations.values(), key=lambda x: x.number):
... print reg.number, reg.numberWaiting
0 3
As the participants on the waiting list get priority over newly registering
participants the available capacity will still be 0 as long as there are
people on the waiting list.
>>> event1.availableCapacity
0
>>> input = {'action': 'update', 'service.event1': 2}
>>> regView = RegistrationTemplateView(regForm, TestRequest(form=input))
>>> regView.setClientName('')
>>> regView.update()
False
>>> for reg in sorted(event1.registrations.values(), key=lambda x: x.numberWaiting):
... print reg.number, reg.numberWaiting
0 2
0 3
Now the participant on the waiting list registers again - and gets the
free place.
>>> input = {'action': 'update', 'service.event1': 3, 'id': client4Name}
>>> regView = RegistrationTemplateView(regForm, TestRequest(form=input))
>>> regView.update()
False
>>> for reg in sorted(event1.registrations.values(), key=lambda x: x.number):
... print reg.number, reg.numberWaiting
0 2
1 2
Let's finally fix this registration by running the checkout process.
>>> input = dict(action='update', id=client4Name)
>>> request = TestRequest(form=input)
>>> request._app_names = ['workshop', 'checkout.html']
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: ...
Excel Export
============
>>> from cybertools.organize.browser.report import RegistrationsExportCsv
>>> input = dict(get_data_method='getData')
>>> csv = RegistrationsExportCsv(workshop, TestRequest(form=input))
>>> print csv.render()
"Service","Client ID","Organization","First Name","Last Name","E-Mail","Number","State"
"Event 1","...","","Walker","","john@walker.tv",1,"submitted"
>>> input = dict(get_data_method='getAllDataInColumns')
>>> csv = RegistrationsExportCsv(workshop, TestRequest(form=input))
>>> result = csv.render().splitlines()
>>> print result[0]
"Client ID","Time Stamp","Last Name","First Name","Email Address","Age","Personal Address","Academic Titles","Street","City","Country","Event 1","WL Event 1","Event 2","WL Event 2"
>>> len(result)
2
>>> print [f.strip('"') for f in result[1].split(',')[1:]]
['...', 'Walker', 'John', 'john@walker.tv', '', 'Mr', '', '', '', '', '1', '2', '0', '0']
Removal of services and clients
===============================
>>> from cybertools.organize.service import serviceRemoved, clientRemoved
>>> client4 = workshop.clients[client4Name]
>>> regs = IClientRegistrations(client4)
>>> regs.template = regForm
>>> len(regs.getRegistrations())
1
>>> serviceRemoved(event1, None)
>>> len(regs.getRegistrations())
0
>>> regs.register([event2])
>>> len(event2.registrations)
2
>>> clientRemoved(client4, None)
>>> len(event2.registrations)
1
Fin de partie
=============
>>> placefulTearDown()

View file

@ -7,8 +7,12 @@ $Id$
"""
import unittest, doctest
from zope import component
from zope.testing.doctestunit import DocFileSuite
from cybertools.composer.schema import client, field, instance
from cybertools.organize.party import Person
from cybertools.organize import service
class TestParty(unittest.TestCase):
"Basic tests for the party module."
@ -19,11 +23,23 @@ class TestParty(unittest.TestCase):
self.assertEqual('Meier', p.lastName)
def setUp(site):
component.provideAdapter(client.ClientFactory)
component.provideAdapter(instance.ClientInstance)
component.provideAdapter(instance.ClientInstanceEditor, name='editor')
component.provideAdapter(field.FieldInstance)
component.provideAdapter(field.NumberFieldInstance, name='number')
component.provideAdapter(field.EmailFieldInstance, name='email')
component.provideAdapter(service.StatefulRegistration)
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return unittest.TestSuite((
unittest.makeSuite(TestParty),
DocFileSuite('README.txt', optionflags=flags),
DocFileSuite('formmanager.txt', optionflags=flags),
DocFileSuite('servicemanager.txt', optionflags=flags),
DocFileSuite('work.txt', optionflags=flags),
))