Skip to content

Commit cd04630

Browse files
committed
Fix tests
1 parent 7c8b2e4 commit cd04630

File tree

9 files changed

+180
-82
lines changed

9 files changed

+180
-82
lines changed

ios/MullvadVPN.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@
507507
7A516C3A2B7111A700BBD33D /* IPOverrideWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */; };
508508
7A516C3C2B712F0B00BBD33D /* IPOverrideWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */; };
509509
7A52C4502F6D8A6A005CD885 /* RecentItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A52C44F2F6D8A60005CD885 /* RecentItemView.swift */; };
510+
7A52C45A2F7277C9005CD885 /* BreadcrumbsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2917F52F606D76001E5DB6 /* BreadcrumbsProvider.swift */; };
510511
7A52F96A2C1735AE00B133B9 /* RelaySelectorStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FE25EF2AA77664003D1918 /* RelaySelectorStub.swift */; };
511512
7A52F96C2C17450C00B133B9 /* RelaySelectorWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A52F96B2C17450C00B133B9 /* RelaySelectorWrapperTests.swift */; };
512513
7A5468AC2C6A55B100590086 /* LocationRelays.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5468AB2C6A55B100590086 /* LocationRelays.swift */; };
@@ -6106,6 +6107,7 @@
61066107
44B3C43D2C00CBBD0079782C /* PacketTunnelActorReducerTests.swift in Sources */,
61076108
F0A086902C22D6A700BF83E7 /* TunnelSettingsStrategyTests.swift in Sources */,
61086109
A9A5F9EC2ACB05160083449F /* CodingErrors+CustomErrorDescription.swift in Sources */,
6110+
7A52C45A2F7277C9005CD885 /* BreadcrumbsProvider.swift in Sources */,
61096111
A9A5F9ED2ACB05160083449F /* NSRegularExpression+IPAddress.swift in Sources */,
61106112
A9A5F9EE2ACB05160083449F /* StorePaymentOutcome.swift in Sources */,
61116113
F0AC644E2F3B53150024427C /* UNUserNotificationCenter+Permission.swift in Sources */,

ios/MullvadVPN/View controllers/SelectLocation/DataSource/LocationDataSourceProtocol.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,20 @@ extension LocationDataSourceProtocol {
8686
/// It prevent the user from making a selection that would lead to the blocked state.
8787
/// - Parameters:
8888
/// - constraint: The selection that should be checked for exclusion.
89-
func setExcludedNode(constraint: RelayConstraint<UserSelectedRelays>) {
90-
guard let selectedRelayLocations = constraint.value?.locations else {
91-
return
92-
}
93-
94-
guard selectedRelayLocations.count == 1,
95-
let selectedRelayLocation = selectedRelayLocations.first
96-
else {
97-
return
98-
}
99-
89+
func setExcludedNode(constraint: RelayConstraint<UserSelectedRelays>?) {
10090
nodes.forEachNode { node in
10191
node.isExcluded = false
10292

93+
guard let selectedRelayLocations = constraint?.value?.locations else {
94+
return
95+
}
96+
97+
guard selectedRelayLocations.count == 1,
98+
let selectedRelayLocation = selectedRelayLocations.first
99+
else {
100+
return
101+
}
102+
103103
let locations = Set((node.flattened + [node]).flatMap { $0.locations })
104104
if locations
105105
.contains(selectedRelayLocation) && node.activeRelayNodes.count == 1

ios/MullvadVPNTests/MullvadVPN/View controllers/SelectLocation/AllLocationsDataSourceTests.swift

Lines changed: 107 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import MullvadMockData
10+
import MullvadREST
1011
import MullvadTypes
1112
import XCTest
1213

@@ -30,6 +31,15 @@ class AllLocationsDataSourceTests: XCTestCase {
3031
XCTAssertNotNil(rootNode.descendantNodeFor(codes: ["se2-wireguard"]))
3132
}
3233

34+
func testAddAutomaticLocation() throws {
35+
let automaticNode = dataSource.nodes.compactMap { $0.asAutomaticLocationNode }.first!
36+
37+
XCTAssertTrue(automaticNode.name == "Automatic")
38+
XCTAssertTrue(automaticNode.code == "automatic")
39+
XCTAssertTrue(automaticNode.locations.isEmpty)
40+
XCTAssertTrue(automaticNode.locationInfo == nil)
41+
}
42+
3343
func testSearchCity() throws {
3444
dataSource.search(by: "got")
3545
let rootNode = RootLocationNode(children: dataSource.nodes)
@@ -85,34 +95,113 @@ class AllLocationsDataSourceTests: XCTestCase {
8595
func testNodeByLocation() throws {
8696
let rootNode = RootLocationNode(children: dataSource.nodes)
8797

88-
var nodeByLocation = dataSource.node(by: .init(locations: [.country("es")]))
98+
var nodeByLocation = dataSource.node(by: .only(.init(locations: [.country("es")])))
8999
var nodeByCode = rootNode.descendantNodeFor(codes: ["es"])
90100
XCTAssertEqual(nodeByLocation, nodeByCode)
91101

92-
nodeByLocation = dataSource.node(by: .init(locations: [.city("es", "mad")]))
102+
nodeByLocation = dataSource.node(by: .only(.init(locations: [.city("es", "mad")])))
93103
nodeByCode = rootNode.descendantNodeFor(codes: ["es", "mad"])
94104
XCTAssertEqual(nodeByLocation, nodeByCode)
95105

96-
nodeByLocation = dataSource.node(by: .init(locations: [.hostname("es", "mad", "es1-wireguard")]))
106+
nodeByLocation = dataSource.node(by: .only(.init(locations: [.hostname("es", "mad", "es1-wireguard")])))
97107
nodeByCode = rootNode.descendantNodeFor(codes: ["es1-wireguard"])
98108
XCTAssertEqual(nodeByLocation, nodeByCode)
99109
}
100110

101-
func testConnectedNode() throws {
111+
func testConnectedNodeWithValidHostname() throws {
102112
let hostname = "es1-wireguard"
103-
dataSource.setConnectedRelay(hostname: hostname)
113+
let constraint = RelayConstraint<UserSelectedRelays>.only(.init(locations: [.hostname("es", "mad", hostname)]))
114+
let selectedRelay = SelectedRelay(
115+
endpoint: .init(
116+
socketAddress: .ipv4(.init(ip: .loopback, port: 0)),
117+
ipv4Gateway: .loopback,
118+
ipv6Gateway: .loopback,
119+
publicKey: Data(),
120+
obfuscation: .off
121+
),
122+
hostname: hostname,
123+
location: .init(
124+
country: "",
125+
countryCode: "",
126+
city: "",
127+
cityCode: "",
128+
latitude: 0,
129+
longitude: 0
130+
),
131+
features: nil
132+
)
133+
134+
dataSource.setConnectedRelay(relayConstraint: constraint, selectedRelay: selectedRelay)
104135
dataSource.nodes.forEachNode { node in
105136
XCTAssertEqual(node.isConnected, node.name == hostname)
106137
}
138+
}
107139

108-
dataSource.setConnectedRelay(hostname: "invalid-hostname")
140+
func testConnectedNodeWithInvalidHostname() throws {
141+
let constraint = RelayConstraint<UserSelectedRelays>.only(
142+
.init(locations: [.hostname("es", "mad", "es1-wireguard")]))
143+
let selectedRelay = SelectedRelay(
144+
endpoint: .init(
145+
socketAddress: .ipv4(.init(ip: .loopback, port: 0)),
146+
ipv4Gateway: .loopback,
147+
ipv6Gateway: .loopback,
148+
publicKey: Data(),
149+
obfuscation: .off
150+
),
151+
hostname: "invalid-hostname",
152+
location: .init(
153+
country: "",
154+
countryCode: "",
155+
city: "",
156+
cityCode: "",
157+
latitude: 0,
158+
longitude: 0
159+
),
160+
features: nil
161+
)
162+
163+
dataSource.setConnectedRelay(relayConstraint: constraint, selectedRelay: selectedRelay)
109164
dataSource.nodes.forEachNode { node in
110165
XCTAssertFalse(node.isConnected)
111166
}
112167
}
113168

169+
func testConnectedNodeWithAutomaticLocation() throws {
170+
let constraint = RelayConstraint<UserSelectedRelays>.any
171+
let selectedRelay = SelectedRelay(
172+
endpoint: .init(
173+
socketAddress: .ipv4(.init(ip: .loopback, port: 0)),
174+
ipv4Gateway: .loopback,
175+
ipv6Gateway: .loopback,
176+
publicKey: Data(),
177+
obfuscation: .off
178+
),
179+
hostname: "",
180+
location: .init(
181+
country: "Sweden",
182+
countryCode: "",
183+
city: "Gothenburg",
184+
cityCode: "",
185+
latitude: 0,
186+
longitude: 0
187+
),
188+
features: nil
189+
)
190+
191+
dataSource.setConnectedRelay(relayConstraint: constraint, selectedRelay: selectedRelay)
192+
193+
let connectedNodes = dataSource.nodes.filter { node in
194+
node.isConnected
195+
}
196+
XCTAssert(connectedNodes.count == 1)
197+
198+
let connectedNode = try XCTUnwrap(connectedNodes.first?.asAutomaticLocationNode)
199+
XCTAssertTrue(connectedNode.isConnected)
200+
XCTAssertEqual(connectedNode.locationInfo, ["Sweden", "Gothenburg"])
201+
}
202+
114203
func testSetSelectedLocation() throws {
115-
dataSource.setSelectedNode(selectedRelays: .init(locations: [.country("es")]))
204+
dataSource.setSelectedNode(constraint: .only(.init(locations: [.country("es")])))
116205

117206
dataSource.nodes.forEachNode { node in
118207
if node.locations == [.country("es")] {
@@ -124,7 +213,7 @@ class AllLocationsDataSourceTests: XCTestCase {
124213

125214
dataSource
126215
.setSelectedNode(
127-
selectedRelays: .init(locations: [.country("invalid")])
216+
constraint: .only(.init(locations: [.country("invalid")]))
128217
)
129218
dataSource.nodes.forEachNode { node in
130219
XCTAssertFalse(node.isSelected)
@@ -133,16 +222,16 @@ class AllLocationsDataSourceTests: XCTestCase {
133222

134223
func testExcludeLocation() throws {
135224
let excludedRelays = UserSelectedRelays(locations: [.hostname("se", "sto", "se2-wireguard")])
136-
dataSource.setExcludedNode(excludedSelection: excludedRelays)
137-
let excludedNode = dataSource.node(by: excludedRelays)!
225+
dataSource.setExcludedNode(constraint: .only(excludedRelays))
226+
let excludedNode = dataSource.node(by: .only(excludedRelays))!
138227

139228
XCTAssertTrue(excludedNode.isExcluded)
140229

141230
excludedNode.forEachAncestor { ancestor in
142231
XCTAssertFalse(ancestor.isExcluded)
143232
}
144233

145-
let includedNode = dataSource.node(by: .init(locations: [.country("es")]))!
234+
let includedNode = dataSource.node(by: .only(.init(locations: [.country("es")])))!
146235
XCTAssertFalse(includedNode.isExcluded)
147236
includedNode.forEachDescendant { child in
148237
XCTAssertFalse(child.isExcluded)
@@ -156,13 +245,13 @@ class AllLocationsDataSourceTests: XCTestCase {
156245
let entryRelays = UserSelectedRelays(locations: [.hostname("jp", "tyo", "jp1-wireguard")])
157246

158247
// Simulate multihop: exclusion is applied, Japan is excluded.
159-
dataSource.setExcludedNode(excludedSelection: entryRelays)
160-
let jpNode = dataSource.node(by: entryRelays)!
248+
dataSource.setExcludedNode(constraint: .only(entryRelays))
249+
let jpNode = dataSource.node(by: .only(entryRelays))!
161250
XCTAssertTrue(jpNode.isExcluded)
162251

163252
// Simulate switching to singlehop: the view model should pass nil
164253
// to clear exclusions rather than passing the entry relay.
165-
dataSource.setExcludedNode(excludedSelection: nil)
254+
dataSource.setExcludedNode(constraint: nil)
166255

167256
// In singlehop, Japan should NOT be excluded
168257
XCTAssertFalse(jpNode.isExcluded)
@@ -173,8 +262,8 @@ class AllLocationsDataSourceTests: XCTestCase {
173262

174263
func testExcludeLocationIncludesAncestors() throws {
175264
let excludedRelays = UserSelectedRelays(locations: [.hostname("jp", "tyo", "jp1-wireguard")])
176-
dataSource.setExcludedNode(excludedSelection: excludedRelays)
177-
let excludedNode = dataSource.node(by: excludedRelays)!
265+
dataSource.setExcludedNode(constraint: .only(excludedRelays))
266+
let excludedNode = dataSource.node(by: .only(excludedRelays))!
178267

179268
XCTAssertTrue(excludedNode.isExcluded)
180269

@@ -183,7 +272,7 @@ class AllLocationsDataSourceTests: XCTestCase {
183272
XCTAssertTrue(ancestor.isExcluded)
184273
}
185274

186-
let includedNode = dataSource.node(by: .init(locations: [.country("se")]))!
275+
let includedNode = dataSource.node(by: .only(.init(locations: [.country("se")])))!
187276
XCTAssertFalse(includedNode.isExcluded)
188277
includedNode.forEachDescendant { child in
189278
XCTAssertFalse(child.isExcluded)
@@ -198,5 +287,6 @@ extension AllLocationsDataSourceTests {
198287

199288
dataSource = AllLocationDataSource()
200289
dataSource.reload(relays)
290+
dataSource.addAutomaticLocationNode()
201291
}
202292
}

ios/MullvadVPNTests/MullvadVPN/View controllers/SelectLocation/CustomListsDataSourceTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class CustomListsDataSourceTests: XCTestCase {
7777
customListSelection: .init(listId: customListId, isList: false)
7878
)
7979

80-
let nodeByLocations = dataSource.node(by: relays)
80+
let nodeByLocations = dataSource.node(by: .only(relays))
8181
let nodeByCode = dataSource.nodes.first?.descendantNodeFor(codes: ["Netflix", "es1-wireguard"])
8282

8383
XCTAssertEqual(nodeByLocations, nodeByCode)
@@ -92,7 +92,7 @@ class CustomListsDataSourceTests: XCTestCase {
9292

9393
dataSource
9494
.setSelectedNode(
95-
selectedRelays: userSelectedRelays
95+
constraint: .only(userSelectedRelays)
9696
)
9797

9898
dataSource.nodes.forEachNode { node in
@@ -105,7 +105,7 @@ class CustomListsDataSourceTests: XCTestCase {
105105

106106
dataSource
107107
.setSelectedNode(
108-
selectedRelays: .init(locations: [.country("invalid")])
108+
constraint: .only(.init(locations: [.country("invalid")]))
109109
)
110110
dataSource.nodes.forEachNode { node in
111111
XCTAssertFalse(node.isSelected)
@@ -119,7 +119,7 @@ class CustomListsDataSourceTests: XCTestCase {
119119
]
120120
)
121121

122-
dataSource.setSelectedNode(selectedRelays: selectedRelays)
122+
dataSource.setSelectedNode(constraint: .only(selectedRelays))
123123

124124
dataSource.nodes.forEachNode { node in
125125
XCTAssertFalse(node.isSelected)

0 commit comments

Comments
 (0)