Expand Bird Voice Webhook tests to cover scenarios with shared gates and distinct entrance/exit gates, refine payload validation, and enhance gate resolution logic.
This commit is contained in:
@@ -122,6 +122,17 @@ final class BirdVoiceWebhookLifecycleRouteTestDouble extends \routes\birdVoiceWe
|
||||
return $this->gatesByDepartmentAndType[$departmentId . ':' . $gateType] ?? null;
|
||||
}
|
||||
|
||||
protected function resolvePhoneCallGateById(int $gateId): ?department_gates_o
|
||||
{
|
||||
foreach ($this->gatesByDepartmentAndType as $gate) {
|
||||
if ((int)$gate->id === $gateId) {
|
||||
return $gate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function shouldAcceptInboundCall(bird $client): bool
|
||||
{
|
||||
return true;
|
||||
@@ -321,7 +332,7 @@ it('accepts legacy initial webhook payloads with top-level call identifiers', fu
|
||||
expect($state['wait_timeout'] ?? null)->toBe('PT10M');
|
||||
});
|
||||
|
||||
it('returns a flow-data gather payload after department selection in native flow mode', function (): void {
|
||||
it('returns a flow-data gather payload after department selection in native flow mode when distinct gate choices exist', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
|
||||
$route->runLifecycle(bird_webhook_legacy_initial_payload());
|
||||
@@ -342,6 +353,39 @@ it('returns a flow-data gather payload after department selection in native flow
|
||||
expect($state['selected_department_id'] ?? null)->toBe(11);
|
||||
});
|
||||
|
||||
it('opens the gate immediately after department selection when entrance and exit resolve to the same gate in native flow mode', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
$route->eligibleDepartments = [
|
||||
[
|
||||
'department_id' => 44,
|
||||
'department_name' => 'Shared',
|
||||
'order_priority' => 1,
|
||||
'has_entrance_gate' => true,
|
||||
'has_exit_gate' => true,
|
||||
],
|
||||
];
|
||||
$sharedGate = new BirdVoiceWebhookLifecycleGateFake(4401);
|
||||
$route->gatesByDepartmentAndType = [
|
||||
'44:entrance' => $sharedGate,
|
||||
'44:exit' => $sharedGate,
|
||||
];
|
||||
|
||||
$route->runLifecycle(bird_webhook_legacy_initial_payload());
|
||||
$result = $route->runLifecycle(bird_webhook_flow_selection_payload('1'));
|
||||
|
||||
expect($result['statusCode'])->toBe(200);
|
||||
expect($result['status'] ?? null)->toBe('completed');
|
||||
expect($result['completed'] ?? null)->toBeTrue();
|
||||
expect($result['action'] ?? null)->toBe('gate_opened');
|
||||
expect($result['gateOpened'] ?? null)->toBeTrue();
|
||||
expect($result['departmentId'] ?? null)->toBe(44);
|
||||
expect($result['departmentName'] ?? null)->toBe('Shared');
|
||||
expect($result['gateType'] ?? null)->toBeNull();
|
||||
expect($result['gateId'] ?? null)->toBe(4401);
|
||||
expect($route->openedGates)->toBe([4401]);
|
||||
expect($route->loadState('call_1'))->toBeNull();
|
||||
});
|
||||
|
||||
it('returns a flow-data completion payload after gate confirmation in native flow mode', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
|
||||
@@ -362,7 +406,7 @@ it('returns a flow-data completion payload after gate confirmation in native flo
|
||||
expect($route->loadState('call_1'))->toBeNull();
|
||||
});
|
||||
|
||||
it('returns a second-stage raw 202 gather response after department selection', function (): void {
|
||||
it('returns a second-stage raw 202 gather response after department selection when distinct gate choices exist', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
|
||||
$route->runLifecycle(bird_webhook_initial_payload());
|
||||
@@ -381,6 +425,36 @@ it('returns a second-stage raw 202 gather response after department selection',
|
||||
expect($route->openedGates)->toBe([]);
|
||||
});
|
||||
|
||||
it('opens the shared gate immediately after department selection in raw command mode', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
$route->eligibleDepartments = [
|
||||
[
|
||||
'department_id' => 44,
|
||||
'department_name' => 'Shared',
|
||||
'order_priority' => 1,
|
||||
'has_entrance_gate' => true,
|
||||
'has_exit_gate' => true,
|
||||
],
|
||||
];
|
||||
$sharedGate = new BirdVoiceWebhookLifecycleGateFake(4401);
|
||||
$route->gatesByDepartmentAndType = [
|
||||
'44:entrance' => $sharedGate,
|
||||
'44:exit' => $sharedGate,
|
||||
];
|
||||
|
||||
$route->runLifecycle(bird_webhook_initial_payload());
|
||||
$result = $route->runLifecycle(bird_webhook_resumed_payload('1'));
|
||||
|
||||
expect($result['statusCode'])->toBe(200);
|
||||
expect($result['result']['action'] ?? null)->toBe('gate_opened');
|
||||
expect($result['result']['gateOpened'] ?? null)->toBeTrue();
|
||||
expect($result['result']['departmentId'] ?? null)->toBe(44);
|
||||
expect($result['result']['gateType'] ?? null)->toBeNull();
|
||||
expect($result['result']['gateId'] ?? null)->toBe(4401);
|
||||
expect($route->openedGates)->toBe([4401]);
|
||||
expect($route->loadState('call_1'))->toBeNull();
|
||||
});
|
||||
|
||||
it('opens the selected gate and clears redis state on final selection', function (): void {
|
||||
$route = new BirdVoiceWebhookLifecycleRouteTestDouble();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user