import Foundation import Testing @testable import Hutch struct SystemStatusServiceTests { @Test func parsesCurrentStatusHTMLIntoServicesAndActiveIncidents() throws { let snapshot = try SystemStatusService.parseSnapshotHTML(Self.sampleHTML, fetchedAt: Date(timeIntervalSince1970: 100)) #expect(snapshot.services.count == 3) #expect(snapshot.services[0].name == "git.sr.ht") #expect(snapshot.services[0].status == .degraded) #expect(snapshot.services[1].status == .operational) #expect(snapshot.hasDisruption) #expect(snapshot.activeIncidents.count == 1) #expect(snapshot.activeIncidents[0].title == "SourceHut disrupted due to DDoS attack") #expect(snapshot.activeIncidents[0].summary == "SourceHut was disrupted by a DDoS attack.") #expect(snapshot.activeIncidents[0].url?.absoluteString == "https://status.sr.ht/issues/2026-04-06-ddos-attack/") } @Test func parsesStatusHTMLWithClassOrderChangesAndTimeElements() throws { let snapshot = try SystemStatusService.parseSnapshotHTML(Self.variantHTML, fetchedAt: .now) #expect(snapshot.services.count == 2) #expect(snapshot.services[0].status == .operational) #expect(snapshot.services[1].status == .majorOutage) #expect(snapshot.activeIncidents.count == 1) #expect(snapshot.activeIncidents[0].title == "builds.sr.ht outage") #expect(snapshot.activeIncidents[0].publishedAt == ISO8601DateFormatter().date(from: "2026-04-07T12:00:00Z")) } @Test func parsesIncidentFeedRSS() async throws { let incidents = try await SystemStatusService.parseIncidentFeedXML(Data(Self.sampleRSS.utf8)) #expect(incidents.count == 2) #expect(incidents[0].title == "SourceHut disrupted due to DDoS attack") #expect(incidents[0].isActive == true) #expect(incidents[0].summary == "SourceHut was disrupted by a DDoS attack.") #expect(incidents[1].title == "Planned maintenance on all services") #expect(incidents[1].isActive == false) #expect(incidents[1].updatedAt != nil) } @Test func parsesIncidentFeedWithISO8601Dates() async throws { let incidents = try await SystemStatusService.parseIncidentFeedXML(Data(Self.variantRSS.utf8)) #expect(incidents.count == 1) #expect(incidents[0].title == "Status feed moved") #expect(incidents[0].publishedAt == ISO8601DateFormatter().date(from: "2026-04-07T15:30:00Z")) } @Test func bannerSummaryPrefersSpecificServiceThenCount() { let operational = SystemStatusSnapshot( services: [ StatusServiceState(id: "git.sr.ht", name: "git.sr.ht", slug: "git.sr.ht", status: .operational, description: nil) ], activeIncidents: [], lastUpdated: .now ) let oneDisrupted = SystemStatusSnapshot( services: [ StatusServiceState(id: "git.sr.ht", name: "git.sr.ht", slug: "git.sr.ht", status: .degraded, description: nil), StatusServiceState(id: "hg.sr.ht", name: "hg.sr.ht", slug: "hg.sr.ht", status: .operational, description: nil) ], activeIncidents: [], lastUpdated: .now ) let multipleDisrupted = SystemStatusSnapshot( services: [ StatusServiceState(id: "git.sr.ht", name: "git.sr.ht", slug: "git.sr.ht", status: .degraded, description: nil), StatusServiceState(id: "builds.sr.ht", name: "builds.sr.ht", slug: "builds.sr.ht", status: .majorOutage, description: nil) ], activeIncidents: [], lastUpdated: .now ) #expect(operational.hasDisruption == false) #expect(oneDisrupted.bannerSummary == "git.sr.ht disrupted") #expect(multipleDisrupted.bannerSummary == "2 services disrupted") } private static let sampleHTML = #"""
Build jobs are currently failing.