[Erp5-report] r38924 fabien - in /experimental/bt5/erp5_credential: TestTemplateItem/ bt/

nobody at svn.erp5.org nobody at svn.erp5.org
Wed Oct 6 14:47:47 CEST 2010


Author: fabien
Date: Wed Oct  6 14:47:45 2010
New Revision: 38924

URL: http://svn.erp5.org?rev=38924&view=rev
Log:
add a test to check that Credential Recovery permit to change password

Modified:
    experimental/bt5/erp5_credential/TestTemplateItem/testERP5Credential.py
    experimental/bt5/erp5_credential/bt/revision

Modified: experimental/bt5/erp5_credential/TestTemplateItem/testERP5Credential.py
URL: http://svn.erp5.org/experimental/bt5/erp5_credential/TestTemplateItem/testERP5Credential.py?rev=38924&r1=38923&r2=38924&view=diff
==============================================================================
--- experimental/bt5/erp5_credential/TestTemplateItem/testERP5Credential.py [utf8] (original)
+++ experimental/bt5/erp5_credential/TestTemplateItem/testERP5Credential.py [utf8] Wed Oct  6 14:47:45 2010
@@ -28,9 +28,15 @@
 import unittest
 from Products.ERP5Type.tests.utils import reindex
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+from Products.ERP5Type.tests.utils import DummyMailHost
 from Products.ERP5Type.tests.Sequence import SequenceList
+import email, re
+from email.Header import decode_header, make_header
+from email.Utils import parseaddr
 from zLOG import LOG
 import transaction
+import cgi
+from urlparse import urlparse
 
 use_verbose_security = 0
 if use_verbose_security:
@@ -54,6 +60,10 @@ class TestERP5Credential(ERP5TypeTestCas
   def afterSetUp(self):
     """Prepare the test."""
     self.createCategories()
+    # add a dummy mailhost not to send real messages
+    if 'MailHost' in self.portal.objectIds():
+      self.portal.manage_delObjects(['MailHost'])
+    self.portal._setObject('MailHost', DummyMailHost('MailHost'))
 
   @reindex
   def createCategories(self):
@@ -110,6 +120,65 @@ class TestERP5Credential(ERP5TypeTestCas
     self.tic()
     self.logout()
 
+  # Copied from bt5/erp5_egov/TestTemplateItem/testEGovMixin.py
+  def decode_email(self, file):
+    # Prepare result
+    theMail = {
+      'attachment_list': [],
+      'body': '',
+      # Place all the email header in the headers dictionary in theMail
+      'headers': {}
+    }
+    # Get Message
+    msg = email.message_from_string(file)
+    # Back up original file
+    theMail['__original__'] = file
+    # Recode headers to UTF-8 if needed
+    for key, value in msg.items():
+      decoded_value_list = decode_header(value)
+      unicode_value = make_header(decoded_value_list)
+      new_value = unicode_value.__unicode__().encode('utf-8')
+      theMail['headers'][key.lower()] = new_value
+    # Filter mail addresses
+    for header in ('resent-to', 'resent-from', 'resent-cc', 'resent-sender',
+                   'to', 'from', 'cc', 'sender', 'reply-to'):
+      header_field = theMail['headers'].get(header)
+      if header_field:
+          theMail['headers'][header] = parseaddr(header_field)[1]
+    # Get attachments
+    body_found = 0
+    for part in msg.walk():
+      content_type = part.get_content_type()
+      file_name = part.get_filename()
+      # multipart/* are just containers
+      # XXX Check if data is None ?
+      if content_type.startswith('multipart'):
+        continue
+      # message/rfc822 contains attached email message
+      # next 'part' will be the message itself
+      # so we ignore this one to avoid doubling
+      elif content_type == 'message/rfc822':
+        continue
+      elif content_type in ("text/plain", "text/html"):
+        charset = part.get_content_charset()
+        payload = part.get_payload(decode=True)
+        #LOG('CMFMailIn -> ',0,'charset: %s, payload: %s' % (charset,payload))
+        if charset:
+          payload = unicode(payload, charset).encode('utf-8')
+        if body_found:
+          # Keep the content type
+          theMail['attachment_list'].append((file_name,
+                                             content_type, payload))
+        else:
+          theMail['body'] = payload
+          body_found = 1
+      else:
+        payload = part.get_payload(decode=True)
+        # Keep the content type
+        theMail['attachment_list'].append((file_name, content_type,
+                                           payload))
+    return theMail
+
   def _getPreference(self):
     portal_preferences = self.getPreferenceTool()
     preference = getattr(portal_preferences, 'test_site_preference', None)
@@ -134,8 +203,8 @@ class TestERP5Credential(ERP5TypeTestCas
     self.login()
     preference = self._getPreference()
     preference.edit(preferred_credential_request_automatic_approval=False,
-                    preferred_organisation_credential_update_automatic_approval=False,
                     preferred_credential_recovery_automatic_approval=False,
+                    preferred_organisation_credential_update_automatic_approval=False,
                     preferred_person_credential_update_automatic_approval=False)
     self._enablePreference()
     transaction.commit()
@@ -408,6 +477,115 @@ class TestERP5Credential(ERP5TypeTestCas
     self.assertEquals(related_person.getDefaultCredentialQuestionAnswer(),
         'Renault 4L')
 
+  def stepCreateCredentialRecovery(self, sequence=None, sequence_list=None,
+      **kw):
+    '''
+    Create a simple subscription request
+    '''
+    portal = self.getPortalObject()
+    # create a person with 'secret' as password
+    self.login()
+    person_module = portal.getDefaultModule('Person')
+    barney = person_module.newContent(title='Barney',
+                             reference='barney',
+                             password='secret',
+                             default_email_text='barney at duff.com')
+    # create an assignment
+    assignment = barney.newContent(portal_type='Assignment',
+                      function='member')
+    assignment.open()
+    transaction.commit()
+    self.tic()
+    sequence.edit(barney=barney)
+    # check barney can log in the system
+    self._assertUserExists('barney', 'secret')
+    self.login('barney')
+    from AccessControl import getSecurityManager
+    self.assertEquals(str(getSecurityManager().getUser()), 'barney')
+
+    self.login()
+    # create a credential recovery
+    credential_recovery_module = portal.getDefaultModule('Credential Recovery')
+    credential_recovery = credential_recovery_module.newContent(portal_type=\
+        'Credential Recovery')
+
+    # associate it with barney
+    credential_recovery.setDestinationDecisionValue(barney)
+    sequence.edit(credential_recovery=credential_recovery)
+
+  def stepSubmitCredentialRecovery(self, sequence=None, sequence_list=None,
+      **kw):
+    credential_recovery = sequence.get('credential_recovery')
+    credential_recovery.submit()
+
+  def stepAcceptCredentialRecovery(self, sequence=None, sequence_list=None,
+      **kw):
+    credential_recovery = sequence.get('credential_recovery')
+    credential_recovery.accept()
+
+  def stepCheckEmailIsSent(self, sequence=None, sequence_list=None, **kw):
+    '''
+      Check an email containing the password reset link as been sent
+    '''
+    barney = sequence.get('barney')
+
+    # after accept, an email is send containing the reset link
+    last_message = self.portal.MailHost._last_message
+    rawstr = r"""PasswordTool_viewResetPassword"""
+    decoded_message = self.decode_email(last_message[2])
+    body_message = decoded_message['body']
+    match_obj = re.search(rawstr, body_message)
+
+    # check the reset password link is in the mail
+    self.assertNotEquals(match_obj, None)
+
+    # check the mail is sent to the requester :
+    send_to = decoded_message['headers']['to']
+    self.assertEqual(barney.getDefaultEmailText(), send_to)
+
+  def stepCheckPasswordChange(self, sequence=None, sequence_list=None, **kw):
+    '''
+      check it's possible to change the user password using the link in the
+      email
+    '''
+    # get the url
+    last_message = self.portal.MailHost._last_message
+    rawstr = r"""PasswordTool_viewResetPassword"""
+    decoded_message = self.decode_email(last_message[2])
+    body_message = decoded_message['body']
+    match_obj = re.search(rawstr, body_message)
+    # check the reset password link is in the mail
+    self.assertNotEquals(match_obj, None)
+    url = None
+    for line in body_message.splitlines():
+      match_obj = re.search(rawstr, line)
+      if match_obj is not None:
+        url = line[line.find('http:'):]
+    self.assertNotEquals(url, None)
+    response = self.publish(url)
+    parameters = cgi.parse_qs(urlparse(url)[4])
+    self.assertTrue('reset_key' in parameters)
+    key = parameters['reset_key'][0]
+    self.logout()
+    # before changing, check that the user exists with 'secret' password
+    self._assertUserExists('barney', 'secret')
+
+    self.portal.portal_password.changeUserPassword(user_login="barney",
+                                                   password="new_password",
+                                                   password_confirmation="new_password",
+                                                   password_key=key)
+    transaction.commit()
+    self.tic()
+
+    # reset the cache
+    self.portal.portal_caches.clearAllCache()
+
+    # check we cannot login anymore with the previous password 'secret'
+    self._assertUserDoesNotExists('barney', 'secret')
+
+    # check we can now login with the new password 'new_password'
+    self._assertUserExists('barney', 'new_password')
+
   def test_01_simpleSubsciptionRequest(self):
     '''
     Check that is possible to subscribe to erp5
@@ -505,11 +683,20 @@ class TestERP5Credential(ERP5TypeTestCas
     sequence_list.addSequenceString(sequence_string)
     sequence_list.play(self)
 
-  def test_xx_passwordRecovery(self):
+  def test_08_passwordRecovery(self):
     '''
     check that a user that forget his password is able to set a new one and
     log in the system with this new password
     '''
+    sequence_list = SequenceList()
+    sequence_string = 'CreateCredentialRecovery Tic '\
+                      'SubmitCredentialRecovery Tic '\
+                      'AcceptCredentialRecovery Tic '\
+                      'CheckEmailIsSent Tic '\
+                      'CheckPasswordChange Tic '\
+
+    sequence_list.addSequenceString(sequence_string)
+    sequence_list.play(self)
 
   def test_xx_checkCredentialQuestionIsNotCaseSensitive(self):
     '''

Modified: experimental/bt5/erp5_credential/bt/revision
URL: http://svn.erp5.org/experimental/bt5/erp5_credential/bt/revision?rev=38924&r1=38923&r2=38924&view=diff
==============================================================================
--- experimental/bt5/erp5_credential/bt/revision [utf8] (original)
+++ experimental/bt5/erp5_credential/bt/revision [utf8] Wed Oct  6 14:47:45 2010
@@ -1 +1 @@
-263
\ No newline at end of file
+264




More information about the Erp5-report mailing list