Rework the dashboard, environment topology view, header navigation, and status rendering, and standardise selects on a shadcn-vue component. Replace the thin database seeder with a SimulatedEnvironmentSeeder that builds a fully wired, mostly-running organisation (ACTIVE server fleet, managed + GHCR registries, Gitea source provider, ClipBin app with production/staging environments, services, slices, endpoints, managed variables, build artifacts, and a completed/in-progress/failed operations history) so the new UI renders against realistic data.
101 lines
4.1 KiB
PHP
101 lines
4.1 KiB
PHP
<?php
|
|
|
|
use App\Enums\BuildArtifactStatus;
|
|
use App\Enums\EnvironmentVariableSource;
|
|
use App\Enums\OperationStatus;
|
|
use App\Enums\RegistryType;
|
|
use App\Enums\ServiceStatus;
|
|
use App\Enums\ServiceType;
|
|
use App\Models\Application;
|
|
use App\Models\Operation;
|
|
use App\Models\Organisation;
|
|
use App\Models\ServiceReplica;
|
|
use Database\Seeders\DatabaseSeeder;
|
|
use Illuminate\Support\Facades\Bus;
|
|
|
|
beforeEach(function (): void {
|
|
Bus::fake();
|
|
$this->seed(DatabaseSeeder::class);
|
|
});
|
|
|
|
it('does not dispatch any deployment jobs while seeding', function (): void {
|
|
Bus::assertNothingDispatched();
|
|
});
|
|
|
|
it('seeds an organisation with registries including a ready managed registry', function (): void {
|
|
$organisation = Organisation::where('name', 'Stratbucket')->firstOrFail();
|
|
|
|
expect($organisation->registries()->count())->toBeGreaterThanOrEqual(2);
|
|
|
|
$managed = $organisation->registries()->where('type', RegistryType::MANAGED)->firstOrFail();
|
|
|
|
expect($managed->isReady())->toBeTrue()
|
|
->and($managed->health_status)->toBe('healthy')
|
|
->and($managed->control_server_id)->not->toBeNull();
|
|
});
|
|
|
|
it('seeds a fleet of active servers with a control node', function (): void {
|
|
$organisation = Organisation::where('name', 'Stratbucket')->firstOrFail();
|
|
|
|
expect($organisation->servers()->where('is_control_node', true)->where('build_enabled', true)->count())->toBe(1)
|
|
->and($organisation->servers()->count())->toBeGreaterThanOrEqual(4);
|
|
});
|
|
|
|
it('seeds an application with production and staging environments', function (): void {
|
|
$application = Application::where('name', 'ClipBin')->firstOrFail();
|
|
|
|
expect($application->source_provider_id)->not->toBeNull()
|
|
->and($application->environments()->pluck('name')->sort()->values()->all())
|
|
->toBe(['production', 'staging']);
|
|
});
|
|
|
|
it('wires each environment with web, postgres, valkey and caddy services', function (): void {
|
|
$application = Application::where('name', 'ClipBin')->firstOrFail();
|
|
|
|
foreach ($application->environments as $environment) {
|
|
$types = $environment->services()->pluck('type')->map->value->sort()->values()->all();
|
|
|
|
expect($types)->toBe(['caddy', 'laravel', 'postgres', 'valkey'])
|
|
->and($environment->status)->toBe('active');
|
|
|
|
$postgres = $environment->services()->where('type', ServiceType::POSTGRES)->firstOrFail();
|
|
|
|
expect($postgres->status)->toBe(ServiceStatus::RUNNING)
|
|
->and($postgres->slices()->where('type', 'database_user')->where('status', 'active')->exists())->toBeTrue()
|
|
->and($postgres->endpoints()->exists())->toBeTrue();
|
|
}
|
|
});
|
|
|
|
it('syncs managed database variables that are not overridable', function (): void {
|
|
$environment = Application::where('name', 'ClipBin')->firstOrFail()
|
|
->environments()->where('name', 'production')->firstOrFail();
|
|
|
|
$password = $environment->variables()->where('key', 'DB_PASSWORD')->firstOrFail();
|
|
|
|
expect($password->source)->toBe(EnvironmentVariableSource::MANAGED_ATTACHMENT)
|
|
->and($password->overridable)->toBeFalse()
|
|
->and($environment->variables()->where('key', 'APP_NAME')->where('source', EnvironmentVariableSource::USER)->exists())->toBeTrue();
|
|
});
|
|
|
|
it('seeds build artifacts in available and building states', function (): void {
|
|
$statuses = Application::where('name', 'ClipBin')->firstOrFail()
|
|
->environments()
|
|
->with('buildArtifacts')
|
|
->get()
|
|
->flatMap->buildArtifacts
|
|
->pluck('status');
|
|
|
|
expect($statuses)->toContain(BuildArtifactStatus::AVAILABLE)
|
|
->and($statuses)->toContain(BuildArtifactStatus::BUILDING);
|
|
});
|
|
|
|
it('seeds an operations history with completed, in-progress and failed operations', function (): void {
|
|
expect(Operation::where('status', OperationStatus::COMPLETED)->exists())->toBeTrue()
|
|
->and(Operation::where('status', OperationStatus::IN_PROGRESS)->exists())->toBeTrue()
|
|
->and(Operation::where('status', OperationStatus::FAILED)->exists())->toBeTrue();
|
|
});
|
|
|
|
it('seeds at least one unhealthy replica for state variety', function (): void {
|
|
expect(ServiceReplica::where('health_status', 'unhealthy')->exists())->toBeTrue();
|
|
});
|