- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
234 lines
7.1 KiB
PHP
234 lines
7.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\Core\ValueObjects\Duration;
|
|
use App\Framework\LiveComponents\ValueObjects\CacheConfig;
|
|
|
|
describe('CacheConfig', function () {
|
|
it('creates basic cache config', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(10)
|
|
);
|
|
|
|
expect($config->enabled)->toBeTrue();
|
|
expect($config->ttl->toSeconds())->toBe(600);
|
|
expect($config->varyBy)->toBe([]);
|
|
expect($config->staleWhileRevalidate)->toBeFalse();
|
|
expect($config->staleWhileRevalidateTtl)->toBeNull();
|
|
});
|
|
|
|
it('creates config with varyBy parameters', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
varyBy: ['user_id', 'category', 'sort']
|
|
);
|
|
|
|
expect($config->varyBy)->toBe(['user_id', 'category', 'sort']);
|
|
});
|
|
|
|
it('creates config with stale-while-revalidate', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
staleWhileRevalidate: true,
|
|
staleWhileRevalidateTtl: Duration::fromMinutes(60)
|
|
);
|
|
|
|
expect($config->staleWhileRevalidate)->toBeTrue();
|
|
expect($config->staleWhileRevalidateTtl->toMinutes())->toBe(60);
|
|
});
|
|
|
|
it('creates disabled cache config', function () {
|
|
$config = new CacheConfig(
|
|
enabled: false,
|
|
ttl: Duration::fromMinutes(10)
|
|
);
|
|
|
|
expect($config->enabled)->toBeFalse();
|
|
});
|
|
|
|
it('creates from array', function () {
|
|
$data = [
|
|
'enabled' => true,
|
|
'ttl' => 600, // seconds
|
|
'varyBy' => ['filter', 'page'],
|
|
'staleWhileRevalidate' => true,
|
|
'staleWhileRevalidateTtl' => 3600,
|
|
];
|
|
|
|
$config = CacheConfig::fromArray($data);
|
|
|
|
expect($config->enabled)->toBeTrue();
|
|
expect($config->ttl->toSeconds())->toBe(600);
|
|
expect($config->varyBy)->toBe(['filter', 'page']);
|
|
expect($config->staleWhileRevalidate)->toBeTrue();
|
|
expect($config->staleWhileRevalidateTtl->toSeconds())->toBe(3600);
|
|
});
|
|
|
|
it('creates disabled config', function () {
|
|
$config = CacheConfig::disabled();
|
|
|
|
expect($config->enabled)->toBeFalse();
|
|
expect($config->ttl->toSeconds())->toBe(0);
|
|
expect($config->varyBy)->toBe([]);
|
|
expect($config->staleWhileRevalidate)->toBeFalse();
|
|
});
|
|
|
|
it('creates default config', function () {
|
|
$config = CacheConfig::default();
|
|
|
|
expect($config->enabled)->toBeTrue();
|
|
expect($config->ttl->toMinutes())->toBe(5); // Default 5 minutes
|
|
expect($config->varyBy)->toBe([]);
|
|
expect($config->staleWhileRevalidate)->toBeFalse();
|
|
});
|
|
|
|
it('checks if cache is enabled', function () {
|
|
$enabled = new CacheConfig(enabled: true, ttl: Duration::fromMinutes(5));
|
|
expect($enabled->isEnabled())->toBeTrue();
|
|
|
|
$disabled = new CacheConfig(enabled: false, ttl: Duration::fromMinutes(5));
|
|
expect($disabled->isEnabled())->toBeFalse();
|
|
});
|
|
|
|
it('checks if has variation', function () {
|
|
$withVariation = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
varyBy: ['user_id']
|
|
);
|
|
expect($withVariation->hasVariation())->toBeTrue();
|
|
|
|
$withoutVariation = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
varyBy: []
|
|
);
|
|
expect($withoutVariation->hasVariation())->toBeFalse();
|
|
});
|
|
|
|
it('checks if uses stale-while-revalidate', function () {
|
|
$withSWR = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
staleWhileRevalidate: true,
|
|
staleWhileRevalidateTtl: Duration::fromMinutes(60)
|
|
);
|
|
expect($withSWR->usesStaleWhileRevalidate())->toBeTrue();
|
|
|
|
$withoutSWR = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
staleWhileRevalidate: false
|
|
);
|
|
expect($withoutSWR->usesStaleWhileRevalidate())->toBeFalse();
|
|
});
|
|
|
|
it('gets effective TTL with SWR', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(5),
|
|
staleWhileRevalidate: true,
|
|
staleWhileRevalidateTtl: Duration::fromMinutes(60)
|
|
);
|
|
|
|
$effectiveTtl = $config->getEffectiveTtl();
|
|
|
|
// With SWR, effective TTL should be the SWR TTL
|
|
expect($effectiveTtl->toMinutes())->toBe(60);
|
|
});
|
|
|
|
it('gets effective TTL without SWR', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(10),
|
|
staleWhileRevalidate: false
|
|
);
|
|
|
|
$effectiveTtl = $config->getEffectiveTtl();
|
|
|
|
// Without SWR, effective TTL should be the regular TTL
|
|
expect($effectiveTtl->toMinutes())->toBe(10);
|
|
});
|
|
|
|
it('handles various TTL durations', function () {
|
|
$configs = [
|
|
Duration::fromSeconds(30),
|
|
Duration::fromMinutes(5),
|
|
Duration::fromMinutes(15),
|
|
Duration::fromHours(1),
|
|
Duration::fromHours(24),
|
|
Duration::fromDays(7),
|
|
];
|
|
|
|
foreach ($configs as $duration) {
|
|
$config = new CacheConfig(enabled: true, ttl: $duration);
|
|
expect($config->ttl)->toBe($duration);
|
|
}
|
|
});
|
|
|
|
it('supports multiple varyBy parameters', function () {
|
|
$varyByParams = [
|
|
'user_id',
|
|
'team_id',
|
|
'filter_category',
|
|
'filter_price_min',
|
|
'filter_price_max',
|
|
'sort_by',
|
|
'sort_order',
|
|
'page',
|
|
'per_page',
|
|
];
|
|
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(10),
|
|
varyBy: $varyByParams
|
|
);
|
|
|
|
expect($config->varyBy)->toBe($varyByParams);
|
|
expect($config->hasVariation())->toBeTrue();
|
|
});
|
|
|
|
it('converts to array', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromMinutes(10),
|
|
varyBy: ['filter', 'page'],
|
|
staleWhileRevalidate: true,
|
|
staleWhileRevalidateTtl: Duration::fromMinutes(60)
|
|
);
|
|
|
|
$array = $config->toArray();
|
|
|
|
expect($array)->toBe([
|
|
'enabled' => true,
|
|
'ttl' => 600,
|
|
'varyBy' => ['filter', 'page'],
|
|
'staleWhileRevalidate' => true,
|
|
'staleWhileRevalidateTtl' => 3600,
|
|
]);
|
|
});
|
|
|
|
it('creates config for short-lived cache', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromSeconds(10)
|
|
);
|
|
|
|
expect($config->ttl->toSeconds())->toBe(10);
|
|
});
|
|
|
|
it('creates config for long-lived cache', function () {
|
|
$config = new CacheConfig(
|
|
enabled: true,
|
|
ttl: Duration::fromDays(7)
|
|
);
|
|
|
|
expect($config->ttl->toDays())->toBe(7);
|
|
});
|
|
});
|