import Foundation import Testing @testable import gitbay private func makeClient() throws -> (GitbayClient, StubProtocol.Box) { let box = StubProtocol.box() let client = GitbayClient( instance: try GitbayInstance(url: "https://gitbay.org"), token: "test-token", session: box.session() ) return (client, box) } private func posted(_ stub: StubProtocol.Box) throws -> [[String]] { try stub.seen.filter { $0.method == "POST" }.map { seen in let body = try #require(try JSONSerialization.jsonObject(with: seen.body) as? [String: Any]) return try #require(body["argv"] as? [String]) } } @MainActor struct RepoTransferDeleteTests { @Test func transferNamesTheNewOwnerAndReturnsTheNewPath() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"repo":"krz/app","was":"cmc/app"},"exit_code":0}"#, match: "cmd")) let model = RepoSettingsViewModel(client: client, repoPath: "cmc/app") let moved = await model.transfer(to: " krz ") #expect(moved == "krz/app") #expect(try posted(stub) == [["repo", "transfer", "cmc/app", "krz"]]) } @Test func aRefusedTransferSaysWhy() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 403, json: #"{"protocol_version":1,"error":"you cannot create repositories in krz","exit_code":4}"#, match: "cmd")) let model = RepoSettingsViewModel(client: client, repoPath: "cmc/app") #expect(await model.transfer(to: "krz") == nil) #expect(model.actionError == "you cannot create repositories in krz") } @Test func deleteSendsYesAndReportsIt() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{"deleted":"cmc/app"},"exit_code":0}"#, match: "cmd")) let model = RepoSettingsViewModel(client: client, repoPath: "cmc/app") #expect(await model.delete()) #expect(try posted(stub) == [["repo", "delete", "cmc/app", "--yes"]]) } @Test func aRefusedDeleteSaysWhy() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 403, json: #"{"protocol_version":1,"error":"only the owner or an admin can delete cmc/app","exit_code":4}"#, match: "cmd")) let model = RepoSettingsViewModel(client: client, repoPath: "cmc/app") #expect(!(await model.delete())) #expect(model.actionError == "only the owner or an admin can delete cmc/app") } @Test func aDeleteWhoseRetryFindsNothingIsDone() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 500, json: #"{"protocol_version":1,"error":"removing the directory: busy","exit_code":1}"#, match: "cmd")) stub.enqueue(.init(status: 404, json: #"{"protocol_version":1,"error":"no repository cmc/app","exit_code":3}"#, match: "cmd")) let model = RepoSettingsViewModel(client: client, repoPath: "cmc/app") #expect(await model.delete()) #expect(model.actionError == nil) } }