krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

v3.3.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
 63        #expect(attention.map(\.id) == [2, 3])
 64        #expect(active.map(\.id) == [3])
 65    }
 66
 67    @Test
 68    func buildFilterRestrictsJobsToSelectedLookbackWindow() {
 69        let now = Date(timeIntervalSince1970: 60 * 60 * 24 * 20)
 70        let jobs = [
 71            makeJob(
 72                id: 1,
 73                status: .failed,
 74                tags: [],
 75                updated: now.addingTimeInterval(-(60 * 60 * 24))
 76            ),
 77            makeJob(
 78                id: 2,
 79                status: .running,
 80                tags: [],
 81                updated: now.addingTimeInterval(-(60 * 60 * 24 * 8))
 82            ),
 83            makeJob(
 84                id: 3,
 85                status: .success,
 86                tags: [],
 87                updated: now.addingTimeInterval(-(60 * 60 * 24 * 2))
 88            ),
 89        ]
 90
 91        let filtered = BuildListViewModel.filterJobs(
 92            jobs,
 93            filter: .all,
 94            lookbackDays: 3,
 95            now: now,
 96            calendar: Calendar(identifier: .gregorian)
 97        )
 98
 99        #expect(filtered.map(\.id) == [1, 3])
100    }
101
102    private func filterJobs(_ jobs: [JobSummary], query: String) -> [JobSummary] {
103        BuildListViewModel.searchJobs(jobs, matching: query)
104    }
105
106    private func makeJob(
107        id: Int,
108        status: JobStatus = .success,
109        tags: [String],
110        updated: Date = Date()
111    ) -> JobSummary {
112        JobSummary(
113            id: id,
114            created: updated,
115            updated: updated,
116            status: status,
117            note: nil,
118            tags: tags,
119            visibility: nil,
120            image: nil,
121            tasks: []
122        )
123    }
124}