delete(); $this->adminId = (int) DB::table('saas_admin_users')->insertGetId([ 'email' => 'inc-'.bin2hex(random_bytes(3)).'@test', 'full_name' => 'Incident Admin', 'password_hash' => bcrypt('test1234'), 'is_active' => true, 'role' => 'support', 'created_at' => now(), ]); }); function makeShowIncident(int $adminId, array $overrides = []): int { $started = $overrides['started_at'] ?? now()->subHours(3); $detected = $overrides['detected_at'] ?? $started; return (int) DB::table('incidents_log')->insertGetId(array_merge([ 'type' => 'service_outage', 'severity' => 'high', 'started_at' => $started, 'detected_at' => $detected, 'resolved_at' => null, 'summary' => 'Show test incident', 'created_by_admin_id' => $adminId, 'created_at' => now(), ], $overrides)); } test('GET /api/admin/incidents/{id} 200 + полная карточка', function () { $id = makeShowIncident($this->adminId, ['summary' => 'API 502 burst', 'severity' => 'critical']); $r = $this->getJson("/api/admin/incidents/{$id}"); $r->assertOk(); expect($r->json('incident.id'))->toBe($id); expect($r->json('incident.summary'))->toBe('API 502 burst'); expect($r->json('incident.severity'))->toBe('critical'); expect($r->json('incident.incident_id'))->toMatch('/^INC-\d{4}-\d{4}-\d{4}$/'); expect($r->json('incident.status'))->toBe('investigating'); expect($r->json('incident.created_by_admin'))->toBe('Incident Admin'); }); test('GET /api/admin/incidents/{id} несуществующий → 404', function () { $this->getJson('/api/admin/incidents/99999999')->assertStatus(404); }); test('GET /api/admin/incidents/{id} data_breach без rkn_notified_at → rkn_deadline_at +24ч', function () { $id = makeShowIncident($this->adminId, ['type' => 'data_breach', 'detected_at' => now()->subHour()]); $r = $this->getJson("/api/admin/incidents/{$id}"); expect($r->json('incident.rkn_notified'))->toBeFalse(); expect($r->json('incident.rkn_deadline_at'))->toBeString(); }); test('GET /api/admin/incidents/{id} разрешает имена affected_tenants', function () { $tenantId = (int) DB::table('tenants')->insertGetId([ 'subdomain' => 'inc-'.bin2hex(random_bytes(4)), 'organization_name' => 'Affected Org', 'contact_email' => 'a@test.local', 'created_at' => now(), ]); $id = makeShowIncident($this->adminId, ['affected_tenant_ids' => '{'.$tenantId.'}']); $r = $this->getJson("/api/admin/incidents/{$id}"); expect($r->json('incident.affected_tenants'))->toHaveCount(1); expect($r->json('incident.affected_tenants.0.organization_name'))->toBe('Affected Org'); }); test('GET /api/admin/incidents/{id} resolved инцидент → status resolved', function () { $id = makeShowIncident($this->adminId, ['resolved_at' => now()]); expect($this->getJson("/api/admin/incidents/{$id}")->json('incident.status'))->toBe('resolved'); });