seed(DatabaseSeeder::class); }); test('anyone can search tickets by ticket id', function (): void { $user = User::factory()->create(); $user->assignRole('user'); $this->actingAs($user); $service = app(TicketService::class); // Create Ticket 1 $dto1 = new CreateTicketRequest( userId: $user->id, connectedAppId: null, issueCategory: 'Technical Issue', description: 'First test ticket.', notifiedRoleIds: [], notifiedUserIds: [], attachment: null, ); $ticket1Data = $service->create($dto1); // Create Ticket 2 $dto2 = new CreateTicketRequest( userId: $user->id, connectedAppId: null, issueCategory: 'Billing Query', description: 'Second test ticket.', notifiedRoleIds: [], notifiedUserIds: [], attachment: null, ); $ticket2Data = $service->create($dto2); // Search by Ticket 1 code/ID using Livewire component Livewire::test('pages::tickets.index') ->set('search', $ticket1Data->ticketId) ->assertSee($ticket1Data->ticketId) ->assertDontSee($ticket2Data->ticketId); // Search by Ticket 2 code/ID Livewire::test('pages::tickets.index') ->set('search', $ticket2Data->ticketId) ->assertSee($ticket2Data->ticketId) ->assertDontSee($ticket1Data->ticketId); }); test('tickets table is paginated to 10 items per page', function (): void { $user = User::factory()->create(); $user->assignRole('user'); $this->actingAs($user); $service = app(TicketService::class); // Create 12 tickets $createdTicketIds = []; for ($i = 1; $i <= 12; $i++) { $dto = new CreateTicketRequest( userId: $user->id, connectedAppId: null, issueCategory: 'Technical Issue', description: "Ticket number {$i}.", notifiedRoleIds: [], notifiedUserIds: [], attachment: null, ); $ticketData = $service->create($dto); Ticket::where('id', $ticketData->id)->update([ 'created_at' => now()->addSeconds($i), ]); $createdTicketIds[] = $ticketData->ticketId; } $component = Livewire::test('pages::tickets.index'); // On page 1, we should see the latest 10 tickets (since we order by latest, the last 10 created) $page1Tickets = array_slice(array_reverse($createdTicketIds), 0, 10); $page2Tickets = array_slice(array_reverse($createdTicketIds), 10, 2); foreach ($page1Tickets as $id) { $component->assertSee($id); } foreach ($page2Tickets as $id) { $component->assertDontSee($id); } // Go to page 2 $component->call('gotoPage', 2); foreach ($page1Tickets as $id) { $component->assertDontSee($id); } foreach ($page2Tickets as $id) { $component->assertSee($id); } }); test('status filtering works on paginated data at query level', function (): void { $user = User::factory()->create(); $user->assignRole('user'); $this->actingAs($user); $service = app(TicketService::class); $admin = User::where('email', 'admin@example.com')->firstOrFail(); // Create Ticket 1 (Open status by default) $dto1 = new CreateTicketRequest( userId: $user->id, connectedAppId: null, issueCategory: 'Technical Issue', description: 'Open ticket.', notifiedRoleIds: [], notifiedUserIds: [], attachment: null, ); $ticket1Data = $service->create($dto1); // Create Ticket 2 and change its status to Hold $dto2 = new CreateTicketRequest( userId: $user->id, connectedAppId: null, issueCategory: 'Billing Query', description: 'Hold ticket.', notifiedRoleIds: [], notifiedUserIds: [], attachment: null, ); $ticket2Data = $service->create($dto2); // Act as admin to change status $this->actingAs($admin); $service->updateStatus($ticket2Data->id, TicketStatusEnum::Hold->value); // Act as user to view $this->actingAs($user); // Filter by Open Livewire::test('pages::tickets.index') ->set('statusFilter', TicketStatusEnum::Open->value) ->assertSee($ticket1Data->ticketId) ->assertDontSee($ticket2Data->ticketId); // Filter by Hold Livewire::test('pages::tickets.index') ->set('statusFilter', TicketStatusEnum::Hold->value) ->assertSee($ticket2Data->ticketId) ->assertDontSee($ticket1Data->ticketId); }); test('normal user can see status filter and see custom empty state message when no results match search', function (): void { $user = User::factory()->create(); $user->assignRole('user'); $this->actingAs($user); // Initial load: Should see default empty state message Livewire::test('pages::tickets.index') ->assertSee('No Support Tickets Found') ->assertDontSee('No Matching Tickets Found') ->assertSee('You have not raised any support tickets yet.'); // Search for non-existent ticket ID: Should see the custom empty search state message Livewire::test('pages::tickets.index') ->set('search', 'TKT-NONEXISTENT-99') ->assertSee('No Matching Tickets Found') ->assertDontSee('No Support Tickets Found') ->assertSee('matching your search query or filter criteria'); // Filter by Hold status: Should see the custom empty filter state message Livewire::test('pages::tickets.index') ->set('statusFilter', 'hold') ->assertSee('No Matching Tickets Found') ->assertDontSee('No Support Tickets Found') ->assertSee('matching your search query or filter criteria'); });