- 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.
169 lines
4.8 KiB
PHP
169 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Framework\Logging;
|
|
|
|
use App\Framework\Logging\ValueObjects\CorrelationId;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class CorrelationIdTest extends TestCase
|
|
{
|
|
public function test_creates_from_string(): void
|
|
{
|
|
$id = CorrelationId::fromString('test-correlation-id-123');
|
|
|
|
$this->assertEquals('test-correlation-id-123', $id->toString());
|
|
$this->assertEquals('test-correlation-id-123', (string) $id);
|
|
}
|
|
|
|
public function test_generates_uuid_format(): void
|
|
{
|
|
$id = CorrelationId::generate();
|
|
|
|
$this->assertTrue($id->isUuid());
|
|
$this->assertFalse($id->isUlid());
|
|
$this->assertMatchesRegularExpression(
|
|
'/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i',
|
|
$id->toString()
|
|
);
|
|
}
|
|
|
|
public function test_generates_ulid_format(): void
|
|
{
|
|
$id = CorrelationId::generateUlid();
|
|
|
|
$this->assertTrue($id->isUlid());
|
|
$this->assertFalse($id->isUuid());
|
|
$this->assertEquals(26, strlen($id->toString()));
|
|
}
|
|
|
|
public function test_rejects_empty_string(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('cannot be empty');
|
|
|
|
CorrelationId::fromString('');
|
|
}
|
|
|
|
public function test_rejects_too_long_string(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('too long');
|
|
|
|
CorrelationId::fromString(str_repeat('a', 256));
|
|
}
|
|
|
|
public function test_rejects_invalid_characters(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('invalid characters');
|
|
|
|
CorrelationId::fromString('test-id-with-invalid-chars-äöü');
|
|
}
|
|
|
|
public function test_allows_valid_characters(): void
|
|
{
|
|
$validIds = [
|
|
'simple-id-123',
|
|
'UPPERCASE-ID-456',
|
|
'mixed_Case-ID_789',
|
|
'12345-67890',
|
|
'a_b-c_d-e_f',
|
|
];
|
|
|
|
foreach ($validIds as $validId) {
|
|
$id = CorrelationId::fromString($validId);
|
|
$this->assertEquals($validId, $id->toString());
|
|
}
|
|
}
|
|
|
|
public function test_to_short_string(): void
|
|
{
|
|
$id = CorrelationId::fromString('very-long-correlation-id-123456789');
|
|
|
|
$this->assertEquals('very-lon', $id->toShortString());
|
|
}
|
|
|
|
public function test_equals(): void
|
|
{
|
|
$id1 = CorrelationId::fromString('test-123');
|
|
$id2 = CorrelationId::fromString('test-123');
|
|
$id3 = CorrelationId::fromString('test-456');
|
|
|
|
$this->assertTrue($id1->equals($id2));
|
|
$this->assertFalse($id1->equals($id3));
|
|
}
|
|
|
|
public function test_json_serializable(): void
|
|
{
|
|
$id = CorrelationId::fromString('test-json-123');
|
|
|
|
$json = json_encode(['id' => $id]);
|
|
|
|
$this->assertEquals('{"id":"test-json-123"}', $json);
|
|
}
|
|
|
|
public function test_from_globals_with_correlation_header(): void
|
|
{
|
|
$_SERVER['HTTP_X_CORRELATION_ID'] = 'header-correlation-123';
|
|
|
|
$id = CorrelationId::fromGlobals();
|
|
|
|
$this->assertEquals('header-correlation-123', $id->toString());
|
|
|
|
unset($_SERVER['HTTP_X_CORRELATION_ID']);
|
|
}
|
|
|
|
public function test_from_globals_fallback_to_request_id(): void
|
|
{
|
|
$_SERVER['HTTP_X_REQUEST_ID'] = 'request-id-456';
|
|
|
|
$id = CorrelationId::fromGlobals('X-Correlation-ID');
|
|
|
|
$this->assertEquals('request-id-456', $id->toString());
|
|
|
|
unset($_SERVER['HTTP_X_REQUEST_ID']);
|
|
}
|
|
|
|
public function test_from_globals_generates_when_no_header(): void
|
|
{
|
|
unset($_SERVER['HTTP_X_CORRELATION_ID'], $_SERVER['HTTP_X_REQUEST_ID']);
|
|
|
|
$id = CorrelationId::fromGlobals();
|
|
|
|
$this->assertTrue($id->isUuid());
|
|
}
|
|
|
|
public function test_from_globals_generates_when_invalid_header(): void
|
|
{
|
|
$_SERVER['HTTP_X_CORRELATION_ID'] = 'invalid-chars-äöü';
|
|
|
|
$id = CorrelationId::fromGlobals();
|
|
|
|
// Should generate new valid ID instead of using invalid one
|
|
$this->assertTrue($id->isUuid());
|
|
$this->assertNotEquals('invalid-chars-äöü', $id->toString());
|
|
|
|
unset($_SERVER['HTTP_X_CORRELATION_ID']);
|
|
}
|
|
|
|
public function test_creates_from_uuid(): void
|
|
{
|
|
$uuid = \Ramsey\Uuid\Uuid::uuid4();
|
|
$id = CorrelationId::fromUuid($uuid);
|
|
|
|
$this->assertEquals($uuid->toString(), $id->toString());
|
|
$this->assertTrue($id->isUuid());
|
|
}
|
|
|
|
public function test_creates_from_ulid(): void
|
|
{
|
|
$ulid = \App\Framework\Ulid\Ulid::generate();
|
|
$id = CorrelationId::fromUlid($ulid);
|
|
|
|
$this->assertEquals((string) $ulid, $id->toString());
|
|
$this->assertTrue($id->isUlid());
|
|
}
|
|
}
|