Skip to content

Commit 71809a3

Browse files
committed
Refactor group list split logic, add more error and type checking
1 parent 2791f4c commit 71809a3

File tree

2 files changed

+68
-37
lines changed

2 files changed

+68
-37
lines changed

tests/test_connections.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,53 @@ def test_no_group_split():
369369
user.add_to_groups(groups=add_groups, group_type=GroupTypes.usergroup)
370370
assert user.maybe_split_groups(10) is False
371371
assert len(user.commands) == 1
372+
373+
374+
def test_complex_group_split():
375+
"""
376+
Test a complex command with add and remove directive, with multiple group types
377+
UserAction's interface doesn't support this, so we build our own command array
378+
:return:
379+
"""
380+
group_prefix = "G"
381+
add_groups = [group_prefix+six.text_type(n+1) for n in range(0, 150)]
382+
add_products = [group_prefix+six.text_type(n+1) for n in range(0, 26)]
383+
user = UserAction(id_type=IdentityTypes.enterpriseID, email="[email protected]")
384+
user.commands = [{
385+
"add": {
386+
GroupTypes.usergroup.name: add_groups,
387+
GroupTypes.product.name: add_products,
388+
},
389+
}]
390+
assert user.maybe_split_groups(10) is True
391+
assert len(user.commands) == 15
392+
assert len([c for c in user.commands if 'product' in c['add']]) == 3
393+
assert GroupTypes.product.name not in user.commands[3]['add']
394+
395+
396+
def test_split_remove_all():
397+
"""
398+
Don't split groups if "remove" is "all" instead of list
399+
:return:
400+
"""
401+
group_prefix = "G"
402+
add_groups = [group_prefix+six.text_type(n+1) for n in range(0, 11)]
403+
user = UserAction(id_type=IdentityTypes.enterpriseID, email="[email protected]")
404+
user.remove_from_groups(all_groups=True)
405+
assert user.maybe_split_groups(1) is False
406+
assert user.wire_dict() == {'do': [{'remove': 'all'}], 'user': '[email protected]'}
407+
user.add_to_groups(groups=add_groups)
408+
assert user.maybe_split_groups(10) is True
409+
assert user.wire_dict() == {'do': [{'remove': 'all'},
410+
{'add': {'product': ['G1',
411+
'G2',
412+
'G3',
413+
'G4',
414+
'G5',
415+
'G6',
416+
'G7',
417+
'G8',
418+
'G9',
419+
'G10']}},
420+
{'add': {'product': ['G11']}}],
421+
'user': '[email protected]'}

umapi_client/functional.py

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,6 @@ class RoleTypes(Enum):
4343
productAdmin = 2
4444

4545

46-
class StepKeys(Enum):
47-
add = 1
48-
addAdobeID = 2
49-
addRoles = 3
50-
createEnterpriseID = 4
51-
remove = 5
52-
removeFromOrg = 6
53-
removeRoles = 7
54-
update = 8
55-
56-
5746
class IfAlreadyExistsOptions(Enum):
5847
ignoreIfAlreadyExists = 1
5948
updateIfAlreadyExists = 2
@@ -328,40 +317,32 @@ def maybe_split_groups(self, max_groups):
328317
new_commands = []
329318
# return True if we split at least once
330319
maybe_split = False
320+
valid_step_keys = ['add', 'addRoles', 'remove']
331321
for command in self.commands:
322+
# commands are assumed to contain a single key
332323
step_key, step_args = next(six.iteritems(command))
333-
if step_key not in [StepKeys.add.name, StepKeys.remove.name, StepKeys.addRoles.name]:
324+
if step_key not in valid_step_keys:
334325
new_commands.append(command)
335326
continue
336-
split_commands = self._split_groups(step_key, command, max_groups)
337-
if len(split_commands) > 1:
338-
maybe_split = True
327+
split_commands = [command]
328+
while True:
329+
new_command = {step_key: {}}
330+
if not isinstance(command[step_key], dict):
331+
break
332+
for group_type, groups in six.iteritems(command[step_key]):
333+
if len(groups) > max_groups:
334+
maybe_split = True
335+
command[step_key][group_type], new_command[step_key][group_type] = \
336+
groups[0:max_groups], groups[max_groups:]
337+
if new_command[step_key]:
338+
split_commands.append(new_command)
339+
command = new_command
340+
else:
341+
break
339342
new_commands += split_commands
340343
self.commands = new_commands
341344
return maybe_split
342345

343-
def _split_groups(self, step_key, command, max_groups):
344-
"""
345-
Split long group lists of individual command
346-
Creates additional commands for each split and recursively splits new groups until no commands exceed group
347-
limit. Assumes that at least one split should occur.
348-
:param step_key: Step key (add, remove, etc)
349-
:param command: Single command containing one or more group lists to add, remove, etc
350-
:param max_groups: Max group list size
351-
:return: List of at least two commands that resulted from split
352-
"""
353-
new_commands = [command]
354-
while True:
355-
new_command = {step_key: {}}
356-
for group_type, groups in six.iteritems(command[step_key]):
357-
if len(groups) > max_groups:
358-
command[step_key][group_type], new_command[step_key][group_type] = \
359-
groups[0:max_groups], groups[max_groups:]
360-
if new_command[step_key]:
361-
new_commands += self._split_groups(step_key, new_command, max_groups)
362-
else:
363-
return new_commands
364-
365346

366347
class UsersQuery(QueryMultiple):
367348
"""

0 commit comments

Comments
 (0)