From 90da3a7aa2bf991904c1d7201250154ea84f1493 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Wed, 18 Mar 2026 20:07:59 -0500 Subject: Omit resolution when reopening resolved tickets --- Hutch/Views/Tickets/TicketDetailView.swift | 5 +---- Hutch/Views/Tickets/TicketDetailViewModel.swift | 20 ++++++++++++----- HutchTests/TicketDetailViewModelTests.swift | 30 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 HutchTests/TicketDetailViewModelTests.swift diff --git a/Hutch/Views/Tickets/TicketDetailView.swift b/Hutch/Views/Tickets/TicketDetailView.swift index 6b2be4f..f553bd8 100644 --- a/Hutch/Views/Tickets/TicketDetailView.swift +++ b/Hutch/Views/Tickets/TicketDetailView.swift @@ -71,10 +71,7 @@ struct TicketDetailView: View { if ticket.status == .resolved { Button { Task { - await viewModel.updateStatus( - status: .reported, - resolution: .unresolved - ) + await viewModel.updateStatus(status: .reported) } } label: { SwiftUI.Label("Reopen", systemImage: "arrow.uturn.backward") diff --git a/Hutch/Views/Tickets/TicketDetailViewModel.swift b/Hutch/Views/Tickets/TicketDetailViewModel.swift index 70eaf0a..90e33aa 100644 --- a/Hutch/Views/Tickets/TicketDetailViewModel.swift +++ b/Hutch/Views/Tickets/TicketDetailViewModel.swift @@ -130,6 +130,19 @@ final class TicketDetailViewModel { return lhs.created < rhs.created } + static func statusUpdateInput( + status: TicketStatus, + resolution: TicketResolution? + ) -> [String: any Sendable] { + var input: [String: any Sendable] = [ + "status": status.rawValue + ] + if status == .resolved, let resolution { + input["resolution"] = resolution.rawValue + } + return input + } + init(ownerUsername: String, trackerName: String, trackerId: Int, trackerRid: String, ticketId: Int, client: SRHTClient) { self.ownerUsername = ownerUsername self.trackerName = trackerName @@ -360,16 +373,13 @@ final class TicketDetailViewModel { // MARK: - Ticket Actions - func updateStatus(status: TicketStatus, resolution: TicketResolution) async { + func updateStatus(status: TicketStatus, resolution: TicketResolution? = nil) async { guard !isPerformingAction else { return } isPerformingAction = true error = nil do { - let input: [String: any Sendable] = [ - "status": status.rawValue, - "resolution": resolution.rawValue - ] + let input = Self.statusUpdateInput(status: status, resolution: resolution) _ = try await client.execute( service: .todo, query: Self.updateStatusMutation, diff --git a/HutchTests/TicketDetailViewModelTests.swift b/HutchTests/TicketDetailViewModelTests.swift new file mode 100644 index 0000000..bf0bc60 --- /dev/null +++ b/HutchTests/TicketDetailViewModelTests.swift @@ -0,0 +1,30 @@ +import Foundation +import Testing +@testable import Hutch + +struct TicketDetailViewModelTests { + + @Test + @MainActor + func reopenStatusInputOmitsResolution() { + let input = TicketDetailViewModel.statusUpdateInput( + status: .reported, + resolution: .unresolved + ) + + #expect(input["status"] as? String == TicketStatus.reported.rawValue) + #expect(input["resolution"] == nil) + } + + @Test + @MainActor + func resolveStatusInputIncludesResolution() { + let input = TicketDetailViewModel.statusUpdateInput( + status: .resolved, + resolution: .fixed + ) + + #expect(input["status"] as? String == TicketStatus.resolved.rawValue) + #expect(input["resolution"] as? String == TicketResolution.fixed.rawValue) + } +} -- cgit v1.2.3