create(); [$user] = createUserWithTenant(role: 'owner'); $finding = Finding::factory()->for($tenant)->create(); $this->actingAs($user) ->get(FindingResource::getUrl('index', tenant: $tenant)) ->assertNotFound(); $this->actingAs($user) ->get(FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant)) ->assertNotFound(); }); it('shows triage row action disabled for readonly members', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); $this->actingAs($user); Filament::setTenant($tenant, true); $finding = Finding::factory()->for($tenant)->create([ 'status' => Finding::STATUS_NEW, ]); Livewire::test(ListFindings::class) ->assertTableActionVisible('triage', $finding) ->assertTableActionDisabled('triage', $finding); }); it('enforces 404 for non-member and 403 for member missing capability in workflow service', function (): void { [$owner, $tenant] = createUserWithTenant(role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $outsider = \App\Models\User::factory()->create(); $finding = Finding::factory()->for($tenant)->create([ 'status' => Finding::STATUS_NEW, ]); $service = app(FindingWorkflowService::class); expect(fn () => $service->triage($finding, $tenant, $outsider)) ->toThrow(NotFoundHttpException::class); expect(fn () => $service->triage($finding, $tenant, $readonly)) ->toThrow(AuthorizationException::class); $triaged = $service->triage($finding, $tenant, $owner); expect($triaged->status)->toBe(Finding::STATUS_TRIAGED); });