[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