diff options
Diffstat (limited to 'HutchTests')
| -rw-r--r-- | HutchTests/BuildListViewModelTests.swift | 58 | ||||
| -rw-r--r-- | HutchTests/SettingsViewModelTests.swift | 55 |
2 files changed, 108 insertions, 5 deletions
diff --git a/HutchTests/BuildListViewModelTests.swift b/HutchTests/BuildListViewModelTests.swift index fccd7cf..aa2e46b 100644 --- a/HutchTests/BuildListViewModelTests.swift +++ b/HutchTests/BuildListViewModelTests.swift @@ -49,22 +49,70 @@ struct BuildListViewModelTests { makeJob(id: 4, status: .cancelled, tags: []) ] - let attention = BuildListViewModel.filterJobs(jobs, filter: .attention) - let active = BuildListViewModel.filterJobs(jobs, filter: .active) + let attention = BuildListViewModel.filterJobs( + jobs, + filter: .attention, + lookbackDays: BuildListViewModel.defaultLookbackDays + ) + let active = BuildListViewModel.filterJobs( + jobs, + filter: .active, + lookbackDays: BuildListViewModel.defaultLookbackDays + ) #expect(attention.map(\.id) == [2, 3]) #expect(active.map(\.id) == [3]) } + @Test + func buildFilterRestrictsJobsToSelectedLookbackWindow() { + let now = Date(timeIntervalSince1970: 60 * 60 * 24 * 20) + let jobs = [ + makeJob( + id: 1, + status: .failed, + tags: [], + updated: now.addingTimeInterval(-(60 * 60 * 24)) + ), + makeJob( + id: 2, + status: .running, + tags: [], + updated: now.addingTimeInterval(-(60 * 60 * 24 * 8)) + ), + makeJob( + id: 3, + status: .success, + tags: [], + updated: now.addingTimeInterval(-(60 * 60 * 24 * 2)) + ), + ] + + let filtered = BuildListViewModel.filterJobs( + jobs, + filter: .all, + lookbackDays: 3, + now: now, + calendar: Calendar(identifier: .gregorian) + ) + + #expect(filtered.map(\.id) == [1, 3]) + } + private func filterJobs(_ jobs: [JobSummary], query: String) -> [JobSummary] { BuildListViewModel.searchJobs(jobs, matching: query) } - private func makeJob(id: Int, status: JobStatus = .success, tags: [String]) -> JobSummary { + private func makeJob( + id: Int, + status: JobStatus = .success, + tags: [String], + updated: Date = Date() + ) -> JobSummary { JobSummary( id: id, - created: Date(), - updated: Date(), + created: updated, + updated: updated, status: status, note: nil, tags: tags, diff --git a/HutchTests/SettingsViewModelTests.swift b/HutchTests/SettingsViewModelTests.swift index fc18162..9e4b912 100644 --- a/HutchTests/SettingsViewModelTests.swift +++ b/HutchTests/SettingsViewModelTests.swift @@ -2,6 +2,37 @@ import Foundation import Testing @testable import Hutch +private final class SettingsViewModelCapturingURLProtocol: URLProtocol, @unchecked Sendable { + nonisolated(unsafe) static var capturedRequests: [URLRequest] = [] + + override class func canInit(with _: URLRequest) -> Bool { true } + override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } + + override func startLoading() { + Self.capturedRequests.append(request) + + let response = HTTPURLResponse( + url: request.url!, + statusCode: 401, + httpVersion: nil, + headerFields: nil + )! + client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) + client?.urlProtocol(self, didLoad: Data()) + client?.urlProtocolDidFinishLoading(self) + } + + override func stopLoading() { + // No cleanup is needed because the stub responds immediately in `startLoading()`. + } + + static func makeSession() -> URLSession { + let config = URLSessionConfiguration.ephemeral + config.protocolClasses = [Self.self] + return URLSession(configuration: config) + } +} + private struct DeletePGPKeyEnvelope: Decodable { let deletePGPKey: DeleteResultPayload? } @@ -10,6 +41,7 @@ private struct DeleteResultPayload: Decodable { let id: Int? } +@Suite(.serialized) struct SettingsViewModelTests { @Test @@ -36,4 +68,27 @@ struct SettingsViewModelTests { #expect(decoded.data?.deletePGPKey == nil) #expect(decoded.errors?.first?.message.contains("preferred PGP key") == true) } + + @Test + @MainActor + func loadProfileDoesNotRequestSSHKeyFingerprintField() async throws { + SettingsViewModelCapturingURLProtocol.capturedRequests = [] + + let client = SRHTClient( + session: SettingsViewModelCapturingURLProtocol.makeSession(), + token: "test-token" + ) + let viewModel = SettingsViewModel(client: client) + + await viewModel.loadProfile() + + let request = try #require(SettingsViewModelCapturingURLProtocol.capturedRequests.first) + let body = try #require(request.httpBody) + let jsonObject = try #require(JSONSerialization.jsonObject(with: body) as? [String: Any]) + let query = try #require(jsonObject["query"] as? String) + + #expect(query.contains("sshKeys")) + #expect(!query.contains("results { id fingerprint comment created lastUsed }")) + #expect(!query.contains("fingerprint comment created lastUsed")) + } } |
