Transitioned from obsolete gateway object classes (`edge_gateway_shell_action_jobs_o`, `edge_gateway_shell_events_o`, `edge_gateway_shell_sessions_o`, `edge_gateway_update_jobs_o`) to the new agent implementation (`edge-gateway-agent/agent.php`).
120 lines
3.7 KiB
PHP
120 lines
3.7 KiB
PHP
<?php
|
|
|
|
app_require('classes/order_bookings_counts_cache.php');
|
|
|
|
use classes\order_bookings_counts_cache;
|
|
|
|
if (!class_exists('OrderBookingsCountsCacheRedisFake')) {
|
|
class OrderBookingsCountsCacheRedisFake
|
|
{
|
|
/** @var array<string,string> */
|
|
public array $store = [];
|
|
|
|
public function get(string $key): ?string
|
|
{
|
|
return $this->store[$key] ?? null;
|
|
}
|
|
|
|
public function setEx(string $key, string $value, int $ttl): void
|
|
{
|
|
$this->store[$key] = $value;
|
|
}
|
|
|
|
public function clear_keys(string $pattern): void
|
|
{
|
|
$regex = '/^' . str_replace('\*', '.*', preg_quote($pattern, '/')) . '$/';
|
|
foreach (array_keys($this->store) as $key) {
|
|
if (preg_match($regex, $key) === 1) {
|
|
unset($this->store[$key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
beforeEach(function (): void {
|
|
$this->oldTtl = getenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL');
|
|
$this->redis = new OrderBookingsCountsCacheRedisFake();
|
|
order_bookings_counts_cache::setAdapterForTests($this->redis);
|
|
});
|
|
|
|
afterEach(function (): void {
|
|
order_bookings_counts_cache::setAdapterForTests(null);
|
|
|
|
if ($this->oldTtl === false) {
|
|
putenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL');
|
|
return;
|
|
}
|
|
|
|
putenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL=' . $this->oldTtl);
|
|
});
|
|
|
|
it('uses sane ttl defaults and clamps negative ttl to zero', function (): void {
|
|
putenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL');
|
|
expect(order_bookings_counts_cache::getTtl())->toBe(30);
|
|
|
|
putenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL=20');
|
|
expect(order_bookings_counts_cache::getTtl())->toBe(20);
|
|
|
|
putenv('ORDER_BOOKINGS_COUNTS_CACHE_TTL=-1');
|
|
expect(order_bookings_counts_cache::getTtl())->toBe(0);
|
|
});
|
|
|
|
it('builds deterministic keys for equivalent count contexts', function (): void {
|
|
$keyA = order_bookings_counts_cache::buildKey([
|
|
'route' => '/order-bookings/counts',
|
|
'day' => '2026-04-21',
|
|
'department_ids' => ['3', '1'],
|
|
'customer_number' => null,
|
|
]);
|
|
|
|
$keyB = order_bookings_counts_cache::buildKey([
|
|
'customer_number' => null,
|
|
'route' => '/order-bookings/counts',
|
|
'department_ids' => [1, 3],
|
|
'day' => '2026-04-21',
|
|
]);
|
|
|
|
expect($keyA)->toBe($keyB);
|
|
expect($keyA)->toStartWith(order_bookings_counts_cache::PREFIX);
|
|
});
|
|
|
|
it('stores and retrieves normalized booking counts', function (): void {
|
|
$key = order_bookings_counts_cache::buildKey([
|
|
'route' => '/order-bookings/counts',
|
|
'day' => '2026-04-21',
|
|
'department_ids' => [12],
|
|
]);
|
|
|
|
order_bookings_counts_cache::storeCounts($key, [
|
|
'past' => '2',
|
|
'current' => 3,
|
|
'future' => 1,
|
|
], 60);
|
|
|
|
expect(order_bookings_counts_cache::getCounts($key))->toEqual([
|
|
'past' => 2,
|
|
'current' => 3,
|
|
'future' => 1,
|
|
]);
|
|
});
|
|
|
|
it('ignores malformed payloads and clears order-bookings count caches', function (): void {
|
|
$validKey = order_bookings_counts_cache::buildKey([
|
|
'route' => '/order-bookings/counts',
|
|
'day' => '2026-04-21',
|
|
]);
|
|
|
|
$this->redis->store[$validKey] = '{"past":1,"current":2,"future":3}';
|
|
$this->redis->store[order_bookings_counts_cache::PREFIX . 'broken'] = '{"count":5}';
|
|
$this->redis->store['other:key'] = '{"keep":true}';
|
|
|
|
expect(order_bookings_counts_cache::getCounts(order_bookings_counts_cache::PREFIX . 'broken'))->toBeNull();
|
|
|
|
order_bookings_counts_cache::clearAll();
|
|
|
|
expect($this->redis->store)->toHaveKey('other:key');
|
|
expect($this->redis->store)->not->toHaveKey($validKey);
|
|
expect($this->redis->store)->not->toHaveKey(order_bookings_counts_cache::PREFIX . 'broken');
|
|
});
|