[Checkins] SVN: gocept.registration/trunk/ Imported first draft.
Christian Theune
ct at gocept.com
Wed Mar 12 17:27:54 EDT 2008
Log message for revision 84626:
Imported first draft.
This is a generalization of a previous internal implentation.
Changed:
A gocept.registration/trunk/
A gocept.registration/trunk/COPYRIGHT.txt
A gocept.registration/trunk/LICENSE.txt
A gocept.registration/trunk/bootstrap.py
A gocept.registration/trunk/buildout.cfg
A gocept.registration/trunk/setup.py
A gocept.registration/trunk/src/
A gocept.registration/trunk/src/gocept/
A gocept.registration/trunk/src/gocept/__init__.py
A gocept.registration/trunk/src/gocept/registration/
A gocept.registration/trunk/src/gocept/registration/README.txt
A gocept.registration/trunk/src/gocept/registration/__init__.py
A gocept.registration/trunk/src/gocept/registration/email.py
A gocept.registration/trunk/src/gocept/registration/interfaces.py
A gocept.registration/trunk/src/gocept/registration/registrations.py
A gocept.registration/trunk/src/gocept/registration/tests.py
-=-
Added: gocept.registration/trunk/COPYRIGHT.txt
===================================================================
--- gocept.registration/trunk/COPYRIGHT.txt (rev 0)
+++ gocept.registration/trunk/COPYRIGHT.txt 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,9 @@
+Copyright (c) 2008 Zope Foundation and contributors.
+All Rights Reserved.
+
+This software is subject to the provisions of the Zope Public License,
+Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+FOR A PARTICULAR PURPOSE.
Property changes on: gocept.registration/trunk/COPYRIGHT.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/LICENSE.txt
===================================================================
--- gocept.registration/trunk/LICENSE.txt (rev 0)
+++ gocept.registration/trunk/LICENSE.txt 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,44 @@
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies the
+copyright holders.
+
+This license has been certified as open source. It has also been designated as
+GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions in source code must retain the accompanying copyright
+notice, this list of conditions, and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying copyright
+notice, this list of conditions, and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to endorse or promote
+products derived from this software without prior written permission from the
+copyright holders.
+
+4. The right to distribute this software or to use it for any purpose does not
+give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright
+holders. Use of them is covered by separate agreement with the copyright
+holders.
+
+5. If any files are modified, you must cause the modified files to carry
+prominent notices stating that you changed the files and the date of any
+change.
+
+Disclaimer
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
Property changes on: gocept.registration/trunk/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/bootstrap.py
===================================================================
--- gocept.registration/trunk/bootstrap.py (rev 0)
+++ gocept.registration/trunk/bootstrap.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 73964 2007-04-01 18:58:20Z srichter $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Property changes on: gocept.registration/trunk/bootstrap.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/buildout.cfg
===================================================================
--- gocept.registration/trunk/buildout.cfg (rev 0)
+++ gocept.registration/trunk/buildout.cfg 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,7 @@
+[buildout]
+parts = test
+develop = .
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = gocept.registration [test]
Added: gocept.registration/trunk/setup.py
===================================================================
--- gocept.registration/trunk/setup.py (rev 0)
+++ gocept.registration/trunk/setup.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import os.path
+
+from setuptools import setup, find_packages
+
+
+setup(
+ name = 'gocept.registration',
+ version = "0.1",
+ author = "Christian Theune, Stephan Richter and others",
+ author_email = "mail at gocept.com",
+ description = "User self-registration",
+ long_description = file(os.path.join(os.path.dirname(__file__),
+ 'src', 'gocept', 'registration',
+ 'README.txt')).read(),
+ license = "ZPL 2.1",
+ url='http://pypi.python.org/pypi/gocept.registration/',
+
+ packages = find_packages('src'),
+ package_dir = {'': 'src'},
+
+ include_package_data = True,
+ zip_safe = False,
+
+ namespace_packages = ['gocept'],
+ install_requires = [
+ 'setuptools',
+ 'zope.app.container',
+ 'zope.component',
+ 'zope.interface',
+ 'zope.sendmail',
+ ],
+ extras_require = dict(
+ test=['zope.testing',
+ ])
+ )
Property changes on: gocept.registration/trunk/setup.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/__init__.py
===================================================================
--- gocept.registration/trunk/src/gocept/__init__.py (rev 0)
+++ gocept.registration/trunk/src/gocept/__init__.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,8 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
+
Property changes on: gocept.registration/trunk/src/gocept/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/README.txt
===================================================================
--- gocept.registration/trunk/src/gocept/registration/README.txt (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/README.txt 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,164 @@
+======================
+User self-registration
+======================
+
+This package provides functionality to implement user self-registration for
+applications.
+
+The general workflow requires that every user provides at least his email
+address but additional data may be provided, too. After a user registered, an
+email is send out asking him to confirm his identity by clicking a link that
+is embedded in the email. Once a registration is confirmed, the temporarily
+stored registration data is deleted.
+
+Applications can customize the registration behaviour by subscribing to events
+for registration and confirmation and providing application-specific views and
+adapters for registration and email creation.
+
+Registering a user
+==================
+
+Registrations are managed by the registrations utility:
+
+ >>> from gocept.registration.registrations import Registrations
+ >>> registrations = Registrations()
+
+We can now register a user by passing his email address and some additional
+data:
+
+ >>> peter = registrations.register('peter at example.com', {'name': u'Peter'})
+ >>> peter
+ <gocept.registration.registrations.Registration object at 0x...>
+
+All registrations have a hash that anonymous identifies them, the email and
+the data attached:
+
+ >>> peter.hash
+ '<SHA-HASH>'
+ >>> peter.email
+ 'peter at example.com'
+ >>> peter.data
+ {'name': u'Peter'}
+
+Peter's registration is contained in the utility identified by the hash:
+
+ >>> registrations[peter.hash]
+ <gocept.registration.registrations.Registration object at 0x...>
+
+Peter can now confirm his registration using the hash that was given to him:
+
+ >>> registrations.confirm(peter.hash)
+
+Now that he confirmed his registration, it isn't stored in the utility
+anymore:
+
+ >>> registrations[peter.hash]
+ Traceback (most recent call last):
+ KeyError: '<SHA-HASH>'
+
+
+Application hooks
+=================
+
+There are two hooks that applications can tap into for customizing the registration process:
+
+- the ObjectAddedEvent for the registration object, and
+- the RegistrationConfirmedEvent when the user confirms his registration
+
+Let's register a subscriber for both events to demonstrate where each is called:
+
+ >>> def registered(event):
+ ... print event, event.object
+ >>> import zope.component
+ >>> from zope.app.container.interfaces import IObjectAddedEvent
+ >>> zope.component.provideHandler(registered, (IObjectAddedEvent,))
+
+ >>> chuck = registrations.register('chuck at example.com', {'name': u'LeChuck'})
+ <zope.app.container.contained.ObjectAddedEvent object at 0x...>
+ <gocept.registration.registrations.Registration object at 0x...>
+
+ >>> def confirmed(event):
+ ... print event, event.registration
+ >>> from gocept.registration.interfaces import IRegistrationConfirmed
+ >>> zope.component.provideHandler(confirmed, (IRegistrationConfirmed,))
+
+ >>> registrations.confirm(chuck.hash)
+ <gocept.registration.interfaces.RegistrationConfirmedEvent object at 0x...>
+ <gocept.registration.registrations.Registration object at 0x...>
+
+Let's clean those registrations up again:
+
+ >>> from zope.app.testing import placelesssetup
+ >>> placelesssetup.tearDown()
+
+
+Confirmation emails
+===================
+
+Sending out registration emails is divided into two parts: creating the email
+itself, and sending it.
+
+Creating confirmation mails
+---------------------------
+
+To provide some central configuration, registrations can be adapted to
+IRegistrationEmailConfiguration:
+
+ >>> from gocept.registration.interfaces import IEmailConfiguration
+ >>> from gocept.registration.interfaces import IRegistration
+ >>> class TestConfig(object):
+ ... zope.interface.implements(IEmailConfiguration)
+ ... addr_from = "Ad Ministrator <admin at example.com>"
+ ... confirmation_url = "http://example.com/confirm?hash=%s"
+ ... confirmation_template = """From: %(from)s
+ ... To: %(to)s
+ ... Subject: Please confirm your registration
+ ...
+ ... We received your registration. To activate it, please follow this confirmation
+ ...
+ ... link:
+ ...
+ ... %(link)s"""
+ ... def __init__(self, registration):
+ ... pass
+ >>> zope.component.provideAdapter(TestConfig, adapts=(IRegistration,))
+
+The confirmation email is created by adapting the registration object to the
+IRegistrationEmail interface. We provide a simple implementation to start
+from.
+
+ >>> from gocept.registration.email import ConfirmationEmail
+ >>> mail = ConfirmationEmail(chuck)
+ >>> print mail.message
+ From: Ad Ministrator <admin at example.com>
+ To: chuck at example.com
+ Subject: Please confirm your registration
+ <BLANKLINE>
+ We received your registration. To activate it, please follow this confirmation
+ link:
+ <BLANKLINE>
+ http://example.com/confirm?hash=<SHA-HASH>
+
+
+Sending confirmation mails
+--------------------------
+
+We provide a standard event handler that will send out an email for the
+registration:
+
+ >>> from gocept.registration.email import send_registration_mail
+ >>> zope.component.provideAdapter(ConfirmationEmail, (IRegistration,))
+ >>> zope.component.provideHandler(send_registration_mail, (IObjectAddedEvent,))
+ >>> from gocept.registration.tests import DummyMailer
+ >>> zope.component.provideUtility(DummyMailer())
+ >>> janine = registrations.register('janine at example.com')
+ (Ad Ministrator <admin at example.com> -> ['janine at example.com'])
+ From: Ad Ministrator <admin at example.com>
+ To: janine at example.com
+ Subject: Please confirm your registration
+ <BLANKLINE>
+ We received your registration. To activate it, please follow this confirmation
+ <BLANKLINE>
+ link:
+ <BLANKLINE>
+ http://example.com/confirm?hash=<SHA-HASH>
Property changes on: gocept.registration/trunk/src/gocept/registration/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/__init__.py
===================================================================
--- gocept.registration/trunk/src/gocept/registration/__init__.py (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/__init__.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1 @@
+# Make this a Python package
Property changes on: gocept.registration/trunk/src/gocept/registration/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/email.py
===================================================================
--- gocept.registration/trunk/src/gocept/registration/email.py (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/email.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Confirmation emails."""
+
+import gocept.registration.interfaces
+import zope.interface
+
+
+class ConfirmationEmail(object):
+ """A basic confirmation email."""
+
+ zope.interface.implements(
+ gocept.registration.interfaces.IConfirmationEmail)
+
+ def __init__(self, registration):
+ config = gocept.registration.interfaces.IEmailConfiguration(
+ registration)
+ self.message = config.confirmation_template % {
+ 'to': registration.email,
+ 'from': config.addr_from,
+ 'link': config.confirmation_url % registration.hash}
+
+
+def send_registration_mail(event):
+ """Listen for a registration and send a mail to the user, asking for
+ confirmation.
+ """
+ registration = event.object
+ email = gocept.registration.interfaces.IConfirmationEmail(registration)
+ config = gocept.registration.interfaces.IEmailConfiguration(registration)
+ mailer = zope.component.getUtility(zope.sendmail.interfaces.IMailer)
+ mailer.send(config.addr_from, [registration.email], email.message)
Property changes on: gocept.registration/trunk/src/gocept/registration/email.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/interfaces.py
===================================================================
--- gocept.registration/trunk/src/gocept/registration/interfaces.py (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/interfaces.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,103 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""User self-registration interfaces. """
+
+import zope.interface
+import zope.schema
+
+
+class IRegistrations(zope.interface.Interface):
+ """Provide self-registration functionality.
+
+ Registrations are done for users giving their email address and
+ possibly more data.
+
+ A registration requires confirmation by the user. For this we
+ send an email containing a confirmation link to his address.
+
+ Upon opening the link a RegistrationConfirmedEvent is sent out
+ and the application can perform whatever is necessary to active
+ the user's account.
+
+ After the successful confirmation the intermediate registration
+ object is deleted.
+
+ """
+
+ def register(email, data=None):
+ """Create a new registration for the given email address and
+ data.
+
+ Sends out an ObjectAddedEvent for the newly created
+ IRegistration object.
+
+ """
+
+ def confirm(hash):
+ """Confirm the registration identified by the hash.
+
+ If successful sends out an IRegistrationConfirmed event.
+
+ """
+
+
+class IEmailConfiguration(zope.interface.Interface):
+ """Defines configuration data for sending registration-related emails."""
+
+ addr_from = zope.schema.TextLine(
+ title=u"The sender's name and email address.")
+
+ confirmation_url = zope.schema.TextLine(
+ title=u"A URL including a single '%s' which can be replaced "
+ u"by the confirmation hash.")
+
+ confirmation_template = zope.interface.Attribute(
+ u"A string with an RFC 822 message. The string is required "
+ u"to include %()s places for the variables `from`, `to`, and "
+ u"`link`.")
+
+
+class IConfirmationEmail(zope.interface.Interface):
+ """An email to confirm a registration."""
+
+ message = zope.interface.Attribute(
+ "A string containing an RFC 2822 message.")
+
+
+class IRegistration(zope.interface.Interface):
+ """A registration."""
+
+ hash = zope.schema.BytesLine(
+ title=u"A hash identifying this registration",)
+
+ email = zope.schema.TextLine(
+ title=u"The email for sending the confirmation mail to.")
+
+ data = zope.interface.Attribute(
+ u"Application-specific registration data.")
+
+
+class IRegistrationConfirmed(zope.interface.Interface):
+
+ registration = zope.schema.Object(
+ title=u"The registration that was confirmed.",
+ schema=IRegistration)
+
+
+class RegistrationConfirmedEvent(object):
+
+ zope.interface.implements(IRegistrationConfirmed)
+
+ def __init__(self, registration):
+ self.registration = registration
Property changes on: gocept.registration/trunk/src/gocept/registration/interfaces.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/registrations.py
===================================================================
--- gocept.registration/trunk/src/gocept/registration/registrations.py (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/registrations.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""A utility for managing registrations."""
+
+import datetime
+import gocept.registration.interfaces
+import persistent
+import sha
+import zope.app.container.btree
+import zope.interface
+
+
+class Registrations(zope.app.container.btree.BTreeContainer):
+
+ zope.interface.implements(gocept.registration.interfaces.IRegistrations)
+
+ def register(self, email, data=None):
+ """Create a new registration for the given email address and data."""
+ hash = sha.new(email+datetime.datetime.now().isoformat()).hexdigest()
+ self[hash] = registration = Registration(hash, email, data)
+ return registration
+
+ def confirm(self, hash):
+ """Confirm the registration identified by the hash."""
+ registration = self[hash]
+
+ event = gocept.registration.interfaces.RegistrationConfirmedEvent(
+ registration)
+ zope.event.notify(event)
+
+ del self[hash]
+
+
+class Registration(zope.app.container.contained.Contained,
+ persistent.Persistent):
+
+ zope.interface.implements(gocept.registration.interfaces.IRegistration)
+
+ def __init__(self, hash, email, data):
+ self.hash = hash
+ self.email = email
+ self.data = data
Property changes on: gocept.registration/trunk/src/gocept/registration/registrations.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: gocept.registration/trunk/src/gocept/registration/tests.py
===================================================================
--- gocept.registration/trunk/src/gocept/registration/tests.py (rev 0)
+++ gocept.registration/trunk/src/gocept/registration/tests.py 2008-03-12 21:27:54 UTC (rev 84626)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test harness for gocept.registration."""
+
+import re
+import unittest
+import zope.testing.renormalizing
+import zope.sendmail.interfaces
+
+from zope.app.testing import placelesssetup
+from zope.testing import doctest
+
+
+checker = zope.testing.renormalizing.RENormalizing([
+ (re.compile('[a-z0-9]{40}'), '<SHA-HASH>')])
+
+
+class DummyMailer(object):
+ """A dummy mailer."""
+
+ zope.interface.implements(zope.sendmail.interfaces.IMailer)
+
+ def send(self, fromaddr, toaddr, msg):
+ print "(%s -> %s)" % (fromaddr, toaddr)
+ print msg
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(doctest.DocFileSuite(
+ 'README.txt',
+ optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE,
+ checker=checker, setUp=placelesssetup.setUp,
+ tearDown=placelesssetup.tearDown))
+ return suite
Property changes on: gocept.registration/trunk/src/gocept/registration/tests.py
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list