krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
v3.8.1: HutchTests/BuildListViewModelTests.swift · raw
1import Foundation
2import Testing
3@testable import Hutch
4
5struct BuildListViewModelTests {
6
7 @Test
8 func filteredJobsReturnsAllWhenSearchTextIsEmpty() {
9 let jobs = [makeJob(id: 1, tags: ["ci"]), makeJob(id: 2, tags: [])]
10 let filtered = filterJobs(jobs, query: "")
11
12 #expect(filtered.count == 2)
13 }
14
15 @Test
16 func filteredJobsMatchesByTag() {
17 let jobs = [makeJob(id: 1, tags: ["ci", "deploy"]), makeJob(id: 2, tags: ["lint"])]
18 let filtered = filterJobs(jobs, query: "deploy")
19
20 #expect(filtered.map(\.id) == [1])
21 }
22
23 @Test
24 func filteredJobsMatchesByJobId() {
25 let jobs = [makeJob(id: 42, tags: []), makeJob(id: 99, tags: [])]
26 let filtered = filterJobs(jobs, query: "42")
27
28 #expect(filtered.map(\.id) == [42])
29 }
30
31 @Test
32 func filteredJobsMatchesByStatus() {
33 let jobs = [
34 makeJob(id: 1, status: .running, tags: []),
35 makeJob(id: 2, status: .success, tags: [])
36 ]
37
38 let filtered = filterJobs(jobs, query: "running")
39
40 #expect(filtered.map(\.id) == [1])
41 }
42
43 @Test
44 func buildFilterPrioritizesActionableStates() {
45 let jobs = [
46 makeJob(id: 1, status: .success, tags: []),
47 makeJob(id: 2, status: .failed, tags: []),
48 makeJob(id: 3, status: .running, tags: []),
49 makeJob(id: 4, status: .cancelled, tags: [])
50 ]
51
52 let attention = BuildListViewModel.filterJobs(
53 jobs,
54 filter: .attention,
55 lookbackDays: BuildListViewModel.defaultLookbackDays
56 )
57 let active = BuildListViewModel.filterJobs(
58 jobs,
59 filter: .active,
60 lookbackDays: BuildListViewModel.defaultLookbackDays
61 )
62 let failed = BuildListViewModel.filterJobs(
63 jobs,
64 filter: .failed,
65 lookbackDays: BuildListViewModel.defaultLookbackDays
66 )
67
68 #expect(attention.map(\.id) == [2, 3])
69 #expect(active.map(\.id) == [3])
70 #expect(failed.map(\.id) == [2])
71 }
72
73 @Test
74 func buildFilterRestrictsJobsToSelectedLookbackWindow() {
75 let now = Date(timeIntervalSince1970: 60 * 60 * 24 * 20)
76 let jobs = [
77 makeJob(
78 id: 1,
79 status: .failed,
80 tags: [],
81 updated: now.addingTimeInterval(-(60 * 60 * 24))
82 ),
83 makeJob(
84 id: 2,
85 status: .running,
86 tags: [],
87 updated: now.addingTimeInterval(-(60 * 60 * 24 * 8))
88 ),
89 makeJob(
90 id: 3,
91 status: .success,
92 tags: [],
93 updated: now.addingTimeInterval(-(60 * 60 * 24 * 2))
94 ),
95 ]
96
97 let filtered = BuildListViewModel.filterJobs(
98 jobs,
99 filter: .all,
100 lookbackDays: 3,
101 now: now,
102 calendar: Calendar(identifier: .gregorian)
103 )
104
105 #expect(filtered.map(\.id) == [1, 3])
106 }
107
108 private func filterJobs(_ jobs: [JobSummary], query: String) -> [JobSummary] {
109 BuildListViewModel.searchJobs(jobs, matching: query)
110 }
111
112 private func makeJob(
113 id: Int,
114 status: JobStatus = .success,
115 tags: [String],
116 updated: Date = Date()
117 ) -> JobSummary {
118 JobSummary(
119 id: id,
120 created: updated,
121 updated: updated,
122 status: status,
123 note: nil,
124 tags: tags,
125 visibility: nil,
126 image: nil,
127 tasks: []
128 )
129 }
130}