krz/octosentry
macOS menu bar app to monitor GitHub security alerts
clone: git clone https://gitbay.org/krz/octosentry.git
1.1.1: octosentryTests/GitHubHostTests.swift · raw
1//
2// GitHubHostTests.swift
3// octosentryTests
4//
5
6import Foundation
7import Testing
8@testable import octosentry
9
10struct GitHubHostTests {
11
12 // MARK: - github.com
13
14 @Test func theDefaultIsGitHubDotCom() {
15 #expect(GitHubHost.dotCom.isDotCom)
16 #expect(GitHubHost.dotCom.displayName == "github.com")
17 #expect(GitHubHost.dotCom.apiBaseURL.absoluteString == "https://api.github.com")
18 #expect(GitHubHost.dotCom.webBaseURL.absoluteString == "https://github.com")
19 }
20
21 @Test func dotComKeepsItsExistingAuthEndpoints() {
22 #expect(GitHubHost.dotCom.deviceCodeURL.absoluteString == "https://github.com/login/device/code")
23 #expect(GitHubHost.dotCom.accessTokenURL.absoluteString == "https://github.com/login/oauth/access_token")
24 }
25
26 // Naming github.com explicitly is still github.com, not an enterprise host.
27 @Test func namingGitHubDotComExplicitlyIsNotEnterprise() {
28 #expect(GitHubHost(host: "github.com", clientID: "abc").isDotCom)
29 #expect(GitHubHost(host: "https://github.com", clientID: "abc").isDotCom)
30 }
31
32 // MARK: - Enterprise Server
33
34 // GHES serves the REST API from the same host under /api/v3, not from a
35 // separate api. domain.
36 @Test func enterpriseAPILivesUnderApiV3OnTheSameHost() {
37 let host = GitHubHost(host: "github.example.com", clientID: "abc")
38
39 #expect(host.apiBaseURL.absoluteString == "https://github.example.com/api/v3")
40 #expect(host.webBaseURL.absoluteString == "https://github.example.com")
41 #expect(!host.isDotCom)
42 }
43
44 @Test func enterpriseAuthEndpointsAreOnTheInstance() {
45 let host = GitHubHost(host: "github.example.com", clientID: "abc")
46
47 #expect(host.deviceCodeURL.absoluteString == "https://github.example.com/login/device/code")
48 #expect(host.accessTokenURL.absoluteString == "https://github.example.com/login/oauth/access_token")
49 }
50
51 // MARK: - Normalizing what a user pastes
52
53 @Test func aPastedURLIsReducedToItsHost() {
54 for input in [
55 "https://github.example.com",
56 "http://github.example.com",
57 "github.example.com/",
58 "https://github.example.com/some/path",
59 " GitHub.Example.com ",
60 ] {
61 #expect(GitHubHost(host: input, clientID: "abc").host == "github.example.com", "input: \(input)")
62 }
63 }
64
65 @Test func anEmptyHostMeansGitHubDotCom() {
66 #expect(GitHubHost(host: "", clientID: nil).isDotCom)
67 #expect(GitHubHost(host: " ", clientID: nil).isDotCom)
68 #expect(GitHubHost(host: nil, clientID: nil).isDotCom)
69 }
70
71 @Test func anEmptyClientIDIsTreatedAsAbsent() {
72 #expect(GitHubHost(host: "github.example.com", clientID: "").clientID == nil)
73 #expect(GitHubHost(host: "github.example.com", clientID: " ").clientID == nil)
74 #expect(GitHubHost(host: "github.example.com", clientID: " abc ").clientID == "abc")
75 }
76
77 // MARK: - Persistence
78
79 @Test func roundTripsThroughCodable() throws {
80 for host in [GitHubHost.dotCom, GitHubHost(host: "github.example.com", clientID: "abc")] {
81 let decoded = try JSONDecoder().decode(GitHubHost.self, from: try JSONEncoder().encode(host))
82 #expect(decoded == host)
83 }
84 }
85
86 // An account written before Enterprise support has no host field.
87 @Test func anAccountWithoutAHostFieldDecodesAsGitHubDotCom() throws {
88 let json = """
89 {"id": 7, "login": "octocat", "keychainAccount": "account-7", "hasRepoScope": false}
90 """
91
92 let account = try JSONDecoder().decode(Account.self, from: Data(json.utf8))
93
94 #expect(account.host == .dotCom)
95 #expect(account.displayName == "octocat")
96 }
97
98 // MARK: - Accounts
99
100 // Ids are only unique within an instance, so two accounts that happen to
101 // share an id on different hosts must not share a Keychain item.
102 @Test func sameIdOnDifferentHostsGetsDifferentKeychainItems() {
103 let dotCom = Account.new(id: 7, login: "octocat", hasRepoScope: false)
104 let enterprise = Account.new(
105 id: 7,
106 login: "octocat",
107 hasRepoScope: false,
108 host: GitHubHost(host: "github.example.com", clientID: "abc")
109 )
110
111 #expect(dotCom.keychainAccount != enterprise.keychainAccount)
112 }
113
114 @Test func enterpriseAccountsAreLabelledWithTheirHost() {
115 let account = Account.new(
116 id: 7,
117 login: "octocat",
118 hasRepoScope: false,
119 host: GitHubHost(host: "github.example.com", clientID: "abc")
120 )
121
122 #expect(account.displayName == "octocat @ github.example.com")
123 }
124}