Deploy Ladill Care / deploy (push) Failing after 57s
Call-next and recall queue announcements for lobby screens without Ladill Queue. Co-authored-by: Cursor <cursoragent@cursor.com>
233 lines
8.1 KiB
PHP
233 lines
8.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Http\Middleware\EnsurePlatformSession;
|
|
use App\Models\Branch;
|
|
use App\Models\CareDisplayScreen;
|
|
use App\Models\CareQueueTicket;
|
|
use App\Models\CareServicePoint;
|
|
use App\Models\CareServiceQueue;
|
|
use App\Models\CareVoiceAnnouncement;
|
|
use App\Models\Member;
|
|
use App\Models\Organization;
|
|
use App\Models\User;
|
|
use App\Services\Care\CareQueueEngine;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class CareDisplayVoiceTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected User $owner;
|
|
|
|
protected Organization $organization;
|
|
|
|
protected Branch $branch;
|
|
|
|
protected CareServiceQueue $queue;
|
|
|
|
protected CareServicePoint $point;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->withoutMiddleware(EnsurePlatformSession::class);
|
|
|
|
$this->owner = User::create([
|
|
'public_id' => 'display-voice-owner',
|
|
'name' => 'Owner',
|
|
'email' => 'display-voice@example.com',
|
|
]);
|
|
|
|
$this->organization = Organization::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'name' => 'Display Voice Clinic',
|
|
'slug' => 'display-voice-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,
|
|
]);
|
|
|
|
$this->point = CareServicePoint::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'service_queue_id' => $this->queue->id,
|
|
'name' => 'Counter 1',
|
|
'is_active' => true,
|
|
]);
|
|
}
|
|
|
|
public function test_display_data_includes_pending_announcement_after_call(): void
|
|
{
|
|
$screen = CareDisplayScreen::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'name' => 'Lobby',
|
|
'layout' => 'standard',
|
|
'service_queue_ids' => [$this->queue->id],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$engine = app(CareQueueEngine::class);
|
|
$engine->issueTicket($this->organization, [
|
|
'service_queue_id' => $this->queue->uuid,
|
|
]);
|
|
$engine->callNext($this->organization, $this->queue->uuid, $this->point->uuid);
|
|
|
|
$response = $this->getJson(route('care.display.data', $screen->access_token));
|
|
|
|
$response->assertOk()
|
|
->assertJsonPath('announcements.0.message', 'Ticket A001, please proceed to Counter 1.')
|
|
->assertJsonPath('waiting_count', 0)
|
|
->assertJsonPath('now_serving.0.ticket_number', 'A001')
|
|
->assertJsonPath('now_serving.0.queue_name', 'Reception')
|
|
->assertJsonPath('now_serving.0.counter', 'Counter 1');
|
|
|
|
$this->get(route('care.display.public', $screen->access_token))
|
|
->assertOk()
|
|
->assertSee('Please proceed to')
|
|
->assertSee('A001')
|
|
->assertSee('Reception')
|
|
->assertSee('Counter 1');
|
|
}
|
|
|
|
public function test_display_shows_only_latest_ticket_per_service_point(): void
|
|
{
|
|
$room12 = CareServicePoint::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'service_queue_id' => $this->queue->id,
|
|
'name' => 'Room 12',
|
|
'is_active' => true,
|
|
]);
|
|
$room14 = CareServicePoint::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'service_queue_id' => $this->queue->id,
|
|
'name' => 'Room 14',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$screen = CareDisplayScreen::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'name' => 'Busy Lobby',
|
|
'layout' => 'standard',
|
|
'service_queue_ids' => [$this->queue->id],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
foreach ([
|
|
['A001', $room12->id, 6],
|
|
['A002', $room12->id, 5],
|
|
['A003', $room12->id, 2],
|
|
['A004', $room14->id, 4],
|
|
['A005', $room14->id, 1],
|
|
] as [$number, $pointId, $minutesAgo]) {
|
|
CareQueueTicket::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'service_queue_id' => $this->queue->id,
|
|
'service_point_id' => $pointId,
|
|
'ticket_number' => $number,
|
|
'status' => CareQueueTicket::STATUS_CALLED,
|
|
'called_at' => now()->subMinutes($minutesAgo),
|
|
]);
|
|
}
|
|
|
|
$payload = $this->getJson(route('care.display.data', $screen->access_token))
|
|
->assertOk()
|
|
->assertJsonCount(2, 'now_serving')
|
|
->json('now_serving');
|
|
|
|
$byCounter = collect($payload)->keyBy('counter');
|
|
$this->assertSame('A003', $byCounter['Room 12']['ticket_number']);
|
|
$this->assertSame('A005', $byCounter['Room 14']['ticket_number']);
|
|
$this->assertSame(['Room 12', 'Room 14'], collect($payload)->pluck('counter')->all());
|
|
}
|
|
|
|
public function test_display_falls_back_to_branch_queues_when_none_assigned(): void
|
|
{
|
|
$screen = CareDisplayScreen::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'name' => 'Lobby',
|
|
'layout' => 'standard',
|
|
'service_queue_ids' => [],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
app(CareQueueEngine::class)->issueTicket($this->organization, [
|
|
'service_queue_id' => $this->queue->uuid,
|
|
]);
|
|
|
|
$this->getJson(route('care.display.data', $screen->access_token))
|
|
->assertOk()
|
|
->assertJsonPath('waiting_count', 1)
|
|
->assertJsonPath('queues.0.name', 'Reception');
|
|
}
|
|
|
|
public function test_display_marks_announcement_played(): void
|
|
{
|
|
$screen = CareDisplayScreen::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'name' => 'Lobby',
|
|
'layout' => 'standard',
|
|
'service_queue_ids' => [$this->queue->id],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$announcement = CareVoiceAnnouncement::create([
|
|
'owner_ref' => $this->owner->public_id,
|
|
'organization_id' => $this->organization->id,
|
|
'branch_id' => $this->branch->id,
|
|
'locale' => 'en',
|
|
'message' => 'Ticket A001, please proceed to Counter 1.',
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
$this->postJson(route('care.display.announcement.played', [
|
|
'token' => $screen->access_token,
|
|
'announcement' => $announcement->id,
|
|
]))->assertOk();
|
|
|
|
$this->assertSame('played', $announcement->fresh()->status);
|
|
}
|
|
}
|