gitbayTests/MergeWhenReadyTests.swift

v1.8.0
gitbay-ios/gitbayTests/MergeWhenReadyTests.swift history · blame · raw

73 lines · 2792 bytes

 1import Foundation
 2import Testing
 3@testable import gitbay
 4
 5private func makeClient() throws -> (GitbayClient, StubProtocol.Box) {
 6    let box = StubProtocol.box()
 7    let client = GitbayClient(
 8        instance: try GitbayInstance(url: "https://gitbay.org"),
 9        token: "test-token",
10        session: box.session()
11    )
12    return (client, box)
13}
14
15private func postedArgv(_ stub: StubProtocol.Box) throws -> [String] {
16    let seen = try #require(stub.seen.first { $0.method == "POST" })
17    let body = try #require(try JSONSerialization.jsonObject(with: seen.body) as? [String: Any])
18    return try #require(body["argv"] as? [String])
19}
20
21private func mrShow(queued: String = "") -> String {
22    """
23    {"protocol_version":1,"data":{"number":5,"title":"t","state":"open","author":"krz",\
24    "source":"feat","target_ref":"main","head_sha":"abc","created_at":"2026-08-20T10:00:00.000Z"\
25    \(queued)},"exit_code":0}
26    """
27}
28
29private let ok = #"{"protocol_version":1,"data":{},"exit_code":0}"#
30
31@MainActor
32struct MergeWhenReadyTests {
33
34    private func loaded(_ json: String) async throws -> (MRDetailViewModel, StubProtocol.Box) {
35        let (client, stub) = try makeClient()
36        stub.enqueue(.init(status: 200, json: json, match: "argv=show"))
37        let model = MRDetailViewModel(client: client, repoPath: "krz/gitbay", number: 5)
38        await model.load()
39        return (model, stub)
40    }
41
42    @Test func aQueuedMergeDecodesWhoQueuedItAndWhy() async throws {
43        let (model, _) = try await loaded(mrShow(queued: #","queued":{"by":"cmc","strategy":"ff","reason":"waiting on 1 approval","queued_at":"2026-08-21T10:00:00.000Z"}"#))
44
45        let queued = try #require(model.state.value?.queued)
46        #expect(queued.by == "cmc")
47        #expect(queued.strategy == "ff")
48        #expect(queued.reason == "waiting on 1 approval")
49    }
50
51    @Test func noQueueDecodesAsNil() async throws {
52        let (model, _) = try await loaded(mrShow())
53        #expect(model.state.value?.queued == nil)
54    }
55
56    @Test func mergeWhenReadyAddsTheFlagAndKeepsTheStrategy() async throws {
57        let (model, stub) = try await loaded(mrShow())
58        stub.enqueue(.init(status: 200, json: ok, match: "cmd"))
59
60        await model.merge(strategy: "ff", whenReady: true)
61
62        #expect(try postedArgv(stub) == ["mr", "merge", "krz/gitbay", "5", "--strategy", "ff", "--when-ready"])
63    }
64
65    @Test func cancellingTheQueueSendsCancelAlone() async throws {
66        let (model, stub) = try await loaded(mrShow(queued: #","queued":{"by":"cmc","queued_at":"2026-08-21T10:00:00.000Z"}"#))
67        stub.enqueue(.init(status: 200, json: ok, match: "cmd"))
68
69        await model.cancelQueuedMerge()
70
71        #expect(try postedArgv(stub) == ["mr", "merge", "krz/gitbay", "5", "--cancel"])
72    }
73}