- 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.
229 lines
6.7 KiB
PHP
229 lines
6.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\LiveComponents\Services\UploadSessionIdGenerator;
|
|
use App\Framework\LiveComponents\ValueObjects\UploadSessionId;
|
|
use App\Framework\Random\RandomGenerator;
|
|
|
|
describe('UploadSessionIdGenerator Service', function () {
|
|
it('generates valid session id', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
$sessionId = $generator->generate();
|
|
|
|
expect($sessionId)->toBeInstanceOf(UploadSessionId::class);
|
|
expect(strlen($sessionId->value))->toBe(32); // 16 bytes = 32 hex chars
|
|
});
|
|
|
|
it('generates hex-encoded session ids', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
$sessionId = $generator->generate();
|
|
|
|
// Verify it's valid hex
|
|
expect(ctype_xdigit($sessionId->value))->toBeTrue();
|
|
});
|
|
|
|
it('generates unique session ids', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
|
|
$id1 = $generator->generate();
|
|
$id2 = $generator->generate();
|
|
$id3 = $generator->generate();
|
|
|
|
expect($id1->equals($id2))->toBeFalse();
|
|
expect($id1->equals($id3))->toBeFalse();
|
|
expect($id2->equals($id3))->toBeFalse();
|
|
});
|
|
|
|
it('generates 100 unique session ids', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
|
|
$sessionIds = [];
|
|
for ($i = 0; $i < 100; $i++) {
|
|
$sessionIds[] = $generator->generate()->value;
|
|
}
|
|
|
|
$uniqueIds = array_unique($sessionIds);
|
|
expect(count($uniqueIds))->toBe(100);
|
|
});
|
|
|
|
it('requests 16 bytes from random generator', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public int $lastRequestedLength = 0;
|
|
|
|
public function bytes(int $length): string
|
|
{
|
|
$this->lastRequestedLength = $length;
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
$generator->generate();
|
|
|
|
expect($randomGen->lastRequestedLength)->toBe(16);
|
|
});
|
|
|
|
it('uses RandomGenerator bytes method', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public bool $bytesCalled = false;
|
|
|
|
public function bytes(int $length): string
|
|
{
|
|
$this->bytesCalled = true;
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
$generator->generate();
|
|
|
|
expect($randomGen->bytesCalled)->toBeTrue();
|
|
});
|
|
|
|
it('produces alphanumeric session ids', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
|
|
for ($i = 0; $i < 10; $i++) {
|
|
$sessionId = $generator->generate();
|
|
expect(ctype_alnum($sessionId->value))->toBeTrue();
|
|
}
|
|
});
|
|
|
|
it('generates consistent length session ids', function () {
|
|
$randomGen = new class implements RandomGenerator {
|
|
public function bytes(int $length): string
|
|
{
|
|
return random_bytes($length);
|
|
}
|
|
|
|
public function int(int $min, int $max): int
|
|
{
|
|
return random_int($min, $max);
|
|
}
|
|
|
|
public function float(): float
|
|
{
|
|
return (float) random_int(0, PHP_INT_MAX) / PHP_INT_MAX;
|
|
}
|
|
};
|
|
|
|
$generator = new UploadSessionIdGenerator($randomGen);
|
|
|
|
$lengths = [];
|
|
for ($i = 0; $i < 50; $i++) {
|
|
$sessionId = $generator->generate();
|
|
$lengths[] = strlen($sessionId->value);
|
|
}
|
|
|
|
$uniqueLengths = array_unique($lengths);
|
|
expect(count($uniqueLengths))->toBe(1);
|
|
expect($uniqueLengths[0])->toBe(32);
|
|
});
|
|
});
|