gitbayTests/PushTargetTests.swift
83 lines · 3701 bytes
9 symbols in this file
accountpayloadtargetResolvesToTheMatchingAccounttargetDistinguishesTheSameUserOnTwoInstancestargetIsNilForAnAccountSignedOuttargetIsNilForAnUnroutablePathtargetMatchesAnInstanceWithATrailingSlashtargetMatchesAnInstanceWithAnExplicitDefaultPorttargetMatchesAnAccountStoredWithAnExplicitDefaultPort
1import Foundation
2import Testing
3@testable import gitbay
4
5private func account(_ host: String, _ user: String) throws -> Account {
6 Account(instance: try GitbayInstance(url: "https://\(host)"), username: user)
7}
8
9private func payload(_ instance: String, _ user: String, _ path: String) throws -> PushPayload {
10 try #require(PushPayload(userInfo: [
11 "aps": ["alert": ["title": "t", "body": "b"]],
12 "instance": instance, "user": user, "path": path,
13 ]))
14}
15
16@Test func targetResolvesToTheMatchingAccount() throws {
17 let accounts = [try account("gitbay.org", "cmc"), try account("dev.local", "cmc")]
18 let target = try #require(PushTarget(
19 payload: try payload("https://dev.local", "cmc", "krz/gitbay/mrs/7"),
20 accounts: accounts))
21 #expect(target.accountID == accounts[1].id)
22 #expect(target.destination == .mr(repo: "krz/gitbay", number: 7))
23}
24
25// Same username on two instances is two accounts; the instance decides.
26@Test func targetDistinguishesTheSameUserOnTwoInstances() throws {
27 let accounts = [try account("gitbay.org", "cmc"), try account("dev.local", "cmc")]
28 let target = try #require(PushTarget(
29 payload: try payload("https://gitbay.org", "cmc", "a/b/issues/1"),
30 accounts: accounts))
31 #expect(target.accountID == accounts[0].id)
32}
33
34@Test func targetIsNilForAnAccountSignedOut() throws {
35 let accounts = [try account("gitbay.org", "cmc")]
36 #expect(PushTarget(payload: try payload("https://other.example", "cmc", "a/b/issues/1"),
37 accounts: accounts) == nil)
38}
39
40// A repository root, or a section the app has no screen for, resolves
41// to no target: the tap opens the app without navigating.
42@Test func targetIsNilForAnUnroutablePath() throws {
43 let accounts = [try account("gitbay.org", "cmc")]
44 #expect(PushTarget(payload: try payload("https://gitbay.org", "cmc", "krz/gitbay"),
45 accounts: accounts) == nil)
46 #expect(PushTarget(payload: try payload("https://gitbay.org", "cmc", "krz/gitbay/wiki/Home"),
47 accounts: accounts) == nil)
48}
49
50// A server's unnormalised site_url must not desync a payload from the
51// account it belongs to: both sides go through GitbayInstance's own
52// normalisation before comparing.
53@Test func targetMatchesAnInstanceWithATrailingSlash() throws {
54 let accounts = [try account("gitbay.org", "cmc")]
55 let target = try #require(PushTarget(
56 payload: try payload("https://gitbay.org/", "cmc", "a/b/issues/1"),
57 accounts: accounts))
58 #expect(target.accountID == accounts[0].id)
59}
60
61@Test func targetMatchesAnInstanceWithAnExplicitDefaultPort() throws {
62 let accounts = [try account("gitbay.org", "cmc")]
63 let target = try #require(PushTarget(
64 payload: try payload("https://gitbay.org:443", "cmc", "a/b/issues/1"),
65 accounts: accounts))
66 #expect(target.accountID == accounts[0].id)
67}
68
69// The other side of the same mismatch: an account stored before the
70// constructor folded the default port keeps ":443" in its baseURL, so
71// decoding is the only way to build one. Its id keeps the port —
72// rewriting that would orphan the Keychain token keyed by it.
73@Test func targetMatchesAnAccountStoredWithAnExplicitDefaultPort() throws {
74 let legacy = try JSONDecoder().decode(
75 GitbayInstance.self, from: Data(#"{"baseURL":"https://gitbay.org:443"}"#.utf8))
76 let accounts = [Account(instance: legacy, username: "cmc")]
77 #expect(accounts[0].id.contains(":443"))
78
79 let target = try #require(PushTarget(
80 payload: try payload("https://gitbay.org", "cmc", "a/b/issues/1"),
81 accounts: accounts))
82 #expect(target.accountID == accounts[0].id)
83}