import Foundation import Testing @testable import gitbay struct RepoStateDecodingTests { private func decode(_ json: String) throws -> RepoDetail { try JSONDecoder().decode(RepoDetail.self, from: Data(json.utf8)) } private let base = """ "path":"krz/gitbay","visibility":"public","default_branch":"main" """ /// All three are omitempty. A repository you have expressed no /// opinion about, which is not a fork, carries none of them. @Test func aRepositoryWithNoStateDecodes() throws { let repo = try decode("{\(base)}") #expect(repo.watch == nil) #expect(repo.bookmarked == false) #expect(repo.forkOf == nil) } @Test func theCallersOwnStateDecodes() throws { let repo = try decode(""" {\(base),"watch":"watching","bookmarked":true,"fork_of":"upstream/thing"} """) #expect(repo.watch == "watching") #expect(repo.bookmarked) #expect(repo.forkOf == "upstream/thing") } @Test func mutedDecodes() throws { #expect(try decode("{\(base),\"watch\":\"muted\"}").watch == "muted") } } struct WatchStateTests { @Test func theThreeStatesMapFromTheWire() { #expect(WatchState("watching") == .watching) #expect(WatchState("muted") == .muted) #expect(WatchState(nil) == .default) // An unknown value the server might add later must not crash or // masquerade as watching. #expect(WatchState("something-new") == .default) } /// `repo unwatch` returns to the default from either state, so it is /// offered from both and never from the default itself. @Test func onlyTheReachableTransitionsAreOffered() { #expect(WatchState.watching.available == [.unwatch, .mute]) #expect(WatchState.muted.available == [.watch, .unwatch]) #expect(WatchState.default.available == [.watch, .mute]) } }