diff options
Diffstat (limited to 'DomainDig/AuditFixtures.swift')
| -rw-r--r-- | DomainDig/AuditFixtures.swift | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/DomainDig/AuditFixtures.swift b/DomainDig/AuditFixtures.swift new file mode 100644 index 0000000..0a9655b --- /dev/null +++ b/DomainDig/AuditFixtures.swift @@ -0,0 +1,168 @@ +#if DEBUG +import Foundation + +/// Deterministic in-memory fixtures for the accessibility audit suite. +/// +/// The dense rows (`WatchlistRowView`, `BatchResultRowView`) and the Dashboard +/// portfolio sections never render on a fresh simulator, so five phases of row +/// treatment shipped unverified by the automated audit. Driving the add-domain +/// UI instead was tried and rejected: typing raises the keyboard, which then +/// follows the audit onto later screens, and the added domains persist across +/// runs, contaminating every other test's baseline. +/// +/// These are activated by the `DOMAIN_DIG_SEED_FIXTURES` launch argument +/// (DEBUG builds only, same pattern as `DOMAIN_DIG_FORCE_PRO_PLUS`) and are +/// **never persisted** — see `seedAuditFixturesIfRequested()`. +/// +/// The set is chosen to exercise every row path: healthy/warning/critical +/// certificate badges, pinned, noted, changed, monitoring on/off, a +/// stress-length domain name, and every batch status including failure. +enum AuditFixtures { + static let launchArgument = "DOMAIN_DIG_SEED_FIXTURES" + + static var requested: Bool { + ProcessInfo.processInfo.arguments.contains(launchArgument) + } + + /// Relative to launch so the recency-gated Dashboard sections (Recent + /// Activity, Attention Required — both keyed to the last 24h) actually + /// render. Label text varies run to run ("2 hr. ago"); the audit measures + /// layout and traits, not string equality, so coverage wins. + private static let now = Date() + + static var trackedDomains: [TrackedDomain] { + [ + TrackedDomain( + domain: "healthy.example", + createdAt: now.addingTimeInterval(-86_400 * 30), + updatedAt: now.addingTimeInterval(-3_600), + isPinned: true, + monitoringEnabled: true, + lastKnownAvailability: .registered, + certificateWarningLevel: .none, + certificateDaysRemaining: 240, + lastMonitoredAt: now.addingTimeInterval(-1_800) + ), + TrackedDomain( + domain: "expiring.example", + createdAt: now.addingTimeInterval(-86_400 * 90), + updatedAt: now.addingTimeInterval(-7_200), + monitoringEnabled: true, + lastKnownAvailability: .registered, + lastChangeSummary: DomainChangeSummary( + hasChanges: true, + changedSections: ["ssl"], + message: "Certificate is approaching expiry", + severity: .medium, + impactClassification: .warning, + generatedAt: now.addingTimeInterval(-7_200) + ), + lastChangeSeverity: .medium, + certificateWarningLevel: .warning, + certificateDaysRemaining: 12, + lastMonitoredAt: now.addingTimeInterval(-7_200), + lastAlertAt: now.addingTimeInterval(-7_000) + ), + TrackedDomain( + domain: "broken.example", + createdAt: now.addingTimeInterval(-86_400 * 7), + updatedAt: now.addingTimeInterval(-600), + note: "Production incident follow-up: certificate replaced?", + monitoringEnabled: false, + lastKnownAvailability: .registered, + lastChangeSummary: DomainChangeSummary( + hasChanges: true, + changedSections: ["ssl", "dns"], + message: "TLS validation failed and NS records changed", + severity: .high, + impactClassification: .critical, + generatedAt: now.addingTimeInterval(-600) + ), + lastChangeSeverity: .high, + certificateWarningLevel: .critical, + certificateDaysRemaining: -3 + ), + TrackedDomain( + domain: "very-long-subdomain.observability.internal.staging.example", + createdAt: now.addingTimeInterval(-86_400), + updatedAt: now.addingTimeInterval(-60), + monitoringEnabled: true, + lastKnownAvailability: .unknown + ) + ] + } + + static var batchResults: [BatchLookupResult] { + [ + BatchLookupResult( + domain: "healthy.example", + historyEntryID: nil, + resultSource: .live, + availability: .registered, + primaryIP: "203.0.113.10", + quickStatus: "Stable", + summaryMessage: nil, + changeSeverity: nil, + changeClassification: nil, + certificateWarningLevel: .none, + riskScore: 12, + riskLevel: .low, + timestamp: now.addingTimeInterval(-120), + status: .completed, + errorMessage: nil + ), + BatchLookupResult( + domain: "expiring.example", + historyEntryID: nil, + resultSource: .cached, + availability: .registered, + primaryIP: "203.0.113.11", + quickStatus: "Changed", + summaryMessage: "Certificate is approaching expiry", + changeSeverity: .medium, + changeClassification: .warning, + certificateWarningLevel: .warning, + riskScore: 41, + riskLevel: .medium, + timestamp: now.addingTimeInterval(-3_600), + status: .completed, + errorMessage: nil + ), + BatchLookupResult( + domain: "broken.example", + historyEntryID: nil, + resultSource: .live, + availability: .registered, + primaryIP: "2001:db8::1f3:44", + quickStatus: "Changed", + summaryMessage: "TLS validation failed", + changeSeverity: .high, + changeClassification: .critical, + certificateWarningLevel: .critical, + riskScore: 78, + riskLevel: .high, + timestamp: now.addingTimeInterval(-60), + status: .completed, + errorMessage: nil + ), + BatchLookupResult( + domain: "unreachable.example", + historyEntryID: nil, + resultSource: .live, + availability: nil, + primaryIP: nil, + quickStatus: "Failed", + summaryMessage: nil, + changeSeverity: nil, + changeClassification: nil, + certificateWarningLevel: .none, + riskScore: nil, + riskLevel: nil, + timestamp: now, + status: .failed, + errorMessage: "The lookup timed out before any records were returned" + ) + ] + } +} +#endif |
