fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled

This commit is contained in:
2025-11-24 21:28:25 +01:00
parent 4eb7134853
commit 77abc65cd7
1327 changed files with 91915 additions and 9909 deletions

View File

@@ -2,15 +2,24 @@
declare(strict_types=1);
use App\Framework\Config\AppConfig;
use App\Framework\Database\ConnectionInterface;
use App\Framework\Database\Exception\DatabaseException;
use App\Framework\Database\Migration\Migration;
use App\Framework\Database\Migration\MigrationCollection;
use App\Framework\Database\Migration\MigrationDependencyGraph;
use App\Framework\Database\Migration\MigrationRunner;
use App\Framework\Database\Migration\Services\MigrationDatabaseManager;
use App\Framework\Database\Migration\Services\MigrationErrorAnalyzer;
use App\Framework\Database\Migration\Services\MigrationLogger;
use App\Framework\Database\Migration\Services\MigrationPerformanceTracker;
use App\Framework\Database\Migration\Services\MigrationValidator;
use App\Framework\Database\Migration\ValueObjects\MigrationTableConfig;
use App\Framework\Database\Platform\MySqlPlatform;
use App\Framework\Database\ResultInterface;
use App\Framework\Database\ValueObjects\SqlQuery;
use App\Framework\DateTime\SystemClock;
use App\Framework\Id\Ulid\UlidGenerator;
use App\Framework\Performance\MemoryMonitor;
use App\Framework\Performance\OperationTracker;
@@ -20,15 +29,49 @@ beforeEach(function () {
$this->clock = new SystemClock();
$this->memoryMonitor = new MemoryMonitor();
$this->operationTracker = new OperationTracker();
$this->ulidGenerator = new class implements UlidGenerator {
public function generate(): string
{
return '01ARZ3NDEKTSV4RRFFQ69G5FAV';
}
};
$this->appConfig = new AppConfig(\App\Framework\Config\EnvironmentType::DEVELOPMENT);
$tableConfig = MigrationTableConfig::withCustomTable('test_migrations');
$dependencyGraph = new MigrationDependencyGraph();
$databaseManager = new MigrationDatabaseManager(
$this->connection,
$this->platform,
$this->clock,
$tableConfig
);
$performanceTracker = new MigrationPerformanceTracker(
$this->operationTracker,
$this->memoryMonitor,
null,
null,
null
);
$migrationLogger = new MigrationLogger(null);
$validator = new MigrationValidator(
$this->connection,
$this->platform,
$this->appConfig
);
$errorAnalyzer = new MigrationErrorAnalyzer();
$this->migrationRunner = new MigrationRunner(
$this->connection,
$this->platform,
$this->clock,
null, // tableConfig
null, // logger
$this->operationTracker,
$this->memoryMonitor
$this->ulidGenerator,
$this->appConfig,
$dependencyGraph,
$databaseManager,
$performanceTracker,
$migrationLogger,
$validator,
$errorAnalyzer
);
});
@@ -38,7 +81,8 @@ test('constructor creates migrations table', function () {
expect($queries)->toHaveCount(1)
->and($queries[0]['type'])->toBe('execute')
->and($queries[0]['sql'])->toContain('CREATE TABLE IF NOT EXISTS test_migrations');
->and($queries[0]['sql'])->toContain('CREATE TABLE')
->and($queries[0]['sql'])->toContain('test_migrations');
});
test('migrate runs pending migrations', function () {
@@ -66,16 +110,12 @@ test('migrate runs pending migrations', function () {
test('migrate skips already applied migrations', function () {
$migration = new TestMigration();
$migrationData = (object) [
'version' => '2024_01_01_000000',
'description' => 'Test Migration',
'instance' => $migration,
];
$migrations = new MigrationCollection($migration);
// Set migration as already applied
$this->connection->setAppliedMigrations([['version' => '2024_01_01_000000']]);
$result = $this->migrationRunner->migrate([$migrationData]);
$result = $this->migrationRunner->migrate($migrations);
expect($result)->toBeEmpty();
expect($migration->wasExecuted())->toBeFalse();
@@ -84,17 +124,13 @@ test('migrate skips already applied migrations', function () {
test('migrate rolls back on failure', function () {
// Mock failing migration
$failingMigration = new FailingTestMigration();
$migrationData = (object) [
'version' => '2024_01_01_000000',
'description' => 'Failing Migration',
'instance' => $failingMigration,
];
$migrations = new MigrationCollection($failingMigration);
// Set no applied migrations initially
$this->connection->setAppliedMigrations([]);
$this->connection->setShouldFail(true);
expect(fn () => $this->migrationRunner->migrate([$migrationData]))
expect(fn () => $this->migrationRunner->migrate($migrations))
->toThrow(DatabaseException::class);
// Verify transaction was used (inTransaction was called)
@@ -103,18 +139,14 @@ test('migrate rolls back on failure', function () {
test('rollback reverts applied migration', function () {
$migration = new TestMigration();
$migrationData = (object) [
'version' => '2024_01_01_000000',
'description' => 'Test Migration',
'instance' => $migration,
];
$migrations = new MigrationCollection($migration);
// Set migration as already applied
$this->connection->setAppliedMigrations([['version' => '2024_01_01_000000']]);
$result = $this->migrationRunner->rollback([$migrationData], 1);
$result = $this->migrationRunner->rollback($migrations, 1);
expect($result)->toContain('2024_01_01_000000');
expect($result)->toHaveCount(1);
expect($migration->wasRolledBack())->toBeTrue();
// Verify the migration record was deleted
@@ -122,31 +154,31 @@ test('rollback reverts applied migration', function () {
$deleteQueries = array_filter(
$queries,
fn ($q) =>
$q['type'] === 'execute' && str_contains($q['sql'], 'DELETE FROM test_migrations')
$q['type'] === 'execute' && str_contains($q['sql'], 'DELETE FROM')
);
expect($deleteQueries)->toHaveCount(1);
});
test('get status returns migration status', function () {
$migration1Data = (object) [
'version' => '2024_01_01_000000',
'description' => 'Applied Migration',
'instance' => new TestMigration(),
];
$migration2Data = (object) [
'version' => '2024_01_02_000000',
'description' => 'Pending Migration',
'instance' => new TestMigration(),
];
$migration1 = new TestMigration();
$migration2 = new class implements Migration {
public function up(ConnectionInterface $connection): void {}
public function down(ConnectionInterface $connection): void {}
public function getDescription(): string { return 'Pending Migration'; }
public function getVersion(): \App\Framework\Database\Migration\MigrationVersion {
return \App\Framework\Database\Migration\MigrationVersion::fromTimestamp('2024_01_02_000000');
}
};
$migrations = new MigrationCollection($migration1, $migration2);
// Set only first migration as applied
$this->connection->setAppliedMigrations([['version' => '2024_01_01_000000']]);
$status = $this->migrationRunner->getStatus([$migration1Data, $migration2Data]);
$status = $this->migrationRunner->getStatus($migrations);
expect($status)->toHaveCount(2)
->and($status[0]['applied'])->toBeTrue()
->and($status[1]['applied'])->toBeFalse();
->and($status[0]->applied)->toBeTrue()
->and($status[1]->applied)->toBeFalse();
});
// Test fixtures
@@ -160,14 +192,14 @@ class TestMigration implements Migration
{
$this->executed = true;
// Simulate migration execution
$connection->execute('CREATE TABLE test_table (id INT)');
$connection->execute(SqlQuery::create('CREATE TABLE test_table (id INT)'));
}
public function down(ConnectionInterface $connection): void
{
$this->rolledBack = true;
// Simulate migration rollback
$connection->execute('DROP TABLE test_table');
$connection->execute(SqlQuery::create('DROP TABLE test_table'));
}
public function getDescription(): string