gitbayTests/AccountDeleteTests.swift

v1.12.0
gitbay-ios/gitbayTests/AccountDeleteTests.swift history · blame · raw

89 lines · 4040 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 posted(_ stub: StubProtocol.Box) throws -> [[String]] {
16    try stub.seen.filter { $0.method == "POST" }.map { seen in
17        let body = try #require(try JSONSerialization.jsonObject(with: seen.body) as? [String: Any])
18        return try #require(body["argv"] as? [String])
19    }
20}
21
22private func scratchDefaults() -> UserDefaults {
23    UserDefaults(suiteName: "gb-test-\(UUID().uuidString)")!
24}
25
26@MainActor
27struct AccountDeleteTests {
28
29    @Test func aRequestIsRememberedForTheLinksDayAndNoLonger() async throws {
30        let (client, stub) = try makeClient()
31        stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"user":"sim","mailed":"sim@example.test"},"exit_code":0}"#, match: "cmd"))
32        let defaults = scratchDefaults()
33        await AccountViewModel(client: client, defaults: defaults).requestDeletion(username: "sim")
34
35        let later = AccountViewModel(client: client, defaults: defaults)
36        later.loadPendingDeletion(username: "sim", now: .now.addingTimeInterval(60 * 60))
37        #expect(later.deletionMailedTo == "sim@example.test")
38
39        let tooLate = AccountViewModel(client: client, defaults: defaults)
40        tooLate.loadPendingDeletion(username: "sim", now: .now.addingTimeInterval(25 * 60 * 60))
41        #expect(tooLate.deletionMailedTo == nil)
42    }
43
44    @Test func withdrawingWhenNothingIsPendingClearsTheNotice() async throws {
45        let (client, stub) = try makeClient()
46        stub.enqueue(.init(status: 404, json: #"{"protocol_version":1,"error":"no deletion is pending for sim","exit_code":3}"#, match: "cmd"))
47        let model = AccountViewModel(client: client, defaults: scratchDefaults())
48
49        await model.cancelDeletion(username: "sim")
50
51        #expect(model.deletionMailedTo == nil)
52        #expect(model.actionError == nil)
53    }
54
55    @Test func askingMailsALinkToTheAddressTheServerNames() async throws {
56        let (client, stub) = try makeClient()
57        stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"user":"sim","mailed":"sim@example.test"},"exit_code":0}"#, match: "cmd"))
58        let model = AccountViewModel(client: client, defaults: scratchDefaults())
59
60        await model.requestDeletion(username: "sim")
61
62        #expect(try posted(stub) == [["account", "delete", "--confirm", "sim"]])
63        #expect(model.deletionMailedTo == "sim@example.test")
64    }
65
66    @Test func aRefusalSaysWhyAndNothingIsPending() async throws {
67        let (client, stub) = try makeClient()
68        stub.enqueue(.init(status: 403, json: #"{"protocol_version":1,"error":"you are the instance's only admin; promote another account first","exit_code":4}"#, match: "cmd"))
69        let model = AccountViewModel(client: client, defaults: scratchDefaults())
70
71        await model.requestDeletion(username: "sim")
72
73        #expect(model.deletionMailedTo == nil)
74        #expect(model.actionError == "you are the instance's only admin; promote another account first")
75    }
76
77    @Test func withdrawingSendsCancel() async throws {
78        let (client, stub) = try makeClient()
79        stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"user":"sim","mailed":"sim@example.test"},"exit_code":0}"#, match: "cmd"))
80        stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"user":"sim","cancelled":true},"exit_code":0}"#, match: "cmd"))
81        let model = AccountViewModel(client: client, defaults: scratchDefaults())
82        await model.requestDeletion(username: "sim")
83
84        await model.cancelDeletion(username: "sim")
85
86        #expect(try posted(stub).last == ["account", "delete", "--cancel"])
87        #expect(model.deletionMailedTo == nil)
88    }
89}