withoutMiddleware(EnsurePlatformSession::class); $this->owner = User::create([ 'public_id' => 'queue-devices-owner', 'name' => 'Owner', 'email' => 'queue-devices@example.com', ]); $this->organization = Organization::create([ 'owner_ref' => $this->owner->public_id, 'name' => 'Queue Devices Clinic', 'slug' => 'queue-devices-clinic', 'settings' => [ 'onboarded' => true, 'facility_type' => 'clinic', 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), 'queue_integration_enabled' => true, ], ]); Member::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'user_ref' => $this->owner->public_id, 'role' => 'hospital_admin', ]); $this->branch = Branch::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'name' => 'Main', 'is_active' => true, ]); $this->queue = CareServiceQueue::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'context' => 'consultation', 'name' => 'Reception', 'prefix' => 'A', 'routing_mode' => 'shared_pool', 'is_active' => true, ]); } public function test_can_register_kiosk_and_issue_ticket(): void { $this->actingAs($this->owner) ->post(route('care.devices.store'), [ 'name' => 'Lobby Kiosk', 'type' => 'kiosk', 'branch_id' => $this->branch->id, 'queue_ids' => [$this->queue->id], 'reset_seconds' => 20, ]) ->assertRedirect(); $device = Device::query()->where('type', 'kiosk')->first(); $this->assertNotNull($device); $token = app(DeviceService::class)->publicAccessToken($device); $this->assertNotEmpty($token); $this->get(route('care.kiosk.device', $token)) ->assertOk() ->assertSee('Welcome to Queue Devices Clinic', false) ->assertSee('Tap to begin', false); $this->postJson(route('care.kiosk.device.issue', $token), [ 'queue_id' => $this->queue->id, 'customer_name' => 'Ama', ]) ->assertOk() ->assertJsonPath('data.source', 'kiosk') ->assertJsonPath('data.queue.name', 'Reception'); $this->assertDatabaseHas('care_queue_tickets', [ 'service_queue_id' => $this->queue->id, 'source' => 'kiosk', 'customer_name' => 'Ama', 'status' => CareQueueTicket::STATUS_WAITING, ]); } public function test_kiosk_rejects_unassigned_queue(): void { $other = CareServiceQueue::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'context' => 'billing', 'name' => 'Billing', 'prefix' => 'B', 'routing_mode' => 'shared_pool', 'is_active' => true, ]); $device = Device::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'name' => 'Lobby Kiosk', 'type' => 'kiosk', 'connection_mode' => Device::MODE_MANUAL, 'status' => Device::STATUS_OFFLINE, 'metadata' => ['service_queue_ids' => [$this->queue->id]], ]); $token = app(DeviceService::class)->issueToken($device); $this->postJson(route('care.kiosk.device.issue', $token), [ 'queue_id' => $other->id, ])->assertForbidden(); } public function test_can_register_display_device_with_waiting_screen(): void { $this->actingAs($this->owner) ->post(route('care.devices.store'), [ 'name' => 'Waiting Room TV', 'type' => 'display', 'branch_id' => $this->branch->id, 'queue_ids' => [$this->queue->id], 'layout' => 'standard', ]) ->assertRedirect(); $device = Device::query()->where('type', 'display')->first(); $this->assertNotNull($device); $this->assertNotEmpty($device->metadata['display_screen_id'] ?? null); $screen = CareDisplayScreen::query()->find($device->metadata['display_screen_id']); $this->assertNotNull($screen); $this->assertSame('Waiting Room TV', $screen->name); $this->assertContains($this->queue->id, $screen->service_queue_ids); $this->get(route('care.display.public', $screen->access_token))->assertOk(); } }