Files
michaelschiemer/tests/Framework/Database/Migration/MigrationLoaderTest.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

180 lines
6.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Database\Migration;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Database\Migration\Migration;
use App\Framework\Database\Migration\MigrationCollection;
use App\Framework\Database\Migration\MigrationLoader;
use App\Framework\Database\Migration\MigrationVersion;
use App\Framework\DI\Container;
use App\Framework\Discovery\Results\AttributeRegistry;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Discovery\Results\InterfaceRegistry;
use App\Framework\Discovery\Results\RouteRegistry;
use App\Framework\Discovery\Results\TemplateRegistry;
use App\Framework\Discovery\ValueObjects\InterfaceMapping;
use App\Framework\Filesystem\ValueObjects\FilePath;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
final class MigrationLoaderTest extends TestCase
{
private Container $container;
protected function setUp(): void
{
$this->container = $this->createMock(Container::class);
}
#[Test]
public function loadMigrations_returns_empty_collection_when_no_migrations_found(): void
{
// Setup interface registry with no migrations
$interfaceRegistry = new InterfaceRegistry();
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new RouteRegistry(),
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$result = $loader->loadMigrations();
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertTrue($result->isEmpty());
$this->assertSame(0, $result->count());
}
#[Test]
public function loadMigrations_returns_sorted_collection_of_migrations(): void
{
// Create mock migration instances (in unsorted order)
$migration1 = $this->createMockMigration('2024_01_03_120000', 'Third migration');
$migration2 = $this->createMockMigration('2024_01_01_120000', 'First migration');
$migration3 = $this->createMockMigration('2024_01_02_120000', 'Second migration');
// Create interface mappings
$mapping1 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration1'),
FilePath::create('/path/to/migration1.php')
);
$mapping2 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration2'),
FilePath::create('/path/to/migration2.php')
);
$mapping3 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration3'),
FilePath::create('/path/to/migration3.php')
);
// Setup interface registry
$interfaceRegistry = new InterfaceRegistry();
$interfaceRegistry->add($mapping1);
$interfaceRegistry->add($mapping2);
$interfaceRegistry->add($mapping3);
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new RouteRegistry(),
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
// Setup container to return migration instances
$this->container->method('get')
->willReturnMap([
['App\\Migration1', $migration1],
['App\\Migration2', $migration2],
['App\\Migration3', $migration3],
]);
$result = $loader->loadMigrations();
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertSame(3, $result->count());
// Verify migrations are sorted by version
$migrations = $result->toArray();
$this->assertSame($migration2, $migrations[0]); // 2024_01_01_120000
$this->assertSame($migration3, $migrations[1]); // 2024_01_02_120000
$this->assertSame($migration1, $migrations[2]); // 2024_01_03_120000
}
#[Test]
public function loadMigrations_uses_discovery_registry_to_find_migration_implementations(): void
{
$interfaceRegistry = new InterfaceRegistry();
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new RouteRegistry(),
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$result = $loader->loadMigrations();
// Verify that the discovery registry was used by checking we get an empty collection
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertTrue($result->isEmpty());
}
#[Test]
public function loadMigrations_uses_container_to_instantiate_migrations(): void
{
$migration = $this->createMockMigration('2024_01_01_120000', 'Test migration');
$mapping = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\TestMigration'),
FilePath::create('/path/to/test_migration.php')
);
$interfaceRegistry = new InterfaceRegistry();
$interfaceRegistry->add($mapping);
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new RouteRegistry(),
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$this->container->expects($this->once())
->method('get')
->with('App\\TestMigration')
->willReturn($migration);
$result = $loader->loadMigrations();
$this->assertSame(1, $result->count());
$this->assertSame($migration, $result->toArray()[0]);
}
private function createMockMigration(string $version, string $description): Migration
{
$migration = $this->createMock(Migration::class);
$migration->method('getVersion')
->willReturn(MigrationVersion::fromTimestamp($version));
$migration->method('getDescription')
->willReturn($description);
return $migration;
}
}