TenantAtlas/apps/platform/tests/Feature/Findings/FindingWorkflowRegressionTest.php
ahmido 29ad8852ca
Some checks failed
Main Confidence / confidence (push) Failing after 1m1s
Heavy Governance Lane / heavy-governance (push) Has been skipped
Browser Lane / browser (push) Has been skipped
merge: platform-dev into dev (#295)
## Summary
- integrate the current `platform-dev` branch into `dev`
- bring the latest platform work from the integration branch into the main development branch
- include the recent findings lifecycle backfill removal slice together with the already accumulated `platform-dev` changes

## Scope
- source branch: `platform-dev`
- target branch: `dev`
- branch role: integration PR, not a single-feature PR

## Validation
- branch state reviewed before PR creation
- `platform-dev` is ahead of `dev` with the expected integration history
- this PR intentionally carries the accumulated `platform-dev` commits into `dev`

## Notes
- this is the correct merge direction for the current workflow, where feature branches land in `platform-dev` first and `platform-dev` is then merged into `dev`
- after merging, `platform-dev` can be recreated fresh from `dev` as usual

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #295
2026-04-28 22:11:20 +00:00

62 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Finding;
use App\Models\User;
use App\Services\Findings\FindingWorkflowService;
use App\Support\Audit\AuditActionId;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
it('keeps canonical findings workflow behavior after removing the backfill runtime surfaces', function (): void {
[$owner, $tenant] = createUserWithTenant(role: 'owner');
$assignee = User::factory()->create();
createUserWithTenant(tenant: $tenant, user: $assignee, role: 'operator');
$service = app(FindingWorkflowService::class);
$finding = $this->makeFindingForWorkflow($tenant, Finding::STATUS_NEW, [
'owner_user_id' => null,
'assignee_user_id' => null,
'sla_days' => 14,
'due_at' => now()->addDays(14),
]);
$triaged = $service->triage($finding, $tenant, $owner);
$assigned = $service->assign(
finding: $triaged,
tenant: $tenant,
actor: $owner,
assigneeUserId: (int) $assignee->getKey(),
ownerUserId: (int) $owner->getKey(),
);
$inProgress = $service->startProgress($assigned, $tenant, $owner);
$resolved = $service->resolve($inProgress, $tenant, $owner, Finding::RESOLVE_REASON_REMEDIATED);
$riskAccepted = $service->riskAccept(
$this->makeFindingForWorkflow($tenant, Finding::STATUS_NEW),
$tenant,
$owner,
Finding::CLOSE_REASON_ACCEPTED_RISK,
);
expect($triaged->status)->toBe(Finding::STATUS_TRIAGED)
->and($triaged->triaged_at)->not->toBeNull()
->and((int) $assigned->owner_user_id)->toBe((int) $owner->getKey())
->and((int) $assigned->assignee_user_id)->toBe((int) $assignee->getKey())
->and($assigned->sla_days)->toBe(14)
->and($assigned->due_at)->not->toBeNull()
->and($inProgress->status)->toBe(Finding::STATUS_IN_PROGRESS)
->and($inProgress->in_progress_at)->not->toBeNull()
->and($resolved->status)->toBe(Finding::STATUS_RESOLVED)
->and($resolved->resolved_reason)->toBe(Finding::RESOLVE_REASON_REMEDIATED)
->and($riskAccepted->status)->toBe(Finding::STATUS_RISK_ACCEPTED)
->and($riskAccepted->closed_reason)->toBe(Finding::CLOSE_REASON_ACCEPTED_RISK);
expect($this->latestFindingAudit($triaged, AuditActionId::FindingTriaged))->not->toBeNull()
->and($this->latestFindingAudit($assigned, AuditActionId::FindingAssigned))->not->toBeNull()
->and($this->latestFindingAudit($inProgress, AuditActionId::FindingInProgress))->not->toBeNull()
->and($this->latestFindingAudit($resolved, AuditActionId::FindingResolved))->not->toBeNull()
->and($this->latestFindingAudit($riskAccepted, AuditActionId::FindingRiskAccepted))->not->toBeNull();
});