Files
michaelschiemer/tests/Unit/Framework/Database/ValueObjects/SqlStateTest.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- 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.
2025-10-25 19:18:37 +02:00

220 lines
8.1 KiB
PHP

<?php
declare(strict_types=1);
use App\Framework\Database\ValueObjects\SqlState;
describe('SqlState Value Object', function () {
it('validates SQLSTATE format', function () {
// Valid 5-character alphanumeric codes
expect(fn() => new SqlState('23505'))->not->toThrow(\InvalidArgumentException::class);
expect(fn() => new SqlState('08001'))->not->toThrow(\InvalidArgumentException::class);
expect(fn() => new SqlState('42S02'))->not->toThrow(\InvalidArgumentException::class);
expect(fn() => new SqlState('HY000'))->not->toThrow(\InvalidArgumentException::class);
});
it('rejects invalid SQLSTATE formats', function () {
// Too short
expect(fn() => new SqlState('2350'))->toThrow(\InvalidArgumentException::class);
// Too long
expect(fn() => new SqlState('235050'))->toThrow(\InvalidArgumentException::class);
// Invalid characters
expect(fn() => new SqlState('23-05'))->toThrow(\InvalidArgumentException::class);
expect(fn() => new SqlState('23@05'))->toThrow(\InvalidArgumentException::class);
expect(fn() => new SqlState('abcde'))->toThrow(\InvalidArgumentException::class);
});
it('extracts SQLSTATE class correctly', function () {
$sqlState = new SqlState('23505');
expect($sqlState->getClass())->toBe('23');
$sqlState = new SqlState('08001');
expect($sqlState->getClass())->toBe('08');
$sqlState = new SqlState('42S02');
expect($sqlState->getClass())->toBe('42');
});
it('extracts SQLSTATE subclass correctly', function () {
$sqlState = new SqlState('23505');
expect($sqlState->getSubclass())->toBe('505');
$sqlState = new SqlState('08001');
expect($sqlState->getSubclass())->toBe('001');
$sqlState = new SqlState('42S02');
expect($sqlState->getSubclass())->toBe('S02');
});
it('identifies connection errors', function () {
$connectionError = new SqlState('08001');
expect($connectionError->isConnectionError())->toBeTrue();
$otherError = new SqlState('23505');
expect($otherError->isConnectionError())->toBeFalse();
});
it('identifies constraint violations', function () {
$constraintViolation = new SqlState('23505');
expect($constraintViolation->isConstraintViolation())->toBeTrue();
$otherError = new SqlState('08001');
expect($otherError->isConstraintViolation())->toBeFalse();
});
it('identifies transaction rollbacks', function () {
$transactionRollback = new SqlState('40001');
expect($transactionRollback->isTransactionRollback())->toBeTrue();
$otherError = new SqlState('23505');
expect($otherError->isTransactionRollback())->toBeFalse();
});
it('identifies syntax errors', function () {
$syntaxError = new SqlState('42000');
expect($syntaxError->isSyntaxError())->toBeTrue();
$otherError = new SqlState('23505');
expect($otherError->isSyntaxError())->toBeFalse();
});
it('identifies driver errors', function () {
$driverError = new SqlState('HY000');
expect($driverError->isDriverError())->toBeTrue();
$otherError = new SqlState('23505');
expect($otherError->isDriverError())->toBeFalse();
});
it('identifies unique violations', function () {
$uniqueViolation = new SqlState('23505');
expect($uniqueViolation->isUniqueViolation())->toBeTrue();
$otherConstraint = new SqlState('23503');
expect($otherConstraint->isUniqueViolation())->toBeFalse();
});
it('identifies foreign key violations', function () {
$foreignKeyViolation = new SqlState('23503');
expect($foreignKeyViolation->isForeignKeyViolation())->toBeTrue();
$otherConstraint = new SqlState('23505');
expect($otherConstraint->isForeignKeyViolation())->toBeFalse();
});
it('identifies not null violations', function () {
$notNullViolation = new SqlState('23502');
expect($notNullViolation->isNotNullViolation())->toBeTrue();
$otherConstraint = new SqlState('23505');
expect($otherConstraint->isNotNullViolation())->toBeFalse();
});
it('identifies check constraint violations', function () {
$checkViolation = new SqlState('23514');
expect($checkViolation->isCheckViolation())->toBeTrue();
$otherConstraint = new SqlState('23505');
expect($otherConstraint->isCheckViolation())->toBeFalse();
});
it('identifies table not found errors', function () {
$tableNotFound = new SqlState('42S02');
expect($tableNotFound->isTableNotFound())->toBeTrue();
$otherError = new SqlState('42S22');
expect($otherError->isTableNotFound())->toBeFalse();
});
it('identifies column not found errors', function () {
$columnNotFound = new SqlState('42S22');
expect($columnNotFound->isColumnNotFound())->toBeTrue();
$otherError = new SqlState('42S02');
expect($otherError->isColumnNotFound())->toBeFalse();
});
it('identifies deadlocks', function () {
$deadlock = new SqlState('40001');
expect($deadlock->isDeadlock())->toBeTrue();
$otherError = new SqlState('40002');
expect($otherError->isDeadlock())->toBeFalse();
});
it('identifies serialization failures', function () {
$serializationFailure = new SqlState('40001');
expect($serializationFailure->isSerializationFailure())->toBeTrue();
$otherError = new SqlState('40002');
expect($otherError->isSerializationFailure())->toBeFalse();
});
it('identifies connection failures', function () {
$connectionFailure = new SqlState('08001');
expect($connectionFailure->isConnectionFailure())->toBeTrue();
$otherConnectionError = new SqlState('08003');
expect($otherConnectionError->isConnectionFailure())->toBeFalse();
});
it('identifies connection does not exist', function () {
$connectionDoesNotExist = new SqlState('08003');
expect($connectionDoesNotExist->isConnectionDoesNotExist())->toBeTrue();
$otherConnectionError = new SqlState('08001');
expect($otherConnectionError->isConnectionDoesNotExist())->toBeFalse();
});
it('identifies connection rejected', function () {
$connectionRejected = new SqlState('08004');
expect($connectionRejected->isConnectionRejected())->toBeTrue();
$otherConnectionError = new SqlState('08001');
expect($otherConnectionError->isConnectionRejected())->toBeFalse();
});
it('compares SQLSTATE codes for equality', function () {
$sqlState1 = new SqlState('23505');
$sqlState2 = new SqlState('23505');
$sqlState3 = new SqlState('23503');
expect($sqlState1->equals($sqlState2))->toBeTrue();
expect($sqlState1->equals($sqlState3))->toBeFalse();
});
it('converts to string representation', function () {
$sqlState = new SqlState('23505');
expect($sqlState->toString())->toBe('23505');
expect((string) $sqlState)->toBe('23505');
expect($sqlState->__toString())->toBe('23505');
});
it('handles PostgreSQL-specific codes', function () {
$pgUniqueViolation = new SqlState('23505');
expect($pgUniqueViolation->isUniqueViolation())->toBeTrue();
expect($pgUniqueViolation->isConstraintViolation())->toBeTrue();
$pgTableNotFound = new SqlState('42P01');
expect($pgTableNotFound->isSyntaxError())->toBeTrue();
});
it('handles MySQL-specific codes', function () {
$mysqlTableNotFound = new SqlState('42S02');
expect($mysqlTableNotFound->isTableNotFound())->toBeTrue();
expect($mysqlTableNotFound->isSyntaxError())->toBeTrue();
$mysqlColumnNotFound = new SqlState('42S22');
expect($mysqlColumnNotFound->isColumnNotFound())->toBeTrue();
});
it('handles driver-specific codes', function () {
$driverError = new SqlState('HY000');
expect($driverError->isDriverError())->toBeTrue();
expect($driverError->getClass())->toBe('HY');
});
});