fix: unify workflow action permissions
This commit is contained in:
parent
919ac890a9
commit
c3f2c0f136
|
|
@ -1,3 +1,60 @@
|
||||||
from django.test import TestCase
|
from types import SimpleNamespace
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
# Create your tests here.
|
from django.test import SimpleTestCase
|
||||||
|
from rest_framework.test import APIRequestFactory
|
||||||
|
|
||||||
|
from apps.wf.views import TicketViewSet
|
||||||
|
|
||||||
|
|
||||||
|
class TicketAvailableActionsTests(SimpleTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.request = APIRequestFactory().get('/api/wf/ticket/1/available_actions/')
|
||||||
|
self.request.user = SimpleNamespace(id='user-1')
|
||||||
|
self.view = TicketViewSet()
|
||||||
|
self.ticket = SimpleNamespace(in_add_node=False)
|
||||||
|
self.view.get_object = MagicMock(return_value=self.ticket)
|
||||||
|
|
||||||
|
@patch('apps.wf.views.TransitionSerializer')
|
||||||
|
@patch('apps.wf.views.WfService.get_ticket_transitions')
|
||||||
|
@patch('apps.wf.views.WfService.ticket_handle_permission_check')
|
||||||
|
def test_returns_transitions_when_user_can_handle(
|
||||||
|
self, permission_check, get_transitions, serializer):
|
||||||
|
permission_check.return_value = {
|
||||||
|
'permission': True,
|
||||||
|
'need_accept': False,
|
||||||
|
'msg': '',
|
||||||
|
}
|
||||||
|
transitions = MagicMock()
|
||||||
|
transitions.select_related.return_value = transitions
|
||||||
|
get_transitions.return_value = transitions
|
||||||
|
serializer.return_value.data = [{'id': 'transition-1', 'name': '同意'}]
|
||||||
|
|
||||||
|
response = self.view.available_actions(self.request)
|
||||||
|
|
||||||
|
self.assertTrue(response.data['permission'])
|
||||||
|
self.assertFalse(response.data['need_accept'])
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['transitions'],
|
||||||
|
[{'id': 'transition-1', 'name': '同意'}],
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch('apps.wf.views.TransitionSerializer')
|
||||||
|
@patch('apps.wf.views.WfService.get_ticket_transitions')
|
||||||
|
@patch('apps.wf.views.WfService.ticket_handle_permission_check')
|
||||||
|
def test_hides_transitions_and_requests_accept_for_active_distribution(
|
||||||
|
self, permission_check, get_transitions, serializer):
|
||||||
|
permission_check.return_value = {
|
||||||
|
'permission': False,
|
||||||
|
'need_accept': True,
|
||||||
|
'msg': '需要先接单再处理',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.view.available_actions(self.request)
|
||||||
|
|
||||||
|
self.assertFalse(response.data['permission'])
|
||||||
|
self.assertTrue(response.data['need_accept'])
|
||||||
|
self.assertEqual(response.data['message'], '需要先接单再处理')
|
||||||
|
self.assertEqual(response.data['transitions'], [])
|
||||||
|
get_transitions.assert_not_called()
|
||||||
|
serializer.assert_not_called()
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,34 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R
|
||||||
transitions = WfService.get_ticket_transitions(ticket)
|
transitions = WfService.get_ticket_transitions(ticket)
|
||||||
return Response(TransitionSerializer(instance=transitions.select_related('source_state', 'destination_state'), many=True).data)
|
return Response(TransitionSerializer(instance=transitions.select_related('source_state', 'destination_state'), many=True).data)
|
||||||
|
|
||||||
|
@action(methods=['get'], detail=True, perms_map={'get': '*'})
|
||||||
|
def available_actions(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
获取当前用户对工单可执行的操作及接单状态。
|
||||||
|
|
||||||
|
前端应使用该接口决定是否展示处理按钮,避免自行解释 participant
|
||||||
|
后与后端实际处理权限不一致。原 transitions 接口保留用于兼容。
|
||||||
|
"""
|
||||||
|
ticket = self.get_object()
|
||||||
|
permission_result = WfService.ticket_handle_permission_check(
|
||||||
|
ticket, request.user
|
||||||
|
)
|
||||||
|
transitions = []
|
||||||
|
if permission_result.get('permission', False):
|
||||||
|
transition_queryset = WfService.get_ticket_transitions(
|
||||||
|
ticket
|
||||||
|
).select_related('source_state', 'destination_state')
|
||||||
|
transitions = TransitionSerializer(
|
||||||
|
instance=transition_queryset, many=True
|
||||||
|
).data
|
||||||
|
return Response({
|
||||||
|
'permission': permission_result.get('permission', False),
|
||||||
|
'need_accept': permission_result.get('need_accept', False),
|
||||||
|
'message': permission_result.get('msg', ''),
|
||||||
|
'in_add_node': ticket.in_add_node,
|
||||||
|
'transitions': transitions,
|
||||||
|
})
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post': '*'})
|
@action(methods=['post'], detail=True, perms_map={'post': '*'})
|
||||||
def accpet(self, request, pk=None):
|
def accpet(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue