Files
coolify/tests/Unit/ExcludeFromHealthCheckTest.php
T
Andras BacsaiandClaude Opus 5.5 a79ee909c6 chore: remove unused components and markup-only tests
- Delete Blade components, component classes, Livewire components and
  views that nothing uses after the redesign.
- Delete tests that only compare Blade/CSS source text; keep the source
  checks for authorization gates, stable wire:key values and escaping.
- Update stale tests to the current UI and behaviour.
- Update DESIGN.md to the current navigation and layout.
- Add a lesson: test behaviour, not source markup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:18:16 +02:00

132 lines
6.5 KiB
PHP

<?php
/**
* Unit tests to verify that applications and services with all containers
* excluded from health checks (exclude_from_hc: true) show correct status.
*
* These tests verify the fix for the issue where services with all containers
* excluded would show incorrect status, causing broken UI state.
*
* The fix now returns status with :excluded suffix to show real container state
* while indicating monitoring is disabled (e.g., "running:excluded").
*/
it('ensures ComplexStatusCheck returns excluded status when all containers excluded', function () {
$complexStatusCheckFile = file_get_contents(__DIR__.'/../../app/Actions/Shared/ComplexStatusCheck.php');
// Check that when all containers are excluded, ComplexStatusCheck uses the trait
expect($complexStatusCheckFile)
->toContain('// If all containers are excluded, calculate status from excluded containers')
->toContain('// but mark it with :excluded to indicate monitoring is disabled')
->toContain('if ($relevantContainers->isEmpty()) {')
->toContain('return $this->calculateExcludedStatus($containers, $excludedContainers);');
// Check that the trait uses ContainerStatusAggregator and appends :excluded suffix
$traitFile = file_get_contents(__DIR__.'/../../app/Traits/CalculatesExcludedStatus.php');
expect($traitFile)
->toContain('ContainerStatusAggregator')
->toContain('appendExcludedSuffix')
->toContain('$aggregator->aggregateFromContainers($excludedOnly)')
->toContain("return 'degraded:excluded';")
->toContain("return 'paused:excluded';")
->toContain("return 'exited';")
->toContain('return "$status:excluded";'); // For running:healthy:excluded
});
it('ensures Service model returns excluded status when all services excluded', function () {
$serviceModelFile = file_get_contents(__DIR__.'/../../app/Models/Service.php');
// Check that when all services are excluded from status checks,
// the Service model calculates real status and returns it with :excluded suffix
expect($serviceModelFile)
->toContain('exclude_from_status')
->toContain(':excluded')
->toContain('CalculatesExcludedStatus');
});
it('ensures Service model returns unknown:unknown:excluded when no containers exist', function () {
$serviceModelFile = file_get_contents(__DIR__.'/../../app/Models/Service.php');
// Check that when a service has no applications or databases at all,
// the Service model returns 'unknown:unknown:excluded' instead of 'exited'
// This prevents misleading status display when containers don't exist
expect($serviceModelFile)
->toContain('// If no status was calculated at all (no containers exist), return unknown')
->toContain('if ($excludedStatus === null && $excludedHealth === null) {')
->toContain("return 'unknown:unknown:excluded';");
});
it('ensures GetContainersStatus calculates excluded status when all containers excluded', function () {
$getContainersStatusFile = file_get_contents(__DIR__.'/../../app/Actions/Docker/GetContainersStatus.php');
// Check that when all containers are excluded, the aggregateApplicationStatus
// method calculates and returns status with :excluded suffix
expect($getContainersStatusFile)
->toContain('// If all containers are excluded, calculate status from excluded containers')
->toContain('if ($relevantStatuses->isEmpty()) {')
->toContain('return $this->calculateExcludedStatusFromStrings($containerStatuses);');
});
it('ensures exclude_from_hc flag is properly checked in ComplexStatusCheck', function () {
$complexStatusCheckFile = file_get_contents(__DIR__.'/../../app/Actions/Shared/ComplexStatusCheck.php');
// Verify that exclude_from_hc is parsed using trait helper
expect($complexStatusCheckFile)
->toContain('$excludedContainers = $this->getExcludedContainersFromDockerCompose($dockerComposeRaw);');
});
it('ensures exclude_from_hc flag is properly checked in GetContainersStatus', function () {
$getContainersStatusFile = file_get_contents(__DIR__.'/../../app/Actions/Docker/GetContainersStatus.php');
// Verify that exclude_from_hc is parsed using trait helper
expect($getContainersStatusFile)
->toContain('$excludedContainers = $this->getExcludedContainersFromDockerCompose($dockerComposeRaw);');
});
/**
* Unit tests for YAML validation in CalculatesExcludedStatus trait
*/
it('ensures YAML validation has proper exception handling for parse errors', function () {
$traitFile = file_get_contents(__DIR__.'/../../app/Traits/CalculatesExcludedStatus.php');
// Verify that ParseException is imported and caught separately from generic Exception
expect($traitFile)
->toContain('use Symfony\Component\Yaml\Exception\ParseException')
->toContain('use Illuminate\Support\Facades\Log')
->toContain('} catch (ParseException $e) {')
->toContain('} catch (\Exception $e) {');
});
it('ensures YAML validation logs parse errors with context', function () {
$traitFile = file_get_contents(__DIR__.'/../../app/Traits/CalculatesExcludedStatus.php');
// Verify that parse errors are logged with useful context (error message, line, snippet)
expect($traitFile)
->toContain('Log::warning(\'Failed to parse Docker Compose YAML for health check exclusions\'')
->toContain('\'error\' => $e->getMessage()')
->toContain('\'line\' => $e->getParsedLine()')
->toContain('\'snippet\' => $e->getSnippet()');
});
it('ensures YAML validation logs unexpected errors', function () {
$traitFile = file_get_contents(__DIR__.'/../../app/Traits/CalculatesExcludedStatus.php');
// Verify that unexpected errors are logged with error level
expect($traitFile)
->toContain('Log::error(\'Unexpected error parsing Docker Compose YAML\'')
->toContain('\'trace\' => $e->getTraceAsString()');
});
it('ensures YAML validation checks structure after parsing', function () {
$traitFile = file_get_contents(__DIR__.'/../../app/Traits/CalculatesExcludedStatus.php');
// Verify that parsed result is validated to be an array
expect($traitFile)
->toContain('if (! is_array($dockerCompose)) {')
->toContain('Log::warning(\'Docker Compose YAML did not parse to array\'');
// Verify that services is validated to be an array
expect($traitFile)
->toContain('if (! is_array($services)) {')
->toContain('Log::warning(\'Docker Compose services is not an array\'');
});