From 531dbe52b9cf063e0090036ed74776cc73a05b89 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 8 Sep 2026 10:24:28 -0300 Subject: [PATCH] feat(scanner): expose scan result labels --- .../Resources/Scanner/ScanAttemptResource.php | 22 +++++++++++++++++++ .../Ticket/ScannerTicketControllerTest.php | 21 ++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/app/Domains/Ticket/Resources/Scanner/ScanAttemptResource.php b/app/Domains/Ticket/Resources/Scanner/ScanAttemptResource.php index 13cdffe..661f7e5 100644 --- a/app/Domains/Ticket/Resources/Scanner/ScanAttemptResource.php +++ b/app/Domains/Ticket/Resources/Scanner/ScanAttemptResource.php @@ -21,6 +21,28 @@ class ScanAttemptResource extends JsonResource 'attempted_at' => $this->created_at, 'resolved_at' => $this->resolved_at, 'result' => $this->result->value, + 'result_label' => match ($this->result) { + ScanAttemptResult::Processing => 'Procesando', + ScanAttemptResult::Accepted => 'Verificado', + ScanAttemptResult::InvalidQr => 'QR inválido', + ScanAttemptResult::TicketNotFound => 'Ticket inexistente', + ScanAttemptResult::CategoryForbidden => 'Categoría no permitida', + ScanAttemptResult::AlreadyScanned => 'Ya escaneado', + ScanAttemptResult::Expired => 'Vencido', + ScanAttemptResult::NotValid => 'No válido', + ScanAttemptResult::UnexpectedError => 'Error', + }, + 'result_detail_label' => match ($this->result) { + ScanAttemptResult::Processing => 'Error', + ScanAttemptResult::Accepted => 'Verificado', + ScanAttemptResult::InvalidQr => 'QR no pertenece al evento', + ScanAttemptResult::TicketNotFound => 'Error', + ScanAttemptResult::CategoryForbidden => 'Error', + ScanAttemptResult::AlreadyScanned => 'Usado', + ScanAttemptResult::Expired => 'Vencido', + ScanAttemptResult::NotValid => 'No válido', + ScanAttemptResult::UnexpectedError => 'Error', + }, 'can_view_ticket' => $this->ticket !== null && $this->result !== ScanAttemptResult::CategoryForbidden, ]; diff --git a/tests/Feature/Ticket/ScannerTicketControllerTest.php b/tests/Feature/Ticket/ScannerTicketControllerTest.php index 62e1ce2..dd2b014 100644 --- a/tests/Feature/Ticket/ScannerTicketControllerTest.php +++ b/tests/Feature/Ticket/ScannerTicketControllerTest.php @@ -91,6 +91,8 @@ class ScannerTicketControllerTest extends TestCase ->assertJsonPath('data.0.ticket', $newerTicket->ticket) ->assertJsonPath('data.0.resolved_at', $newer->resolved_at->toJSON()) ->assertJsonPath('data.0.result', ScanAttemptResult::Accepted->value) + ->assertJsonPath('data.0.result_label', 'Verificado') + ->assertJsonPath('data.0.result_detail_label', 'Verificado') ->assertJsonPath('data.0.can_view_ticket', true) ->assertJsonPath('data.1.id', $older->id) ->assertJsonPath('meta.current_page', 1) @@ -156,6 +158,8 @@ class ScannerTicketControllerTest extends TestCase ->assertJsonPath('data.scan_attempt.id', $scanAttempt->id) ->assertJsonPath('data.scan_attempt.ticket_id', $ticket->id) ->assertJsonPath('data.scan_attempt.result', ScanAttemptResult::Accepted->value) + ->assertJsonPath('data.scan_attempt.result_label', 'Verificado') + ->assertJsonPath('data.scan_attempt.result_detail_label', 'Verificado') ->assertJsonPath('data.ticket.id', $ticket->id) ->assertJsonPath('data.ticket.ticket', $ticket->ticket) ->assertJsonPath('data.ticket.client', $this->ticketOwner->nombre_apellido) @@ -186,10 +190,25 @@ class ScannerTicketControllerTest extends TestCase $this->getJson("/api/v1/scanner/attempts/{$scanAttempt->id}") ->assertOk() ->assertJsonPath('data.scan_attempt.id', $scanAttempt->id) + ->assertJsonPath('data.scan_attempt.result_label', 'Ticket inexistente') + ->assertJsonPath('data.scan_attempt.result_detail_label', 'Error') ->assertJsonPath('data.ticket', null) ->assertJsonPath('data.client', null); } + public function test_scan_attempt_detail_returns_specific_invalid_qr_label(): void + { + $scanAttempt = $this->createScanAttempt('not-a-valid-qr', [ + 'result' => ScanAttemptResult::InvalidQr, + ]); + Sanctum::actingAs($this->scanner); + + $this->getJson("/api/v1/scanner/attempts/{$scanAttempt->id}") + ->assertOk() + ->assertJsonPath('data.scan_attempt.result_label', 'QR inválido') + ->assertJsonPath('data.scan_attempt.result_detail_label', 'QR no pertenece al evento'); + } + public function test_scanner_can_read_an_authorized_ticket_detail_by_uuid(): void { $ticket = $this->createTicket('44444444-4444-4444-8444-444444444444'); @@ -247,6 +266,8 @@ class ScannerTicketControllerTest extends TestCase ->assertJsonPath('data.scan_attempt.ticket_id', $ticket->id) ->assertJsonPath('data.scan_attempt.ticket', $ticket->ticket) ->assertJsonPath('data.scan_attempt.result', ScanAttemptResult::Accepted->value) + ->assertJsonPath('data.scan_attempt.result_label', 'Verificado') + ->assertJsonPath('data.scan_attempt.result_detail_label', 'Verificado') ->assertJsonPath('data.ticket.ticket', $ticket->ticket) ->assertJsonPath('data.ticket.scanner_user_id', $this->scanner->id) ->assertJsonPath('data.ticket.is_valid', false)