[Testbot] Plone 5.0 - Python 2.7 - Build # 3511 - Still failing! - 0 failure(s)

jenkins at plone.org jenkins at plone.org
Fri Oct 31 09:55:18 UTC 2014


-------------------------------------------------------------------------------
Plone 5.0 - Python 2.7 - Build # 3511 - Still Failing!
-------------------------------------------------------------------------------

http://jenkins.plone.org/job/plone-5.0-python-2.7/3511/


-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------

Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-30T23:50:24Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/27633166de35b4535206b08f8aae8ead5ab2bf04

updated classifiers

Files changed:
M setup.py

diff --git a/setup.py b/setup.py
index 8f9c654..0443ee6 100644
--- a/setup.py
+++ b/setup.py
@@ -9,9 +9,11 @@
               open("CHANGES.txt").read(),
       classifiers=[
         "Framework :: Plone",
+        "Framework :: Plone :: 5.0",
         "Framework :: Zope2",
         "License :: OSI Approved :: GNU General Public License (GPL)",
         "Programming Language :: Python",
+        "Programming Language :: Python :: 2.7",
         ],
       keywords='password reset plone',
       author='J. Cameron Cooper',


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T08:25:04Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/daf5317c93b6a019c3d77b864b3b771a703c4266

Changed PTC for plone.app.testing

Files changed:
M Products/PasswordResetTool/tests/browser.txt
M Products/PasswordResetTool/tests/test_doctests.py
M Products/PasswordResetTool/tests/view.txt
M setup.py

diff --git a/Products/PasswordResetTool/tests/browser.txt b/Products/PasswordResetTool/tests/browser.txt
index 284a992..1180ac7 100644
--- a/Products/PasswordResetTool/tests/browser.txt
+++ b/Products/PasswordResetTool/tests/browser.txt
@@ -8,12 +8,9 @@ Note that our usage of testbrowser is unusual and inconsistent, mostly
 because Plone forms have inconsistencies and because testbrowser makes
 assumptions that are not true for Plone forms.
 
-  >>> from Products.PloneTestCase import PloneTestCase as PTC
-  >>> from Products.Five.testbrowser import Browser
-  >>> browser = Browser()
-  >>> browser.handleErrors = False
-  >>> browser.open('http://nohost/plone/')
-
+  >>> from plone.testing.z2 import Browser
+  >>> from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
+  >>> browser = Browser(layer['app'])
 
 Assumptions
 -----------
@@ -84,8 +81,8 @@ type in his initial password, so we need to enable that:
 
   >>> browser.open('http://nohost/plone/login')
   >>> browser.getLink('Log in').click()
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = TEST_USER_NAME
+  >>> browser.getControl(name='__ac_password').value = TEST_USER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -157,7 +154,7 @@ As part of our test setup, we replaced the original MailHost with our
 own version.  Our version doesn't mail messages, it just collects them
 in a list called ``messages``:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   1
   >>> msg = mailhost.messages[0]
@@ -224,8 +221,8 @@ Log out again:
 First, we want to login as the portal owner:
 
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -271,8 +268,8 @@ password.
 First off, we need to set ``validate_mail`` to False:
 
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -308,7 +305,7 @@ Now register:
 
 We should have received an e-mail at this point:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   2
   >>> msg = str(mailhost.messages[-1])
@@ -363,10 +360,10 @@ e-mail is sent containing the URL that lets the user log in.
 
 First, we want to login as the portal owner:
 
-  >>> from Products.PloneTestCase import PloneTestCase as PTC
+  >>> from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -394,7 +391,7 @@ Now register and logout:
 
 We should have received an e-mail at this point:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   3
   >>> msg = str(mailhost.messages[-1])
diff --git a/Products/PasswordResetTool/tests/test_doctests.py b/Products/PasswordResetTool/tests/test_doctests.py
index d49f07e..02901cc 100644
--- a/Products/PasswordResetTool/tests/test_doctests.py
+++ b/Products/PasswordResetTool/tests/test_doctests.py
@@ -4,45 +4,45 @@
 
 import doctest
 import unittest
-from Testing.ZopeTestCase import FunctionalDocFileSuite
-from Products.PloneTestCase import PloneTestCase
 from Products.MailHost.interfaces import IMailHost
 from zope.component import getSiteManager
 from Acquisition import aq_base
 
-PloneTestCase.setupPloneSite()
-
 from Products.CMFPlone.tests.utils import MockMailHost
-
+from plone.app import testing
+from plone.testing import layered
 
 OPTIONFLAGS = (doctest.ELLIPSIS |
                doctest.NORMALIZE_WHITESPACE)
 
-class MockMailHostTestCase(PloneTestCase.FunctionalTestCase):
+class MockMailFixture(testing.PloneSandboxLayer):
 
-    def afterSetUp(self):
-        self.portal._original_MailHost = self.portal.MailHost
-        self.portal.MailHost = mailhost = MockMailHost('MailHost')
+    defaultBases = (testing.PLONE_FIXTURE,)
+
+    def setUpPloneSite(self, portal):
+        portal._original_MailHost = self.portal.MailHost
+        portal.MailHost = mailhost = MockMailHost('MailHost')
         mailhost.smtp_host = 'localhost'
-        sm = getSiteManager(context=self.portal)
+        sm = getSiteManager(context=portal)
         sm.unregisterUtility(provided=IMailHost)
         sm.registerUtility(mailhost, provided=IMailHost)
-        self.portal.email_from_address = 'test at example.com'
+        portal.email_from_address = 'test at example.com'
 
-    def beforeTearDown(self):
-        self.portal.MailHost = self.portal._original_MailHost
-        sm = getSiteManager(context=self.portal)
-        sm.unregisterUtility(provided=IMailHost)
-        sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost)
+#    def beforeTearDown(self):
+#        self.portal.MailHost = self.portal._original_MailHost
+#        sm = getSiteManager(context=self.portal)
+#        sm.unregisterUtility(provided=IMailHost)
+#        sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost)
 
+MOCK_MAIL_FIXTURE = MockMailFixture()
 
 def test_suite():
     return unittest.TestSuite((
-        FunctionalDocFileSuite('browser.txt',
+        doctest.DocFileSuite('browser.txt',
                                optionflags=OPTIONFLAGS,
                                package='Products.PasswordResetTool.tests',
                                test_class=MockMailHostTestCase),
-        FunctionalDocFileSuite('view.txt',
+        doctest.DocFileSuite('view.txt',
                                optionflags=OPTIONFLAGS,
                                package='Products.PasswordResetTool.tests',
                                test_class=MockMailHostTestCase),
diff --git a/Products/PasswordResetTool/tests/view.txt b/Products/PasswordResetTool/tests/view.txt
index fca4ef4..dd2c9eb 100644
--- a/Products/PasswordResetTool/tests/view.txt
+++ b/Products/PasswordResetTool/tests/view.txt
@@ -1,16 +1,16 @@
 Test passwordreset BrowserView 
 
-    >>> from Products.PloneTestCase import PloneTestCase as PTC
-    >>> from Products.Five.testbrowser import Browser
-    >>> browser = Browser()
-    >>> browser.handleErrors = False
+    >>> from plone.testing.z2 import Browser
+    >>> from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
+    >>> browser = Browser(layer['app'])
     >>> browser.open('http://nohost/plone/')
 
     Setup Plone email sender
 
-    >>> self.portal.email_from_name=u'Old\u0159ich a Bo\u017eena'
-    >>> self.portal.email_from_address='smith at example.com'
-    >>> self.portal.title=u'Koko\u0159\xedn Portal'
+    >>> portal = layer['portal']
+    >>> portal.email_from_name=u'Old\u0159ich a Bo\u017eena'
+    >>> portal.email_from_address='smith at example.com'
+    >>> portal.title=u'Koko\u0159\xedn Portal'
     
     Check view methods
     
diff --git a/setup.py b/setup.py
index 0443ee6..54cad27 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@
       zip_safe=False,
       extras_require=dict(
         test=[
-            'Products.PloneTestCase',
+            'plone.app.testing',
         ]
       ),
       install_requires=[


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T08:46:20Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/1877f17745a0009f5c2bb6ac686f464e98b80070

removed unused browser setup

Files changed:
M Products/PasswordResetTool/tests/view.txt

diff --git a/Products/PasswordResetTool/tests/view.txt b/Products/PasswordResetTool/tests/view.txt
index dd2c9eb..0616084 100644
--- a/Products/PasswordResetTool/tests/view.txt
+++ b/Products/PasswordResetTool/tests/view.txt
@@ -1,10 +1,5 @@
 Test passwordreset BrowserView 
 
-    >>> from plone.testing.z2 import Browser
-    >>> from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
-    >>> browser = Browser(layer['app'])
-    >>> browser.open('http://nohost/plone/')
-
     Setup Plone email sender
 
     >>> portal = layer['portal']
@@ -14,7 +9,7 @@ Test passwordreset BrowserView
     
     Check view methods
     
-    >>> view = self.portal.restrictedTraverse('@@passwordreset_view')
+    >>> view = portal.restrictedTraverse('@@passwordreset_view')
     >>> view.encoded_mail_sender()
     '"=?utf-8?q?Old=C5=99ich_a_Bo=C5=BEena?=" <smith at example.com>'
 


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T08:47:00Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/1cf1cf9ba2405bf0de138c21b4632f91f066d653

readded teardown and put layers around doctests

Files changed:
M Products/PasswordResetTool/tests/test_doctests.py

diff --git a/Products/PasswordResetTool/tests/test_doctests.py b/Products/PasswordResetTool/tests/test_doctests.py
index 02901cc..65ea4e3 100644
--- a/Products/PasswordResetTool/tests/test_doctests.py
+++ b/Products/PasswordResetTool/tests/test_doctests.py
@@ -11,6 +11,7 @@
 from Products.CMFPlone.tests.utils import MockMailHost
 from plone.app import testing
 from plone.testing import layered
+from transaction import commit
 
 OPTIONFLAGS = (doctest.ELLIPSIS |
                doctest.NORMALIZE_WHITESPACE)
@@ -20,30 +21,34 @@ class MockMailFixture(testing.PloneSandboxLayer):
     defaultBases = (testing.PLONE_FIXTURE,)
 
     def setUpPloneSite(self, portal):
-        portal._original_MailHost = self.portal.MailHost
+        portal._original_MailHost = portal.MailHost
         portal.MailHost = mailhost = MockMailHost('MailHost')
         mailhost.smtp_host = 'localhost'
         sm = getSiteManager(context=portal)
         sm.unregisterUtility(provided=IMailHost)
         sm.registerUtility(mailhost, provided=IMailHost)
         portal.email_from_address = 'test at example.com'
+        commit()
+
+    def tearDownPloneSite(self, portal):
+        portal.MailHost = portal._original_MailHost
+        sm = getSiteManager(context=portal)
+        sm.unregisterUtility(provided=IMailHost)
+        sm.registerUtility(aq_base(portal._original_MailHost), provided=IMailHost)
 
-#    def beforeTearDown(self):
-#        self.portal.MailHost = self.portal._original_MailHost
-#        sm = getSiteManager(context=self.portal)
-#        sm.unregisterUtility(provided=IMailHost)
-#        sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost)
 
 MOCK_MAIL_FIXTURE = MockMailFixture()
+MM_FUNCTIONAL_TESTING = testing.FunctionalTesting(
+            bases=(MOCK_MAIL_FIXTURE,), name='PloneTestCase:Functional')
+
 
 def test_suite():
     return unittest.TestSuite((
-        doctest.DocFileSuite('browser.txt',
-                               optionflags=OPTIONFLAGS,
-                               package='Products.PasswordResetTool.tests',
-                               test_class=MockMailHostTestCase),
-        doctest.DocFileSuite('view.txt',
-                               optionflags=OPTIONFLAGS,
-                               package='Products.PasswordResetTool.tests',
-                               test_class=MockMailHostTestCase),
-        ))
+        layered(doctest.DocFileSuite('browser.txt',
+            optionflags=OPTIONFLAGS,
+            package='Products.PasswordResetTool.tests',),
+            layer=MM_FUNCTIONAL_TESTING),
+        layered(doctest.DocFileSuite('view.txt',
+            optionflags=OPTIONFLAGS,
+            package='Products.PasswordResetTool.tests',),
+            layer=MM_FUNCTIONAL_TESTING)))


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T09:25:33Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/e459b555ce9138f39a3613650a48e491c2f95dd6

reorder test a bit to have a simpler login / logout story

Files changed:
M Products/PasswordResetTool/tests/browser.txt
M Products/PasswordResetTool/tests/test_doctests.py

diff --git a/Products/PasswordResetTool/tests/browser.txt b/Products/PasswordResetTool/tests/browser.txt
index 1180ac7..75f656a 100644
--- a/Products/PasswordResetTool/tests/browser.txt
+++ b/Products/PasswordResetTool/tests/browser.txt
@@ -76,9 +76,22 @@ What we do here:
   - Reset our password
   - Log in with our new password
 
+Let's go directly to the security control panel:
+
+  >>> from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD
+  >>> browser.addHeader('Authorization',
+  ...                   'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD))
+  >>> browser.open('http://nohost/plone/@@security-controlpanel')
+  >>> ctrl = browser.getControl(name="form.enable_self_reg")
+  >>> ctrl.value = "on"
+  >>> ctrl = browser.getControl(name="form.enable_user_pwd_choice")
+  >>> ctrl.value = "on"
+  >>> browser.getControl(name="form.actions.save").click()
+
 Let's join as a new user. Plone's default settings won't let the user
 type in his initial password, so we need to enable that:
 
+  >>> browser = Browser(layer['app'])
   >>> browser.open('http://nohost/plone/login')
   >>> browser.getLink('Log in').click()
   >>> browser.getControl(name='__ac_name').value = TEST_USER_NAME
@@ -87,15 +100,6 @@ type in his initial password, so we need to enable that:
   >>> "You are now logged in" in browser.contents
   True
 
-Let's go directly to the security control panel:
-
-  >>> browser.open('http://nohost/plone/@@security-controlpanel')
-  >>> ctrl = browser.getControl(name="form.enable_self_reg")
-  >>> ctrl.value = "on"
-  >>> ctrl = browser.getControl(name="form.enable_user_pwd_choice")
-  >>> ctrl.value = "on"
-  >>> browser.getControl(name="form.actions.save").click()
-
 Log out again and then join:
 
   >>> browser.getLink('Log out').click()
diff --git a/Products/PasswordResetTool/tests/test_doctests.py b/Products/PasswordResetTool/tests/test_doctests.py
index 65ea4e3..a2e88b7 100644
--- a/Products/PasswordResetTool/tests/test_doctests.py
+++ b/Products/PasswordResetTool/tests/test_doctests.py
@@ -14,7 +14,8 @@
 from transaction import commit
 
 OPTIONFLAGS = (doctest.ELLIPSIS |
-               doctest.NORMALIZE_WHITESPACE)
+               doctest.NORMALIZE_WHITESPACE |
+               doctest.REPORT_ONLY_FIRST_FAILURE)
 
 class MockMailFixture(testing.PloneSandboxLayer):
 


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T09:28:25Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/704e6859b105fc5ef77a84a19d17dea46d898f0c

cleanups reported by frosted

Files changed:
M Products/PasswordResetTool/browser.py

diff --git a/Products/PasswordResetTool/browser.py b/Products/PasswordResetTool/browser.py
index 877e6b1..f031467 100644
--- a/Products/PasswordResetTool/browser.py
+++ b/Products/PasswordResetTool/browser.py
@@ -1,4 +1,3 @@
-from Acquisition import aq_inner
 from zope.interface import implements
 from zope.component import getMultiAdapter
 from Products.Five import BrowserView
@@ -48,8 +47,6 @@ def registered_notify_subject(self):
                            context=self.request)
 
     def mail_password_subject(self):
-        portal = self.portal_state().portal()
-        portal_name = portal.Title()
         return translate(_(u"mailtemplate_subject_resetpasswordrequest",
                            default=u"Password reset request"),
                            context=self.request)


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T09:29:42Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/47825efa26437d13ef7f61b39d22f8ec9fbe731b

pep8ify

Files changed:
M Products/PasswordResetTool/PasswordResetTool.py
M Products/PasswordResetTool/__init__.py
M Products/PasswordResetTool/browser.py
M Products/PasswordResetTool/django_random.py
M Products/PasswordResetTool/interfaces/__init__.py
M Products/PasswordResetTool/interfaces/portal_password_reset.py
M Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
M Products/PasswordResetTool/tests/test_doctests.py

diff --git a/Products/PasswordResetTool/PasswordResetTool.py b/Products/PasswordResetTool/PasswordResetTool.py
index 1de8ca9..dd03c3e 100644
--- a/Products/PasswordResetTool/PasswordResetTool.py
+++ b/Products/PasswordResetTool/PasswordResetTool.py
@@ -29,26 +29,35 @@
 
 from interfaces.portal_password_reset import portal_password_reset as IPWResetTool
 
-import datetime, time, socket
+import datetime
+import time
+import socket
 from DateTime import DateTime
 from zope.interface import implements
 
 module_security = ModuleSecurityInfo('Products.PasswordResetTool.PasswordResetTool')
 
 module_security.declarePublic('InvalidRequestError')
+
+
 class InvalidRequestError(Exception):
     def __init__(self, value=''):
         self.value = value
+
     def __str__(self):
         return repr(self.value)
 
 module_security.declarePublic('ExpiredRequestError')
+
+
 class ExpiredRequestError(Exception):
     def __init__(self, value=''):
         self.value = value
+
     def __str__(self):
         return repr(self.value)
 
+
 class PasswordResetTool (UniqueObject, SimpleItem):
     """Provides a default implementation for a password reset scheme.
 
@@ -59,7 +68,6 @@ class PasswordResetTool (UniqueObject, SimpleItem):
 
     The user visits that URL (the 'reset form') and enters their username,
     """
-
     ## other things needed for this to work
     # skins:
     #  - handler script for forgotten password form (probably over-riding
@@ -75,23 +83,25 @@ class PasswordResetTool (UniqueObject, SimpleItem):
 
     security = ClassSecurityInfo()
 
-    manage_options=(( { 'label' : 'Overview'
-                        , 'action' : 'manage_overview'
+    manage_options = (({'label': 'Overview'
+                        , 'action': 'manage_overview'
                         },
                       ) + SimpleItem.manage_options
                     )
 
     ##   ZMI methods
     security.declareProtected(ManagePortal, 'manage_overview')
-    manage_overview = DTMLFile('dtml/explainPWResetTool', globals() )
+    manage_overview = DTMLFile('dtml/explainPWResetTool', globals())
 
     security.declareProtected(ManagePortal, 'manage_setTimeout')
+
     def manage_setTimeout(self, hours=168, REQUEST=None):
         """ZMI method for setting the expiration timeout in hours."""
         self.setExpirationTimeout(int(hours))
         return self.manage_overview(manage_tabs_message="Timeout set to %s hours" % hours)
 
     security.declareProtected(ManagePortal, 'manage_toggleUserCheck')
+
     def manage_toggleUserCheck(self, REQUEST=None):
         """ZMI method for toggling the flag for checking user names on return.
         """
@@ -99,16 +109,16 @@ def manage_toggleUserCheck(self, REQUEST=None):
         m = self.checkUser() and 'on' or 'off'
         return self.manage_overview(manage_tabs_message="Returning username check turned %s" % m)
 
-
     def __init__(self):
         self._requests = {}
 
     ## Internal attributes
     _user_check = 1
-    _timedelta = 168 # misleading name, the number of hours are actually stored as int
+    _timedelta = 168  # misleading name, the number of hours are actually stored as int
 
     ## Interface fulfillment ##
     security.declareProtected(ManagePortal, 'requestReset')
+
     def requestReset(self, userid):
         """Ask the system to start the password reset procedure for
         user 'userid'.
@@ -125,7 +135,7 @@ def requestReset(self, userid):
         self._requests[randomstring] = (userid, expiry)
 
         self.clearExpired(10)   # clear out untouched records more than 10 days old
-                                # this is a cheap sort of "automatic" clearing
+        # this is a cheap sort of "automatic" clearing
         self._p_changed = 1
 
         retval = {}
@@ -135,6 +145,7 @@ def requestReset(self, userid):
         return retval
 
     security.declarePublic('resetPassword')
+
     def resetPassword(self, userid, randomstring, password):
         """Set the password (in 'password') for the user who maps to
         the string in 'randomstring' iff the entered 'userid' is equal
@@ -187,13 +198,12 @@ def resetPassword(self, userid, randomstring, password):
         # clean out the request
         del self._requests[randomstring]
         self._p_changed = 1
-
-
     ## Implementation ##
 
     # external
 
     security.declareProtected(ManagePortal, 'setExpirationTimeout')
+
     def setExpirationTimeout(self, timedelta):
         """Set the length of time a reset request will be valid.
 
@@ -204,6 +214,7 @@ def setExpirationTimeout(self, timedelta):
         self._timedelta = abs(timedelta)
 
     security.declarePublic('getExpirationTimeout')
+
     def getExpirationTimeout(self):
         """Get the length of time a reset request will be valid.
 
@@ -216,6 +227,7 @@ def getExpirationTimeout(self):
         return self._timedelta
 
     security.declareProtected(ManagePortal, 'toggleUserCheck')
+
     def toggleUserCheck(self):
         """Changes whether or not the tool requires someone to give the uerid
         they're trying to change on a 'password reset' page. Highly recommended
@@ -226,6 +238,7 @@ def toggleUserCheck(self):
         self._user_check = not self._user_check
 
     security.declarePublic('checkUser')
+
     def checkUser(self):
         """Returns a boolean representing the state of 'user check' as described
         in 'toggleUserCheck'. True means on, and is the default."""
@@ -235,6 +248,7 @@ def checkUser(self):
         return self._user_check
 
     security.declarePublic('verifyKey')
+
     def verifyKey(self, key):
         """Verify a key. Raises an exception if the key is invalid or expired.
         """
@@ -250,6 +264,7 @@ def verifyKey(self, key):
             raise InvalidRequestError('No such user')
 
     security.declareProtected(ManagePortal, 'getStats')
+
     def getStats(self):
         """Return a dictionary like so:
             {"open":3, "expired":0}
@@ -258,25 +273,28 @@ def getStats(self):
         good = 0
         bad = 0
         for stored_user, expiry in self._requests.values():
-            if self.expired(expiry): bad += 1
-            else: good += 1
+            if self.expired(expiry):
+                bad += 1
+            else:
+                good += 1
 
         return {"open": good, "expired": bad}
 
     security.declarePrivate('clearExpired')
+
     def clearExpired(self, days=0):
         """Destroys all expired reset request records.
         Parameter controls how many days past expired it must be to disappear.
         """
         for key, record in self._requests.items():
             stored_user, expiry = record
-            if self.expired(expiry, DateTime()-days):
+            if self.expired(expiry, DateTime() - days):
                 del self._requests[key]
                 self._p_changed = 1
-
     # customization points
 
     security.declarePrivate('uniqueString')
+
     def uniqueString(self, userid):
         """Returns a string that is random and unguessable, or at
         least as close as possible.
@@ -290,10 +308,10 @@ def uniqueString(self, userid):
         # this is the informal UUID algorithm of
         # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/213761
         # by Carl Free Jr
-        t = long( time.time() * 1000 )
+        t = long(time.time() * 1000)
         r = django_random.get_random_string(64)
         try:
-            a = socket.gethostbyname( socket.gethostname() )
+            a = socket.gethostbyname(socket.gethostname())
         except:
             # if we can't get a network address, just imagine one
             a = django_random.get_random_string(64)
@@ -302,6 +320,7 @@ def uniqueString(self, userid):
         return str(data)
 
     security.declarePrivate('expirationDate')
+
     def expirationDate(self):
         """Returns a DateTime for exipiry of a request from the
         current time.
@@ -310,7 +329,7 @@ def expirationDate(self):
         and stored in reset request records."""
         if not hasattr(self, '_timedelta'):
             self._timedelta = 168
-        if isinstance(self._timedelta,datetime.timedelta):
+        if isinstance(self._timedelta, datetime.timedelta):
             expire = datetime.datetime.utcnow() + self._timedelta
             return DateTime(expire.year,
                             expire.month,
@@ -319,10 +338,11 @@ def expirationDate(self):
                             expire.minute,
                             expire.second,
                             'UTC')
-        expire = time.time() + self._timedelta*3600  # 60 min/hr * 60 sec/min
+        expire = time.time() + self._timedelta * 3600  # 60 min/hr * 60 sec/min
         return DateTime(expire)
 
     security.declarePrivate('getValidUser')
+
     def getValidUser(self, userid):
         """Returns the member with 'userid' if available and None otherwise."""
         if get_member_by_login_name:
@@ -332,10 +352,10 @@ def getValidUser(self, userid):
                     self, userid, raise_exceptions=False)
         membertool = getToolByName(self, 'portal_membership')
         return membertool.getMemberById(userid)
-
     # internal
 
     security.declarePrivate('expired')
+
     def expired(self, datetime, now=None):
         """Tells whether a DateTime or timestamp 'datetime' is expired
         with regards to either 'now', if provided, or the current
diff --git a/Products/PasswordResetTool/__init__.py b/Products/PasswordResetTool/__init__.py
index d1a8ced..cc5ab52 100644
--- a/Products/PasswordResetTool/__init__.py
+++ b/Products/PasswordResetTool/__init__.py
@@ -5,10 +5,11 @@
 from zope.i18nmessageid import MessageFactory
 passwordresetMessageFactory = MessageFactory('passwordresettool')
 
-tools = ( PasswordResetTool.PasswordResetTool, )
+tools = (PasswordResetTool.PasswordResetTool, )
+
 
 def initialize(context):
     utils.ToolInit('Password Reset Tool',
-                    tools = tools,
+                    tools=tools,
                     icon='tool.gif'
-                    ).initialize( context )
+                    ).initialize(context)
diff --git a/Products/PasswordResetTool/browser.py b/Products/PasswordResetTool/browser.py
index f031467..cea6f83 100644
--- a/Products/PasswordResetTool/browser.py
+++ b/Products/PasswordResetTool/browser.py
@@ -9,6 +9,7 @@
 from Products.PasswordResetTool import passwordresetMessageFactory as _
 from email.Header import Header
 
+
 class PasswordResetToolView(BrowserView):
     implements(IPasswordResetToolView)
 
@@ -35,7 +36,7 @@ def encoded_mail_sender(self):
         """ returns encoded version of Portal name <portal_email> """
         portal = self.portal_state().portal()
         from_ = portal.getProperty('email_from_name')
-        mail  = portal.getProperty('email_from_address')
+        mail = portal.getProperty('email_from_address')
         return '"%s" <%s>' % (self.encode_mail_header(from_), mail)
 
     def registered_notify_subject(self):
@@ -43,7 +44,7 @@ def registered_notify_subject(self):
         portal_name = portal.Title()
         return translate(_(u"mailtemplate_user_account_info",
                            default=u"User Account Information for ${portal_name}",
-                           mapping={'portal_name':safe_unicode(portal_name)}),
+                           mapping={'portal_name': safe_unicode(portal_name)}),
                            context=self.request)
 
     def mail_password_subject(self):
diff --git a/Products/PasswordResetTool/django_random.py b/Products/PasswordResetTool/django_random.py
index a4fcece..9dc2fd4 100644
--- a/Products/PasswordResetTool/django_random.py
+++ b/Products/PasswordResetTool/django_random.py
@@ -42,7 +42,6 @@
 
 import time
 
-
 # generated when process started, hard to guess
 SECRET = random.randint(0, 1000000)
 
diff --git a/Products/PasswordResetTool/interfaces/__init__.py b/Products/PasswordResetTool/interfaces/__init__.py
index dbf403b..5cf9602 100644
--- a/Products/PasswordResetTool/interfaces/__init__.py
+++ b/Products/PasswordResetTool/interfaces/__init__.py
@@ -1,6 +1,7 @@
 # Interface definitions
 from zope.interface import Interface
 
+
 class IPasswordResetToolView(Interface):
     """ BrowserView with utility methods """
 
diff --git a/Products/PasswordResetTool/interfaces/portal_password_reset.py b/Products/PasswordResetTool/interfaces/portal_password_reset.py
index 7a1b924..cb396af 100644
--- a/Products/PasswordResetTool/interfaces/portal_password_reset.py
+++ b/Products/PasswordResetTool/interfaces/portal_password_reset.py
@@ -1,5 +1,6 @@
 from zope.interface import Interface, Attribute
 
+
 class portal_password_reset(Interface):
     """Defines an interface for a tool that provides a facility to
     reset forgotten passwords.
@@ -9,7 +10,7 @@ class portal_password_reset(Interface):
     process) The details of the process are in the implementation,
     where they belong."""
 
-    id = Attribute('id','Must be set to "portal_password_reset"')
+    id = Attribute('id', 'Must be set to "portal_password_reset"')
 
     def requestReset(userid):
         """Ask the system to start the password reset procedure for
diff --git a/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py b/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
index 61d3b32..5b03301 100644
--- a/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
+++ b/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
@@ -8,7 +8,7 @@
 ##parameters=randomstring
 from zExceptions import Forbidden
 if container.REQUEST.get('PUBLISHED') is script:
-   raise Forbidden('Script may not be published.')
+    raise Forbidden('Script may not be published.')
 
 host = context.restrictedTraverse('@@plone_portal_state').navigation_root_url()
 return "%s/passwordreset/%s" % (host, randomstring)
diff --git a/Products/PasswordResetTool/tests/test_doctests.py b/Products/PasswordResetTool/tests/test_doctests.py
index a2e88b7..802c4cf 100644
--- a/Products/PasswordResetTool/tests/test_doctests.py
+++ b/Products/PasswordResetTool/tests/test_doctests.py
@@ -17,9 +17,10 @@
                doctest.NORMALIZE_WHITESPACE |
                doctest.REPORT_ONLY_FIRST_FAILURE)
 
+
 class MockMailFixture(testing.PloneSandboxLayer):
 
-    defaultBases = (testing.PLONE_FIXTURE,)
+    defaultBases = (testing.PLONE_FIXTURE, )
 
     def setUpPloneSite(self, portal):
         portal._original_MailHost = portal.MailHost
@@ -37,19 +38,18 @@ def tearDownPloneSite(self, portal):
         sm.unregisterUtility(provided=IMailHost)
         sm.registerUtility(aq_base(portal._original_MailHost), provided=IMailHost)
 
-
 MOCK_MAIL_FIXTURE = MockMailFixture()
 MM_FUNCTIONAL_TESTING = testing.FunctionalTesting(
-            bases=(MOCK_MAIL_FIXTURE,), name='PloneTestCase:Functional')
+            bases=(MOCK_MAIL_FIXTURE, ), name='PloneTestCase:Functional')
 
 
 def test_suite():
     return unittest.TestSuite((
         layered(doctest.DocFileSuite('browser.txt',
             optionflags=OPTIONFLAGS,
-            package='Products.PasswordResetTool.tests',),
+            package='Products.PasswordResetTool.tests', ),
             layer=MM_FUNCTIONAL_TESTING),
         layered(doctest.DocFileSuite('view.txt',
             optionflags=OPTIONFLAGS,
-            package='Products.PasswordResetTool.tests',),
+            package='Products.PasswordResetTool.tests', ),
             layer=MM_FUNCTIONAL_TESTING)))


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T09:32:12Z
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/268939f35705b33874be2665dd1d7cedb1915771

document changes

Files changed:
M CHANGES.txt

diff --git a/CHANGES.txt b/CHANGES.txt
index 1430b57..458ecc7 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -7,6 +7,9 @@ Changelog
 - Fix i18n of 'This field is required' for the login field in pwreset form.
   [vincentfretin]
 
+- Ported tests to plone.app.testing
+  [tomgross]
+
 
 2.1.0 (2014-02-26)
 ------------------


Repository: Products.PasswordResetTool
Branch: refs/heads/master
Date: 2014-10-31T09:56:06Z
Author: Gil Forcada (gforcada) <gforcada at gnome.org>
Commit: https://github.com/plone/Products.PasswordResetTool/commit/060eb9e66025d12d2cda954643d400eeabed2da7

Merge branch 'tomgross-ptc'

Files changed:
M CHANGES.txt
M Products/PasswordResetTool/PasswordResetTool.py
M Products/PasswordResetTool/__init__.py
M Products/PasswordResetTool/browser.py
M Products/PasswordResetTool/django_random.py
M Products/PasswordResetTool/interfaces/__init__.py
M Products/PasswordResetTool/interfaces/portal_password_reset.py
M Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
M Products/PasswordResetTool/tests/browser.txt
M Products/PasswordResetTool/tests/test_doctests.py
M Products/PasswordResetTool/tests/view.txt
M setup.py

diff --git a/CHANGES.txt b/CHANGES.txt
index 5fcd071..991d1da 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -13,6 +13,9 @@ Changelog
 - Fix i18n of 'This field is required' for the login field in pwreset form.
   [vincentfretin]
 
+- Ported tests to plone.app.testing
+  [tomgross]
+
 
 2.1.0 (2014-02-26)
 ------------------
diff --git a/Products/PasswordResetTool/PasswordResetTool.py b/Products/PasswordResetTool/PasswordResetTool.py
index 1de8ca9..dd03c3e 100644
--- a/Products/PasswordResetTool/PasswordResetTool.py
+++ b/Products/PasswordResetTool/PasswordResetTool.py
@@ -29,26 +29,35 @@
 
 from interfaces.portal_password_reset import portal_password_reset as IPWResetTool
 
-import datetime, time, socket
+import datetime
+import time
+import socket
 from DateTime import DateTime
 from zope.interface import implements
 
 module_security = ModuleSecurityInfo('Products.PasswordResetTool.PasswordResetTool')
 
 module_security.declarePublic('InvalidRequestError')
+
+
 class InvalidRequestError(Exception):
     def __init__(self, value=''):
         self.value = value
+
     def __str__(self):
         return repr(self.value)
 
 module_security.declarePublic('ExpiredRequestError')
+
+
 class ExpiredRequestError(Exception):
     def __init__(self, value=''):
         self.value = value
+
     def __str__(self):
         return repr(self.value)
 
+
 class PasswordResetTool (UniqueObject, SimpleItem):
     """Provides a default implementation for a password reset scheme.
 
@@ -59,7 +68,6 @@ class PasswordResetTool (UniqueObject, SimpleItem):
 
     The user visits that URL (the 'reset form') and enters their username,
     """
-
     ## other things needed for this to work
     # skins:
     #  - handler script for forgotten password form (probably over-riding
@@ -75,23 +83,25 @@ class PasswordResetTool (UniqueObject, SimpleItem):
 
     security = ClassSecurityInfo()
 
-    manage_options=(( { 'label' : 'Overview'
-                        , 'action' : 'manage_overview'
+    manage_options = (({'label': 'Overview'
+                        , 'action': 'manage_overview'
                         },
                       ) + SimpleItem.manage_options
                     )
 
     ##   ZMI methods
     security.declareProtected(ManagePortal, 'manage_overview')
-    manage_overview = DTMLFile('dtml/explainPWResetTool', globals() )
+    manage_overview = DTMLFile('dtml/explainPWResetTool', globals())
 
     security.declareProtected(ManagePortal, 'manage_setTimeout')
+
     def manage_setTimeout(self, hours=168, REQUEST=None):
         """ZMI method for setting the expiration timeout in hours."""
         self.setExpirationTimeout(int(hours))
         return self.manage_overview(manage_tabs_message="Timeout set to %s hours" % hours)
 
     security.declareProtected(ManagePortal, 'manage_toggleUserCheck')
+
     def manage_toggleUserCheck(self, REQUEST=None):
         """ZMI method for toggling the flag for checking user names on return.
         """
@@ -99,16 +109,16 @@ def manage_toggleUserCheck(self, REQUEST=None):
         m = self.checkUser() and 'on' or 'off'
         return self.manage_overview(manage_tabs_message="Returning username check turned %s" % m)
 
-
     def __init__(self):
         self._requests = {}
 
     ## Internal attributes
     _user_check = 1
-    _timedelta = 168 # misleading name, the number of hours are actually stored as int
+    _timedelta = 168  # misleading name, the number of hours are actually stored as int
 
     ## Interface fulfillment ##
     security.declareProtected(ManagePortal, 'requestReset')
+
     def requestReset(self, userid):
         """Ask the system to start the password reset procedure for
         user 'userid'.
@@ -125,7 +135,7 @@ def requestReset(self, userid):
         self._requests[randomstring] = (userid, expiry)
 
         self.clearExpired(10)   # clear out untouched records more than 10 days old
-                                # this is a cheap sort of "automatic" clearing
+        # this is a cheap sort of "automatic" clearing
         self._p_changed = 1
 
         retval = {}
@@ -135,6 +145,7 @@ def requestReset(self, userid):
         return retval
 
     security.declarePublic('resetPassword')
+
     def resetPassword(self, userid, randomstring, password):
         """Set the password (in 'password') for the user who maps to
         the string in 'randomstring' iff the entered 'userid' is equal
@@ -187,13 +198,12 @@ def resetPassword(self, userid, randomstring, password):
         # clean out the request
         del self._requests[randomstring]
         self._p_changed = 1
-
-
     ## Implementation ##
 
     # external
 
     security.declareProtected(ManagePortal, 'setExpirationTimeout')
+
     def setExpirationTimeout(self, timedelta):
         """Set the length of time a reset request will be valid.
 
@@ -204,6 +214,7 @@ def setExpirationTimeout(self, timedelta):
         self._timedelta = abs(timedelta)
 
     security.declarePublic('getExpirationTimeout')
+
     def getExpirationTimeout(self):
         """Get the length of time a reset request will be valid.
 
@@ -216,6 +227,7 @@ def getExpirationTimeout(self):
         return self._timedelta
 
     security.declareProtected(ManagePortal, 'toggleUserCheck')
+
     def toggleUserCheck(self):
         """Changes whether or not the tool requires someone to give the uerid
         they're trying to change on a 'password reset' page. Highly recommended
@@ -226,6 +238,7 @@ def toggleUserCheck(self):
         self._user_check = not self._user_check
 
     security.declarePublic('checkUser')
+
     def checkUser(self):
         """Returns a boolean representing the state of 'user check' as described
         in 'toggleUserCheck'. True means on, and is the default."""
@@ -235,6 +248,7 @@ def checkUser(self):
         return self._user_check
 
     security.declarePublic('verifyKey')
+
     def verifyKey(self, key):
         """Verify a key. Raises an exception if the key is invalid or expired.
         """
@@ -250,6 +264,7 @@ def verifyKey(self, key):
             raise InvalidRequestError('No such user')
 
     security.declareProtected(ManagePortal, 'getStats')
+
     def getStats(self):
         """Return a dictionary like so:
             {"open":3, "expired":0}
@@ -258,25 +273,28 @@ def getStats(self):
         good = 0
         bad = 0
         for stored_user, expiry in self._requests.values():
-            if self.expired(expiry): bad += 1
-            else: good += 1
+            if self.expired(expiry):
+                bad += 1
+            else:
+                good += 1
 
         return {"open": good, "expired": bad}
 
     security.declarePrivate('clearExpired')
+
     def clearExpired(self, days=0):
         """Destroys all expired reset request records.
         Parameter controls how many days past expired it must be to disappear.
         """
         for key, record in self._requests.items():
             stored_user, expiry = record
-            if self.expired(expiry, DateTime()-days):
+            if self.expired(expiry, DateTime() - days):
                 del self._requests[key]
                 self._p_changed = 1
-
     # customization points
 
     security.declarePrivate('uniqueString')
+
     def uniqueString(self, userid):
         """Returns a string that is random and unguessable, or at
         least as close as possible.
@@ -290,10 +308,10 @@ def uniqueString(self, userid):
         # this is the informal UUID algorithm of
         # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/213761
         # by Carl Free Jr
-        t = long( time.time() * 1000 )
+        t = long(time.time() * 1000)
         r = django_random.get_random_string(64)
         try:
-            a = socket.gethostbyname( socket.gethostname() )
+            a = socket.gethostbyname(socket.gethostname())
         except:
             # if we can't get a network address, just imagine one
             a = django_random.get_random_string(64)
@@ -302,6 +320,7 @@ def uniqueString(self, userid):
         return str(data)
 
     security.declarePrivate('expirationDate')
+
     def expirationDate(self):
         """Returns a DateTime for exipiry of a request from the
         current time.
@@ -310,7 +329,7 @@ def expirationDate(self):
         and stored in reset request records."""
         if not hasattr(self, '_timedelta'):
             self._timedelta = 168
-        if isinstance(self._timedelta,datetime.timedelta):
+        if isinstance(self._timedelta, datetime.timedelta):
             expire = datetime.datetime.utcnow() + self._timedelta
             return DateTime(expire.year,
                             expire.month,
@@ -319,10 +338,11 @@ def expirationDate(self):
                             expire.minute,
                             expire.second,
                             'UTC')
-        expire = time.time() + self._timedelta*3600  # 60 min/hr * 60 sec/min
+        expire = time.time() + self._timedelta * 3600  # 60 min/hr * 60 sec/min
         return DateTime(expire)
 
     security.declarePrivate('getValidUser')
+
     def getValidUser(self, userid):
         """Returns the member with 'userid' if available and None otherwise."""
         if get_member_by_login_name:
@@ -332,10 +352,10 @@ def getValidUser(self, userid):
                     self, userid, raise_exceptions=False)
         membertool = getToolByName(self, 'portal_membership')
         return membertool.getMemberById(userid)
-
     # internal
 
     security.declarePrivate('expired')
+
     def expired(self, datetime, now=None):
         """Tells whether a DateTime or timestamp 'datetime' is expired
         with regards to either 'now', if provided, or the current
diff --git a/Products/PasswordResetTool/__init__.py b/Products/PasswordResetTool/__init__.py
index d1a8ced..cc5ab52 100644
--- a/Products/PasswordResetTool/__init__.py
+++ b/Products/PasswordResetTool/__init__.py
@@ -5,10 +5,11 @@
 from zope.i18nmessageid import MessageFactory
 passwordresetMessageFactory = MessageFactory('passwordresettool')
 
-tools = ( PasswordResetTool.PasswordResetTool, )
+tools = (PasswordResetTool.PasswordResetTool, )
+
 
 def initialize(context):
     utils.ToolInit('Password Reset Tool',
-                    tools = tools,
+                    tools=tools,
                     icon='tool.gif'
-                    ).initialize( context )
+                    ).initialize(context)
diff --git a/Products/PasswordResetTool/browser.py b/Products/PasswordResetTool/browser.py
index 877e6b1..cea6f83 100644
--- a/Products/PasswordResetTool/browser.py
+++ b/Products/PasswordResetTool/browser.py
@@ -1,4 +1,3 @@
-from Acquisition import aq_inner
 from zope.interface import implements
 from zope.component import getMultiAdapter
 from Products.Five import BrowserView
@@ -10,6 +9,7 @@
 from Products.PasswordResetTool import passwordresetMessageFactory as _
 from email.Header import Header
 
+
 class PasswordResetToolView(BrowserView):
     implements(IPasswordResetToolView)
 
@@ -36,7 +36,7 @@ def encoded_mail_sender(self):
         """ returns encoded version of Portal name <portal_email> """
         portal = self.portal_state().portal()
         from_ = portal.getProperty('email_from_name')
-        mail  = portal.getProperty('email_from_address')
+        mail = portal.getProperty('email_from_address')
         return '"%s" <%s>' % (self.encode_mail_header(from_), mail)
 
     def registered_notify_subject(self):
@@ -44,12 +44,10 @@ def registered_notify_subject(self):
         portal_name = portal.Title()
         return translate(_(u"mailtemplate_user_account_info",
                            default=u"User Account Information for ${portal_name}",
-                           mapping={'portal_name':safe_unicode(portal_name)}),
+                           mapping={'portal_name': safe_unicode(portal_name)}),
                            context=self.request)
 
     def mail_password_subject(self):
-        portal = self.portal_state().portal()
-        portal_name = portal.Title()
         return translate(_(u"mailtemplate_subject_resetpasswordrequest",
                            default=u"Password reset request"),
                            context=self.request)
diff --git a/Products/PasswordResetTool/django_random.py b/Products/PasswordResetTool/django_random.py
index a4fcece..9dc2fd4 100644
--- a/Products/PasswordResetTool/django_random.py
+++ b/Products/PasswordResetTool/django_random.py
@@ -42,7 +42,6 @@
 
 import time
 
-
 # generated when process started, hard to guess
 SECRET = random.randint(0, 1000000)
 
diff --git a/Products/PasswordResetTool/interfaces/__init__.py b/Products/PasswordResetTool/interfaces/__init__.py
index dbf403b..5cf9602 100644
--- a/Products/PasswordResetTool/interfaces/__init__.py
+++ b/Products/PasswordResetTool/interfaces/__init__.py
@@ -1,6 +1,7 @@
 # Interface definitions
 from zope.interface import Interface
 
+
 class IPasswordResetToolView(Interface):
     """ BrowserView with utility methods """
 
diff --git a/Products/PasswordResetTool/interfaces/portal_password_reset.py b/Products/PasswordResetTool/interfaces/portal_password_reset.py
index 7a1b924..cb396af 100644
--- a/Products/PasswordResetTool/interfaces/portal_password_reset.py
+++ b/Products/PasswordResetTool/interfaces/portal_password_reset.py
@@ -1,5 +1,6 @@
 from zope.interface import Interface, Attribute
 
+
 class portal_password_reset(Interface):
     """Defines an interface for a tool that provides a facility to
     reset forgotten passwords.
@@ -9,7 +10,7 @@ class portal_password_reset(Interface):
     process) The details of the process are in the implementation,
     where they belong."""
 
-    id = Attribute('id','Must be set to "portal_password_reset"')
+    id = Attribute('id', 'Must be set to "portal_password_reset"')
 
     def requestReset(userid):
         """Ask the system to start the password reset procedure for
diff --git a/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py b/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
index 61d3b32..5b03301 100644
--- a/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
+++ b/Products/PasswordResetTool/skins/PasswordReset/pwreset_constructURL.py
@@ -8,7 +8,7 @@
 ##parameters=randomstring
 from zExceptions import Forbidden
 if container.REQUEST.get('PUBLISHED') is script:
-   raise Forbidden('Script may not be published.')
+    raise Forbidden('Script may not be published.')
 
 host = context.restrictedTraverse('@@plone_portal_state').navigation_root_url()
 return "%s/passwordreset/%s" % (host, randomstring)
diff --git a/Products/PasswordResetTool/tests/browser.txt b/Products/PasswordResetTool/tests/browser.txt
index 284a992..75f656a 100644
--- a/Products/PasswordResetTool/tests/browser.txt
+++ b/Products/PasswordResetTool/tests/browser.txt
@@ -8,12 +8,9 @@ Note that our usage of testbrowser is unusual and inconsistent, mostly
 because Plone forms have inconsistencies and because testbrowser makes
 assumptions that are not true for Plone forms.
 
-  >>> from Products.PloneTestCase import PloneTestCase as PTC
-  >>> from Products.Five.testbrowser import Browser
-  >>> browser = Browser()
-  >>> browser.handleErrors = False
-  >>> browser.open('http://nohost/plone/')
-
+  >>> from plone.testing.z2 import Browser
+  >>> from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
+  >>> browser = Browser(layer['app'])
 
 Assumptions
 -----------
@@ -79,19 +76,11 @@ What we do here:
   - Reset our password
   - Log in with our new password
 
-Let's join as a new user. Plone's default settings won't let the user
-type in his initial password, so we need to enable that:
-
-  >>> browser.open('http://nohost/plone/login')
-  >>> browser.getLink('Log in').click()
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
-  >>> browser.getControl(name='submit').click()
-  >>> "You are now logged in" in browser.contents
-  True
-
 Let's go directly to the security control panel:
 
+  >>> from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD
+  >>> browser.addHeader('Authorization',
+  ...                   'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD))
   >>> browser.open('http://nohost/plone/@@security-controlpanel')
   >>> ctrl = browser.getControl(name="form.enable_self_reg")
   >>> ctrl.value = "on"
@@ -99,6 +88,18 @@ Let's go directly to the security control panel:
   >>> ctrl.value = "on"
   >>> browser.getControl(name="form.actions.save").click()
 
+Let's join as a new user. Plone's default settings won't let the user
+type in his initial password, so we need to enable that:
+
+  >>> browser = Browser(layer['app'])
+  >>> browser.open('http://nohost/plone/login')
+  >>> browser.getLink('Log in').click()
+  >>> browser.getControl(name='__ac_name').value = TEST_USER_NAME
+  >>> browser.getControl(name='__ac_password').value = TEST_USER_PASSWORD
+  >>> browser.getControl(name='submit').click()
+  >>> "You are now logged in" in browser.contents
+  True
+
 Log out again and then join:
 
   >>> browser.getLink('Log out').click()
@@ -157,7 +158,7 @@ As part of our test setup, we replaced the original MailHost with our
 own version.  Our version doesn't mail messages, it just collects them
 in a list called ``messages``:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   1
   >>> msg = mailhost.messages[0]
@@ -224,8 +225,8 @@ Log out again:
 First, we want to login as the portal owner:
 
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -271,8 +272,8 @@ password.
 First off, we need to set ``validate_mail`` to False:
 
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -308,7 +309,7 @@ Now register:
 
 We should have received an e-mail at this point:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   2
   >>> msg = str(mailhost.messages[-1])
@@ -363,10 +364,10 @@ e-mail is sent containing the URL that lets the user log in.
 
 First, we want to login as the portal owner:
 
-  >>> from Products.PloneTestCase import PloneTestCase as PTC
+  >>> from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD
   >>> browser.open('http://nohost/plone/login')
-  >>> browser.getControl(name='__ac_name').value = PTC.portal_owner
-  >>> browser.getControl(name='__ac_password').value = PTC.default_password
+  >>> browser.getControl(name='__ac_name').value = SITE_OWNER_NAME
+  >>> browser.getControl(name='__ac_password').value = SITE_OWNER_PASSWORD
   >>> browser.getControl(name='submit').click()
   >>> "You are now logged in" in browser.contents
   True
@@ -394,7 +395,7 @@ Now register and logout:
 
 We should have received an e-mail at this point:
 
-  >>> mailhost = self.portal.MailHost
+  >>> mailhost = layer['portal'].MailHost
   >>> len(mailhost.messages)
   3
   >>> msg = str(mailhost.messages[-1])
diff --git a/Products/PasswordResetTool/tests/test_doctests.py b/Products/PasswordResetTool/tests/test_doctests.py
index d49f07e..802c4cf 100644
--- a/Products/PasswordResetTool/tests/test_doctests.py
+++ b/Products/PasswordResetTool/tests/test_doctests.py
@@ -4,46 +4,52 @@
 
 import doctest
 import unittest
-from Testing.ZopeTestCase import FunctionalDocFileSuite
-from Products.PloneTestCase import PloneTestCase
 from Products.MailHost.interfaces import IMailHost
 from zope.component import getSiteManager
 from Acquisition import aq_base
 
-PloneTestCase.setupPloneSite()
-
 from Products.CMFPlone.tests.utils import MockMailHost
-
+from plone.app import testing
+from plone.testing import layered
+from transaction import commit
 
 OPTIONFLAGS = (doctest.ELLIPSIS |
-               doctest.NORMALIZE_WHITESPACE)
+               doctest.NORMALIZE_WHITESPACE |
+               doctest.REPORT_ONLY_FIRST_FAILURE)
+
 
-class MockMailHostTestCase(PloneTestCase.FunctionalTestCase):
+class MockMailFixture(testing.PloneSandboxLayer):
 
-    def afterSetUp(self):
-        self.portal._original_MailHost = self.portal.MailHost
-        self.portal.MailHost = mailhost = MockMailHost('MailHost')
+    defaultBases = (testing.PLONE_FIXTURE, )
+
+    def setUpPloneSite(self, portal):
+        portal._original_MailHost = portal.MailHost
+        portal.MailHost = mailhost = MockMailHost('MailHost')
         mailhost.smtp_host = 'localhost'
-        sm = getSiteManager(context=self.portal)
+        sm = getSiteManager(context=portal)
         sm.unregisterUtility(provided=IMailHost)
         sm.registerUtility(mailhost, provided=IMailHost)
-        self.portal.email_from_address = 'test at example.com'
+        portal.email_from_address = 'test at example.com'
+        commit()
 
-    def beforeTearDown(self):
-        self.portal.MailHost = self.portal._original_MailHost
-        sm = getSiteManager(context=self.portal)
+    def tearDownPloneSite(self, portal):
+        portal.MailHost = portal._original_MailHost
+        sm = getSiteManager(context=portal)
         sm.unregisterUtility(provided=IMailHost)
-        sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost)
+        sm.registerUtility(aq_base(portal._original_MailHost), provided=IMailHost)
+
+MOCK_MAIL_FIXTURE = MockMailFixture()
+MM_FUNCTIONAL_TESTING = testing.FunctionalTesting(
+            bases=(MOCK_MAIL_FIXTURE, ), name='PloneTestCase:Functional')
 
 
 def test_suite():
     return unittest.TestSuite((
-        FunctionalDocFileSuite('browser.txt',
-                               optionflags=OPTIONFLAGS,
-                               package='Products.PasswordResetTool.tests',
-                               test_class=MockMailHostTestCase),
-        FunctionalDocFileSuite('view.txt',
-                               optionflags=OPTIONFLAGS,
-                               package='Products.PasswordResetTool.tests',
-                               test_class=MockMailHostTestCase),
-        ))
+        layered(doctest.DocFileSuite('browser.txt',
+            optionflags=OPTIONFLAGS,
+            package='Products.PasswordResetTool.tests', ),
+            layer=MM_FUNCTIONAL_TESTING),
+        layered(doctest.DocFileSuite('view.txt',
+            optionflags=OPTIONFLAGS,
+            package='Products.PasswordResetTool.tests', ),
+            layer=MM_FUNCTIONAL_TESTING)))
diff --git a/Products/PasswordResetTool/tests/view.txt b/Products/PasswordResetTool/tests/view.txt
index fca4ef4..0616084 100644
--- a/Products/PasswordResetTool/tests/view.txt
+++ b/Products/PasswordResetTool/tests/view.txt
@@ -1,20 +1,15 @@
 Test passwordreset BrowserView 
 
-    >>> from Products.PloneTestCase import PloneTestCase as PTC
-    >>> from Products.Five.testbrowser import Browser
-    >>> browser = Browser()
-    >>> browser.handleErrors = False
-    >>> browser.open('http://nohost/plone/')
-
     Setup Plone email sender
 
-    >>> self.portal.email_from_name=u'Old\u0159ich a Bo\u017eena'
-    >>> self.portal.email_from_address='smith at example.com'
-    >>> self.portal.title=u'Koko\u0159\xedn Portal'
+    >>> portal = layer['portal']
+    >>> portal.email_from_name=u'Old\u0159ich a Bo\u017eena'
+    >>> portal.email_from_address='smith at example.com'
+    >>> portal.title=u'Koko\u0159\xedn Portal'
     
     Check view methods
     
-    >>> view = self.portal.restrictedTraverse('@@passwordreset_view')
+    >>> view = portal.restrictedTraverse('@@passwordreset_view')
     >>> view.encoded_mail_sender()
     '"=?utf-8?q?Old=C5=99ich_a_Bo=C5=BEena?=" <smith at example.com>'
 
diff --git a/setup.py b/setup.py
index ad7ed68..9c93e2f 100644
--- a/setup.py
+++ b/setup.py
@@ -9,9 +9,11 @@
               open("CHANGES.txt").read(),
       classifiers=[
         "Framework :: Plone",
+        "Framework :: Plone :: 5.0",
         "Framework :: Zope2",
         "License :: OSI Approved :: GNU General Public License (GPL)",
         "Programming Language :: Python",
+        "Programming Language :: Python :: 2.7",
         ],
       keywords='password reset plone',
       author='J. Cameron Cooper',
@@ -24,7 +26,7 @@
       zip_safe=False,
       extras_require=dict(
         test=[
-            'Products.PloneTestCase',
+            'plone.app.testing',
         ]
       ),
       install_requires=[




-------------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CHANGES.log
Type: application/octet-stream
Size: 60789 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20141031/c74f443c/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: build.log
Type: application/octet-stream
Size: 3319 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20141031/c74f443c/attachment-0003.obj>


More information about the Testbot mailing list