from django import forms from django.contrib.admin import AdminSite from django.test import TestCase from django.test.utils import override_settings from django.contrib.auth import get_user_model from unittest.mock import MagicMock, Mock, patch from osusers.forms import INVALID_SSH_PUBLIC_KEY, DUPLICATE_SSH_PUBLIC_KEY_FOR_USER from osusers.models import Group, SshPublicKey, User from osusers.admin import ( GroupAdmin, PASSWORD_MISMATCH_ERROR, SshPublicKeyAdmin, SshPublicKeyCreationForm, UserAdmin, UserCreationForm, ) Customer = get_user_model() class CustomerTestCase(TestCase): def setUp(self): self.customer = Customer.objects.create_user("test") super(CustomerTestCase, self).setUp() class UserCreationFormTest(CustomerTestCase): def test_clean_password2_same(self): form = UserCreationForm() form.cleaned_data = { "customer": self.customer, "password1": "secret", "password2": "secret", } self.assertEqual(form.clean_password2(), "secret") def test_clean_password2_empty(self): form = UserCreationForm() form.cleaned_data = {} self.assertIsNone(form.clean_password2()) def test_clean_password2_mismatch(self): form = UserCreationForm() form.cleaned_data = { "customer": self.customer, "password1": "secretx", "password2": "secrety", } with self.assertRaises(forms.ValidationError) as cm: form.clean_password2() self.assertEqual(cm.exception.message, PASSWORD_MISMATCH_ERROR) @override_settings( CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory" ) def test_save_commit(self): form = UserCreationForm() form.cleaned_data = { "customer": self.customer, "password1": "secret", "password2": "secret", } user = form.save() self.assertIsNotNone(user) self.assertEqual(User.objects.get(pk=user.uid), user) def test_save_m2m_returns_none(self): form = UserCreationForm() self.assertIsNone(form.save_m2m()) class UserAdminTest(CustomerTestCase): def setUp(self): site = AdminSite() self.uadmin = UserAdmin(User, site) super(UserAdminTest, self).setUp() def test_get_form_without_object(self): form = self.uadmin.get_form(Mock(name="request")) self.assertEqual(form.Meta.fields, ["customer", "password1", "password2"]) @override_settings( CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory" ) def test_get_form_with_object(self): user = User.objects.create_user(customer=self.customer) form = self.uadmin.get_form(Mock(name="request"), user) self.assertEqual( form.Meta.fields, ["username", "group", "gecos", "homedir", "shell", "customer", "uid"], ) def test_get_inline_instances_without_object(self): inlines = self.uadmin.get_inline_instances(Mock(name="request")) self.assertEqual(len(inlines), 2) @override_settings( CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory" ) def test_get_inline_instances_with_object(self): user = User.objects.create_user(customer=self.customer) inlines = self.uadmin.get_inline_instances(Mock(name="request"), user) self.assertEqual(len(inlines), len(UserAdmin.inlines)) for index in range(len(inlines)): 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): def setUp(self): site = AdminSite() self.gadmin = GroupAdmin(Group, site) super(GroupAdminTest, self).setUp() def test_get_inline_instances_without_object(self): inlines = self.gadmin.get_inline_instances(Mock(name="request")) self.assertEqual(inlines, []) @override_settings( CELERY_ALWAYS_EAGER=True, CELERY_CACHE_BACKEND="memory", BROKER_BACKEND="memory" ) def test_get_inline_instances_with_object(self): group = Group.objects.create(gid=1000, groupname="test") inlines = self.gadmin.get_inline_instances(Mock(name="request"), group) self.assertEqual(len(inlines), len(GroupAdmin.inlines)) for index in range(len(inlines)): 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_key_text = 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_key_text = 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_key_text") def test_clean_once(self, parse_key_text): parse_key_text.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_key_text") def test_clean_again(self, parse_key_text): parse_key_text.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_key_text") def test_save(self, parse_key_text): parse_key_text.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))