diff options
| author | Christian Cleberg <[email protected]> | 2026-04-12 00:55:42 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-12 00:55:42 -0500 |
| commit | 9050405b4f33b2b9b70458fcf3e43b80c940eef7 (patch) | |
| tree | 983c3a07a560258059cfe421beb3ffcf3c18baf4 /HutchTests | |
| parent | 5f6d545eb3455a9e4da5a3cb4460811e3a48d939 (diff) | |
| download | hutch-2.15.0.tar.gz hutch-2.15.0.tar.bz2 hutch-2.15.0.zip | |
add shortcuts widgets and power-user workflowsv2.15.0
Diffstat (limited to 'HutchTests')
| -rw-r--r-- | HutchTests/DeepLinkTests.swift | 90 | ||||
| -rw-r--r-- | HutchTests/HutchIntentsTests.swift | 75 | ||||
| -rw-r--r-- | HutchTests/SystemStatusWidgetSnapshotTests.swift | 73 |
3 files changed, 238 insertions, 0 deletions
diff --git a/HutchTests/DeepLinkTests.swift b/HutchTests/DeepLinkTests.swift new file mode 100644 index 0000000..12f759b --- /dev/null +++ b/HutchTests/DeepLinkTests.swift @@ -0,0 +1,90 @@ +import Foundation +import Testing +@testable import Hutch + +struct DeepLinkTests { + + @Test + func parsesHomeLink() { + let link = DeepLink(url: URL(string: "hutch://home")!) + #expect(link == .home) + } + + @Test + func parsesNilPathAsHome() { + let link = DeepLink(url: URL(string: "hutch://")!) + #expect(link == .home) + } + + @Test + func parsesRepositoryLink() { + let link = DeepLink(url: URL(string: "hutch://git/~user/repo")!) + #expect(link == .repository(owner: "~user", repo: "repo")) + } + + @Test + func parsesTicketLink() { + let link = DeepLink(url: URL(string: "hutch://todo/~owner/tracker/42")!) + #expect(link == .ticket(owner: "~owner", tracker: "tracker", ticketId: 42)) + } + + @Test + func parsesBuildJobLink() { + let link = DeepLink(url: URL(string: "hutch://builds/12345")!) + #expect(link == .build(jobId: 12345)) + } + + @Test + func parsesBuildsTabLink() { + let link = DeepLink(url: URL(string: "hutch://builds")!) + #expect(link == .buildsTab) + } + + @Test + func parsesRepositoriesTabLink() { + let link = DeepLink(url: URL(string: "hutch://repositories")!) + #expect(link == .repositoriesTab) + } + + @Test + func parsesTrackersTabLink() { + let link = DeepLink(url: URL(string: "hutch://trackers")!) + #expect(link == .trackersTab) + } + + @Test + func parsesSystemStatusLink() { + let link = DeepLink(url: URL(string: "hutch://status")!) + #expect(link == .systemStatus) + } + + @Test + func parsesLookupLink() { + let link = DeepLink(url: URL(string: "hutch://lookup")!) + #expect(link == .lookup) + } + + @Test + func rejectsNonHutchScheme() { + let link = DeepLink(url: URL(string: "https://example.com/home")!) + #expect(link == nil) + } + + @Test + func rejectsUnknownPath() { + let link = DeepLink(url: URL(string: "hutch://unknown")!) + #expect(link == nil) + } + + @Test + func rejectsTicketLinkWithNonNumericId() { + let link = DeepLink(url: URL(string: "hutch://todo/~owner/tracker/abc")!) + #expect(link == nil) + } + + @Test + func rejectsBuildLinkWithNonNumericId() { + let link = DeepLink(url: URL(string: "hutch://builds/abc")!) + #expect(link == nil) + } +} diff --git a/HutchTests/HutchIntentsTests.swift b/HutchTests/HutchIntentsTests.swift new file mode 100644 index 0000000..94ecbf0 --- /dev/null +++ b/HutchTests/HutchIntentsTests.swift @@ -0,0 +1,75 @@ +import Foundation +import Testing +@testable import Hutch + +@MainActor +struct HutchIntentsTests { + + @Test + func checkSystemStatusReturnsOperationalWhenNoDisruption() async throws { + let defaultsName = "HutchIntentsTests-status-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let snapshot = SystemStatusWidgetSnapshot( + services: [ + .init(id: "git", name: "git.sr.ht", status: "Operational", requiresAttention: false), + ], + hasDisruption: false, + overallStatusText: "All monitored services operational", + bannerSummary: "", + updatedAt: .now + ) + SystemStatusWidgetSnapshotStore.save(snapshot, defaults: defaults) + + let loaded = SystemStatusWidgetSnapshotStore.load(defaults: defaults) + #expect(loaded != nil) + #expect(loaded?.hasDisruption == false) + } + + @Test + func checkSystemStatusReturnsDisruptionDetails() async throws { + let defaultsName = "HutchIntentsTests-disruption-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let snapshot = SystemStatusWidgetSnapshot( + services: [ + .init(id: "git", name: "git.sr.ht", status: "Degraded", requiresAttention: true), + .init(id: "meta", name: "meta.sr.ht", status: "Operational", requiresAttention: false), + ], + hasDisruption: true, + overallStatusText: "Experiencing disruptions", + bannerSummary: "git.sr.ht disrupted", + updatedAt: .now + ) + SystemStatusWidgetSnapshotStore.save(snapshot, defaults: defaults) + + let loaded = SystemStatusWidgetSnapshotStore.load(defaults: defaults) + #expect(loaded?.hasDisruption == true) + + let disrupted = loaded!.services.filter(\.requiresAttention) + #expect(disrupted.count == 1) + #expect(disrupted.first?.name == "git.sr.ht") + } + + @Test + func needsAttentionSnapshotSupportsBuildsCheck() { + let defaultsName = "HutchIntentsTests-builds-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let snapshot = NeedsAttentionSnapshot( + unreadInboxThreads: 5, + assignedOpenTickets: 3, + failedBuilds: 2, + updatedAt: .now + ) + NeedsAttentionSnapshotStore.save(snapshot, defaults: defaults) + + let loaded = NeedsAttentionSnapshotStore.load(defaults: defaults) + #expect(loaded?.failedBuilds == 2) + #expect(loaded?.unreadInboxThreads == 5) + #expect(loaded?.assignedOpenTickets == 3) + } +} diff --git a/HutchTests/SystemStatusWidgetSnapshotTests.swift b/HutchTests/SystemStatusWidgetSnapshotTests.swift new file mode 100644 index 0000000..ddb74b1 --- /dev/null +++ b/HutchTests/SystemStatusWidgetSnapshotTests.swift @@ -0,0 +1,73 @@ +import Foundation +import Testing +@testable import Hutch + +@MainActor +struct SystemStatusWidgetSnapshotTests { + + @Test + func saveAndLoadRoundTrips() { + let defaultsName = "SystemStatusWidgetSnapshotTests-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let snapshot = SystemStatusWidgetSnapshot( + services: [ + .init(id: "git", name: "git.sr.ht", status: "Operational", requiresAttention: false), + .init(id: "builds", name: "builds.sr.ht", status: "Degraded", requiresAttention: true), + ], + hasDisruption: true, + overallStatusText: "Experiencing disruptions", + bannerSummary: "builds.sr.ht disrupted", + updatedAt: Date(timeIntervalSince1970: 1000) + ) + + SystemStatusWidgetSnapshotStore.save(snapshot, defaults: defaults) + let loaded = SystemStatusWidgetSnapshotStore.load(defaults: defaults) + + #expect(loaded != nil) + #expect(loaded?.services.count == 2) + #expect(loaded?.hasDisruption == true) + #expect(loaded?.bannerSummary == "builds.sr.ht disrupted") + #expect(loaded?.services[0].name == "git.sr.ht") + #expect(loaded?.services[1].requiresAttention == true) + } + + @Test + func loadReturnsNilWhenEmpty() { + let defaultsName = "SystemStatusWidgetSnapshotTests-empty-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let loaded = SystemStatusWidgetSnapshotStore.load(defaults: defaults) + #expect(loaded == nil) + } + + @Test + func clearRemovesSnapshot() { + let defaultsName = "SystemStatusWidgetSnapshotTests-clear-\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: defaultsName)! + defer { defaults.removePersistentDomain(forName: defaultsName) } + + let snapshot = SystemStatusWidgetSnapshot( + services: [.init(id: "meta", name: "meta.sr.ht", status: "Operational", requiresAttention: false)], + hasDisruption: false, + overallStatusText: "All monitored services operational", + bannerSummary: "", + updatedAt: .now + ) + + SystemStatusWidgetSnapshotStore.save(snapshot, defaults: defaults) + #expect(SystemStatusWidgetSnapshotStore.load(defaults: defaults) != nil) + + SystemStatusWidgetSnapshotStore.clear(defaults: defaults) + #expect(SystemStatusWidgetSnapshotStore.load(defaults: defaults) == nil) + } + + @Test + func unavailableSnapshotHasEmptyServices() { + let snapshot = SystemStatusWidgetSnapshot.unavailable + #expect(snapshot.services.isEmpty) + #expect(snapshot.hasDisruption == false) + } +} |
