feat: phase A — backup B2, healthcheck /api/status, vector tiles Tippecanoe
- A1: scripts/backup-postgres.sh — pg_dump quotidien compressé → Backblaze B2 (rclone), rétention 30j - A2: StatusController retourne HTTP 503 + healthy/alertReason si dernière observation > 6h - A4: Dockerfile installe tippecanoe, GenerateTilesCommand génère 5 tilesets (obs + h6/12/24/48), Caddyfile sert /tiles/* sans fallback SPA, SargassesMap.jsx passe en sources vector tiles statiques - chore: backend/public/assets/ ajouté au .gitignore (build artifacts) - chore: setup vitest frontend + ImpactScoreServiceTest (session précédente) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
71
backend/tests/Unit/Service/ImpactScoreServiceTest.php
Normal file
71
backend/tests/Unit/Service/ImpactScoreServiceTest.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Unit\Service;
|
||||
|
||||
use App\Service\Forecast\ImpactScoreService;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use App\Service\Push\PushNotificationService;
|
||||
|
||||
class ImpactScoreServiceTest extends TestCase
|
||||
{
|
||||
private ImpactScoreService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$connection = $this->createStub(Connection::class);
|
||||
$em = $this->createStub(EntityManagerInterface::class);
|
||||
$cache = new ArrayAdapter();
|
||||
$push = $this->createStub(PushNotificationService::class);
|
||||
|
||||
$this->service = new ImpactScoreService(
|
||||
$connection,
|
||||
$em,
|
||||
$cache,
|
||||
new NullLogger(),
|
||||
$push,
|
||||
);
|
||||
}
|
||||
|
||||
// ── scoreToLevel ──────────────────────────────────────────────────────────
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('scoreLevelProvider')]
|
||||
public function testScoreToLevel(int $score, string $expected): void
|
||||
{
|
||||
$method = new \ReflectionMethod(ImpactScoreService::class, 'scoreToLevel');
|
||||
$result = $method->invoke($this->service, $score);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
/** @return array<string, array{int, string}> */
|
||||
public static function scoreLevelProvider(): array
|
||||
{
|
||||
return [
|
||||
'score 0 → low' => [0, 'low'],
|
||||
'score 30 → low' => [30, 'low'],
|
||||
'score 31 → medium' => [31, 'medium'],
|
||||
'score 70 → medium' => [70, 'medium'],
|
||||
'score 71 → high' => [71, 'high'],
|
||||
'score 100 → high' => [100, 'high'],
|
||||
];
|
||||
}
|
||||
|
||||
// ── emptyScore ────────────────────────────────────────────────────────────
|
||||
|
||||
public function testEmptyScoreReturnsCorrectStructure(): void
|
||||
{
|
||||
$method = new \ReflectionMethod(ImpactScoreService::class, 'emptyScore');
|
||||
$result = $method->invoke($this->service);
|
||||
|
||||
self::assertSame(0, $result['score']);
|
||||
self::assertSame('low', $result['level']);
|
||||
self::assertNull($result['distance']);
|
||||
self::assertSame(0.0, $result['density']);
|
||||
self::assertSame('stable', $result['trend']);
|
||||
self::assertNull($result['etaHours']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user