Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Models/ComponentGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public function isExpanded(): bool
public function hasActiveIncident(): bool
{
return Incident::query()
->whereIn('component_id', $this->components->pluck('id'))
->unresolved()
->whereHas('components', fn ($query) => $query->whereIn('components.id', $this->components->pluck('id')))
->exists();
}

Expand Down
136 changes: 136 additions & 0 deletions tests/Unit/Models/ComponentGroupTest.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<?php

use Cachet\Enums\ComponentGroupVisibilityEnum;
use Cachet\Enums\IncidentStatusEnum;
use Cachet\Enums\ResourceVisibilityEnum;
use Cachet\Models\Component;
use Cachet\Models\ComponentGroup;
use Cachet\Models\Incident;

it('can have components', function () {
$group = ComponentGroup::factory()->hasComponents(2)->create();
Expand All @@ -21,3 +25,135 @@
->and(ComponentGroup::query()->visibility(ResourceVisibilityEnum::guest)->count())->toBe(1)
->and(ComponentGroup::query()->visibility(ResourceVisibilityEnum::hidden)->count())->toBe(1);
});

it('is always collapsed when collapsed option is set', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed]);

expect($group->isExpanded())->toBeFalse();
});

it('is always expanded when expanded option is set', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::expanded]);

expect($group->isExpanded())->toBeTrue();
});

it('is collapsed when collapsed_unless_incident is set and no incidents exist', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

expect($group->isExpanded())->toBeFalse();
});

it('is expanded when collapsed_unless_incident is set and an unresolved incident exists', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::investigating]);
$incident->components()->attach($component);

expect($group->isExpanded())->toBeTrue();
});

it('is collapsed when collapsed_unless_incident is set and only resolved incidents exist', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::fixed]);
$incident->components()->attach($component);

expect($group->isExpanded())->toBeFalse();
});

it('expands when an incident is started on a component', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();

// Initially collapsed
expect($group->isExpanded())->toBeFalse();

// Create an incident and attach it to the component
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::investigating]);
$incident->components()->attach($component);

// Should now be expanded
expect($group->fresh()->isExpanded())->toBeTrue();
});

it('collapses when all incidents are resolved', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::investigating]);
$incident->components()->attach($component);

// Should be expanded with active incident
expect($group->isExpanded())->toBeTrue();

// Mark incident as fixed
$incident->update(['status' => IncidentStatusEnum::fixed]);

// Should now be collapsed
expect($group->fresh()->isExpanded())->toBeFalse();
});

it('has active incident returns true for all unresolved statuses', function (IncidentStatusEnum $status) {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();
$incident = Incident::factory()->create(['status' => $status]);
$incident->components()->attach($component);

expect($group->hasActiveIncident())->toBeTrue();
})->with([
'unknown' => IncidentStatusEnum::unknown,
'investigating' => IncidentStatusEnum::investigating,
'identified' => IncidentStatusEnum::identified,
'watching' => IncidentStatusEnum::watching,
]);

it('has active incident returns false for fixed status', function () {
$group = ComponentGroup::factory()
->hasComponents(1)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$component = $group->components->first();
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::fixed]);
$incident->components()->attach($component);

expect($group->hasActiveIncident())->toBeFalse();
});

it('expands when any component in the group has an active incident', function () {
$group = ComponentGroup::factory()
->hasComponents(3)
->create(['collapsed' => ComponentGroupVisibilityEnum::collapsed_unless_incident]);

$components = $group->components;

// No incidents - should be collapsed
expect($group->isExpanded())->toBeFalse();

// Add incident to just one component
$incident = Incident::factory()->create(['status' => IncidentStatusEnum::investigating]);
$incident->components()->attach($components->first());

// Should be expanded
expect($group->fresh()->isExpanded())->toBeTrue();
});