forked from erp-dev/erp
175 lines
7.0 KiB
Python
175 lines
7.0 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import Group, Permission
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.test import TestCase
|
|
from rest_framework.test import APIClient
|
|
|
|
from basic_info import models as basic_models
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class CoreAPITestCase(TestCase):
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.merchant = basic_models.Merchant.objects.create(
|
|
name="核心商户",
|
|
type=basic_models.MerchantTypeEnum.STORE,
|
|
)
|
|
self.other_merchant = basic_models.Merchant.objects.create(
|
|
name="其他商户",
|
|
type=basic_models.MerchantTypeEnum.STORE,
|
|
)
|
|
self.super_user = User.objects.create_superuser(
|
|
username="core_admin",
|
|
password="pass12345",
|
|
email="core@example.com",
|
|
)
|
|
self.employee = basic_models.Employee.objects.create(
|
|
merchant=self.merchant,
|
|
sys_user=self.super_user,
|
|
name="核心管理员",
|
|
)
|
|
self.normal_user = User.objects.create_user(username="normal", password="pass12345")
|
|
self.no_employee_super_user = User.objects.create_superuser(
|
|
username="no_employee_admin",
|
|
password="pass12345",
|
|
)
|
|
|
|
def authenticate_super_admin(self):
|
|
self.client.force_authenticate(user=self.super_user)
|
|
|
|
def test_core_api_requires_superuser_and_employee_merchant(self):
|
|
response = self.client.get("/api/core/users/")
|
|
self.assertEqual(response.status_code, 401)
|
|
|
|
self.client.force_authenticate(user=self.normal_user)
|
|
response = self.client.get("/api/core/users/")
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
self.client.force_authenticate(user=self.no_employee_super_user)
|
|
response = self.client.get("/api/core/users/")
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_user_list_is_merchant_scoped(self):
|
|
same_user = User.objects.create_user(username="same_merchant", password="pass12345")
|
|
basic_models.UserProfile.objects.create(user=same_user, merchant=self.merchant)
|
|
|
|
other_user = User.objects.create_user(username="other_merchant", password="pass12345")
|
|
basic_models.UserProfile.objects.create(user=other_user, merchant=self.other_merchant)
|
|
|
|
self.authenticate_super_admin()
|
|
response = self.client.get("/api/core/users/", {"limit": 100})
|
|
self.assertEqual(response.status_code, 200)
|
|
usernames = {item["username"] for item in response.data["results"]}
|
|
self.assertIn("core_admin", usernames)
|
|
self.assertIn("same_merchant", usernames)
|
|
self.assertNotIn("other_merchant", usernames)
|
|
|
|
detail_response = self.client.get(f"/api/core/users/{other_user.id}/")
|
|
self.assertEqual(detail_response.status_code, 404)
|
|
|
|
def test_create_user_creates_profile_but_not_employee(self):
|
|
group = Group.objects.create(name="核心角色")
|
|
self.authenticate_super_admin()
|
|
response = self.client.post(
|
|
"/api/core/users/",
|
|
{
|
|
"username": "core_created",
|
|
"password": "pass12345",
|
|
"email": "created@example.com",
|
|
"first_name": "Core",
|
|
"is_active": True,
|
|
"groups": [group.id],
|
|
},
|
|
format="json",
|
|
)
|
|
self.assertEqual(response.status_code, 201)
|
|
|
|
user = User.objects.get(username="core_created")
|
|
self.assertEqual(user.profile.merchant, self.merchant)
|
|
self.assertFalse(hasattr(user, "employee"))
|
|
self.assertIn(group, user.groups.all())
|
|
|
|
def test_user_cannot_be_deleted_and_self_cannot_be_deactivated_or_demoted(self):
|
|
self.authenticate_super_admin()
|
|
response = self.client.delete(f"/api/core/users/{self.super_user.id}/")
|
|
self.assertEqual(response.status_code, 405)
|
|
|
|
response = self.client.patch(
|
|
f"/api/core/users/{self.super_user.id}/",
|
|
{"is_active": False},
|
|
format="json",
|
|
)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertIn("is_active", response.data)
|
|
|
|
response = self.client.patch(
|
|
f"/api/core/users/{self.super_user.id}/",
|
|
{"is_superuser": False},
|
|
format="json",
|
|
)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertIn("is_superuser", response.data)
|
|
|
|
def test_groups_are_global_full_crud(self):
|
|
content_type = ContentType.objects.get_for_model(User)
|
|
permission = Permission.objects.get(content_type=content_type, codename="view_user")
|
|
self.authenticate_super_admin()
|
|
|
|
create_response = self.client.post(
|
|
"/api/core/groups/",
|
|
{"name": "全局核心组", "permissions": [permission.id]},
|
|
format="json",
|
|
)
|
|
self.assertEqual(create_response.status_code, 201)
|
|
group_id = create_response.data["id"]
|
|
|
|
detail_response = self.client.get(f"/api/core/groups/{group_id}/")
|
|
self.assertEqual(detail_response.status_code, 200)
|
|
self.assertEqual(detail_response.data["name"], "全局核心组")
|
|
self.assertEqual(detail_response.data["permissions"], [permission.id])
|
|
|
|
patch_response = self.client.patch(
|
|
f"/api/core/groups/{group_id}/",
|
|
{"name": "已更新核心组"},
|
|
format="json",
|
|
)
|
|
self.assertEqual(patch_response.status_code, 200)
|
|
self.assertEqual(patch_response.data["name"], "已更新核心组")
|
|
|
|
delete_response = self.client.delete(f"/api/core/groups/{group_id}/")
|
|
self.assertEqual(delete_response.status_code, 204)
|
|
self.assertFalse(Group.objects.filter(id=group_id).exists())
|
|
|
|
def test_permissions_are_read_only(self):
|
|
content_type = ContentType.objects.get_for_model(User)
|
|
permission = Permission.objects.get(content_type=content_type, codename="view_user")
|
|
self.authenticate_super_admin()
|
|
|
|
list_response = self.client.get("/api/core/permissions/", {"limit": 100})
|
|
self.assertEqual(list_response.status_code, 200)
|
|
self.assertTrue(any(item["id"] == permission.id for item in list_response.data["results"]))
|
|
|
|
detail_response = self.client.get(f"/api/core/permissions/{permission.id}/")
|
|
self.assertEqual(detail_response.status_code, 200)
|
|
self.assertEqual(detail_response.data["full_code"], "auth.view_user")
|
|
|
|
create_response = self.client.post(
|
|
"/api/core/permissions/",
|
|
{"name": "fake", "codename": "fake_permission", "content_type": content_type.id},
|
|
format="json",
|
|
)
|
|
self.assertEqual(create_response.status_code, 405)
|
|
|
|
patch_response = self.client.patch(
|
|
f"/api/core/permissions/{permission.id}/",
|
|
{"name": "renamed"},
|
|
format="json",
|
|
)
|
|
self.assertEqual(patch_response.status_code, 405)
|
|
|
|
delete_response = self.client.delete(f"/api/core/permissions/{permission.id}/")
|
|
self.assertEqual(delete_response.status_code, 405)
|