Back to index

plone3  3.1.7
test_migration.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # PlonePAS - Adapt PluggableAuthService for use in Plone
00004 # Copyright (C) 2005 Enfold Systems, Kapil Thangavelu, et al
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE.
00013 #
00014 ##############################################################################
00015 """
00016 """
00017 
00018 import unittest
00019 
00020 if __name__ == '__main__':
00021     execfile(os.path.join(os.path.dirname(sys.argv[0]), 'framework.py'))
00022 
00023 from PlonePASTestCase import PlonePASTestCase
00024 
00025 from Acquisition import aq_base, aq_inner, aq_parent
00026 from Products.CMFCore.utils import getToolByName
00027 
00028 class SanityCheck:
00029 
00030     _users = (
00031         ('user1', 'u1', ['Member'], [],
00032          {'email': 'user1@host.com',
00033           'fullname': 'User #1',
00034           }
00035          ),
00036         ('user2', 'u2', ['Member', 'Reviewer'], [],
00037          {'email': 'user2@host.com',
00038           'fullname': 'User #2',
00039           }
00040          ),
00041         ('user3', 'u3', [], [],
00042          {'email': 'user3@host.com',
00043           'fullname': 'User #3',
00044           }
00045          ),
00046         ('user4', 'u4', [], [],
00047          {'email': 'user4@host.com',
00048           'fullname': 'User #4',
00049           }
00050          ),
00051         )
00052 
00053     _groups = (
00054         ('group0', ['Member'], [],
00055          {'title': 'Group #0',
00056           'description': 'Group #0 Description',
00057           'email': 'group0@host.com',
00058           }
00059          ),
00060         ('group1', ['Member'], [],
00061          {'title': 'Group #1',
00062           'description': 'Group #1 Description',
00063           'email': 'group1@host.com',
00064           }
00065          ),
00066         ('group2', ['Reviewer'], ['group0'],
00067          {'title': 'Group #2',
00068           'description': 'Group #2 Description',
00069           'email': 'group2@host.com',
00070           }
00071          ),
00072         )
00073 
00074     _group_members = {
00075         'group0': ('user4',),
00076         'group1': ('user3',),
00077         'group2': ('user1', 'user2'),
00078         }
00079 
00080     def __init__(self, testcase, portal):
00081         self.portal = portal
00082         self.tc = testcase
00083 
00084     def uf(self):
00085         return getToolByName(self.portal, 'acl_users')
00086 
00087     def checkUserFolder(self):
00088         uf = self.uf()
00089         self.tc.failUnless(uf.meta_type == 'Pluggable Auth Service',
00090                            uf.meta_type)
00091         parent = aq_parent(aq_inner(uf))
00092         self.tc.failUnless(aq_base(parent) == aq_base(self.portal),
00093                            (parent, self.portal, uf))
00094 
00095     def checkUsers(self):
00096         mt = getToolByName(self.portal, 'portal_membership')
00097         md = getToolByName(self.portal, 'portal_memberdata')
00098         propids = md.propertyIds()
00099         uf = self.uf()
00100         for uid, upw, uroles, udomains, uprops in self._users:
00101             user = uf.getUserById(uid)
00102             self.tc.failIf(user is None, uid)
00103 
00104             # Ignore password check?
00105             # pw = user.getPassword()
00106             # self.tc.failUnless(pw == upw, (uid, pw, upw)
00107 
00108             roles = [r for r in user.getRoles() if r not in ('Authenticated',)]
00109             for role in uroles:
00110                 self.tc.failUnless(role in roles, (uid, role, roles))
00111 
00112             # Ignore domains check?
00113             # domains = user.getDomains()
00114             # self.tc.failUnless(domains == udomains, (uid, domains, udomains))
00115 
00116             member = mt.getMemberById(uid)
00117 
00118             for k, v in uprops.items():
00119                 propval = member.getProperty(k, None)
00120                 self.tc.failUnless(propval == v, (uid, k, propval, v))
00121 
00122     def checkGroups(self):
00123         gt = getToolByName(self.portal, 'portal_groups')
00124         gd = getToolByName(self.portal, 'portal_groupdata')
00125         propids = gd.propertyIds()
00126         for gid, groles, gsubs, gprops in self._groups:
00127             group = gt.getGroupById(gid)
00128             self.tc.failIf(group is None, gid)
00129 
00130             roles = [r for r in group.getRoles() if r != 'Authenticated']
00131             for role in groles:
00132                 self.tc.failUnless(role in roles, (gid, role, roles))
00133 
00134             # XXX fails currently because getGroupMembers tries to do
00135             # getUserById with the group id and PAS looks only at
00136             # IUserEnumeration.
00137             # members = group.getGroupMemberIds()
00138             # expected = self._group_members[gid]
00139             # for member in expected:
00140             #     self.tc.failUnless(member in members, (gid, member, members))
00141 
00142             # XXX This seems to be expected to break too.
00143             for k, v in gprops.items():
00144                 propval = group.getProperty(k, None)
00145                 self.tc.failUnless(propval == v, (gid, k, propval, v))
00146 
00147     def populateUsers(self):
00148         mt = getToolByName(self.portal, 'portal_membership')
00149         for u in self._users:
00150             member = mt.getMemberById(u[0])
00151             if member is None:
00152                 mt.addMember(*u)
00153             else:
00154                 member.setMemberProperties(u[-1])
00155 
00156 
00157     def populateGroups(self):
00158         gt = getToolByName(self.portal, 'portal_groups')
00159         for g in self._groups:
00160             try:
00161                 gt.addGroup(*g[:-1], **g[-1])
00162             except TypeError:
00163                 # GRUF 2.x doesn't accept properties in addgroup
00164                 gt.addGroup(g[0],"",*g[1:-1])   # old addGroup uses password
00165                 group = gt.getGroupById(g[0])
00166                 group.setGroupProperties(g[-1])
00167 
00168             gid = g[0]
00169             group = gt.getGroupById(gid)
00170             for mid in self._group_members[gid]:
00171                 group.addMember(mid)
00172 
00173     def run(self, *actions):
00174         for name in actions:
00175             getattr(self, name)()
00176 
00177 class BaseTest(PlonePASTestCase):
00178 
00179     vanilla_plone = True
00180 
00181     def afterSetUp(self):
00182         self.checker = SanityCheck(self, self.portal)
00183 
00184 class MigrationTest(BaseTest):
00185 
00186     def afterSetUp(self):
00187         BaseTest.afterSetUp(self)
00188         self.qi = getToolByName(self.portal, 'portal_quickinstaller')
00189 
00190     def test_migrate_no_user_folder_empty(self):
00191         self.loginAsPortalOwner()
00192         if 'acl_users' in self.portal.objectIds():
00193             self.portal.manage_delObjects(ids=['acl_users'])
00194 
00195         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00196         self.qi.installProduct('PlonePAS', reinstall=True)
00197         self.checker.run('checkUserFolder')
00198 
00199     def test_migrate_memberdata_with_selection_property(self):
00200         self.loginAsPortalOwner()
00201         pm = getToolByName(self.portal, 'portal_memberdata')
00202         pm._setProperty('select_choice', ('A', 'B', 'C'), 'lines')
00203         pm._setProperty('choice', 'select_choice', 'selection')
00204         pm._updateProperty('choice', 'A')
00205         property = pm.getProperty('select_choice')
00206         self.assertEquals(property, ('A', 'B', 'C'))
00207         property = pm.getProperty('choice')
00208         self.assertEquals(property, 'A')
00209         
00210         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00211         self.qi.installProduct('PlonePAS', reinstall=True)
00212         
00213         pm = getToolByName(self.portal, 'portal_memberdata')
00214         property = pm.getProperty('select_choice')
00215         self.assertEquals(property, ('A', 'B', 'C'))
00216         property = pm.getProperty('choice')
00217         self.assertEquals(property, 'A')
00218 
00219     def test_migrate_memberdata_with_multiple_selection_property(self):
00220         self.loginAsPortalOwner()
00221         pm = getToolByName(self.portal, 'portal_memberdata')
00222         pm._setProperty('select_choice', ('A', 'B', 'C'), 'lines')
00223         pm._setProperty('choice', 'select_choice', 'multiple selection')
00224         pm._updateProperty('choice', ('A', 'C'))
00225         property = pm.getProperty('select_choice')
00226         self.assertEquals(property, ('A', 'B', 'C'))
00227         property = pm.getProperty('choice')
00228         self.assertEquals(property, ('A', 'C'))
00229         
00230         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00231         self.qi.installProduct('PlonePAS', reinstall=True)
00232         
00233         pm = getToolByName(self.portal, 'portal_memberdata')
00234         property = pm.getProperty('select_choice')
00235         self.assertEquals(property, ('A', 'B', 'C'))
00236         property = pm.getProperty('choice')
00237         self.assertEquals(property, ('A', 'C'))
00238 
00239     def test_migrate_groupdata_with_selection_property(self):
00240         self.loginAsPortalOwner()
00241         gd = getToolByName(self.portal, 'portal_groupdata')
00242         gd._setProperty('select_choice', ('A', 'B', 'C'), 'lines')
00243         gd._setProperty('choice', 'select_choice', 'selection')
00244         gd._updateProperty('choice', 'A')
00245         property = gd.getProperty('select_choice')
00246         self.assertEquals(property, ('A', 'B', 'C'))
00247         property = gd.getProperty('choice')
00248         self.assertEquals(property, 'A')
00249         
00250         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00251         self.qi.installProduct('PlonePAS', reinstall=True)
00252         
00253         gd = getToolByName(self.portal, 'portal_groupdata')
00254         property = gd.getProperty('select_choice')
00255         self.assertEquals(property, ('A', 'B', 'C'))
00256         property = gd.getProperty('choice')
00257         self.assertEquals(property, 'A')
00258 
00259     def test_migrate_groupdata_with_multiple_selection_property(self):
00260         self.loginAsPortalOwner()
00261         gd = getToolByName(self.portal, 'portal_groupdata')
00262         gd._setProperty('select_choice', ('A', 'B', 'C'), 'lines')
00263         gd._setProperty('choice', 'select_choice', 'multiple selection')
00264         gd._updateProperty('choice', ('A', 'C'))
00265         property = gd.getProperty('select_choice')
00266         self.assertEquals(property, ('A', 'B', 'C'))
00267         property = gd.getProperty('choice')
00268         self.assertEquals(property, ('A', 'C'))
00269         
00270         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00271         self.qi.installProduct('PlonePAS', reinstall=True)
00272         
00273         gd = getToolByName(self.portal, 'portal_groupdata')
00274         property = gd.getProperty('select_choice')
00275         self.assertEquals(property, ('A', 'B', 'C'))
00276         property = gd.getProperty('choice')
00277         self.assertEquals(property, ('A', 'C'))
00278 
00279     def test_migrate_no_user_folder_populated_users(self):
00280         # XXX This will never work: removing acl_users means loosing all login
00281         # information, so there is nothing useful to (re)create users
00282         self.loginAsPortalOwner()
00283         if 'acl_users' in self.portal.objectIds():
00284             self.portal.manage_delObjects(ids=['acl_users'])
00285 
00286         self.checker.run('populateUsers')
00287         # Don't remove the tools
00288         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00289         self.qi.installProduct('PlonePAS', reinstall=True)
00290         self.checker.run('checkUserFolder', 'checkUsers')
00291 
00292     def test_migrate_normal_uf_no_group_tools(self):
00293         self.loginAsPortalOwner()
00294         if 'acl_users' in self.portal.objectIds():
00295             self.portal.manage_delObjects(ids=['acl_users'])
00296         to_remove = ('portal_groups', 'portal_groupdata')
00297         for tname in to_remove:
00298             if tname in self.portal.objectIds():
00299                 self.portal.manage_delObjects(ids=[tname])
00300 
00301         self.checker.run('populateUsers')
00302         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00303         self.qi.installProduct('PlonePAS', reinstall=True)
00304         self.checker.run('checkUserFolder', 'checkUsers')
00305 
00306     def test_migrate_populated(self):
00307         self.loginAsPortalOwner()
00308         self.checker.run('populateUsers', 'populateGroups',
00309                          'checkUsers', 'checkGroups')
00310 
00311         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00312         self.qi.installProduct('PlonePAS', reinstall=True)
00313         self.checker.run('checkUserFolder', 'checkUsers', 'checkGroups')
00314 
00315     def test_migrate_populated_gruf_no_group_tools(self):
00316         self.loginAsPortalOwner()
00317         self.checker.run('populateUsers', 'populateGroups')
00318         to_remove = ('portal_groups', 'portal_groupdata')
00319         for tname in to_remove:
00320             if tname in self.portal.objectIds():
00321                 self.portal.manage_delObjects(ids=[tname])
00322 
00323         self.qi.uninstallProducts(['PlonePAS'], reinstall=True)
00324         self.qi.installProduct('PlonePAS', reinstall=True)
00325         self.checker.run('checkUserFolder', 'checkUsers')
00326 
00327 def test_suite():
00328     suite = unittest.TestSuite()
00329     suite.addTest(unittest.makeSuite(MigrationTest))
00330     return suite
00331