import unittest
import Zope # ugh just because of __init__.py
Zope.startup()

from Products.Groups.GroupsService import GroupsService
from Products.Groups.GroupsMapping import GroupsMapping
from Products.Groups.GroupsErrors import GroupsError


class FakeUser:
    def __init__(self, name):
        self._name = name
        
    def getUserName(self):
        return self._name
   
class FakeRequest:

    _ip = '10.1.1.140'
    
    def getClientAddr(self):
        return self._ip
   
class GroupsServiceTestCase(unittest.TestCase):
    def setUp(self):
        self.gs = GroupsService()
        self.gs.addUserToZODBGroup('foo', 'Alpha')
        self.gs.addUserToZODBGroup('foo', 'Beta')
        self.gs.addUserToZODBGroup('bar', 'Alpha')
        self.gs.addUserToZODBGroup('baz', 'Beta')
        
    def tearDown(self):
        pass

    def test_getGroups(self):
        self.assertEquals({'Alpha':1, 'Beta':1}, self.gs.getGroups(FakeUser('foo')))
        self.assertEquals({'Alpha':1}, self.gs.getGroups(FakeUser('bar')))
        self.assertEquals({'Beta':1}, self.gs.getGroups(FakeUser('baz')))

    def test_removeUserFromGroup(self):
        self.gs.removeUserFromZODBGroup('foo', 'Alpha')
        self.assertEquals({'Beta':1}, self.gs.getGroups(FakeUser('foo')))
        self.gs.removeUserFromZODBGroup('foo', 'Beta')
        self.assertEquals({}, self.gs.getGroups(FakeUser('foo')))
        # test whether bar is unaffected
        self.assertEquals({'Alpha':1}, self.gs.getGroups(FakeUser('bar')))

    def test_addVirtualGroup(self):
        self.gs.addVirtualGroup('v1')
        self.gs.addGroupToVirtualGroup('Alpha', 'v1')
        self.gs.addGroupToVirtualGroup('Beta', 'v1')
        self.assertEquals({'Alpha':1, 'Beta':1, 'v1':1},
                          self.gs.getGroups(FakeUser('foo')))
        self.assertEquals({'Alpha':1}, self.gs.getGroups(FakeUser('bar')))
        self.gs.addVirtualGroup('v2')
        self.gs.addGroupToVirtualGroup('Alpha', 'v2')
        self.assertEquals({'Alpha':1, 'Beta':1, 'v1':1, 'v2':1},
                          self.gs.getGroups(FakeUser('foo')))
        self.assertEquals({'Alpha':1, 'v2':1}, self.gs.getGroups(FakeUser('bar')))

    def test_addVirtualGroup2(self):
        self.gs.addNormalGroup('Alpha')
        self.gs.addVirtualGroup('v1')
        self.gs.addVirtualGroup('v2')
        self.gs.addGroupToVirtualGroup('Alpha', 'v1')
        self.gs.addGroupToVirtualGroup('Beta', 'v1')
        self.assertRaises(
            GroupsError, self.gs.addVirtualGroup, 'Alpha')
        self.assertRaises(
            GroupsError, self.gs.addGroupToVirtualGroup, 'v2', 'v2')

    def test_isGroup1(self):
        self.assert_(not self.gs.isGroup('Alpha'))
        self.assert_(not self.gs.isGroup('Beta'))
        self.assert_(not self.gs.isGroup('v1'))
        self.assert_(not self.gs.isNormalGroup('Alpha'))
        self.assert_(not self.gs.isNormalGroup('Beta'))
        self.assert_(not self.gs.isVirtualGroup('v1'))
        
    def test_isGroup2(self):
        self.gs.addNormalGroup('Alpha')
        self.gs.addNormalGroup('Beta')
        self.assert_(self.gs.isGroup('Alpha'))
        self.assert_(self.gs.isGroup('Beta'))
        self.assert_(self.gs.isNormalGroup('Alpha'))
        self.assert_(self.gs.isNormalGroup('Beta'))

        self.assert_(not self.gs.isVirtualGroup('v1'))
        self.gs.addVirtualGroup('v1')
        self.gs.addGroupToVirtualGroup('Alpha', 'v1')
        self.gs.addGroupToVirtualGroup('Beta', 'v1')
        self.assert_(self.gs.isGroup('v1'))
        self.assert_(self.gs.isVirtualGroup('v1'))
        self.assert_(not self.gs.isNormalGroup('v1'))
       
    def test_ipgropup(self):
        self.gs.addIPGroup('Alpha')
        self.gs.addIPGroup('Gamma')
        self.gs.addIPRangeToIPGroup(self.gs.createIPRange('10.0.0.0/8'), 'Alpha')
        self.gs.addIPRangeToIPGroup(self.gs.createIPRange('10.0.0.0/8'), 'Gamma')
        self.gs.addIPGroup('Beta')
        self.gs.addIPRangeToIPGroup(self.gs.createIPRange('11.0.0.0/8'), 'Beta')
        self.assertEquals(self.gs.listIPGroups(), ['Alpha', 'Beta', 'Gamma'])
        user = FakeUser('iponly')
        req = FakeRequest()
        user.REQUEST = req
        self.assertEquals(self.gs.getGroups(user), {'Alpha': 1, 'Gamma': 1})
        self.gs.removeIPRangeFromIPGroup(self.gs.createIPRange('10.0.0.0/8'),
            'Gamma')
        self.assertEquals(self.gs.getGroups(user), {'Alpha': 1})
       
class GroupsMappingTestCase(unittest.TestCase):
    def setUp(self):
        self.gs = gs = GroupsService()
        gs.addUserToZODBGroup('foo', 'Alpha')
        gs.addUserToZODBGroup('foo', 'Beta')

        gs.addUserToZODBGroup('bar', 'Alpha')
        gs.addUserToZODBGroup('baz', 'Beta')
        
        gs.addVirtualGroup('v1')
        gs.addGroupToVirtualGroup('Alpha', 'v1')
        gs.addGroupToVirtualGroup('Beta', 'v1')
        gs.addVirtualGroup('v2')
        gs.addGroupToVirtualGroup('Alpha', 'v2')        
        gs.addVirtualGroup('v3')

        self.gm = GroupsMapping()
        self.gm.addMapping('Alpha', ['Editor'])
        self.gm.addMapping('v1', ['ChiefEditor'])
        self.gm.addMapping('v3', ['Manager'])
        self.gm.service_groups = gs
        
    def tearDown(self):
        pass

    def test_getRoles(self):
        self.assertEquals({'Editor':1, 'ChiefEditor':1},
                          self.gm.getRoles(FakeUser('foo')))
        self.assertEquals({'Editor':1},
                           self.gm.getRoles(FakeUser('bar')))
        self.assertEquals({},
                          self.gm.getRoles(FakeUser('baz')))
        
    def test_getRolesMultiple(self):
        self.gm.addMapping('Beta', ['Author', 'Reader'])
        self.assertEquals({'Author':1, 'Reader':1},
                          self.gm.getRoles(FakeUser('baz')))
        self.assertEquals({'Author':1, 'Reader':1, 'Editor':1, 'ChiefEditor':1},
                          self.gm.getRoles(FakeUser('foo')))

    def test_assignRolesToGroup(self):
        self.gm.assignRolesToGroup('Alpha', ['Author'])
        self.assertEquals({'Editor':1, 'Author':1}, self.gm.getRoles(FakeUser('bar')))
        self.gm.assignRolesToGroup('Beta', ['Editor'])
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('baz')))
        self.assertEquals({'Editor':1, 'Author':1, 'ChiefEditor':1}, self.gm.getRoles(FakeUser('foo')))
        self.gm.assignRolesToGroup('v1', ['Manager'])
        self.assertEquals({'Editor':1, 'Author':1, 'ChiefEditor':1, 'Manager':1}, self.gm.getRoles(FakeUser('foo')))
        self.gm.assignRolesToGroup('v3', ['Author'])
        self.assertEquals({'Editor':1, 'Author':1, 'ChiefEditor':1, 'Manager':1}, self.gm.getRoles(FakeUser('foo')))

    def test_revokeRolesFromGroup(self):
        self.gm.revokeRolesFromGroup('v1', ['ChiefEditor'])
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('foo')))
        self.gm.revokeRolesFromGroup('Alpha', ['Editor'])
        self.assertEquals({}, self.gm.getRoles(FakeUser('foo')))

    def test_emptyVirtualGroups(self):
        self.gs.removeGroupFromVirtualGroup('Alpha', 'v1')        
        self.assertEquals({'Editor':1, 'ChiefEditor':1}, self.gm.getRoles(FakeUser('foo')))
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('bar')))
        self.assertEquals({'ChiefEditor':1}, self.gm.getRoles(FakeUser('baz')))        
        self.gs.removeGroupFromVirtualGroup('Beta', 'v1')
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('foo')))
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('bar')))
        self.assertEquals({}, self.gm.getRoles(FakeUser('baz')))

    def test_emptyVirtualGroups2(self):
        self.gs.addGroupToVirtualGroup('Beta', 'v3')
        self.gs.removeGroupFromVirtualGroup('Beta', 'v3')
        self.assertEquals({'Editor':1, 'ChiefEditor':1}, self.gm.getRoles(FakeUser('foo')))
        self.assertEquals({'Editor':1}, self.gm.getRoles(FakeUser('bar')))
        self.assertEquals({}, self.gm.getRoles(FakeUser('baz')))        

def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(GroupsServiceTestCase, 'test'))
    suite.addTest(unittest.makeSuite(GroupsMappingTestCase, 'test'))
    return suite


    
def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()
