fix: fix organizations view queryset and add API tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7e089bd5ec
commit
cc2cd40532
|
|
@ -18,5 +18,5 @@ class OrganizationTreeSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
def get_children(self, obj):
|
def get_children(self, obj):
|
||||||
return OrganizationSerializer(
|
return OrganizationSerializer(
|
||||||
obj.children.filter(is_active=True), many=True
|
obj.children.filter(is_active=True), many=True, context=self.context
|
||||||
).data
|
).data
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,61 @@ class TestOrganizationModel:
|
||||||
Organization.objects.create(name='子A', email='a@example.com', parent=parent)
|
Organization.objects.create(name='子A', email='a@example.com', parent=parent)
|
||||||
Organization.objects.create(name='子B', email='b@example.com', parent=parent)
|
Organization.objects.create(name='子B', email='b@example.com', parent=parent)
|
||||||
assert parent.children.count() == 2
|
assert parent.children.count() == 2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
class TestOrganizationPublicAPI:
|
||||||
|
def test_public_list_returns_top_level_orgs(self, client):
|
||||||
|
parent = Organization.objects.create(name='集团', email='g@example.com')
|
||||||
|
Organization.objects.create(name='子A', email='a@example.com', parent=parent)
|
||||||
|
response = client.get('/api/organizations/public/')
|
||||||
|
assert response.status_code == 200
|
||||||
|
# 只返回顶级组织(集团),不直接返回子公司
|
||||||
|
assert response.data['count'] == 1
|
||||||
|
assert response.data['results'][0]['name'] == '集团'
|
||||||
|
|
||||||
|
def test_inactive_org_not_in_public_list(self, client):
|
||||||
|
Organization.objects.create(name='停用集团', email='inactive@example.com', is_active=False)
|
||||||
|
Organization.objects.create(name='启用集团', email='active@example.com', is_active=True)
|
||||||
|
response = client.get('/api/organizations/public/')
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.data['count'] == 1
|
||||||
|
|
||||||
|
def test_manage_requires_auth(self, client):
|
||||||
|
response = client.get('/api/organizations/manage/')
|
||||||
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
class TestOrganizationManageAPI:
|
||||||
|
def test_superadmin_can_create_org(self, client):
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
User = get_user_model()
|
||||||
|
superadmin = User.objects.create_user(
|
||||||
|
username='super1', password='pass123', role='superadmin'
|
||||||
|
)
|
||||||
|
refresh = RefreshToken.for_user(superadmin)
|
||||||
|
token = str(refresh.access_token)
|
||||||
|
response = client.post(
|
||||||
|
'/api/organizations/manage/',
|
||||||
|
{'name': '新集团', 'email': 'new@example.com'},
|
||||||
|
content_type='application/json',
|
||||||
|
HTTP_AUTHORIZATION=f'Bearer {token}'
|
||||||
|
)
|
||||||
|
assert response.status_code == 201
|
||||||
|
|
||||||
|
def test_seeker_cannot_access_manage(self, client):
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
User = get_user_model()
|
||||||
|
seeker = User.objects.create_user(
|
||||||
|
username='seeker1', password='pass123', role='seeker'
|
||||||
|
)
|
||||||
|
refresh = RefreshToken.for_user(seeker)
|
||||||
|
token = str(refresh.access_token)
|
||||||
|
response = client.get(
|
||||||
|
'/api/organizations/manage/',
|
||||||
|
HTTP_AUTHORIZATION=f'Bearer {token}'
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ from apps.accounts.permissions import IsSuperAdmin
|
||||||
|
|
||||||
|
|
||||||
class OrganizationPublicViewSet(viewsets.ReadOnlyModelViewSet):
|
class OrganizationPublicViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""公开只读:门户展示用"""
|
"""公开只读:门户展示用,返回顶级组织(集团)及其子公司树"""
|
||||||
queryset = Organization.objects.filter(is_active=True, parent__isnull=False)
|
queryset = Organization.objects.filter(is_active=True, parent__isnull=True)
|
||||||
serializer_class = OrganizationSerializer
|
serializer_class = OrganizationTreeSerializer
|
||||||
permission_classes = [AllowAny]
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue