feat: consolidate ticket domain baseline
This commit is contained in:
@@ -3,7 +3,14 @@ from datetime import timedelta
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.tickets.models import Ticket, TicketCategory, TicketEvent
|
||||
from apps.solutions.models import TicketResolution
|
||||
from apps.tickets.models import (
|
||||
Ticket,
|
||||
TicketCategory,
|
||||
TicketCollaborator,
|
||||
TicketComment,
|
||||
TicketEvent,
|
||||
)
|
||||
|
||||
|
||||
def test_create_ticket_returns_ticket_detail(admin_client, db):
|
||||
@@ -205,8 +212,8 @@ def test_business_ticket_can_be_resolved_directly_with_resolution(admin_client,
|
||||
assert response.status_code == 200
|
||||
ticket.refresh_from_db()
|
||||
assert ticket.status == "resolved"
|
||||
assert ticket.resolution_summary == "已查询采集进度,当前已完成 80%。"
|
||||
assert ticket.is_resolved is True
|
||||
assert ticket.resolution.solution_text == "已查询采集进度,当前已完成 80%。"
|
||||
assert response.json()["is_resolved"] is True
|
||||
assert ticket.replied_to_customer is True
|
||||
|
||||
|
||||
@@ -238,20 +245,19 @@ def test_closing_resolved_ticket_keeps_resolved_flag(admin_client, db):
|
||||
title="已解决待关闭",
|
||||
description="A",
|
||||
status="resolved",
|
||||
is_resolved=True,
|
||||
resolution_summary="已完成处理",
|
||||
)
|
||||
TicketResolution.objects.create(ticket=ticket, solution_text="已完成处理")
|
||||
|
||||
response = admin_client.post(
|
||||
f"/api/tickets/{ticket.id}/status",
|
||||
data={"status": "closed", "remark": "已回复", "is_resolved": False},
|
||||
data={"status": "closed", "remark": "已回复"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
ticket.refresh_from_db()
|
||||
assert ticket.status == "closed"
|
||||
assert ticket.is_resolved is True
|
||||
assert response.json()["is_resolved"] is True
|
||||
|
||||
|
||||
def test_get_ticket_events_returns_real_timeline_with_operator(admin_client, db):
|
||||
@@ -287,3 +293,88 @@ def test_get_ticket_events_returns_real_timeline_with_operator(admin_client, db)
|
||||
assert payload[1]["to_value"] == {"status": "in_progress"}
|
||||
assert payload[1]["remark"] == "开始排查认证链路"
|
||||
assert payload[1]["operator"]["display_name"] == "admin"
|
||||
|
||||
|
||||
def test_ticket_comments_return_history_author_and_validate_visibility(admin_client, db):
|
||||
ticket = Ticket.objects.create(
|
||||
ticket_no="TK202607270301",
|
||||
title="评论历史",
|
||||
description="需要协同排查",
|
||||
)
|
||||
|
||||
created = admin_client.post(
|
||||
f"/api/tickets/{ticket.id}/comments",
|
||||
data={
|
||||
"content": " 已检查应用日志,等待数据库同事反馈。 ",
|
||||
"comment_type": "internal_note",
|
||||
"visibility": "internal",
|
||||
},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert created.status_code == 200
|
||||
assert created.json()["content"] == "已检查应用日志,等待数据库同事反馈。"
|
||||
assert created.json()["created_by"]["username"] == "admin"
|
||||
history = admin_client.get(f"/api/tickets/{ticket.id}/comments")
|
||||
assert history.status_code == 200
|
||||
assert history.json()[0]["created_by"]["display_name"] == "admin"
|
||||
assert TicketEvent.objects.filter(ticket=ticket, event_type="commented").count() == 1
|
||||
|
||||
mismatched = admin_client.post(
|
||||
f"/api/tickets/{ticket.id}/comments",
|
||||
data={
|
||||
"content": "客户可见内容",
|
||||
"comment_type": "user_reply",
|
||||
"visibility": "internal",
|
||||
},
|
||||
content_type="application/json",
|
||||
)
|
||||
assert mismatched.status_code == 400
|
||||
assert TicketComment.objects.filter(ticket=ticket).count() == 1
|
||||
|
||||
|
||||
def test_ticket_collaboration_lists_active_users_and_is_idempotent(admin_client, db):
|
||||
user_model = get_user_model()
|
||||
active_user = user_model.objects.create_user(
|
||||
username="collaborator",
|
||||
first_name="协作成员",
|
||||
is_active=True,
|
||||
)
|
||||
user_model.objects.create_user(username="disabled-collaborator", is_active=False)
|
||||
ticket = Ticket.objects.create(
|
||||
ticket_no="TK202607270302",
|
||||
title="协作管理",
|
||||
description="需要多人处理",
|
||||
)
|
||||
|
||||
participants = admin_client.get("/api/tickets/participants")
|
||||
assert participants.status_code == 200
|
||||
usernames = {item["username"] for item in participants.json()}
|
||||
assert "collaborator" in usernames
|
||||
assert "disabled-collaborator" not in usernames
|
||||
|
||||
payload = {"user_id": active_user.id, "role": "collaborator"}
|
||||
first = admin_client.post(
|
||||
f"/api/tickets/{ticket.id}/collaborators",
|
||||
data=payload,
|
||||
content_type="application/json",
|
||||
)
|
||||
duplicate = admin_client.post(
|
||||
f"/api/tickets/{ticket.id}/collaborators",
|
||||
data=payload,
|
||||
content_type="application/json",
|
||||
)
|
||||
assert first.status_code == duplicate.status_code == 200
|
||||
assert first.json()["id"] == duplicate.json()["id"]
|
||||
assert TicketCollaborator.objects.filter(ticket=ticket).count() == 1
|
||||
assert TicketEvent.objects.filter(ticket=ticket, event_type="collaborator_added").count() == 1
|
||||
|
||||
listed = admin_client.get(f"/api/tickets/{ticket.id}/collaborators")
|
||||
assert listed.status_code == 200
|
||||
assert listed.json()[0]["user"]["display_name"] == "协作成员"
|
||||
|
||||
removed = admin_client.delete(
|
||||
f"/api/tickets/{ticket.id}/collaborators/{first.json()['id']}"
|
||||
)
|
||||
assert removed.status_code == 200
|
||||
assert TicketCollaborator.objects.filter(ticket=ticket).count() == 0
|
||||
|
||||
Reference in New Issue
Block a user