import Foundation import Testing @testable import gitbay private func route(_ path: String) -> WebURLRoute? { WebURLRoute(url: URL(string: "https://gitbay.org\(path)")!) } @Test func webURLOwnerAndRepo() { #expect(route("/krz") == .repo(.profile("krz"))) #expect(route("/krz/") == .repo(.profile("krz"))) #expect(route("/krz/gitbay") == .repo(.repo("krz/gitbay"))) #expect(route("/krz/gitbay/") == .repo(.repo("krz/gitbay"))) } @Test func webURLOwnerPages() { #expect(route("/krz/-/repositories") == .repo(.profile("krz"))) #expect(route("/krz/-/bookmarks") == .repo(.profile("krz"))) #expect(route("/krz/-/people") == .repo(.profile("krz"))) #expect(route("/krz/-/labels") == .org(.labels("krz"))) #expect(route("/krz/-/milestones") == .org(.milestones("krz"))) #expect(route("/cmc/-/snippets") == .snippet(.list(owner: "cmc"))) #expect(route("/cmc/-/snippets/a1b2") == .snippet(.snippet(id: "a1b2"))) } @Test func webURLTopLevelPages() { #expect(route("/bookmarks") == .repo(.bookmarks)) #expect(route("/notifications") == .repo(.notifications)) } @Test func webURLIssuesMRsBuilds() { #expect(route("/krz/gitbay/issues") == .issue(.list(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/issues/12") == .issue(.issue(repo: "krz/gitbay", number: 12))) #expect(route("/krz/gitbay/mrs") == .mr(.list(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/mrs/7") == .mr(.mr(repo: "krz/gitbay", number: 7))) #expect(route("/krz/gitbay/builds") == .build(.list(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/builds/1510") == .build(.detail(repo: "krz/gitbay", number: 1510))) } // Query and fragment do not change the screen: a comment anchor or a // list filter still lands on the page it belongs to. @Test func webURLIgnoresQueryAndFragment() { #expect(route("/krz/gitbay/issues/12#comment-3") == .issue(.issue(repo: "krz/gitbay", number: 12))) #expect(route("/krz/gitbay/issues?state=closed") == .issue(.list(repo: "krz/gitbay"))) } @Test func webURLFiles() { #expect(route("/krz/gitbay/tree/main") == .repo(.tree(repo: "krz/gitbay", directory: "", ref: "main"))) #expect(route("/krz/gitbay/tree/main/") == .repo(.tree(repo: "krz/gitbay", directory: "", ref: "main"))) #expect(route("/krz/gitbay/tree/main/internal/httpd") == .repo(.tree(repo: "krz/gitbay", directory: "internal/httpd", ref: "main"))) #expect(route("/krz/gitbay/blob/v1.0.0/README.org") == .repo(.file(repo: "krz/gitbay", path: "README.org", ref: "v1.0.0"))) #expect(route("/krz/gitbay/blame/main/cmd/gitbay/main.go") == .repo(.blame(repo: "krz/gitbay", path: "cmd/gitbay/main.go", ref: "main"))) } // Each segment is decoded on its own, so an escaped slash stays inside // the ref instead of splitting it. @Test func webURLDecodesSegments() { #expect(route("/krz/gitbay/blob/main/docs/My%20Notes.md") == .repo(.file(repo: "krz/gitbay", path: "docs/My Notes.md", ref: "main"))) #expect(route("/krz/gitbay/tree/feature%2Fx/docs") == .repo(.tree(repo: "krz/gitbay", directory: "docs", ref: "feature/x"))) } @Test func webURLHistoryAndRefs() { #expect(route("/krz/gitbay/commit/d0c63c4") == .repo(.commit(repo: "krz/gitbay", sha: "d0c63c4"))) #expect(route("/krz/gitbay/log") == .repo(.log(repo: "krz/gitbay", ref: nil, path: nil))) #expect(route("/krz/gitbay/log/main") == .repo(.log(repo: "krz/gitbay", ref: "main", path: nil))) #expect(route("/krz/gitbay/refs") == .repo(.refs(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/compare") == .repo(.compare(repo: "krz/gitbay", defaultBranch: nil))) } @Test func webURLRepoSections() { #expect(route("/krz/gitbay/releases") == .release(.list(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/milestones") == .repo(.milestones(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/labels") == .repo(.labels(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/wiki") == .repo(.wiki(repo: "krz/gitbay"))) #expect(route("/krz/gitbay/wiki/Home") == .repo(.wikiPage(repo: "krz/gitbay", page: "Home"))) #expect(route("/krz/gitbay/wiki/Architecture/00-Overview") == .repo(.wikiPage(repo: "krz/gitbay", page: "Architecture/00-Overview"))) } // Pages the app has no screen for, and malformed ids, are nil: the // caller hands those to Safari. @Test func webURLUnroutable() { for path in [ "", "/", "/krz/gitbay/issues/new", "/krz/gitbay/issues/abc", "/krz/gitbay/issues/12/extra", "/krz/gitbay/mrs/new", "/krz/gitbay/mrs/7/range-diff", "/krz/gitbay/builds/0", "/krz/gitbay/blob/main", "/krz/gitbay/tree", "/krz/gitbay/commit", "/krz/gitbay/raw/main/README.org", "/krz/gitbay/archive/main.tar.gz", "/krz/gitbay/releases/download/v1/x.tgz", "/krz/gitbay/settings", "/krz/gitbay/wiki/_raw/a.svg", "/krz/gitbay/compare/main...x", "/krz/gitbay/log/main/extra", "/krz/-", "/krz/-/queries", "/krz/-/snippets/a1b2/raw/x.txt", ] { #expect(route(path) == nil, "\(path)") } #expect(WebURLRoute(url: URL(string: "mailto:cmc@gitbay.org")!) == nil) #expect(WebURLRoute(url: URL(string: "ftp://gitbay.org/krz")!) == nil) } private func account(_ host: String, _ user: String) throws -> Account { Account(instance: try GitbayInstance(url: "https://\(host)"), username: user) } @Test func webURLAccountPrefersTheCurrentOne() throws { let accounts = [try account("gitbay.org", "cmc"), try account("gitbay.org", "ios-smoke")] let url = URL(string: "https://gitbay.org/krz")! #expect(WebURLRoute.account(for: url, current: accounts[1], accounts: accounts) == accounts[1]) } @Test func webURLAccountFallsBackToOneOnTheInstance() throws { let accounts = [try account("dev.local", "cmc"), try account("gitbay.org", "cmc")] let url = URL(string: "https://gitbay.org/krz")! #expect(WebURLRoute.account(for: url, current: accounts[0], accounts: accounts) == accounts[1]) } @Test func webURLAccountIsNilWithoutOneOnTheInstance() throws { let accounts = [try account("dev.local", "cmc")] let url = URL(string: "https://gitbay.org/krz")! #expect(WebURLRoute.account(for: url, current: accounts[0], accounts: accounts) == nil) #expect(WebURLRoute.account(for: url, current: nil, accounts: []) == nil) } @Test func webURLAccountMatchesAnExplicitDefaultPort() throws { let accounts = [try account("gitbay.org", "cmc")] let url = URL(string: "https://gitbay.org:443/krz")! #expect(WebURLRoute.account(for: url, current: nil, accounts: accounts) == accounts[0]) }