krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
main: HutchTests/PatchsetTests.swift · raw
1import Foundation
2import Testing
3@testable import Hutch
4
5@MainActor
6struct PatchsetStatusTests {
7
8 @Test
9 func statusRawValuesMatchTheGraphQLEnum() {
10 // lists.sr.ht's PatchsetStatus enum values, which are sent verbatim to
11 // updatePatchset.
12 #expect(PatchsetStatus.unknown.rawValue == "UNKNOWN")
13 #expect(PatchsetStatus.proposed.rawValue == "PROPOSED")
14 #expect(PatchsetStatus.needsRevision.rawValue == "NEEDS_REVISION")
15 #expect(PatchsetStatus.superseded.rawValue == "SUPERSEDED")
16 #expect(PatchsetStatus.approved.rawValue == "APPROVED")
17 #expect(PatchsetStatus.rejected.rawValue == "REJECTED")
18 #expect(PatchsetStatus.applied.rawValue == "APPLIED")
19 }
20
21 @Test
22 func assignableStatusesExcludeServerManagedOnes() {
23 // UNKNOWN is a sentinel and SUPERSEDED is set by the server when a newer
24 // version lands, so neither should be offered as a reviewer choice.
25 #expect(!PatchsetStatus.assignable.contains(.unknown))
26 #expect(!PatchsetStatus.assignable.contains(.superseded))
27 #expect(PatchsetStatus.assignable.contains(.approved))
28 #expect(PatchsetStatus.assignable.contains(.rejected))
29 #expect(PatchsetStatus.assignable.contains(.applied))
30 #expect(PatchsetStatus.assignable.contains(.needsRevision))
31 #expect(PatchsetStatus.assignable.contains(.proposed))
32 }
33
34 @Test
35 func openStatusesAreThoseAwaitingADecision() {
36 #expect(PatchsetStatus.proposed.isOpen)
37 #expect(PatchsetStatus.needsRevision.isOpen)
38 #expect(!PatchsetStatus.applied.isOpen)
39 #expect(!PatchsetStatus.rejected.isOpen)
40 #expect(!PatchsetStatus.superseded.isOpen)
41 }
42
43 @Test
44 func statusDecodesFromTheWireFormat() throws {
45 let decoded = try JSONDecoder().decode(PatchsetStatus.self, from: Data("\"NEEDS_REVISION\"".utf8))
46 #expect(decoded == .needsRevision)
47 }
48}
49
50@MainActor
51struct PatchsetSummaryTests {
52
53 @Test
54 func versionLabelIsHiddenForFirstVersion() {
55 let summary = PatchsetSummary(
56 id: 1,
57 subject: "[PATCH] fix the thing",
58 version: 1,
59 prefix: nil,
60 status: .proposed
61 )
62
63 #expect(summary.versionLabel == nil)
64 }
65
66 @Test
67 func versionLabelIsShownForRevisions() {
68 let summary = PatchsetSummary(
69 id: 1,
70 subject: "[PATCH v3] fix the thing",
71 version: 3,
72 prefix: nil,
73 status: .proposed
74 )
75
76 #expect(summary.versionLabel == "v3")
77 }
78}
79
80@MainActor
81struct PatchsetOrderingTests {
82
83 private func makePatch(id: Int, index: Int?, count: Int?) -> PatchsetEmail {
84 PatchsetEmail(
85 id: id,
86 subject: "patch \(id)",
87 date: nil,
88 sender: Entity(canonicalName: "~someone"),
89 contentBlocks: [],
90 index: index,
91 count: count
92 )
93 }
94
95 @Test
96 func patchesAreOrderedBySeriesIndexNotReceiptOrder() {
97 let patches = [
98 makePatch(id: 30, index: 3, count: 3),
99 makePatch(id: 10, index: 1, count: 3),
100 makePatch(id: 20, index: 2, count: 3)
101 ]
102
103 let ordered = PatchsetDetailViewModel.orderPatches(patches)
104
105 #expect(ordered.map(\.index) == [1, 2, 3])
106 }
107
108 @Test
109 func unindexedPatchesAreKeptAtTheEndRatherThanDropped() {
110 let patches = [
111 makePatch(id: 99, index: nil, count: nil),
112 makePatch(id: 20, index: 2, count: 2),
113 makePatch(id: 10, index: 1, count: 2)
114 ]
115
116 let ordered = PatchsetDetailViewModel.orderPatches(patches)
117
118 #expect(ordered.count == 3)
119 #expect(ordered.map(\.index) == [1, 2, nil])
120 }
121
122 @Test
123 func orderingIsStableForASingleUnindexedPatch() {
124 // A lone patch with no [PATCH n/m] prefix is the common one-off case.
125 let patches = [makePatch(id: 1, index: nil, count: nil)]
126
127 let ordered = PatchsetDetailViewModel.orderPatches(patches)
128
129 #expect(ordered.map(\.id) == [1])
130 }
131
132 @Test
133 func seriesLabelIsHiddenForSinglePatchSeries() {
134 let patch = makePatch(id: 1, index: 1, count: 1)
135 #expect(patch.seriesLabel == nil)
136 }
137
138 @Test
139 func seriesLabelShowsPositionForMultiPatchSeries() {
140 let patch = makePatch(id: 1, index: 2, count: 5)
141 #expect(patch.seriesLabel == "2/5")
142 }
143}