All checks were successful
CI / secret-scan (push) Successful in 13s
CI / php-lint (push) Successful in 26s
CI / static-tests (push) Successful in 56s
CI / js-tests (push) Successful in 32s
CI / secret-scan (pull_request) Successful in 11s
CI / php-lint (pull_request) Successful in 21s
CI / static-tests (pull_request) Successful in 50s
CI / js-tests (pull_request) Successful in 29s
Sur push main, le workflow Deploy ouvre une session SSH vers Vision ou une forced command lance scripts/deploy.sh : le runner (Stark, sans socket Docker) ne pilote pas Docker, il delegue a l'hote distant. La cle CI ne peut declencher que le deploiement (forced command + options no-*, cle d'hote epinglee, BatchMode). deploy.sh gagne un mode non-interactif (DEPLOY_YES), grave src/VERSION (SHA + date) et alimente deploy.log. GET /api/health expose version + deployed_at lus depuis src/VERSION : apres un deploiement, la sonde reflete le nouveau commit -> preuve verifiable du CD cote app. Mise en place cote Vision + secrets forge documentes dans docs/architecture/deployment.md. Revue compliance : 1 must_fix integre (BatchMode).
72 lines
2.2 KiB
PHP
72 lines
2.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Controllers;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use App\Controllers\HealthController;
|
|
use App\Core\Config;
|
|
use App\Core\Database;
|
|
use App\Core\Request;
|
|
|
|
/**
|
|
* Sous-classe de test : pointe le fichier VERSION sur une fixture temporaire,
|
|
* pour couvrir l'exposition de la version deployee sans dependre d'un deploiement
|
|
* reel (le fichier est ecrit par scripts/deploy.sh sur l'hote, jamais en test).
|
|
*/
|
|
final class TestHealthController extends HealthController
|
|
{
|
|
public string $versionPath = '';
|
|
|
|
protected function versionFilePath(): string
|
|
{
|
|
return $this->versionPath;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* La sonde expose la version deployee (SHA + date) pour prouver le CD : apres un
|
|
* deploiement, GET /api/health doit refleter le nouveau commit. Le test n'a pas de
|
|
* base : l'appel DB echoue et degrade le statut, mais les champs version restent
|
|
* presents (ils sont independants de la BDD).
|
|
*/
|
|
final class HealthControllerTest extends TestCase
|
|
{
|
|
private function controller(string $versionPath): TestHealthController
|
|
{
|
|
$request = new Request('GET', '/api/health', [], [], '', '203.0.113.5');
|
|
$c = new TestHealthController($request, new Config(), new Database(new Config()));
|
|
$c->versionPath = $versionPath;
|
|
|
|
return $c;
|
|
}
|
|
|
|
public function testExposesDeployedVersionWhenFilePresent(): void
|
|
{
|
|
$fixture = tempnam(sys_get_temp_dir(), 'wakdo_version_');
|
|
file_put_contents($fixture, "3dee190 2026-06-23T14:02:11+02:00\n");
|
|
|
|
try {
|
|
$body = $this->controller($fixture)->index()->body();
|
|
$payload = json_decode($body, true);
|
|
|
|
self::assertSame('3dee190', $payload['version']);
|
|
self::assertSame('2026-06-23T14:02:11+02:00', $payload['deployed_at']);
|
|
} finally {
|
|
@unlink($fixture);
|
|
}
|
|
}
|
|
|
|
public function testVersionNullWhenFileAbsent(): void
|
|
{
|
|
$missing = sys_get_temp_dir() . '/wakdo_version_does_not_exist_' . getmypid();
|
|
@unlink($missing);
|
|
|
|
$body = $this->controller($missing)->index()->body();
|
|
$payload = json_decode($body, true);
|
|
|
|
self::assertNull($payload['version']);
|
|
self::assertNull($payload['deployed_at']);
|
|
}
|
|
}
|