withoutMiddleware(EnsurePlatformSession::class); $this->owner = User::create([ 'public_id' => 'queue-transfer-owner-001', 'name' => 'Owner', 'email' => 'transfer-owner@example.com', 'password' => bcrypt('password'), ]); $this->organization = app(OrganizationResolver::class)->completeOnboarding($this->owner, [ 'organization_name' => 'Transfer Org', 'industry' => 'banking', 'appointment_mode' => 'hybrid', 'branch_name' => 'Main', 'timezone' => 'UTC', ]); $this->branch = Branch::query()->where('organization_id', $this->organization->id)->firstOrFail(); $this->queue = ServiceQueue::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'name' => 'Consultation', 'prefix' => 'A', 'strategy' => 'fifo', 'is_active' => true, ]); $this->lab = ServiceQueue::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'name' => 'Lab', 'prefix' => 'L', 'strategy' => 'fifo', 'is_active' => true, ]); $this->counter = Counter::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'name' => 'Desk 1', 'status' => 'available', 'is_active' => true, ]); $this->counter->serviceQueues()->attach($this->queue->id); $engine = app(QueueEngine::class); $this->ticket = $engine->issueTicket($this->queue, $this->owner->public_id, ['source' => 'staff']); $engine->callTicket($this->ticket, $this->counter, $this->owner->public_id); $engine->startServing($this->ticket->fresh(), $this->owner->public_id); $this->ticket = $this->ticket->fresh(); } public function test_free_console_shows_transfer_as_pro_feature(): void { $this->actingAs($this->owner) ->get(route('qms.console.show', $this->counter)) ->assertOk() ->assertSee('Hand off to another queue') ->assertSee('Pro') ->assertSee('Upgrade to Pro') ->assertDontSee('name="action" value="transfer"', false); } public function test_free_plan_cannot_transfer_via_console(): void { $this->actingAs($this->owner) ->post(route('qms.console.action', $this->counter), [ 'action' => 'transfer', 'ticket_id' => $this->ticket->id, 'to_queue_id' => $this->lab->id, 'reason' => 'Lab tests', ]) ->assertRedirect(route('qms.pro.index')) ->assertSessionHas('error'); $this->assertSame($this->queue->id, $this->ticket->fresh()->service_queue_id); } public function test_pro_plan_can_transfer_via_console(): void { $this->organization->update([ 'settings' => array_merge($this->organization->settings ?? [], [ 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), 'pro_billed_branches' => 1, ]), ]); $this->actingAs($this->owner) ->post(route('qms.console.action', $this->counter), [ 'action' => 'transfer', 'ticket_id' => $this->ticket->id, 'to_queue_id' => $this->lab->id, 'reason' => 'Lab tests', ]) ->assertRedirect() ->assertSessionHas('success'); $this->assertSame($this->lab->id, $this->ticket->fresh()->service_queue_id); $this->assertSame('waiting', $this->ticket->fresh()->status); } public function test_pro_console_shows_handoff_form(): void { $this->organization->update([ 'settings' => array_merge($this->organization->settings ?? [], [ 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), 'pro_billed_branches' => 1, ]), ]); $this->actingAs($this->owner) ->get(route('qms.console.show', $this->counter)) ->assertOk() ->assertSee('Hand off') ->assertSee('Lab') ->assertDontSee('Upgrade to Pro →'); } }