diff options
| author | Christian Cleberg <[email protected]> | 2026-04-12 00:34:54 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-12 00:34:54 -0500 |
| commit | 5f6d545eb3455a9e4da5a3cb4460811e3a48d939 (patch) | |
| tree | 7b7591146da4e02bd617ddb9f26e47b1c4474ef6 /HutchTests | |
| parent | cb1ea5ea4f163d87053285d3fb7999b12a3558b9 (diff) | |
| download | hutch-2.14.0.tar.gz hutch-2.14.0.tar.bz2 hutch-2.14.0.zip | |
improve home attention flows and cross-linkingv2.14.0
Diffstat (limited to 'HutchTests')
| -rw-r--r-- | HutchTests/AppStateTests.swift | 42 | ||||
| -rw-r--r-- | HutchTests/BuildListViewModelTests.swift | 20 | ||||
| -rw-r--r-- | HutchTests/HomeViewModelTests.swift | 13 | ||||
| -rw-r--r-- | HutchTests/InboxViewModelTests.swift | 49 |
4 files changed, 122 insertions, 2 deletions
diff --git a/HutchTests/AppStateTests.swift b/HutchTests/AppStateTests.swift index 9cf4e13..fe357cb 100644 --- a/HutchTests/AppStateTests.swift +++ b/HutchTests/AppStateTests.swift @@ -33,4 +33,46 @@ struct AppStateTests { #expect(appState.selectedTab == .more) #expect(appState.pendingTabNavigation == .systemStatus) } + + @Test + @MainActor + func navigationHelpersQueueExpectedTargets() { + let appState = AppState() + let repository = RepositorySummary( + id: 1, + rid: "repo", + service: .git, + name: "hutch", + description: nil, + visibility: .public, + updated: .distantPast, + owner: Entity(canonicalName: "~owner"), + head: nil + ) + let tracker = TrackerSummary( + id: 2, + rid: "tracker", + name: "todo", + description: nil, + visibility: .public, + updated: .distantPast, + owner: Entity(canonicalName: "~owner") + ) + + appState.navigateToRepository(repository) + #expect(appState.selectedTab == .repositories) + #expect(appState.pendingTabNavigation == .repository(repository)) + + appState.navigateToTracker(tracker) + #expect(appState.selectedTab == .tickets) + #expect(appState.pendingTabNavigation == .tracker(tracker)) + + appState.navigateToBuild(jobId: 42) + #expect(appState.selectedTab == .builds) + #expect(appState.pendingDeepLink == .build(jobId: 42)) + + appState.navigateToTicket(ownerUsername: "owner", trackerName: "todo", ticketId: 9) + #expect(appState.selectedTab == .tickets) + #expect(appState.pendingDeepLink == .ticket(owner: "owner", tracker: "todo", ticketId: 9)) + } } diff --git a/HutchTests/BuildListViewModelTests.swift b/HutchTests/BuildListViewModelTests.swift index a5c2483..a8cdc30 100644 --- a/HutchTests/BuildListViewModelTests.swift +++ b/HutchTests/BuildListViewModelTests.swift @@ -28,6 +28,22 @@ struct BuildListViewModelTests { #expect(filtered.map(\.id) == [42]) } + @Test + func buildFilterPrioritizesActionableStates() { + let jobs = [ + makeJob(id: 1, status: .success, tags: []), + makeJob(id: 2, status: .failed, tags: []), + makeJob(id: 3, status: .running, tags: []), + makeJob(id: 4, status: .cancelled, tags: []) + ] + + let attention = BuildListViewModel.filterJobs(jobs, filter: .attention) + let active = BuildListViewModel.filterJobs(jobs, filter: .active) + + #expect(attention.map(\.id) == [2, 3]) + #expect(active.map(\.id) == [3]) + } + private func filterJobs(_ jobs: [JobSummary], query: String) -> [JobSummary] { let q = query.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() guard !q.isEmpty else { return jobs } @@ -39,12 +55,12 @@ struct BuildListViewModelTests { } } - private func makeJob(id: Int, tags: [String]) -> JobSummary { + private func makeJob(id: Int, status: JobStatus = .success, tags: [String]) -> JobSummary { JobSummary( id: id, created: Date(), updated: Date(), - status: .success, + status: status, note: nil, tags: tags, visibility: nil, diff --git a/HutchTests/HomeViewModelTests.swift b/HutchTests/HomeViewModelTests.swift index fef93e0..72f2e71 100644 --- a/HutchTests/HomeViewModelTests.swift +++ b/HutchTests/HomeViewModelTests.swift @@ -59,6 +59,19 @@ struct HomeViewModelTests { #expect(repository?.name == "hutch") } + @Test + func buildItemsAreSortedForTriage() { + let jobs = [ + makeJob(id: 1, status: .success, created: Date(timeIntervalSince1970: 10)), + makeJob(id: 2, status: .running, created: Date(timeIntervalSince1970: 20)), + makeJob(id: 3, status: .failed, created: Date(timeIntervalSince1970: 30)) + ] + + let sorted = HomeViewModel.buildItems(from: jobs) + + #expect(sorted.map(\.job.id) == [3, 2, 1]) + } + private func makeJob(id: Int, status: JobStatus, created: Date) -> HomeJobPayload { HomeJobPayload( id: id, diff --git a/HutchTests/InboxViewModelTests.swift b/HutchTests/InboxViewModelTests.swift index 597bbc2..a5a0428 100644 --- a/HutchTests/InboxViewModelTests.swift +++ b/HutchTests/InboxViewModelTests.swift @@ -166,6 +166,55 @@ struct InboxViewModelTests { } @Test + func inboxFilterSeparatesPatchThreadsFromDiscussionThreads() { + let baseList = InboxMailingListReference( + id: 1, + rid: "list", + name: "hutch-devel", + owner: Entity(canonicalName: "~owner") + ) + let patchThread = InboxThreadSummary( + rootEmailID: 10, + rootMessageID: "message-1", + threadRootEmailIDs: [10], + threadRootMessageIDs: ["message-1"], + listID: baseList.id, + listRID: baseList.rid, + listName: baseList.name, + listOwner: baseList.owner, + subject: "[PATCH] add search", + latestSender: Entity(canonicalName: "~alice"), + lastActivityAt: Date(timeIntervalSince1970: 100), + messageCount: 1, + repo: "hutch", + containsPatch: true, + isUnread: true + ) + let discussionThread = InboxThreadSummary( + rootEmailID: 11, + rootMessageID: "message-2", + threadRootEmailIDs: [11], + threadRootMessageIDs: ["message-2"], + listID: baseList.id, + listRID: baseList.rid, + listName: baseList.name, + listOwner: baseList.owner, + subject: "release planning", + latestSender: Entity(canonicalName: "~bob"), + lastActivityAt: Date(timeIntervalSince1970: 200), + messageCount: 2, + repo: "hutch", + containsPatch: false, + isUnread: true + ) + + let threads = [patchThread, discussionThread] + + #expect(InboxViewModel.filterThreads(threads, filter: .patches).map(\.rootEmailID) == [10]) + #expect(InboxViewModel.filterThreads(threads, filter: .discussions).map(\.rootEmailID) == [11]) + } + + @Test func segmentsPatchBodyAndTreatsSignatureAsPlainText() { let body = """ From: Christian Cleberg <[email protected]> |
