test(api): lock MiniMax config redaction + isSet contract (#358)
Regression coverage for the read-side shape that the frontend `ConfigurationXLVask.refreshMiniMaxApiKeyStatus` parses. Mirrors `BirdConfigSecretRedactionTest` — locks the contract that `api_key` is redacted with `isSet` reflecting actual persistence, so the XL Vask autopilot's `requireModuleEnabled` cannot silently break on a regression.
No production-code change — backend already correct (verified live 2026-08-10 07:58 against `api-v2.truckwash.io` with both `{variable, value}` and raw-key payload shapes).
Companion pleno-vue PR: #281 ("fix(pleno-vue): persist MiniMax API key across refresh + render fix").
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
app_require('traits/module_config_t.php');
|
||||
|
||||
use traits\module_config_t;
|
||||
|
||||
if (!class_exists('MiniMaxSecretConfigDefinitionStub')) {
|
||||
class MiniMaxSecretConfigDefinitionStub
|
||||
{
|
||||
public bool $config_variable_is_secret = true;
|
||||
|
||||
public function getVariableName(): string
|
||||
{
|
||||
return 'api_key';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists('MiniMaxBoolConfigDefinitionStub')) {
|
||||
class MiniMaxBoolConfigDefinitionStub
|
||||
{
|
||||
public bool $config_variable_is_secret = false;
|
||||
|
||||
public function getVariableName(): string
|
||||
{
|
||||
return 'enabled';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists('MiniMaxModuleConfigRedactionHarness')) {
|
||||
class MiniMaxModuleConfigRedactionHarness
|
||||
{
|
||||
use module_config_t;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config_classes = [
|
||||
MiniMaxSecretConfigDefinitionStub::class,
|
||||
MiniMaxBoolConfigDefinitionStub::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function extract(object $db): array
|
||||
{
|
||||
return $this->extracted($db, 'SELECT test');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it('redacts configured MiniMax secrets while preserving isSet metadata', function (): void {
|
||||
$rows = [
|
||||
['module' => 'miniMax', 'variable' => 'api_key', 'type' => 'string', 'value' => 'never-return-this'],
|
||||
['module' => 'miniMax', 'variable' => 'enabled', 'type' => 'bool', 'value' => 'true'],
|
||||
];
|
||||
$result = new class($rows) {
|
||||
public function __construct(private array $rows)
|
||||
{
|
||||
}
|
||||
|
||||
public function fetch_assoc(): ?array
|
||||
{
|
||||
return array_shift($this->rows);
|
||||
}
|
||||
};
|
||||
$db = new class($result) {
|
||||
public function __construct(private object $result)
|
||||
{
|
||||
}
|
||||
|
||||
public function query(string $sql): object
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
};
|
||||
|
||||
$config = (new MiniMaxModuleConfigRedactionHarness())->extract($db);
|
||||
|
||||
expect($config[0])->toMatchArray([
|
||||
'module' => 'miniMax',
|
||||
'variable' => 'api_key',
|
||||
'type' => 'string',
|
||||
'value' => '[redacted]',
|
||||
'isSecret' => true,
|
||||
'isSet' => true,
|
||||
])->and($config[1])->toMatchArray([
|
||||
'module' => 'miniMax',
|
||||
'variable' => 'enabled',
|
||||
'type' => 'bool',
|
||||
'value' => true,
|
||||
'isSecret' => false,
|
||||
'isSet' => true,
|
||||
]);
|
||||
});
|
||||
|
||||
it('reports isSet=false when the stored MiniMax api_key is empty', function (): void {
|
||||
$rows = [
|
||||
['module' => 'miniMax', 'variable' => 'api_key', 'type' => 'string', 'value' => ''],
|
||||
];
|
||||
$result = new class($rows) {
|
||||
public function __construct(private array $rows)
|
||||
{
|
||||
}
|
||||
|
||||
public function fetch_assoc(): ?array
|
||||
{
|
||||
return array_shift($this->rows);
|
||||
}
|
||||
};
|
||||
$db = new class($result) {
|
||||
public function __construct(private object $result)
|
||||
{
|
||||
}
|
||||
|
||||
public function query(string $sql): object
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
};
|
||||
|
||||
$config = (new MiniMaxModuleConfigRedactionHarness())->extract($db);
|
||||
|
||||
expect($config[0])->toMatchArray([
|
||||
'module' => 'miniMax',
|
||||
'variable' => 'api_key',
|
||||
'type' => 'string',
|
||||
'value' => '',
|
||||
'isSecret' => true,
|
||||
'isSet' => false,
|
||||
]);
|
||||
});
|
||||
Reference in New Issue
Block a user