changeset 4763:13a75c5f65c7

Groups2009: MoinMoin.groups module initial layout and tests. BackendManager and GroupManager classes were introduced.
author Dmitrijs Milajevs <dimazest@gmail.com>
date Mon, 25 May 2009 21:51:08 +0200
parents 0817780f35d4
children a104935ac05c
files MoinMoin/groups/__init__.py MoinMoin/groups/_test/test_backend_namager.py MoinMoin/groups/_test/test_group_manager.py docs/CHANGES.dmilajevs
diffstat 4 files changed, 248 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/groups/__init__.py	Mon May 25 21:51:08 2009 +0200
@@ -0,0 +1,110 @@
+# -*- coding: iso-8859-1 -*-
+
+"""
+MoinMoin - group definition access via various backends.
+
+TODO Group name mapping for the BackendManager.
+
+@copyright: 2009 DmitrijsMilajevs
+@license: GPL, see COPYING for details
+"""
+
+
+class BackendManager(object):
+    """
+    BackendManager maps string to the Group object. String represents
+    group name. It provides access to groups of specific backend.
+    """
+
+    def __init__(self, backend):
+        """
+        Creates backend manager object.
+
+        @type backend: group backend object.
+        @param backend: the backend which provides access to the group
+        definitions.
+        """
+        self._backend = backend
+
+    def __getitem__(self, group_name):
+        """
+        Selection of a group by its name.
+
+        @type group_name: unicode string.
+        @param group_name: name of the group which object to select.
+        """
+        return self._backend[group_name]
+
+    def __iter__(self):
+        """
+        Iteration over group names.
+        """
+        return iter(self._backend)
+
+    def __contains__(self, group_name):
+        """
+        Check if a group called group name is avaliable via this backend.
+
+        @type group_name: unicode string.
+        @param group_name: name of the group which is checked for an containment.
+        """
+        return group_name in self._backend
+
+    def membergroups(self, member):
+        """
+        List all groups where member is a member of.
+        """
+        return [group_name for group_name in self
+                         if member in self[group_name]]
+
+
+class GroupManager(object):
+    """
+    GroupManager manages several group backends.
+    """
+
+    def __init__(self, backends):
+        """
+        Create a group manager object.
+
+        @type backends: list of objects.
+        @param backend: group backends which are used to get access to the
+        group definitions.
+        """
+        self._backends = backends
+
+    def __getitem__(self, group_name):
+        """
+        Selection of a group by its name.
+        """
+        for backend in self._backends:
+            if group_name in backend:
+                return backend[group_name]
+        raise KeyError("There is no such group")
+
+    def __iter__(self):
+        """
+        Iteration over groups names.
+        """
+        yielded_groups = set()
+
+        for backend in self._backends:
+            for group_name in backend:
+                if group_name not in yielded_groups:
+                    yield group_name
+                    yielded_groups.add(group_name)
+
+    def __contains__(self, group_name):
+        """
+        Check if a group called group_name is defined.
+        """
+        for backend in self._backends:
+            if group_name in backend:
+                return True
+
+    def membergroups(self, member):
+        """
+        List all groups where member is a member of.
+        """
+        return [group_name for group_name in self
+                         if member in self[group_name]]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/groups/_test/test_backend_namager.py	Mon May 25 21:51:08 2009 +0200
@@ -0,0 +1,53 @@
+# -*- coding: iso-8859-1 -*-
+
+"""
+MoinMoin.groups.BackendManager test
+
+@copyright: 2009 MoinMoin:DmitrijsMilajevs
+@license: GPL, see COPYING for details
+"""
+
+from py.test import raises
+
+from MoinMoin.groups import BackendManager
+
+
+class TestBackendManager(object):
+
+    def setup_method(self, method):
+        self.admin_group = frozenset([u'Admin', u'JohnDoe'])
+        self.editor_group = frozenset([u'MainEditor', u'JohnDoe'])
+        self.fruit_group = frozenset([u'Apple', u'Banana'])
+
+        groups = {u'AdminGroup': self.admin_group,
+                  u'EditorGroup': self.editor_group,
+                  u'FruitGroup': self.fruit_group}
+
+        self.group_backend = BackendManager(backend=groups)
+
+    def test_getitem(self):
+        assert self.admin_group == self.group_backend[u'AdminGroup']
+        assert self.fruit_group == self.group_backend[u'FruitGroup']
+
+        raises(KeyError, lambda: self.group_backend[u'not existing group'])
+
+    def test_contains(self):
+        assert u'AdminGroup' in self.group_backend
+        assert u'FruitGroup' in self.group_backend
+
+        assert u'not existing group' not in self.group_backend
+
+    def  test_membergroups(self):
+        apple_groups = self.group_backend.membergroups(u'Apple')
+        assert 1 == len(apple_groups)
+        assert u'FruitGroup' in apple_groups
+        assert u'AdminGroup' not in apple_groups
+
+        john_doe_groups = self.group_backend.membergroups(u'JohnDoe')
+        assert 2 == len(john_doe_groups)
+        assert u'EditorGroup' in john_doe_groups
+        assert u'AdminGroup' in john_doe_groups
+        assert u'FruitGroup' not in john_doe_groups
+
+
+coverage_modules = ['MoinMoin.groups']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/groups/_test/test_group_manager.py	Mon May 25 21:51:08 2009 +0200
@@ -0,0 +1,81 @@
+# -*- coding: iso-8859-1 -*-
+
+"""
+MoinMoin.groups.GroupManager test
+
+@copyright: 2009 MoinMoin:DmitrijsMilajevs
+@license: GPL, see COPYING for details
+"""
+
+from py.test import raises
+
+from MoinMoin.groups import BackendManager, GroupManager
+
+
+class TestGroupManager(object):
+
+    def setup_method(self, method):
+
+        self.admin_group = frozenset([u'Admin', u'JohnDoe'])
+        self.editor_group = frozenset([u'MainEditor', u'JohnDoe'])
+        self.fruit_group = frozenset([u'Apple', u'Banana', u'Cherry'])
+
+        first_backend = BackendManager({u'AdminGroup': self.admin_group,
+                                        u'EditorGroup': self.editor_group,
+                                        u'FruitGroup': self.fruit_group})
+
+        self.user_group = frozenset([u'JohnDoe', u'Bob', u'Joe'])
+        self.city_group = frozenset([u'Bolzano', u'Riga', u'London'])
+        # Suppose, someone hacked second backend
+        # and added himself to AdminGroup
+        self.second_admin_group = frozenset([u'TheHacker'])
+
+        second_backend = BackendManager({u'UserGroup': self.user_group,
+                                         u'CityGroup': self.city_group,
+                                         # Here group name clash accours.
+                                         # AdminGroup is defined in both
+                                         # first_backend and second_backend.
+                                         u'AdminGroup': self.second_admin_group})
+
+        self.group_manager = GroupManager(backends = [first_backend,
+                                                      second_backend])
+
+    def test_getitem(self):
+        assert self.fruit_group == self.group_manager[u'FruitGroup']
+        raises(KeyError, lambda: self.group_manager[u'not existing group'])
+
+    def test_clashed_getitem(self):
+        admin_group = self.group_manager[u'AdminGroup']
+
+        assert self.admin_group == admin_group
+
+        # Nevertheless, TheHacker added himself to the second backend,
+        # it must not be taken into consideration, because AdminGroup is defined
+        # in first backend
+        assert u'TheHacker' not in admin_group
+
+    def test_itar(self):
+        all_group_names = [group_name for group_name in self.group_manager]
+
+        assert 5 == len(all_group_names)
+        # There are no dublicates
+        assert len(set(all_group_names)) == len(all_group_names)
+
+    def test_contains(self):
+        assert u'UserGroup' in self.group_manager
+        assert u'not existing group' not in self.group_manager
+
+    def test_membergroups(self):
+        apple_groups = self.group_manager.membergroups(u'Apple')
+        assert 1 == len(apple_groups)
+        assert u'FruitGroup' in apple_groups
+        assert u'AdminGroup' not in apple_groups
+
+        john_doe_groups = self.group_manager.membergroups(u'JohnDoe')
+        assert 3 == len(john_doe_groups)
+        assert u'EditorGroup' in john_doe_groups
+        assert u'AdminGroup' in john_doe_groups
+        assert u'UserGroup' in john_doe_groups
+        assert u'FruitGroup' not in john_doe_groups
+
+coverage_modules = ['MoinMoin.groups']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/CHANGES.dmilajevs	Mon May 25 21:51:08 2009 +0200
@@ -0,0 +1,4 @@
+Version 1.9-groups-dmilajevs:
+
+   New features:
+   * Group backends. Group definitions can be stored outside of MoinMoin.
\ No newline at end of file