Files
api/services/nginx/app/tests/Unit/Invoicing/EconomicTransferQueueOpenApiSpecTest.php
T
Jeppe Bundgaard 6d4066be1c Add unit tests for InvoicingPeriodDraftOverlay and reference suggestion logic, including fake DB integration and aggregation methods
- Implemented `InvoicingPeriodDraftOverlayTest` with coverage for blocking and permitting invoicing actions based on draft states, transactions, and metadata.
- Created `ReferenceSuggestionsApiTest` to validate ranked and filtered suggestions across bookings, orders, and vehicles with varied match relevance, context, and frequency.
- Added `order_reference_suggestions_service` class, including query methods, normalization utilities, and aggregation logic for reference suggestions.
- Enhanced query handling in `InvoicingPeriodDraftOverlayFakeDb` to validate SQL constraints and column cache resets in overlapping invoicing contexts.
2026-05-11 18:18:08 +02:00

160 lines
7.7 KiB
PHP

<?php
function economic_transfer_queue_openapi_content_or_skip(): string
{
$candidates = [];
for ($depth = 1; $depth <= 8; $depth++) {
$candidates[] = dirname(__DIR__, $depth) . DIRECTORY_SEPARATOR . 'openapi.yaml';
}
$cwd = getcwd();
if (is_string($cwd) && $cwd !== '') {
$candidates[] = $cwd . DIRECTORY_SEPARATOR . 'openapi.yaml';
$candidates[] = dirname($cwd) . DIRECTORY_SEPARATOR . 'openapi.yaml';
}
$candidates = array_values(array_unique($candidates));
foreach ($candidates as $candidate) {
if (is_file($candidate)) {
$content = file_get_contents($candidate);
if ($content !== false) {
return $content;
}
}
}
test()->markTestSkipped('openapi.yaml is not available in this runtime environment.');
}
function economic_transfer_queue_openapi_block(string $content, string $start, string $end): string
{
$start_pos = strpos($content, $start);
$end_pos = strpos($content, $end);
expect($start_pos)->not->toBeFalse();
expect($end_pos)->not->toBeFalse();
expect($end_pos)->toBeGreaterThan($start_pos);
return substr($content, (int)$start_pos, (int)$end_pos - (int)$start_pos);
}
it('documents economic transfer queue paths in openapi', function (): void {
$content = economic_transfer_queue_openapi_content_or_skip();
expect($content)->toContain('/collected-invoices/economic:');
expect($content)->toContain('/collected-invoices/stripe/book:');
expect($content)->toContain('/collected-invoices/economic/queue:');
expect($content)->toContain('/collected-invoices/economic/queue/monitor:');
expect($content)->toContain('/collected-invoices/economic/queue/status:');
expect($content)->toContain('/collected-invoices/economic/queue/retry:');
expect($content)->toContain('/collected-invoices/economic/queue/dismiss:');
expect($content)->toContain('/collected-invoices/economic/queue/dismiss-terminal:');
expect($content)->toContain('/collected-invoices/economic/queue/run:');
expect($content)->toContain('/economic/invoice/draft/export:');
expect($content)->toContain('/economic/invoice/draft/export/status:');
expect($content)->toContain('/economic/invoice/draft/export/retry:');
expect($content)->toContain('/economic/invoice/export:');
expect($content)->toContain('/economic/invoice/export/status:');
expect($content)->toContain('/economic/invoice/export/retry:');
});
it('documents economic transfer queue schemas in openapi', function (): void {
$content = economic_transfer_queue_openapi_content_or_skip();
expect($content)->toContain('EconomicTransferQueueStatus:');
expect($content)->toContain('EconomicTransferQueueJob:');
expect($content)->toContain('EconomicTransferQueueEnqueueResponse:');
expect($content)->toContain('EconomicTransferSynchronousFallbackResponse:');
expect($content)->toContain('EconomicTransferQueueStatusResponse:');
expect($content)->toContain('EconomicTransferQueueRetryResponse:');
expect($content)->toContain('EconomicTransferQueueRunResponse:');
expect($content)->toContain('EconomicTransferQueueListResponse:');
expect($content)->toContain('EconomicTransferQueueMonitorResponse:');
expect($content)->toContain('EconomicTransferQueueDismissResponse:');
expect($content)->toContain('EconomicTransferQueueDismissTerminalResponse:');
});
it('documents 200 fallback plus 202 queue contracts for export endpoints and keeps 503 on queue lifecycle endpoints', function (): void {
$content = economic_transfer_queue_openapi_content_or_skip();
expect($content)->toContain('ServiceUnavailable:');
expect($content)->toContain("#/components/schemas/EconomicTransferSynchronousFallbackResponse");
$collected_export = economic_transfer_queue_openapi_block(
$content,
'/collected-invoices/economic:',
'/collected-invoices/stripe/book:'
);
$stripe_export = economic_transfer_queue_openapi_block(
$content,
'/collected-invoices/stripe/book:',
'/collected-invoices/economic/queue:'
);
$draft_export = economic_transfer_queue_openapi_block(
$content,
'/economic/invoice/draft/export:',
'/economic/invoice/draft/export/status:'
);
$invoice_export = economic_transfer_queue_openapi_block(
$content,
'/economic/invoice/export:',
'/economic/invoice/export/status:'
);
foreach ([$collected_export, $stripe_export, $draft_export, $invoice_export] as $block) {
expect($block)->toContain("'200':");
expect($block)->toContain("'202':");
expect($block)->not->toContain("'503': { \$ref: '#/components/responses/ServiceUnavailable' }");
}
$queue_blocks = [
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue:', '/collected-invoices/economic/queue/monitor:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/monitor:', '/collected-invoices/economic/queue/status:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/status:', '/collected-invoices/economic/queue/retry:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/retry:', '/collected-invoices/economic/queue/dismiss:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/dismiss:', '/collected-invoices/economic/queue/dismiss-terminal:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/dismiss-terminal:', '/collected-invoices/economic/queue/run:'),
economic_transfer_queue_openapi_block($content, '/collected-invoices/economic/queue/run:', '/collected-invoices/economic/compare:'),
economic_transfer_queue_openapi_block($content, '/economic/invoice/draft/export/status:', '/economic/invoice/draft/export/retry:'),
economic_transfer_queue_openapi_block($content, '/economic/invoice/export/status:', '/economic/invoice/export/retry:'),
];
foreach ($queue_blocks as $block) {
expect($block)->toContain("'503': { \$ref: '#/components/responses/ServiceUnavailable' }");
}
});
it('documents additive collected-invoice queue pagination metadata and retry conflict semantics', function (): void {
$content = economic_transfer_queue_openapi_content_or_skip();
$queue_list_block = economic_transfer_queue_openapi_block(
$content,
'/collected-invoices/economic/queue:',
'/collected-invoices/economic/queue/monitor:'
);
expect($queue_list_block)->toContain('style: form');
expect($queue_list_block)->toContain('explode: false');
expect($queue_list_block)->toContain("type: array");
expect($queue_list_block)->toContain("\$ref: '#/components/schemas/EconomicTransferQueueStatus'");
$retry_block = economic_transfer_queue_openapi_block(
$content,
'/collected-invoices/economic/queue/retry:',
'/collected-invoices/economic/queue/run:'
);
expect($retry_block)->toContain("'409': { \$ref: '#/components/responses/Conflict' }");
$list_schema_block = economic_transfer_queue_openapi_block(
$content,
'EconomicTransferQueueListResponse:',
'CollectedInvoiceEconomicCompareResponse:'
);
expect($list_schema_block)->toContain('total:');
expect($list_schema_block)->toContain('limit:');
expect($list_schema_block)->toContain('offset:');
expect($list_schema_block)->toContain('has_more:');
expect($list_schema_block)->toContain('- total');
expect($list_schema_block)->toContain('- limit');
expect($list_schema_block)->toContain('- offset');
expect($list_schema_block)->toContain('- has_more');
});