gitbayTests/WikiTests.swift
110 lines · 3896 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 let listingJSON = """
16 {"protocol_version":1,"data":{"path":"krz/gitbay","home":"Home",\
17 "pages":["API","Admin","Home","Parity"]},"exit_code":0}
18 """
19
20@MainActor
21struct WikiViewModelTests {
22
23 @Test func listsPagesAndNamesTheLandingPage() async throws {
24 let (client, stub) = try makeClient()
25 stub.enqueue(.init(status: 200, json: listingJSON))
26 let model = WikiViewModel(client: client, repoPath: "krz/gitbay")
27
28 await model.load()
29
30 let listing = try #require(model.state.value)
31 #expect(listing.home == "Home")
32 #expect(listing.pages == ["API", "Admin", "Home", "Parity"])
33 #expect(stub.seen.first?.url.query() == "argv=wiki&argv=list&argv=krz/gitbay")
34 }
35
36 @Test func aRepoWithoutAWikiIsAnEmptyState() async throws {
37 let (client, stub) = try makeClient()
38 stub.enqueue(.init(status: 404, json:
39 #"{"protocol_version":1,"error":"krz/quiet has no wiki","exit_code":3}"#))
40 let model = WikiViewModel(client: client, repoPath: "krz/quiet")
41
42 await model.load()
43
44 guard case .empty(let message) = model.state else {
45 Issue.record("expected .empty, got \(model.state)")
46 return
47 }
48 #expect(message.contains("no wiki"))
49 }
50
51 @Test func anEmptyWikiIsAnEmptyStateNotAList() async throws {
52 let (client, stub) = try makeClient()
53 stub.enqueue(.init(status: 200, json:
54 #"{"protocol_version":1,"data":{"path":"krz/gitbay","pages":[]},"exit_code":0}"#))
55 let model = WikiViewModel(client: client, repoPath: "krz/gitbay")
56
57 await model.load()
58
59 guard case .empty = model.state else {
60 Issue.record("expected .empty, got \(model.state)")
61 return
62 }
63 }
64}
65
66@MainActor
67struct WikiPageViewModelTests {
68
69 @Test func loadsAPageAndKeepsItsFileName() async throws {
70 let (client, stub) = try makeClient()
71 stub.enqueue(.init(status: 200, json: """
72 {"protocol_version":1,"data":{"path":"krz/gitbay","page":"Parity",\
73 "file":"Parity.org","size":11,"content":"#+title: x"},"exit_code":0}
74 """))
75 let model = WikiPageViewModel(client: client, repoPath: "krz/gitbay", page: "Parity")
76
77 await model.load()
78
79 let page = try #require(model.state.value)
80 // The file name is what picks the renderer, so it must survive.
81 #expect(page.file == "Parity.org")
82 #expect(page.content == "#+title: x")
83 #expect(stub.seen.first?.url.query() ==
84 "argv=wiki&argv=show&argv=krz/gitbay&argv=Parity")
85 }
86
87 @Test func aMissingPageIsAnEmptyState() async throws {
88 let (client, stub) = try makeClient()
89 stub.enqueue(.init(status: 404, json:
90 #"{"protocol_version":1,"error":"no wiki page \"Nope\" in krz/gitbay","exit_code":3}"#))
91 let model = WikiPageViewModel(client: client, repoPath: "krz/gitbay", page: "Nope")
92
93 await model.load()
94
95 guard case .empty = model.state else {
96 Issue.record("expected .empty, got \(model.state)")
97 return
98 }
99 }
100}
101
102struct WikiRenderingTests {
103
104 @Test func orgPagesGetTheOrgRendererAndMarkdownPagesDoNot() {
105 // Wiki pages here are .org as often as .md; the file name decides.
106 #expect(ReadmeView(name: "Parity.org", content: "* x").isOrg)
107 #expect(!ReadmeView(name: "Home.md", content: "# x").isOrg)
108 #expect(!ReadmeView(name: "Notes.markdown", content: "# x").isOrg)
109 }
110}