summaryrefslogtreecommitdiff
path: root/HutchTests
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-15 19:19:43 -0500
committerChristian Cleberg <[email protected]>2026-07-15 19:19:43 -0500
commit4346adc50f01be7f7322249d32745d119c757ff2 (patch)
treeb530424272118e56d1545de460f3cf2433d8ae89 /HutchTests
parented572a864debd7df840ea5873173be18ff27e809 (diff)
downloadhutch-4346adc50f01be7f7322249d32745d119c757ff2.tar.gz
hutch-4346adc50f01be7f7322249d32745d119c757ff2.tar.bz2
hutch-4346adc50f01be7f7322249d32745d119c757ff2.zip
test: repair stale expectations and request-body capture
These tests drifted from the code and went unnoticed because CI never ran them. All four are test-side errors; no app behavior is involved. - TicketListViewModelTests asserted lowercase "resolved"/"fixed"/"reported" against TicketStatus/TicketResolution rawValues, which are uppercase to match the todo.sr.ht GraphQL enums. - HomeViewModelTests expected failedBuilds in ascending id order. Ordering moved to newest-first when sortBuildItemsForTriage landed in 5f6d545; the filtering the test covers is unchanged. - SettingsViewModelTests read request.httpBody inside a URLProtocol, where it is always nil because URLSession moves the body onto httpBodyStream. The stub now reads the body off the stream at capture time.
Diffstat (limited to 'HutchTests')
-rw-r--r--HutchTests/HomeViewModelTests.swift2
-rw-r--r--HutchTests/SettingsViewModelTests.swift26
-rw-r--r--HutchTests/TicketListViewModelTests.swift6
3 files changed, 28 insertions, 6 deletions
diff --git a/HutchTests/HomeViewModelTests.swift b/HutchTests/HomeViewModelTests.swift
index e4f6d9a..851b520 100644
--- a/HutchTests/HomeViewModelTests.swift
+++ b/HutchTests/HomeViewModelTests.swift
@@ -15,7 +15,7 @@ struct HomeViewModelTests {
let failedBuilds = HomeViewModel.failedBuilds(from: jobs)
- #expect(failedBuilds.map(\.job.id) == [2, 3])
+ #expect(failedBuilds.map(\.job.id) == [3, 2])
}
@Test
diff --git a/HutchTests/SettingsViewModelTests.swift b/HutchTests/SettingsViewModelTests.swift
index 9e4b912..906f33f 100644
--- a/HutchTests/SettingsViewModelTests.swift
+++ b/HutchTests/SettingsViewModelTests.swift
@@ -4,12 +4,14 @@ import Testing
private final class SettingsViewModelCapturingURLProtocol: URLProtocol, @unchecked Sendable {
nonisolated(unsafe) static var capturedRequests: [URLRequest] = []
+ nonisolated(unsafe) static var capturedBodies: [Data] = []
override class func canInit(with _: URLRequest) -> Bool { true }
override class func canonicalRequest(for request: URLRequest) -> URLRequest { request }
override func startLoading() {
Self.capturedRequests.append(request)
+ Self.capturedBodies.append(Self.readBody(from: request))
let response = HTTPURLResponse(
url: request.url!,
@@ -26,6 +28,26 @@ private final class SettingsViewModelCapturingURLProtocol: URLProtocol, @uncheck
// No cleanup is needed because the stub responds immediately in `startLoading()`.
}
+ /// `URLSession` moves `httpBody` onto `httpBodyStream` before handing a request
+ /// to a `URLProtocol`, so `request.httpBody` is always nil here and the body has
+ /// to be read back off the stream while it is still open.
+ private static func readBody(from request: URLRequest) -> Data {
+ if let body = request.httpBody { return body }
+ guard let stream = request.httpBodyStream else { return Data() }
+
+ stream.open()
+ defer { stream.close() }
+
+ var data = Data()
+ var buffer = [UInt8](repeating: 0, count: 4096)
+ while stream.hasBytesAvailable {
+ let read = stream.read(&buffer, maxLength: buffer.count)
+ guard read > 0 else { break }
+ data.append(buffer, count: read)
+ }
+ return data
+ }
+
static func makeSession() -> URLSession {
let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [Self.self]
@@ -73,6 +95,7 @@ struct SettingsViewModelTests {
@MainActor
func loadProfileDoesNotRequestSSHKeyFingerprintField() async throws {
SettingsViewModelCapturingURLProtocol.capturedRequests = []
+ SettingsViewModelCapturingURLProtocol.capturedBodies = []
let client = SRHTClient(
session: SettingsViewModelCapturingURLProtocol.makeSession(),
@@ -82,8 +105,7 @@ struct SettingsViewModelTests {
await viewModel.loadProfile()
- let request = try #require(SettingsViewModelCapturingURLProtocol.capturedRequests.first)
- let body = try #require(request.httpBody)
+ let body = try #require(SettingsViewModelCapturingURLProtocol.capturedBodies.first)
let jsonObject = try #require(JSONSerialization.jsonObject(with: body) as? [String: Any])
let query = try #require(jsonObject["query"] as? String)
diff --git a/HutchTests/TicketListViewModelTests.swift b/HutchTests/TicketListViewModelTests.swift
index 7fa5449..a203091 100644
--- a/HutchTests/TicketListViewModelTests.swift
+++ b/HutchTests/TicketListViewModelTests.swift
@@ -162,8 +162,8 @@ struct TicketListViewModelTests {
"status": TicketStatus.resolved.rawValue,
"resolution": TicketResolution.fixed.rawValue
]
- #expect(input["status"] as? String == "resolved")
- #expect(input["resolution"] as? String == "fixed")
+ #expect(input["status"] as? String == "RESOLVED")
+ #expect(input["resolution"] as? String == "FIXED")
}
@Test
@@ -172,7 +172,7 @@ struct TicketListViewModelTests {
let input: [String: any Sendable] = [
"status": TicketStatus.reported.rawValue
]
- #expect(input["status"] as? String == "reported")
+ #expect(input["status"] as? String == "REPORTED")
#expect(input["resolution"] == nil)
}