Add the Bird Control Plane gateway, signed webhook ingestion, policy-gated writes, fail-closed production auto-activation, and RSA-OAEP bootstrap credential flow.
72 lines
3.8 KiB
PHP
72 lines
3.8 KiB
PHP
<?php
|
|
|
|
it('exposes a disabled narrow Bird Control Plane read surface and signed ingestion endpoints', function (): void {
|
|
$content = file_get_contents(app_path('routes/birdControlPlaneRoute.php'));
|
|
|
|
expect($content)->not->toBeFalse()
|
|
->and($content)->toContain('/bird/health')
|
|
->and($content)->toContain('/bird/control-plane/v1/status')
|
|
->and($content)->toContain('/bird/control-plane/v1/channels')
|
|
->and($content)->toContain('/bird/control-plane/v1/events')
|
|
->and($content)->toContain('/bird/control-plane/v1/conversations')
|
|
->and($content)->toContain('/bird/control-plane/v1/messages')
|
|
->and($content)->toContain('/bird/control-plane/v1/calls')
|
|
->and($content)->toContain('/bird/control-plane/v1/recordings')
|
|
->and($content)->toContain('/bird/control-plane/v1/insights')
|
|
->and($content)->toContain('/bird/control-plane/v1/numbers')
|
|
->and($content)->toContain('/bird/webhooks/notifications')
|
|
->and($content)->toContain('/bird/flows/evaluate')
|
|
->and($content)->toContain('verifyBirdWebhookSignature')
|
|
->and($content)->toContain('timestampWithinReplayWindow')
|
|
->and($content)->toContain('verifyFlowSignature')
|
|
->and($content)->toContain('control_plane_enabled')
|
|
->and($content)->toContain('outbound_messages_enabled')
|
|
->and($content)->toContain('Explicit confirmation is required')
|
|
->and($content)->toContain('bird_schema_not_ready')
|
|
->and($content)->toContain("'reference' => \$reference, 'limit' => 100")
|
|
->and($content)->not->toContain('deleteNumber(')
|
|
->and($content)->not->toContain('openGate');
|
|
});
|
|
|
|
it('keeps schema mutation out of request stores', function (): void {
|
|
$schema = file_get_contents(
|
|
app_path('modules/bird/classes/bird_control_plane_schema_bootstrap.php')
|
|
);
|
|
$eventStore = file_get_contents(app_path('modules/bird/classes/bird_webhook_event_store.php'));
|
|
$outboundStore = file_get_contents(app_path('modules/bird/classes/bird_outbound_message_store.php'));
|
|
|
|
expect($schema)->not->toBeFalse()
|
|
->and($schema)->toContain("PHP_SAPI !== 'cli'")
|
|
->and($eventStore)->not->toContain('CREATE TABLE')
|
|
->and($outboundStore)->not->toContain('CREATE TABLE');
|
|
});
|
|
|
|
it('defines all sensitive Bird integration switches as disabled or empty by default', function (): void {
|
|
$module = file_get_contents(app_path('modules/bird/bird_c.php'));
|
|
$controlPlane = file_get_contents(app_path('modules/bird/config/bird_control_plane_enabled_c.php'));
|
|
$flow = file_get_contents(app_path('modules/bird/config/bird_flow_enabled_c.php'));
|
|
$token = file_get_contents(app_path('modules/bird/config/bird_control_plane_token_c.php'));
|
|
$signingKey = file_get_contents(app_path('modules/bird/config/bird_webhook_signing_key_c.php'));
|
|
$allowedChannels = file_get_contents(
|
|
app_path('modules/bird/config/bird_allowed_channel_ids_json_c.php')
|
|
);
|
|
|
|
expect($module)->toContain('bird_workspaceId_c')
|
|
->and($module)->toContain('bird_workplaceId_c')
|
|
->and($controlPlane)->toContain("'false'")
|
|
->and($flow)->toContain("'false'")
|
|
->and($token)->toContain('true,')
|
|
->and($token)->toContain("''")
|
|
->and($signingKey)->toContain('true,')
|
|
->and($signingKey)->toContain("''")
|
|
->and($allowedChannels)->toContain("'[]'");
|
|
});
|
|
|
|
it('prefers canonical workspaceId and falls back to legacy workplaceId only when empty', function (): void {
|
|
$content = file_get_contents(app_path('traits/bird_route_helpers_t.php'));
|
|
|
|
expect($content)->toContain("property_exists(\$client->config, 'workspaceId')")
|
|
->and($content)->toContain("if (\$canonical !== '')")
|
|
->and($content)->toContain("property_exists(\$client->config, 'workplaceId')");
|
|
});
|