from django.urls import reverse from rest_framework.test import APITestCase, APIClient from rest_framework import status from django.contrib.auth import get_user_model from django.utils import timezone from helpdesk.models import Ticket UserModel = get_user_model() class TicketViewSetFunctionalTest(APITestCase): def setUp(self): # สร้าง Agent User self.agent = UserModel.objects.create_user( username="agent1", email="agent1@example.com", password="password123", is_staff=True ) # สร้าง Customer User self.customer = UserModel.objects.create_user( username="customer1", email="customer1@example.com", password="password123", is_staff=False ) # Client สำหรับ Agent self.client_agent = APIClient() self.client_agent.force_authenticate(user=self.agent) # Client สำหรับ Customer self.client_customer = APIClient() self.client_customer.force_authenticate(user=self.customer) # สร้าง Ticket ตัวอย่าง self.ticket = Ticket.objects.create( creator=self.customer, title="Functional Test Ticket", last_message_at=timezone.now() ) def test_ticket_list_authenticated(self): """GET /tickets/ ต้อง return 200 สำหรับผู้ใช้ล็อกอิน""" url = reverse('helpdesk-tickets-list') # ต้องตรงกับ router name response = self.client_agent.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(isinstance(response.data, list)) def test_ticket_list_unauthenticated(self): """GET /tickets/ ต้อง return 401 สำหรับผู้ใช้ไม่ล็อกอิน""" client = APIClient() # client ไม่ล็อกอิน url = reverse('helpdesk-tickets-list') response = client.get(url) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def test_resolve_ticket_by_agent(self): """POST /tickets/{id}/resolve/ ต้องเปลี่ยนสถานะ Ticket เป็น RESOLVED""" resolve_url = reverse('helpdesk-tickets-resolve', args=[self.ticket.id]) # ACT: Agent เรียก resolve response = self.client_agent.post(resolve_url) # ASSERT self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['status'], 'RESOLVED') # ตรวจสอบใน DB อีกครั้ง self.ticket.refresh_from_db() self.assertEqual(self.ticket.status, 'RESOLVED') def test_resolve_ticket_unauthenticated_fails(self): """POST /tickets/{id}/resolve/ ต้อง return 401 เมื่อไม่ล็อกอิน""" client = APIClient() resolve_url = reverse('helpdesk-tickets-resolve', args=[self.ticket.id]) response = client.post(resolve_url) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def test_assign_ticket_by_agent(self): """POST /tickets/{id}/assign/ ต้องมอบหมาย Ticket ให้ Agent ที่ระบุ""" # สร้าง Agent ที่สองเพื่อมอบหมายไปหา agent2 = UserModel.objects.create_user(username="agent2", email="agent2@example.com", password="p", is_staff=True) assign_url = reverse('helpdesk-tickets-assign', args=[self.ticket.id]) payload = {'assignee_id': agent2.id} # ACT: Agent1 เรียก assign response = self.client_agent.post(assign_url, payload, format='json') # ASSERT self.assertEqual(response.status_code, status.HTTP_200_OK) # ตรวจสอบว่า assigned_to ใน Response ตรงกับ ID ของ agent2 self.assertEqual(response.data['assigned_to']['id'], agent2.id) # ตรวจสอบใน DB อีกครั้ง self.ticket.refresh_from_db() self.assertEqual(self.ticket.assigned_to, agent2) def test_assign_ticket_to_non_existent_user_fails(self): """POST /tickets/{id}/assign/ ต้อง return 400 เมื่อมอบหมายให้ User ที่ไม่มีอยู่""" assign_url = reverse('helpdesk-tickets-assign', args=[self.ticket.id]) # ใช้ ID ที่ไม่มีอยู่จริง (สมมติว่า ID 999999 ไม่มี) payload = {'assignee_id': 999999} response = self.client_agent.post(assign_url, payload, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # ตรวจสอบว่าข้อความ Error สื่อถึงปัญหา (ขึ้นอยู่กับ logic ใน ViewSet/Service) self.assertIn('not found', response.data['detail'])