seedLookupData(); $owner = $this->user(); $ticket = $this->ticket(['owner' => $owner, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); Livewire::actingAs($owner) ->test(TicketShow::class, ['ticket' => $ticket]) ->set('commentBody', '

Please can you check this update?

') ->call('addComment') ->assertHasNoErrors() ->assertDispatched('helpdesk-comment-added'); $this->assertDatabaseHas('helpdesk_comments', [ 'ticket_id' => $ticket->id, 'parent_id' => null, 'user_id' => $owner->id, 'is_internal' => false, ]); } public function test_comment_can_have_a_nested_reply(): void { $fixtures = $this->seedLookupData(); $owner = $this->user(); $ticket = $this->ticket(['owner' => $owner, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); $comment = Comment::query()->create([ 'ticket_id' => $ticket->id, 'user_id' => $owner->id, 'body' => '

Parent response

', 'is_internal' => false, ]); Livewire::actingAs($owner) ->test(TicketShow::class, ['ticket' => $ticket]) ->call('startReply', $comment->id) ->set('replyBody', '

Nested reply body

') ->call('addReply') ->assertHasNoErrors() ->assertDispatched('helpdesk-reply-added'); $this->assertDatabaseHas('helpdesk_comments', [ 'ticket_id' => $ticket->id, 'parent_id' => $comment->id, 'body' => '

Nested reply body

', ]); } public function test_comment_post_endpoint_creates_lotus_identity_and_search_text(): void { $fixtures = $this->seedLookupData(); $owner = $this->user(); $ticket = $this->ticket(['owner' => $owner, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); $this->actingAs($owner) ->post(route('helpdesk.tickets.comments.store', $ticket), [ 'commentBody' => '

Searchable response

', ]) ->assertRedirect(route('helpdesk.tickets.show', $ticket)); $comment = Comment::query()->where('ticket_id', $ticket->id)->firstOrFail(); self::assertNotEmpty($comment->guid); self::assertNotEmpty($comment->unid); self::assertSame($comment->unid, $comment->root_unid); self::assertSame('Searchable response', $comment->body_text); self::assertSame(1, $comment->sync_sequence); } public function test_nested_reply_post_endpoint_preserves_lotus_parent_identity(): void { $fixtures = $this->seedLookupData(); $owner = $this->user(); $ticket = $this->ticket(['owner' => $owner, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); $parent = app(\Modules\Helpdesk\Services\TicketService::class)->comment($ticket, $owner, '

Parent response

'); $this->actingAs($owner) ->post(route('helpdesk.tickets.comments.store', $ticket), [ 'parent_id' => $parent->id, 'commentBody' => '

Child response

', ]) ->assertRedirect(route('helpdesk.tickets.show', $ticket)); $reply = Comment::query()->where('parent_id', $parent->id)->firstOrFail(); self::assertSame($parent->unid, $reply->parent_unid); self::assertSame($parent->root_unid, $reply->root_unid); } public function test_agent_can_update_status_to_closed_and_priority(): void { Mail::fake(); $fixtures = $this->seedLookupData(); $owner = $this->user(); $agent = $this->agent(); $ticket = $this->ticket(['owner' => $owner, 'agent' => $agent, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); Livewire::actingAs($agent) ->test(TicketShow::class, ['ticket' => $ticket]) ->set('status_id', $fixtures['closed']->id) ->call('updateStatus') ->assertHasNoErrors() ->assertDispatched('helpdesk-status-updated') ->set('priority_id', $fixtures['high']->id) ->call('updatePriority') ->assertHasNoErrors() ->assertDispatched('helpdesk-priority-updated'); $ticket->refresh(); self::assertNotNull($ticket->completed_at); self::assertSame($fixtures['closed']->id, $ticket->status_id); self::assertSame($fixtures['high']->id, $ticket->priority_id); } public function test_unassigned_agent_cannot_update_another_users_ticket(): void { $fixtures = $this->seedLookupData(); $owner = $this->user(); $agent = $this->agent(); $ticket = $this->ticket(['owner' => $owner, 'agent_id' => null, 'status_id' => $fixtures['open']->id, 'priority_id' => $fixtures['normal']->id]); Livewire::actingAs($agent) ->test(TicketShow::class, ['ticket' => $ticket]) ->assertForbidden(); } }