1 diff -r c3e904a9c00b MoinMoin/groups/__init__.py
   2 --- a/MoinMoin/groups/__init__.py       Sat May 30 08:22:09 2009 +0200
   3 +++ b/MoinMoin/groups/__init__.py       Sat May 30 14:30:10 2009 +0200
   4  -1,9 +1,6 @@
   5  # -*- coding: iso-8859-1 -*-
   6 -
   7  """
   8 -MoinMoin - group definition access via various backends.
   9 -
  10 -TODO Group name mapping for the BackendManager.
  11 +MoinMoin - group access via various backends.
  12  
  13  @copyright: 2009 DmitrijsMilajevs
  14  @license: GPL, see COPYING for details
  15  -12,31 +9,23 @@
  16  
  17  class BackendManager(object):
  18      """
  19 -    BackendManager maps string to the Group object. String represents
  20 -    group name. It provides access to groups of specific backend.
  21 +    A BackendManager maps a group name to a Group object.
  22 +    It provides access to groups of one specific backend.
  23      """
  24  
  25      def __init__(self, request, backend, mapper_to_backend=lambda x: x, mapper_from_backend=lambda x: x):
  26          """
  27 -        Creates backend manager object.
  28 +        Create backend manager object.
  29  
  30          XXX Decorators can be used for group name mapping.
  31  
  32          @param request: request object.
  33 -
  34 -        @type backend: group backend object.
  35 -        @param backend: the backend which provides access to the group
  36 -        definitions.
  37 -
  38 -        @type mapper_to_backend: function which takes one string as an
  39 -        argument and returns a string
  40 -        @param mapper_to_backend: function which maps moin group
  41 -        name to the backend group name
  42 -
  43 -        @type mapper_from_backend: function which takes one string as an
  44 -        argument and returns a string
  45 -        @param mapper_from_backend: function which maps backend group
  46 -        name to the moin group name
  47 +        @param backend: the group backend which provides access to the
  48 +                        group definitions.
  49 +        @param mapper_to_backend: a function mapping the moin group
  50 +                                  name to the backend group name
  51 +        @param mapper_from_backend: a function mapping the backend group
  52 +                                    name to the moin group name
  53          """
  54          self._backend = backend
  55          self.mapper_to_backend = mapper_to_backend
  56  -44,33 +33,32 @@
  57  
  58      def __getitem__(self, group_name):
  59          """
  60 -        Selection of a group by its name.
  61 +        Get a group by its name.
  62  
  63 -        @type group_name: unicode string.
  64 -        @param group_name: name of the group which object to select.
  65 +        @param group_name: name of the group [unicode]
  66          """
  67          return self._backend[self.mapper_to_backend(group_name)]
  68  
  69      def __iter__(self):
  70          """
  71 -        Iteration over group names.
  72 +        Iterate over group names of the groups defined in this backend.
  73          """
  74          return (self.mapper_from_backend(group_name) for group_name in self._backend)
  75  
  76      def __contains__(self, group_name):
  77          """
  78 -        Check if a group called group name is avaliable via this backend.
  79 +        Checks if a group called group_name is available in this backend.
  80  
  81 -        @type group_name: unicode string.
  82 -        @param group_name: name of the group which is checked for an containment.
  83 +        @param group_name: name of the group [unicode]
  84          """
  85          return self.mapper_to_backend(group_name) in self._backend
  86  
  87      def membergroups(self, member):
  88          """
  89 -        List all groups where member is a member of.
  90 -        @rtype: list of unicode strings
  91 -        @return: list of group names in which member takes part in
  92 +        List all group names of the groups where <member> is a member of.
  93 +
  94 +        @param member: member name [unicode]
  95 +        @return: list of group names [unicode]
  96          """
  97          return [group_name for group_name in self
  98                  if member in self[group_name]]
  99  -85,15 +73,16 @@
 100          """
 101          Create a group manager object.
 102  
 103 -        @type backends: list of objects.
 104 -        @param backend: group backends which are used to get access to the
 105 -        group definitions.
 106 +        @param backends: list of group backends which are used to get access
 107 +                         to the group definitions.
 108          """
 109          self._backends = backends
 110  
 111      def __getitem__(self, group_name):
 112          """
 113 -        Selection of a group by its name.
 114 +        Get a group by its name. First match counts.
 115 +
 116 +        @param group_name: name of the group [unicode]
 117          """
 118          for backend in self._backends:
 119              if group_name in backend:
 120  -102,7 +91,7 @@
 121  
 122      def __iter__(self):
 123          """
 124 -        Iteration over groups names.
 125 +        Iterate over group names in all backends (filtering duplicates).
 126          """
 127          yielded_groups = set()
 128  
 129  -114,17 +103,22 @@
 130  
 131      def __contains__(self, group_name):
 132          """
 133 -        Check if a group called group_name is defined.
 134 +        Check if a group called group_name is available in any of the backends.
 135 +
 136 +        @param group_name: name of the group [unicode]
 137          """
 138          for backend in self._backends:
 139              if group_name in backend:
 140                  return True
 141 +        return False
 142  
 143      def membergroups(self, member):
 144          """
 145 -        List all groups where member is a member of.
 146 -        @rtype: list of unicode strings
 147 -        @return: list of group names in which member takes part in
 148 +        List all group names of the groups where <member> is a member of.
 149 +
 150 +        @param member: member name [unicode]
 151 +        @return: list of group names [unicode]
 152          """
 153          return [group_name for group_name in self
 154 -                         if member in self[group_name]]
 155 +                if member in self[group_name]]
 156 +
 157 diff -r c3e904a9c00b MoinMoin/groups/_tests/test_backend_manager.py
 158 --- a/MoinMoin/groups/_tests/test_backend_manager.py    Sat May 30 08:22:09 2009 +0200
 159 +++ b/MoinMoin/groups/_tests/test_backend_manager.py    Sat May 30 14:30:10 2009 +0200
 160  -1,5 +1,4 @@
 161  # -*- coding: iso-8859-1 -*-
 162 -
 163  """
 164  MoinMoin.groups.BackendManager test
 165  
 166  -12,10 +11,7 @@
 167  from MoinMoin.groups import BackendManager
 168  
 169  
 170 -class TestBackendManagerAPI(object):
 171 -    """
 172 -    This tastcase test Backend manager API
 173 -    """
 174 +class TestBackendManager(object):
 175  
 176      def setup_method(self, method):
 177          self.admin_group = frozenset([u'Admin', u'JohnDoe'])
 178  -26,34 +22,21 @@
 179                    u'EditorGroup': self.editor_group,
 180                    u'FruitGroup': self.fruit_group}
 181  
 182 -        self.group_backend = BackendManager(request=self.request,
 183 -                                            backend=groups)
 184 +        self.group_backend = BackendManager(request=self.request, backend=groups)
 185  
 186      def test_getitem(self):
 187 -        """
 188 -        Test of the __getitem__ API method. It should return a group
 189 -        object by the group name.
 190 -        """
 191          assert self.admin_group == self.group_backend[u'AdminGroup']
 192          assert self.fruit_group == self.group_backend[u'FruitGroup']
 193  
 194          raises(KeyError, lambda: self.group_backend[u'not existing group'])
 195  
 196      def test_contains(self):
 197 -        """
 198 -        Test of the __contains__ API method. It checks if a group is
 199 -        avaliable via this backend. Check is done by group's name.
 200 -        """
 201          assert u'AdminGroup' in self.group_backend
 202          assert u'FruitGroup' in self.group_backend
 203  
 204          assert u'not existing group' not in self.group_backend
 205  
 206 -    def  test_membergroups(self):
 207 -        """
 208 -        Test of membergroups API method. It lists all groups where
 209 -        member is a member of. It should  return a list of group names.
 210 -        """
 211 +    def test_membergroups(self):
 212          apple_groups = self.group_backend.membergroups(u'Apple')
 213          assert 1 == len(apple_groups)
 214          assert u'FruitGroup' in apple_groups
 215  -68,28 +51,28 @@
 216  
 217  class TestManagerMapping(object):
 218      """
 219 -    This class tests mapping of the group names from a backend to the
 220 -    moin and from the moin to a backend.
 221 +    Test group name mapping:
 222 +        moin -> backend (e.g. "AdminGroup" -> "Admin")
 223 +        backend -> moin (e.g. "Admin" -> "AdminGroup")
 224  
 225 -    Here the simplest situation is considered. Moin expect groups to
 226 -    be named as *Group, but backend stores group names without this prefix.
 227 -
 228 -    When group names are passed or retrieved from the backend they
 229 -    should be mapped.
 230 +    Moin expects group names to match the page_group_regex (e.g. "AdminGroup"),
 231 +    but a backend might want to use different group names (e.g. just "Admin").
 232      """
 233  
 234      def setup_class(self):
 235          self.admin_group = frozenset([u'Admin', u'JohnDoe'])
 236          self.editor_group = frozenset([u'MainEditor', u'JohnDoe'])
 237  
 238 -        # Group names here do not follow moin convention: they do not
 239 -        # have group prefix.
 240 +        # These backend group names do not follow moin convention:
 241          groups = {u'Admin': self.admin_group,
 242                    u'Editor': self.editor_group}
 243  
 244 -        # Simply drop last five letters, what is length of word "Group"
 245 +        # Simply drop the "Group" postfix for group names given to a backend.
 246 +        # Note: in the real world, this would not work good enough:
 247          mapper_to_backend = lambda group_name: group_name[:-5]
 248 -        # Add "Group" postfix for every group name received from a backend
 249 +
 250 +        # Add "Group" postfix for group names received from a backend.
 251 +        # Note: in the real world, this would not work good enough:
 252          mapper_from_backend = lambda group_name: "%sGroup" % group_name
 253  
 254          self.group_backend = BackendManager(request=self.request,
 255  -108,3 +91,4 @@
 256          assert u'AdminGroup' in self.group_backend.membergroups(u'JohnDoe')
 257  
 258  coverage_modules = ['MoinMoin.groups']
 259 +
 260 diff -r c3e904a9c00b MoinMoin/groups/_tests/test_group_manager.py
 261 --- a/MoinMoin/groups/_tests/test_group_manager.py      Sat May 30 08:22:09 2009 +0200
 262 +++ b/MoinMoin/groups/_tests/test_group_manager.py      Sat May 30 14:30:10 2009 +0200
 263  -1,5 +1,4 @@
 264  # -*- coding: iso-8859-1 -*-
 265 -
 266  """
 267  MoinMoin.groups.GroupManager test
 268  
 269  -12,10 +11,7 @@
 270  
 271  from MoinMoin.groups import BackendManager, GroupManager
 272  
 273 -class TestGroupManagerAPI(object):
 274 -    """
 275 -    Performs test of the API of GroupManager.
 276 -    """
 277 +class TestGroupManager(object):
 278  
 279      from MoinMoin._tests import wikiconfig
 280      class Config(wikiconfig.Config):
 281  -32,8 +28,8 @@
 282  
 283          self.user_group = frozenset([u'JohnDoe', u'Bob', u'Joe'])
 284          self.city_group = frozenset([u'Bolzano', u'Riga', u'London'])
 285 -        # Suppose, someone hacked second backend
 286 -        # and added himself to AdminGroup
 287 +
 288 +        # Suppose someone hacked the second backend and added himself to AdminGroup
 289          self.second_admin_group = frozenset([u'TheHacker'])
 290  
 291          second_backend_groups = {u'UserGroup': self.user_group,
 292  -43,40 +39,32 @@
 293                                   # first_backend and second_backend.
 294                                   u'AdminGroup': self.second_admin_group}
 295  
 296 -        self.Config.group_manager = lambda self, request: GroupManager(backends=[BackendManager(request, first_backend_groups),
 297 -                                                                                 BackendManager(request, second_backend_groups)])
 298 +        self.Config.group_manager = lambda self, request: GroupManager(
 299 +                                        backends=[BackendManager(request, first_backend_groups),
 300 +                                                  BackendManager(request, second_backend_groups)])
 301  
 302      def setup_method(self, method):
 303          self.group_manager = self.request.cfg.group_manager(self.request)
 304  
 305      def test_getitem(self):
 306 -        """
 307 -        Tests __getitem__ API method. It should return a group by its name.
 308 -        """
 309          assert self.fruit_group == self.group_manager[u'FruitGroup']
 310          raises(KeyError, lambda: self.group_manager[u'not existing group'])
 311  
 312      def test_clashed_getitem(self):
 313          """
 314 -        This test check situation when groups with a same name are
 315 -        defined in several backends. In this case, the only one
 316 -        backend must be taken in consideration, that backend which is
 317 -        defined first in the backends list.
 318 +        Check the case when groups of the same name are defined in multiple
 319 +        backends. __getitem__ should return the first match (backends are
 320 +        considered in the order they are given in the backends list).
 321          """
 322          admin_group = self.group_manager[u'AdminGroup']
 323 -
 324          assert self.admin_group == admin_group
 325  
 326 -        # Nevertheless, TheHacker added himself to the second backend,
 327 -        # it must not be taken into consideration, because AdminGroup is defined
 328 -        # in first backend
 329 +        # TheHacker added himself to the second backend, but that must not be
 330 +        # taken into consideration, because AdminGroup is defined in first
 331 +        # backend and we only use the first match.
 332          assert u'TheHacker' not in admin_group
 333  
 334      def test_iter(self):
 335 -        """
 336 -        Tests __iter__ API method. It should iterate over all groups
 337 -        available via backends. It should avoid group name clashes.
 338 -        """
 339          all_group_names = [group_name for group_name in self.group_manager]
 340  
 341          assert 5 == len(all_group_names)
 342  -84,19 +72,10 @@
 343          assert len(set(all_group_names)) == len(all_group_names)
 344  
 345      def test_contains(self):
 346 -        """
 347 -        Tests __contains__ API method. It should check if a group
 348 -        called group_name is available via some backend.
 349 -        """
 350          assert u'UserGroup' in self.group_manager
 351          assert u'not existing group' not in self.group_manager
 352  
 353      def test_membergroups(self):
 354 -        """
 355 -        Tests membergroups API method. It should lists all groups
 356 -        where member is a member of. It should return a list of group
 357 -        names.
 358 -        """
 359          apple_groups = self.group_manager.membergroups(u'Apple')
 360          assert 1 == len(apple_groups)
 361          assert u'FruitGroup' in apple_groups
 362  -110,3 +89,4 @@
 363          assert u'FruitGroup' not in john_doe_groups
 364  
 365  coverage_modules = ['MoinMoin.groups']
 366 +
 367 diff -r c3e904a9c00b MoinMoin/groups/_tests/test_group_manager_acl.py
 368 --- a/MoinMoin/groups/_tests/test_group_manager_acl.py  Sat May 30 08:22:09 2009 +0200
 369 +++ b/MoinMoin/groups/_tests/test_group_manager_acl.py  Sat May 30 14:30:10 2009 +0200
 370  -47,8 +47,7 @@
 371  
 372      def testConfigBackend(self):
 373          """
 374 -        tests getting a group from the group manager, does group
 375 -        membership tests.
 376 +        tests getting a group from the group manager, does group membership tests.
 377          """
 378          # define config groups
 379          groups = {'A': set(['a1', 'a2']),
 380  -75,3 +74,4 @@
 381          assert 'b1' not in group_A
 382  
 383  coverage_modules = ['MoinMoin.groups']
 384 +
 385 

MoinMoin: Groups2009/DocstringTips (last edited 2009-05-31 15:53:43 by DmitriiMiliaev)