Implements MeshVault M1 (issues #6–11): - Four-service Docker Compose stack (nginx, PHP-FPM 8.3, PostgreSQL 17, Node assets) - Slim 4 + PHP-DI routing with escaped PHP views and production/dev error handling - Immutable validated AppConfig with redacted diagnostics - JSON stdout Monolog logging with job-scoped context - Tailwind CSS v4 deterministic locked builds with template scanning - POSIX and PowerShell dev wrappers (up/down/test/lint/assets/watch) - Startup config validation fails before FPM serves as unprivileged www-data - migrate/seed explicitly unavailable until M2 (#12); #10 remains open Verified via clean-start acceptance on remote host (keith@192.168.2.23).
41 lines
1.6 KiB
PHP
41 lines
1.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MeshVault\Tests\Http;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class DeploymentTest extends TestCase
|
|
{
|
|
public function testFpmConfigExistsAndForwardsUndecoratedWorkerLogs(): void
|
|
{
|
|
$path = dirname(__DIR__, 2) . '/docker/php/zz-meshvault.conf';
|
|
self::assertFileExists($path);
|
|
$config = file_get_contents($path);
|
|
self::assertStringContainsString('clear_env = no', $config);
|
|
self::assertStringContainsString('catch_workers_output = yes', $config);
|
|
self::assertStringContainsString('decorate_workers_output = no', $config);
|
|
}
|
|
|
|
public function testComposeSuppliesEveryApplicationSettingAndViewDirectory(): void
|
|
{
|
|
$compose = file_get_contents(dirname(__DIR__, 2) . '/docker-compose.yml');
|
|
$app = explode(' db:', explode(' app:', $compose, 2)[1], 2)[0];
|
|
foreach (['ENV', 'LOG_LEVEL', 'DB_HOST', 'DB_PORT', 'DB_NAME', 'DB_USER', 'DB_PASSWORD'] as $key) {
|
|
self::assertStringContainsString('MESHVAULT_' . $key . ':', $app);
|
|
}
|
|
foreach (['config', 'templates'] as $directory) {
|
|
self::assertStringContainsString('./' . $directory . ':/var/www/html/' . $directory . ':ro', $app);
|
|
}
|
|
}
|
|
|
|
public function testBuildContextIncludesDependencyAndStartupInputs(): void
|
|
{
|
|
$ignore = file_get_contents(dirname(__DIR__, 2) . '/.dockerignore');
|
|
foreach (['composer.json', 'composer.lock', 'bin/', 'bin/**', 'docker/php/**'] as $input) {
|
|
self::assertStringContainsString('!' . $input, $ignore);
|
|
}
|
|
}
|
|
}
|