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.
This commit is contained in:
Jeppe Bundgaard
2026-05-11 18:18:08 +02:00
parent bea7e5697b
commit 6d4066be1c
26 changed files with 2563 additions and 43 deletions
@@ -935,13 +935,44 @@ final class ApiFixtures
return $attributeId;
}
public function preserveModuleConfig(string $module, string $variable): void
{
$existing = $this->fetchModuleConfig($module, $variable);
$conditions = [
'module' => $module,
'variable' => $variable,
];
$this->cleanup->add(function () use ($conditions, $existing): void {
if ($existing === null) {
$this->deleteWhereIfPossible('module_config', $conditions);
return;
}
$current = $this->fetchModuleConfig((string)$conditions['module'], (string)$conditions['variable']);
$data = [
'value' => $existing['value'] ?? null,
'type' => $existing['type'] ?? null,
'created_at' => $existing['created_at'] ?? null,
'updated_at' => $existing['updated_at'] ?? null,
];
if ($current === null) {
$this->insertRow('module_config', [
'module' => $existing['module'] ?? $conditions['module'],
'variable' => $existing['variable'] ?? $conditions['variable'],
...$data,
]);
return;
}
$this->updateWhere('module_config', $conditions, $data);
});
}
public function setModuleConfig(string $module, string $variable, string $value, string $type = 'bool'): void
{
$moduleEscaped = $this->db->real_escape_string($module);
$variableEscaped = $this->db->real_escape_string($variable);
$existing = $this->queryOneBySql(
"SELECT * FROM module_config WHERE module = '{$moduleEscaped}' AND variable = '{$variableEscaped}' LIMIT 1"
);
$existing = $this->fetchModuleConfig($module, $variable);
if ($existing !== null) {
$conditions = [
@@ -1876,6 +1907,16 @@ final class ApiFixtures
return $row ?: null;
}
private function fetchModuleConfig(string $module, string $variable): ?array
{
$moduleEscaped = $this->db->real_escape_string($module);
$variableEscaped = $this->db->real_escape_string($variable);
return $this->queryOneBySql(
"SELECT * FROM module_config WHERE module = '{$moduleEscaped}' AND variable = '{$variableEscaped}' LIMIT 1"
);
}
private function setRedisJson(string $key, array $payload): void
{
if ($this->redis === null) {