Files
WMS/Modules/Helpdesk/Tests/Feature/TicketCrudTest.php
T
2026-06-23 13:39:02 +01:00

143 lines
5.7 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\Helpdesk\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Modules\Helpdesk\Livewire\TicketCreate;
use Modules\Helpdesk\Livewire\TicketIndex;
use Modules\Helpdesk\Models\Ticket;
use Modules\Helpdesk\Tests\Concerns\BuildsHelpdeskFixtures;
use Tests\TestCase;
final class TicketCrudTest extends TestCase
{
use BuildsHelpdeskFixtures;
use RefreshDatabase;
public function test_user_can_create_ticket_with_priority_category_team_and_project(): void
{
$fixtures = $this->seedLookupData();
$user = $this->user(['name' => 'Mark Requester']);
Livewire::actingAs($user)
->test(TicketCreate::class)
->set('subject', 'Warehouse printer does not print labels')
->set('body', '<p>The printer fails every time a dispatch label is generated.</p>')
->set('priority_id', $fixtures['high']->id)
->set('category_id', $fixtures['category']->id)
->set('team_id', $fixtures['team']->id)
->set('project_id', $fixtures['project']->id)
->call('save')
->assertHasNoErrors()
->assertRedirect();
$this->assertDatabaseHas('helpdesk_tickets', [
'user_id' => $user->id,
'subject' => 'Warehouse printer does not print labels',
'priority_id' => $fixtures['high']->id,
'category_id' => $fixtures['category']->id,
'team_id' => $fixtures['team']->id,
'project_id' => $fixtures['project']->id,
]);
}
public function test_ticket_create_does_not_validate_before_submit(): void
{
$this->seedLookupData();
$user = $this->user();
Livewire::actingAs($user)
->test(TicketCreate::class)
->set('subject', 'Draft ticket title only')
->assertHasNoErrors();
}
public function test_ticket_create_validates_required_fields(): void
{
$this->seedLookupData();
$user = $this->user();
Livewire::actingAs($user)
->test(TicketCreate::class)
->call('save')
->assertHasErrors(['subject' => 'required', 'body' => 'required', 'priority_id' => 'required']);
}
public function test_ticket_index_shows_only_visible_tickets_for_standard_user(): void
{
$fixtures = $this->seedLookupData();
$owner = $this->user(['name' => 'Owner User']);
$other = $this->user(['name' => 'Other User']);
$visible = $this->ticket(['owner' => $owner, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id, 'subject' => 'Visible ticket']);
$this->ticket(['owner' => $other, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id, 'subject' => 'Hidden ticket']);
Livewire::actingAs($owner)
->test(TicketIndex::class)
->assertSee($visible->reference)
->assertSee('Visible ticket')
->assertDontSee('Hidden ticket');
}
public function test_agent_sees_assigned_ticket_and_admin_sees_all_tickets(): void
{
$fixtures = $this->seedLookupData();
$agent = $this->agent(['name' => 'Assigned Agent']);
$admin = $this->admin(['name' => 'Admin User']);
$owner = $this->user();
$assigned = $this->ticket(['owner' => $owner, 'agent' => $agent, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id, 'subject' => 'Assigned ticket']);
$unassigned = $this->ticket(['owner' => $this->user(), 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id, 'subject' => 'Another ticket']);
Livewire::actingAs($agent)
->test(TicketIndex::class)
->assertSee($assigned->reference)
->assertDontSee($unassigned->reference);
Livewire::actingAs($admin)
->test(TicketIndex::class)
->assertSee($assigned->reference)
->assertSee($unassigned->reference);
}
public function test_index_filters_by_search_priority_and_closed_scope(): void
{
$fixtures = $this->seedLookupData();
$admin = $this->admin();
$openTicket = $this->ticket(['owner' => $admin, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['high']->id, 'subject' => 'API sync failure']);
$closedTicket = $this->ticket(['owner' => $admin, 'status_id' => $fixtures['closed']->id, 'priority_id' => $fixtures['normal']->id, 'completed_at' => now(), 'subject' => 'Old closed issue']);
Livewire::actingAs($admin)
->test(TicketIndex::class)
->set('search', 'API sync')
->set('priority', (string) $fixtures['high']->id)
->assertSee($openTicket->reference)
->assertDontSee($closedTicket->reference);
Livewire::actingAs($admin)
->test(TicketIndex::class)
->set('scope', 'closed')
->assertSee($closedTicket->reference)
->assertDontSee($openTicket->reference);
}
public function test_created_ticket_has_a_reference_and_last_activity_date(): void
{
$fixtures = $this->seedLookupData();
$user = $this->user();
Livewire::actingAs($user)
->test(TicketCreate::class)
->set('subject', 'Reference check')
->set('body', 'This ticket should have a generated reference.')
->set('priority_id', $fixtures['normal']->id)
->call('save');
$ticket = Ticket::query()->where('subject', 'Reference check')->firstOrFail();
self::assertStringStartsWith('HD-' . now()->format('Y') . '-', $ticket->reference);
self::assertNotNull($ticket->last_activity_at);
}
}