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]) } } struct KeyExpiryTests { @Test func keysCarryLastUseExpiryAndWhoCreatedThem() throws { let json = """ [{"fingerprint":"SHA256:a","algo":"ssh-ed25519","scope":"full","label":"laptop",\ "last_used_at":"2026-10-14T07:32:16.789Z"},\ {"fingerprint":"SHA256:b","algo":"ssh-ed25519","scope":"git","label":"ci",\ "created_by":"phone","expires_at":"2026-01-01T00:00:00Z"},\ {"fingerprint":"SHA256:c","algo":"ssh-ed25519","scope":"full","label":""}] """ let keys = try GitbayClient.decoder().decode([AccountViewModel.SSHKey].self, from: Data(json.utf8)) let now = try Date("2026-10-15T00:00:00Z", strategy: .iso8601) #expect(keys[0].lastUsedAt != nil) #expect(keys[0].expiresAt == nil) #expect(!keys[0].isExpired(at: now)) #expect(keys[1].createdBy == "phone") #expect(keys[1].isExpired(at: now)) #expect(keys[2].lastUsedAt == nil) } } @MainActor struct KeyTTLTests { @Test func anExpiringKeyIsAddedWithItsTTL() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 200, json: #"{"protocol_version":1,"data":{},"exit_code":0}"#, match: "cmd")) let model = AccountViewModel(client: client) await model.addSSHKey("ssh-ed25519 AAAA phone", scope: "full", label: "phone", ttl: "90d") #expect(try posted(stub) == [["keys", "add", "--scope", "full", "--label", "phone", "--ttl", "90d"]]) } }