from django.contrib.auth import get_user_model from apps.tickets.models import Ticket, TicketActorSource, TicketFieldEvidence from apps.tickets.services import update_ticket_fields def test_agent_update_does_not_overwrite_human_protected_field(db): user = get_user_model().objects.create_user(username="support-field-owner") ticket = Ticket.objects.create( ticket_no="TK202607250001", title="原始标题", description="A", ) ticket, _ = update_ticket_fields( ticket, {"title": "人工确认标题"}, user, source=TicketActorSource.HUMAN, ) ticket, skipped = update_ticket_fields( ticket, {"title": "Agent 建议标题"}, source=TicketActorSource.AGENT, agent_run_id=42, ) ticket.refresh_from_db() assert ticket.title == "人工确认标题" assert skipped == {"title": "protected_by_human"} latest = TicketFieldEvidence.objects.filter(ticket=ticket, field_name="title").first() assert latest.source == TicketActorSource.HUMAN assert latest.is_protected is True def test_agent_update_records_evidence_for_unprotected_field(db): ticket = Ticket.objects.create( ticket_no="TK202607250002", title="原始标题", description="A", ) ticket, skipped = update_ticket_fields( ticket, {"related_system": "CRM"}, source=TicketActorSource.AGENT, agent_run_id=99, confidence_by_field={"related_system": 0.93}, evidence_by_field={"related_system": {"quote": "CRM 接口返回 500"}}, ) assert skipped == {} evidence = TicketFieldEvidence.objects.get(ticket=ticket, field_name="related_system") assert evidence.value == "CRM" assert evidence.source == TicketActorSource.AGENT assert evidence.agent_run_id == 99 assert float(evidence.confidence) == 0.93 assert evidence.is_protected is False def test_archive_hides_ticket_from_default_list_and_restore_recovers_it(admin_client, db): ticket = Ticket.objects.create( ticket_no="TK202607250003", title="待归档", description="A", ) archived = admin_client.post(f"/api/tickets/{ticket.id}/archive") default_list = admin_client.get("/api/tickets") archived_list = admin_client.get("/api/tickets?include_archived=true") assert archived.status_code == 200 assert archived.json()["archived_at"] is not None assert default_list.json()["total"] == 0 assert archived_list.json()["total"] == 1 restored = admin_client.post(f"/api/tickets/{ticket.id}/restore") assert restored.status_code == 200 assert restored.json()["archived_at"] is None assert admin_client.get("/api/tickets").json()["total"] == 1 def test_ticket_collaborators_can_be_added_listed_and_removed(admin_client, db): collaborator = get_user_model().objects.create_user(username="ticket-collaborator") ticket = Ticket.objects.create( ticket_no="TK202607250004", title="需要协作", description="A", ) created = admin_client.post( f"/api/tickets/{ticket.id}/collaborators", data={"user_id": collaborator.id, "role": "watcher"}, content_type="application/json", ) assert created.status_code == 200 assert created.json()["user"]["username"] == "ticket-collaborator" assert created.json()["role"] == "watcher" listed = admin_client.get(f"/api/tickets/{ticket.id}/collaborators") assert [item["id"] for item in listed.json()] == [created.json()["id"]] removed = admin_client.delete( f"/api/tickets/{ticket.id}/collaborators/{created.json()['id']}" ) assert removed.status_code == 200 assert admin_client.get(f"/api/tickets/{ticket.id}/collaborators").json() == []