Files
api/services/nginx/app/tests/Unit/Redis/RedisAtomicReservationTest.php
T
Jeppe Bundgaard bea7e5697b Handle empty inputs in Redis and database operations, improve safety seal validation, and enhance related tests
- Return empty arrays for empty inputs in Redis `mget`, `db_object_t`, and `users_o` operations.
- Refactor safety seal validation logic to handle numeric strings and improve clarity.
- Add unit and API tests to verify handling of empty inputs and numeric safety seal strings.
2026-05-11 04:36:11 +02:00

103 lines
2.5 KiB
PHP

<?php
app_require('classes/redis.php');
use classes\redis;
use Predis\Client as PredisClient;
class RedisAtomicReservationTestClient extends PredisClient
{
public array $calls = [];
public function __construct(private mixed $returnValue)
{
}
public function mget(array $keys): array
{
$this->calls[] = ['mget', $keys];
return $this->returnValue;
}
public function set(...$arguments): mixed
{
$this->calls[] = $arguments;
return $this->returnValue;
}
public function disconnect(): void
{
}
}
function redis_test_inject_client(redis $redis, PredisClient $client): void
{
$reflection = new ReflectionClass($redis);
$property = $reflection->getProperty('redis');
$property->setAccessible(true);
$property->setValue($redis, $client);
}
it('claims a slot atomically with nx and expiration', function (): void {
global $REDIS_CONFIG;
$REDIS_CONFIG = [
'host' => 'redis',
'database' => 0,
'password' => '',
];
$client = new RedisAtomicReservationTestClient('OK');
$redis = new redis();
redis_test_inject_client($redis, $client);
expect($redis->set_if_absent_with_expiration('goal_alert_sent:22:2026-03-17', '1', 86400))->toBeTrue();
expect($client->calls)->toBe([
['goal_alert_sent:22:2026-03-17', '1', 'EX', 86400, 'NX'],
]);
});
it('returns false when the slot is already claimed and clamps ttl to one second', function (): void {
global $REDIS_CONFIG;
$REDIS_CONFIG = [
'host' => 'redis',
'database' => 0,
'password' => '',
];
$client = new RedisAtomicReservationTestClient(null);
$redis = new redis();
redis_test_inject_client($redis, $client);
expect($redis->set_if_absent_with_expiration('goal_alert_sent:22:2026-03-17', '1', 0))->toBeFalse();
expect($client->calls)->toBe([
['goal_alert_sent:22:2026-03-17', '1', 'EX', 1, 'NX'],
]);
});
it('does not send empty mget commands to redis', function (): void {
global $REDIS_CONFIG;
$REDIS_CONFIG = [
'host' => 'redis',
'database' => 0,
'password' => '',
];
$client = new RedisAtomicReservationTestClient(['cached-value']);
$redis = new redis();
redis_test_inject_client($redis, $client);
expect($redis->mget([]))->toBe([]);
expect($client->calls)->toBe([]);
expect($redis->mget(['cache-key']))->toBe(['cached-value']);
expect($client->calls)->toBe([
['mget', ['cache-key']],
]);
});