Add tests for osusers.admin
This commit raises the test coverage for osusers.admin to 100% by adding tests for UserAdmin, GroupAdmin, SshPublicKeyCreationForm and SshPublicKeyAdmin. The commit adds a refactoring TODO to SshPublicKeyAdmin.perform_delete_selected because the asynchronous background task should be launched from a signal handler.
This commit is contained in:
parent
fb1f31a9bc
commit
4f39c0d2c4
2 changed files with 170 additions and 7 deletions
|
@ -178,7 +178,7 @@ class UserAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
actions = super(UserAdmin, self).get_actions(request)
|
actions = super(UserAdmin, self).get_actions(request)
|
||||||
if 'delete_selected' in actions:
|
if 'delete_selected' in actions: # pragma: no cover
|
||||||
del actions['delete_selected']
|
del actions['delete_selected']
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ class GroupAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
actions = super(GroupAdmin, self).get_actions(request)
|
actions = super(GroupAdmin, self).get_actions(request)
|
||||||
if 'delete_selected' in actions:
|
if 'delete_selected' in actions: # pragma: no cover
|
||||||
del actions['delete_selected']
|
del actions['delete_selected']
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
@ -257,6 +257,7 @@ class SshPublicKeyCreationForm(forms.ModelForm):
|
||||||
self.add_error(
|
self.add_error(
|
||||||
'publickeytext',
|
'publickeytext',
|
||||||
forms.ValidationError(DUPLICATE_SSH_PUBLIC_KEY_FOR_USER))
|
forms.ValidationError(DUPLICATE_SSH_PUBLIC_KEY_FOR_USER))
|
||||||
|
super(SshPublicKeyCreationForm, self).clean()
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
"""
|
"""
|
||||||
|
@ -347,13 +348,14 @@ class SshPublicKeyAdmin(admin.ModelAdmin):
|
||||||
])
|
])
|
||||||
queryset.delete()
|
queryset.delete()
|
||||||
for user in users:
|
for user in users:
|
||||||
|
# TODO: move to model/signal
|
||||||
TaskResult.objects.create_task_result(
|
TaskResult.objects.create_task_result(
|
||||||
set_file_ssh_authorized_keys.delay(
|
'perform_delete_selected',
|
||||||
|
set_file_ssh_authorized_keys.s(
|
||||||
User.objects.get(uid=user).username,
|
User.objects.get(uid=user).username,
|
||||||
[str(key) for key in SshPublicKey.objects.filter(
|
[str(key) for key in SshPublicKey.objects.filter(
|
||||||
user_id=user)]
|
user_id=user)]
|
||||||
),
|
)
|
||||||
'set_file_ssh_authorized_keys'
|
|
||||||
)
|
)
|
||||||
perform_delete_selected.short_description = _(
|
perform_delete_selected.short_description = _(
|
||||||
'Delete selected SSH public keys')
|
'Delete selected SSH public keys')
|
||||||
|
@ -371,7 +373,7 @@ class SshPublicKeyAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
actions = super(SshPublicKeyAdmin, self).get_actions(request)
|
actions = super(SshPublicKeyAdmin, self).get_actions(request)
|
||||||
if 'delete_selected' in actions:
|
if 'delete_selected' in actions: # pragma: no cover
|
||||||
del actions['delete_selected']
|
del actions['delete_selected']
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,22 @@ from django.test.utils import override_settings
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from mock import Mock
|
from mock import MagicMock, Mock, patch
|
||||||
|
|
||||||
|
from osusers.forms import (
|
||||||
|
INVALID_SSH_PUBLIC_KEY,
|
||||||
|
DUPLICATE_SSH_PUBLIC_KEY_FOR_USER,
|
||||||
|
)
|
||||||
from osusers.models import (
|
from osusers.models import (
|
||||||
Group,
|
Group,
|
||||||
|
SshPublicKey,
|
||||||
User,
|
User,
|
||||||
)
|
)
|
||||||
from osusers.admin import (
|
from osusers.admin import (
|
||||||
GroupAdmin,
|
GroupAdmin,
|
||||||
PASSWORD_MISMATCH_ERROR,
|
PASSWORD_MISMATCH_ERROR,
|
||||||
|
SshPublicKeyAdmin,
|
||||||
|
SshPublicKeyCreationForm,
|
||||||
UserAdmin,
|
UserAdmin,
|
||||||
UserCreationForm,
|
UserCreationForm,
|
||||||
)
|
)
|
||||||
|
@ -119,8 +126,29 @@ class UserAdminTest(CustomerTestCase):
|
||||||
for index in range(len(inlines)):
|
for index in range(len(inlines)):
|
||||||
self.assertIsInstance(inlines[index], UserAdmin.inlines[index])
|
self.assertIsInstance(inlines[index], UserAdmin.inlines[index])
|
||||||
|
|
||||||
|
@override_settings(
|
||||||
|
CELERY_ALWAYS_EAGER=True,
|
||||||
|
CELERY_CACHE_BACKEND='memory',
|
||||||
|
BROKER_BACKEND='memory'
|
||||||
|
)
|
||||||
|
def test_perform_delete_selected(self):
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
self.uadmin.perform_delete_selected(
|
||||||
|
Mock(name='request'), User.objects.filter(uid=user.uid))
|
||||||
|
self.assertEqual(User.objects.filter(uid=user.uid).count(), 0)
|
||||||
|
|
||||||
|
def test_get_actions(self):
|
||||||
|
requestmock = MagicMock(name='request')
|
||||||
|
self.assertNotIn(
|
||||||
|
'delete_selected',
|
||||||
|
self.uadmin.get_actions(requestmock))
|
||||||
|
self.assertIn(
|
||||||
|
'perform_delete_selected',
|
||||||
|
self.uadmin.get_actions(requestmock))
|
||||||
|
|
||||||
|
|
||||||
class GroupAdminTest(TestCase):
|
class GroupAdminTest(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
site = AdminSite()
|
site = AdminSite()
|
||||||
self.gadmin = GroupAdmin(Group, site)
|
self.gadmin = GroupAdmin(Group, site)
|
||||||
|
@ -142,3 +170,136 @@ class GroupAdminTest(TestCase):
|
||||||
self.assertEqual(len(inlines), len(GroupAdmin.inlines))
|
self.assertEqual(len(inlines), len(GroupAdmin.inlines))
|
||||||
for index in range(len(inlines)):
|
for index in range(len(inlines)):
|
||||||
self.assertIsInstance(inlines[index], GroupAdmin.inlines[index])
|
self.assertIsInstance(inlines[index], GroupAdmin.inlines[index])
|
||||||
|
|
||||||
|
def test_perform_delete_selected(self):
|
||||||
|
group = Group.objects.create(gid=1000, groupname='test')
|
||||||
|
self.gadmin.perform_delete_selected(
|
||||||
|
Mock(name='request'), Group.objects.filter(gid=group.gid))
|
||||||
|
self.assertEqual(Group.objects.filter(gid=group.gid).count(), 0)
|
||||||
|
|
||||||
|
def test_get_actions(self):
|
||||||
|
requestmock = MagicMock(name='request')
|
||||||
|
self.assertNotIn(
|
||||||
|
'delete_selected',
|
||||||
|
self.gadmin.get_actions(requestmock))
|
||||||
|
self.assertIn(
|
||||||
|
'perform_delete_selected',
|
||||||
|
self.gadmin.get_actions(requestmock))
|
||||||
|
|
||||||
|
|
||||||
|
class SshPublicKeyCreationFormTest(CustomerTestCase):
|
||||||
|
|
||||||
|
@patch('osusers.admin.SshPublicKey.objects')
|
||||||
|
def test_clean_publickeytext_valid_key(self, sshpkmanager):
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
sshpkmanager.parse_keytext = MagicMock(side_effect=ValueError)
|
||||||
|
form.cleaned_data = {'publickeytext': 'wrongkey'}
|
||||||
|
with self.assertRaises(forms.ValidationError) as ve:
|
||||||
|
form.clean_publickeytext()
|
||||||
|
self.assertEqual(ve.exception.message, INVALID_SSH_PUBLIC_KEY)
|
||||||
|
|
||||||
|
@patch('osusers.admin.SshPublicKey.objects')
|
||||||
|
def test_clean_publickeytext_invalid_key(self, sshpkmanager):
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
sshpkmanager.parse_keytext = MagicMock(return_value='goodkey')
|
||||||
|
form.cleaned_data = {'publickeytext': 'goodkey'}
|
||||||
|
self.assertEqual(form.clean_publickeytext(), 'goodkey')
|
||||||
|
|
||||||
|
def test_clean_missing_data(self):
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
form.cleaned_data = {}
|
||||||
|
form.clean()
|
||||||
|
self.assertEqual(len(form.errors), 0)
|
||||||
|
|
||||||
|
@patch('osusers.admin.SshPublicKey.objects.parse_keytext')
|
||||||
|
def test_clean_once(self, parse_keytext):
|
||||||
|
parse_keytext.return_value = ('good', 'key', 'comment')
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
form.cleaned_data = {
|
||||||
|
'user': user,
|
||||||
|
'publickeytext': 'good key comment'
|
||||||
|
}
|
||||||
|
form.clean()
|
||||||
|
self.assertEqual(len(form.errors), 0)
|
||||||
|
|
||||||
|
@patch('osusers.admin.SshPublicKey.objects.parse_keytext')
|
||||||
|
def test_clean_again(self, parse_keytext):
|
||||||
|
parse_keytext.return_value = ('good', 'key', 'comment')
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
SshPublicKey.objects.create(
|
||||||
|
user=user, algorithm='good', data='key', comment='comment')
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
form.cleaned_data = {
|
||||||
|
'user': user,
|
||||||
|
'publickeytext': 'good key comment'
|
||||||
|
}
|
||||||
|
form.clean()
|
||||||
|
self.assertIn('publickeytext', form.errors)
|
||||||
|
self.assertEqual(
|
||||||
|
form.errors['publickeytext'],
|
||||||
|
[DUPLICATE_SSH_PUBLIC_KEY_FOR_USER])
|
||||||
|
|
||||||
|
@patch('osusers.admin.SshPublicKey.objects.parse_keytext')
|
||||||
|
def test_save(self, parse_keytext):
|
||||||
|
parse_keytext.return_value = ('good', 'key', 'comment')
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
form = SshPublicKeyCreationForm()
|
||||||
|
form.cleaned_data = {
|
||||||
|
'user': user,
|
||||||
|
'publickeytext': 'good key comment'
|
||||||
|
}
|
||||||
|
form.instance.user = user
|
||||||
|
form.save()
|
||||||
|
self.assertTrue(
|
||||||
|
SshPublicKey.objects.filter(
|
||||||
|
user=user, algorithm='good', data='key'))
|
||||||
|
|
||||||
|
|
||||||
|
class SshPublicKeyAdminTest(CustomerTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
site = AdminSite()
|
||||||
|
self.sadmin = SshPublicKeyAdmin(SshPublicKey, site)
|
||||||
|
super(SshPublicKeyAdminTest, self).setUp()
|
||||||
|
|
||||||
|
def test_get_form_no_instance(self):
|
||||||
|
form = self.sadmin.get_form(request=Mock(name='request'))
|
||||||
|
self.assertEqual(form.Meta.model, SshPublicKey)
|
||||||
|
|
||||||
|
def test_get_form_with_instance(self):
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
key = SshPublicKey.objects.create(
|
||||||
|
user=user, algorithm='good', data='key', comment='comment')
|
||||||
|
form = self.sadmin.get_form(request=Mock(name='request'), obj=key)
|
||||||
|
self.assertEqual(form.Meta.model, SshPublicKey)
|
||||||
|
self.assertEqual(
|
||||||
|
form.Meta.fields,
|
||||||
|
['user', 'comment', 'algorithm', 'data'])
|
||||||
|
|
||||||
|
def test_get_readonly_fields_no_instance(self):
|
||||||
|
readonly_fields = self.sadmin.get_readonly_fields(
|
||||||
|
request=Mock(name='request'))
|
||||||
|
self.assertEqual(readonly_fields, [])
|
||||||
|
|
||||||
|
def test_get_readonly_fields_with_instance(self):
|
||||||
|
readonly_fields = self.sadmin.get_readonly_fields(
|
||||||
|
request=Mock(name='request'), obj=Mock())
|
||||||
|
self.assertEqual(readonly_fields, ['algorithm', 'data'])
|
||||||
|
|
||||||
|
def test_perform_delete_selected(self):
|
||||||
|
user = User.objects.create_user(customer=self.customer)
|
||||||
|
key = SshPublicKey.objects.create(
|
||||||
|
user=user, algorithm='good', data='key', comment='comment')
|
||||||
|
self.sadmin.perform_delete_selected(
|
||||||
|
Mock(name='request'), SshPublicKey.objects.filter(id=key.id))
|
||||||
|
self.assertFalse(SshPublicKey.objects.filter(id=key.id).exists())
|
||||||
|
|
||||||
|
def test_get_actions(self):
|
||||||
|
requestmock = MagicMock(name='request')
|
||||||
|
self.assertNotIn(
|
||||||
|
'delete_selected',
|
||||||
|
self.sadmin.get_actions(requestmock))
|
||||||
|
self.assertIn(
|
||||||
|
'perform_delete_selected',
|
||||||
|
self.sadmin.get_actions(requestmock))
|
||||||
|
|
Loading…
Reference in a new issue