from django.contrib.auth import authenticate from django.test import TestCase from rest_framework.test import APIClient from apps.accounts.models import User class AccountAdminModelTests(TestCase): def test_account_admin_flags_and_executive(self): user = User.objects.create_user( user_name="acct1", password="secret", status=User.STATUS_ACCOUNT_ADMIN, ) self.assertTrue(user.is_active) self.assertFalse(user.is_superuser) self.assertTrue(user.is_executive) def test_inactive_clears_flags(self): user = User.objects.create_user( user_name="acct2", password="secret", status=User.STATUS_ACCOUNT_ADMIN, ) user.status = User.STATUS_INACTIVE user.save() user.refresh_from_db() self.assertFalse(user.is_active) self.assertFalse(user.is_superuser) def test_director_admin_is_not_superuser(self): user = User.objects.create_user( user_name="diradmin1", password="secret", status=User.STATUS_DIRECTOR_ADMIN, ) self.assertEqual(user.status, User.STATUS_DIRECTOR_ADMIN) self.assertFalse(user.is_superuser) class AccountAdminApiTests(TestCase): def setUp(self): self.client = APIClient() self.account_admin = User.objects.create_user( user_name="acctadmin", password="acct123", status=User.STATUS_ACCOUNT_ADMIN, ) self.gm = User.objects.create_user( user_name="gm1", password="gm123", status=User.STATUS_GM ) self.buh = User.objects.create_user( user_name="buh1", password="buh123", status=User.STATUS_BUH ) self.director = User.objects.create_user( user_name="dir1", password="dir123", status=User.STATUS_DIRECTOR ) self.superuser = User.objects.create_superuser( user_name="admin1", password="admin123", ) self.assertTrue(self.superuser.is_superuser) self.assertEqual(self.superuser.status, User.STATUS_SUPERUSER) def test_account_admin_creates_user_with_password(self): self.client.force_authenticate(self.account_admin) response = self.client.post( "/api/v1/users/", { "user_name": "newgm", "display_name": "newgm", "status": User.STATUS_GM, "password": "temp-pass", }, format="json", ) self.assertEqual(response.status_code, 201, response.data) created = User.objects.get(display_name="newgm") self.assertEqual(created.status, User.STATUS_GM) self.assertIsNotNone( authenticate(username="newgm", password="temp-pass") ) def test_account_admin_create_requires_password(self): self.client.force_authenticate(self.account_admin) response = self.client.post( "/api/v1/users/", {"user_name": "nopass", "display_name": "nopass", "status": User.STATUS_GM}, format="json", ) self.assertEqual(response.status_code, 400) self.assertIn("password", response.data) def test_gm_cannot_create_user(self): self.client.force_authenticate(self.gm) response = self.client.post( "/api/v1/users/", { "user_name": "blocked", "display_name": "blocked", "status": User.STATUS_GM, "password": "x", }, format="json", ) self.assertEqual(response.status_code, 403) def test_account_admin_lists_all_users(self): self.client.force_authenticate(self.account_admin) response = self.client.get("/api/v1/users/") self.assertEqual(response.status_code, 200) names = {row["display_name"] for row in response.data["results"]} self.assertIn("gm1", names) self.assertIn("buh1", names) self.assertIn("dir1", names) self.assertIn("acctadmin", names) def test_account_admin_set_password(self): self.client.force_authenticate(self.account_admin) response = self.client.post( f"/api/v1/users/{self.gm.pk}/set-password/", {"password": "new-gm-pass"}, format="json", ) self.assertEqual(response.status_code, 200, response.data) self.assertIsNotNone( authenticate(username="gm1", password="new-gm-pass") ) self.assertIsNone(authenticate(username="gm1", password="gm123")) def test_account_admin_deactivate_blocks_login(self): self.client.force_authenticate(self.account_admin) response = self.client.patch( f"/api/v1/users/{self.gm.pk}/", {"status": User.STATUS_INACTIVE}, format="json", ) self.assertEqual(response.status_code, 200, response.data) self.gm.refresh_from_db() self.assertFalse(self.gm.is_active) self.assertIsNone(authenticate(username="gm1", password="gm123")) def test_buh_and_director_cannot_set_password(self): for actor in (self.buh, self.director): self.client.force_authenticate(actor) response = self.client.post( f"/api/v1/users/{self.gm.pk}/set-password/", {"password": "hack"}, format="json", ) self.assertEqual(response.status_code, 403, actor.display_name) def test_superuser_break_glass_create(self): self.client.force_authenticate(self.superuser) response = self.client.post( "/api/v1/users/", { "user_name": "breakglass", "display_name": "breakglass", "status": User.STATUS_BUH, "password": "bg-pass", }, format="json", ) self.assertEqual(response.status_code, 201, response.data) def test_account_admin_cannot_deactivate_self(self): self.client.force_authenticate(self.account_admin) response = self.client.patch( f"/api/v1/users/{self.account_admin.pk}/", {"status": User.STATUS_INACTIVE}, format="json", ) self.assertEqual(response.status_code, 400) self.assertIn("status", response.data) self.account_admin.refresh_from_db() self.assertEqual(self.account_admin.status, User.STATUS_ACCOUNT_ADMIN) self.assertTrue(self.account_admin.is_active) def test_account_admin_cannot_change_own_status(self): self.client.force_authenticate(self.account_admin) response = self.client.patch( f"/api/v1/users/{self.account_admin.pk}/", {"status": User.STATUS_GM}, format="json", ) self.assertEqual(response.status_code, 400) self.assertIn("status", response.data) self.account_admin.refresh_from_db() self.assertEqual(self.account_admin.status, User.STATUS_ACCOUNT_ADMIN) def test_peer_account_admin_can_deactivate_other_account_admin(self): peer = User.objects.create_user( user_name="acctadmin2", password="acct123", status=User.STATUS_ACCOUNT_ADMIN, ) self.client.force_authenticate(self.account_admin) response = self.client.patch( f"/api/v1/users/{peer.pk}/", {"status": User.STATUS_INACTIVE}, format="json", ) self.assertEqual(response.status_code, 200, response.data) peer.refresh_from_db() self.assertEqual(peer.status, User.STATUS_INACTIVE) self.assertFalse(peer.is_active) def test_superuser_hidden_from_user_list(self): User.objects.create_superuser(user_name="hidden_su", password="x") self.client.force_authenticate(self.account_admin) response = self.client.get("/api/v1/users/") self.assertEqual(response.status_code, 200) names = {row["display_name"] for row in response.data["results"]} self.assertNotIn("hidden_su", names) self.assertNotIn("admin1", names) def test_cannot_assign_superuser_status_via_api(self): self.client.force_authenticate(self.account_admin) response = self.client.post( "/api/v1/users/", { "user_name": "bad_su", "display_name": "bad_su", "status": User.STATUS_SUPERUSER, "password": "x", }, format="json", ) self.assertEqual(response.status_code, 400) self.assertIn("status", response.data)