seed(AuthorizationSeeder::class); WebsiteType::query()->create(['codigo' => 'onticket', 'nombre' => 'OnTicket']); } public function test_authentication_is_required(): void { $this->getJson('/api/v1/adminapp/tenant/tickets')->assertUnauthorized(); } public function test_the_tenant_must_have_the_tickets_menu(): void { $tenant = $this->createTenant('fiesta_futbol_infantil'); Sanctum::actingAs($this->createAdminAppUser($tenant)); $this->getJson('/api/v1/adminapp/tenant/tickets')->assertNotFound(); } public function test_it_lists_only_tickets_from_the_authenticated_tenant(): void { $tenant = $this->createTenant('fiesta_futbol_infantil'); $otherTenant = $this->createTenant('other'); $admin = $this->createAdminAppUser($tenant); $otherUser = $this->createAdminAppUser($otherTenant); $this->grantTicketsMenu($tenant); Sanctum::actingAs($admin); $ticket = $this->createTicket($tenant, $admin); $this->createTicket($otherTenant, $otherUser); $this->getJson('/api/v1/adminapp/tenant/tickets') ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.id', $ticket->id) ->assertJsonPath('data.0.tenant_code', $tenant->codigo) ->assertJsonPath('meta.total', 1); } public function test_it_supports_id_and_uuid_search(): void { $tenant = $this->createTenant('fiesta_futbol_infantil'); $admin = $this->createAdminAppUser($tenant); $this->grantTicketsMenu($tenant); Sanctum::actingAs($admin); $matching = $this->createTicket($tenant, $admin); $this->createTicket($tenant, $admin); $this->getJson("/api/v1/adminapp/tenant/tickets?q={$matching->id}") ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.id', $matching->id); $this->getJson('/api/v1/adminapp/tenant/tickets?q='.substr($matching->ticket, 0, 8)) ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.ticket', $matching->ticket); } public function test_it_includes_tenant_scanned_and_total_ticket_counts(): void { $tenant = $this->createTenant('fiesta_futbol_infantil'); $otherTenant = $this->createTenant('other'); $admin = $this->createAdminAppUser($tenant); $otherUser = $this->createAdminAppUser($otherTenant); $this->grantTicketsMenu($tenant); Sanctum::actingAs($admin); $this->createTicket($tenant, $admin)->update(['used_at' => now()]); $this->createTicket($tenant, $admin); $this->createTicket($otherTenant, $otherUser)->update(['used_at' => now()]); $this->getJson('/api/v1/adminapp/tenant/tickets?q=does-not-match') ->assertOk() ->assertJsonCount(0, 'data') ->assertJsonPath('scanned_tickets', 1) ->assertJsonPath('total_tickets', 2); } private function createTenant(string $code): Tenant { $headerLogo = $this->createAttachment("{$code}-header.png"); $footerLogo = $this->createAttachment("{$code}-footer.png"); return Tenant::query()->create([ 'codigo' => $code, 'nombre' => ucfirst($code), 'dominio' => "{$code}.test", 'website_type_code' => 'onticket', 'primary_color' => '#111111', 'secondary_color' => '#222222', 'danger_color' => '#333333', 'success_color' => '#444444', 'header_bg_color' => '#ffffff', 'footer_bg_color' => '#ffffff', 'header_logo_id' => $headerLogo->id, 'footer_logo_id' => $footerLogo->id, ]); } private function createAttachment(string $filename): Attachment { return Attachment::query()->create([ 'path' => "test/{$filename}", 'filename' => $filename, 'type' => AttachmentType::Image, 'mime_type' => 'image/png', ]); } private function createAdminAppUser(Tenant $tenant): User { return User::factory()->create([ 'rol_codigo' => RoleCode::AdminApp->value, 'tenant_codigo' => $tenant->codigo, ]); } private function grantTicketsMenu(Tenant $tenant): void { $menu = Menu::query()->create([ 'code' => 'adminapp.tickets', 'label' => 'Tickets', 'route' => '/admin/tickets', ]); $tenant->menues()->attach($menu->code); } private function createTicket(Tenant $tenant, User $user): Ticket { return Ticket::query()->create([ 'tenant_code' => $tenant->codigo, 'ticket' => (string) Str::uuid(), 'user_id' => $user->id, ]); } }