Files
edx-platform/common/djangoapps/student/management/tests/test_manage_group.py

188 lines
7.2 KiB
Python

"""
Unit tests for user_management management commands.
"""
import sys
import pytest
import ddt
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.core.management import CommandError, call_command
from django.test import TestCase
TEST_EMAIL = 'test@example.com'
TEST_GROUP = 'test-group'
TEST_USERNAME = 'test-user'
TEST_DATA = (
{},
{
TEST_GROUP: ['add_group', 'change_group', 'change_group'],
},
{
'other-group': ['add_group', 'change_group', 'change_group'],
},
)
@ddt.ddt
class TestManageGroupCommand(TestCase):
"""
Tests the `manage_group` command.
"""
def set_group_permissions(self, group_permissions):
"""
Sets up a before-state for groups and permissions in tests, which
can be checked afterward to ensure that a failed atomic
operation has not had any side effects.
"""
content_type = ContentType.objects.get_for_model(Group)
for group_name, permission_codenames in group_permissions.items():
group = Group.objects.create(name=group_name)
for codename in permission_codenames:
group.permissions.add(
Permission.objects.get(content_type=content_type, codename=codename)
)
def check_group_permissions(self, group_permissions):
"""
Checks that the current state of the database matches the specified groups and
permissions.
"""
self.check_groups(list(group_permissions.keys()))
for group_name, permission_codenames in group_permissions.items():
self.check_permissions(group_name, permission_codenames)
def check_groups(self, group_names):
"""
DRY helper.
"""
assert set(group_names) == {g.name for g in Group.objects.all()}
def check_permissions(self, group_name, permission_codenames):
"""
DRY helper.
"""
assert set(permission_codenames) == {p.codename for p in Group.objects.get(name=group_name).permissions.all()}
@ddt.data(
*(
(data, args, exception)
for data in TEST_DATA
for args, exception in (
((), 'too few arguments' if sys.version_info.major == 2 else 'required: group_name'), # no group name
(('x' * 151,), 'invalid group name'), # invalid group name
((TEST_GROUP, 'some-other-group'), 'unrecognized arguments'), # multiple arguments
((TEST_GROUP, '--some-option', 'dummy'), 'unrecognized arguments') # unexpected option name
)
)
)
@ddt.unpack
def test_invalid_input(self, initial_group_permissions, command_args, exception_message):
"""
Ensures that invalid inputs result in errors with relevant output,
and that no persistent state is changed.
"""
self.set_group_permissions(initial_group_permissions)
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', *command_args)
assert exception_message in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
@ddt.data(*TEST_DATA)
def test_invalid_permission(self, initial_group_permissions):
"""
Ensures that a permission that cannot be parsed or resolved results in
and error and that no persistent state is changed.
"""
self.set_group_permissions(initial_group_permissions)
# not parseable
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', TEST_GROUP, '--permissions', 'fail')
assert 'invalid permission option' in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
# not parseable
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', TEST_GROUP, '--permissions', 'f:a:i:l')
assert 'invalid permission option' in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
# invalid app label
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', TEST_GROUP, '--permissions', 'nonexistent-label:dummy-model:dummy-perm')
assert 'no installed app' in str(exc_context.value).lower()
assert 'nonexistent-label' in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
# invalid model name
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:nonexistent-model:dummy-perm')
assert 'nonexistent-model' in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
# invalid model name
with pytest.raises(CommandError) as exc_context:
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:nonexistent-perm')
assert 'invalid permission codename' in str(exc_context.value).lower()
assert 'nonexistent-perm' in str(exc_context.value).lower()
self.check_group_permissions(initial_group_permissions)
def test_group(self):
"""
Ensures that groups are created if they don't exist and reused if they do.
"""
self.check_groups([])
call_command('manage_group', TEST_GROUP)
self.check_groups([TEST_GROUP])
# check idempotency
call_command('manage_group', TEST_GROUP)
self.check_groups([TEST_GROUP])
def test_group_remove(self):
"""
Ensures that groups are removed if they exist and we exit cleanly otherwise.
"""
self.set_group_permissions({TEST_GROUP: ['add_group']})
self.check_groups([TEST_GROUP])
call_command('manage_group', TEST_GROUP, '--remove')
self.check_groups([])
# check idempotency
call_command('manage_group', TEST_GROUP, '--remove')
self.check_groups([])
def test_permissions(self):
"""
Ensures that permissions are set on the group as specified.
"""
self.check_groups([])
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:add_group')
self.check_groups([TEST_GROUP])
self.check_permissions(TEST_GROUP, ['add_group'])
# check idempotency
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:add_group')
self.check_groups([TEST_GROUP])
self.check_permissions(TEST_GROUP, ['add_group'])
# check adding a permission
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:add_group', 'auth:Group:change_group')
self.check_groups([TEST_GROUP])
self.check_permissions(TEST_GROUP, ['add_group', 'change_group'])
# check removing a permission
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:change_group')
self.check_groups([TEST_GROUP])
self.check_permissions(TEST_GROUP, ['change_group'])
# check removing all permissions
call_command('manage_group', TEST_GROUP)
self.check_groups([TEST_GROUP])
self.check_permissions(TEST_GROUP, [])