mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
feat(network): add relay connection policies
This commit is contained in:
@@ -26,7 +26,7 @@ final class AppModelTests: XCTestCase {
|
||||
func testInitializesCoreWithSavedCustomRelayConfiguration() async {
|
||||
let core = FakeCoreGateway()
|
||||
let preferences = Fixtures.preferences()
|
||||
let configuration = RelayConfiguration(mode: .custom, relayURLs: ["https://relay.example"])
|
||||
let configuration = RelayConfiguration(mode: .strictCustom, relayURLs: ["https://relay.example"])
|
||||
preferences.setRelayConfiguration(configuration)
|
||||
_ = makeModel(core, preferences: preferences)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ final class AppPreferencesRepositoryTests: XCTestCase {
|
||||
repo.setNotificationsEnabled(true)
|
||||
repo.setReceiveFolder(ReceiveFolder(kind: .iosSecurityScopedUrl, value: "file:///x", displayName: "Custom"))
|
||||
repo.setRelayConfiguration(RelayConfiguration(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["https://relay-one.example", "https://relay-two.example:443"]
|
||||
))
|
||||
|
||||
@@ -44,7 +44,7 @@ final class AppPreferencesRepositoryTests: XCTestCase {
|
||||
XCTAssertEqual(reloaded.preferences.receiveFolder.displayName, "Custom")
|
||||
XCTAssertEqual(reloaded.preferences.receiveFolder.kind, .iosSecurityScopedUrl)
|
||||
XCTAssertEqual(reloaded.preferences.relayConfiguration, RelayConfiguration(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["https://relay-one.example", "https://relay-two.example:443"]
|
||||
))
|
||||
XCTAssertNotNil(store.data(forKey: "relay_configuration"))
|
||||
@@ -60,7 +60,7 @@ final class AppPreferencesRepositoryTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(
|
||||
repo.preferences.relayConfiguration,
|
||||
RelayConfiguration(mode: .custom, relayURLs: [])
|
||||
RelayConfiguration(mode: .strictCustom, relayURLs: [])
|
||||
)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ final class AppPreferencesRepositoryTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(
|
||||
repo.preferences.relayConfiguration,
|
||||
RelayConfiguration(mode: .custom, relayURLs: [])
|
||||
RelayConfiguration(mode: .strictCustom, relayURLs: [])
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ final class CoreRepositoryLifecycleTests: XCTestCase {
|
||||
|
||||
let concurrentInitialization = await repository.initialize(
|
||||
appDataDir: "/tmp/second",
|
||||
networkConfiguration: RelayConfiguration(mode: .custom, relayURLs: ["https://relay.example"])
|
||||
networkConfiguration: RelayConfiguration(mode: .strictCustom, relayURLs: ["https://relay.example"])
|
||||
)
|
||||
assertLifecycleFailure(concurrentInitialization, equals: .transitionInProgress)
|
||||
|
||||
|
||||
@@ -2,6 +2,32 @@ import XCTest
|
||||
@testable import VniDrop
|
||||
|
||||
final class RelayConfigurationTests: XCTestCase {
|
||||
func testCustomFallbackValidatesAndPreservesItsMode() throws {
|
||||
let result = try RelayConfigurationValidator.validate(
|
||||
mode: .customWithDirectFallback,
|
||||
relayURLs: ["https://relay.example/"]
|
||||
)
|
||||
|
||||
XCTAssertEqual(
|
||||
result,
|
||||
RelayConfiguration(
|
||||
mode: .customWithDirectFallback,
|
||||
relayURLs: ["https://relay.example"]
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testLocalOnlyRetainsPreviouslySavedRelayURLs() throws {
|
||||
let retained = ["https://relay.example"]
|
||||
let result = try RelayConfigurationValidator.validate(
|
||||
mode: .localOnly,
|
||||
relayURLs: ["not a URL"],
|
||||
retainedRelayURLs: retained
|
||||
)
|
||||
|
||||
XCTAssertEqual(result, RelayConfiguration(mode: .localOnly, relayURLs: retained))
|
||||
}
|
||||
|
||||
func testAutomaticModeIgnoresRelayDrafts() throws {
|
||||
let result = try RelayConfigurationValidator.validate(
|
||||
mode: .automatic,
|
||||
@@ -24,32 +50,32 @@ final class RelayConfigurationTests: XCTestCase {
|
||||
|
||||
func testCustomModeTrimsValidHTTPSRelayURLs() throws {
|
||||
let result = try RelayConfigurationValidator.validate(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: [" https://relay.example/ ", "https://backup.example:443"]
|
||||
)
|
||||
XCTAssertEqual(result, RelayConfiguration(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["https://relay.example", "https://backup.example"]
|
||||
))
|
||||
}
|
||||
|
||||
func testCustomModeIgnoresEmptyURLRows() throws {
|
||||
let result = try RelayConfigurationValidator.validate(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["", " ", "https://relay.example"]
|
||||
)
|
||||
XCTAssertEqual(result.relayURLs, ["https://relay.example"])
|
||||
}
|
||||
|
||||
func testCustomModeRequiresAtLeastOneRelay() {
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(mode: .custom, relayURLs: [])) { error in
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(mode: .strictCustom, relayURLs: [])) { error in
|
||||
XCTAssertEqual(error as? RelayConfigurationValidationError, .missingURL)
|
||||
}
|
||||
}
|
||||
|
||||
func testCustomModeRequiresHTTPS() {
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["http://relay.example"]
|
||||
)) { error in
|
||||
XCTAssertEqual(error as? RelayConfigurationValidationError, .httpsRequired(index: 0))
|
||||
@@ -67,7 +93,7 @@ final class RelayConfigurationTests: XCTestCase {
|
||||
]
|
||||
for relayURL in invalidURLs {
|
||||
XCTAssertThrowsError(
|
||||
try RelayConfigurationValidator.validate(mode: .custom, relayURLs: [relayURL]),
|
||||
try RelayConfigurationValidator.validate(mode: .strictCustom, relayURLs: [relayURL]),
|
||||
"Expected \(relayURL) to be rejected"
|
||||
) { error in
|
||||
XCTAssertEqual(error as? RelayConfigurationValidationError, .invalidURL(index: 0))
|
||||
@@ -77,7 +103,7 @@ final class RelayConfigurationTests: XCTestCase {
|
||||
|
||||
func testCustomModeRejectsNormalizedDuplicate() {
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(
|
||||
mode: .custom,
|
||||
mode: .strictCustom,
|
||||
relayURLs: ["https://relay.example", "https://RELAY.example:443/"]
|
||||
)) { error in
|
||||
XCTAssertEqual(error as? RelayConfigurationValidationError, .duplicateURL(index: 1))
|
||||
@@ -88,7 +114,7 @@ final class RelayConfigurationTests: XCTestCase {
|
||||
let relayURLs = (0...RelayConfigurationValidator.maximumRelayCount).map {
|
||||
"https://relay-\($0).example"
|
||||
}
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(mode: .custom, relayURLs: relayURLs)) { error in
|
||||
XCTAssertThrowsError(try RelayConfigurationValidator.validate(mode: .strictCustom, relayURLs: relayURLs)) { error in
|
||||
XCTAssertEqual(error as? RelayConfigurationValidationError, .tooManyURLs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,13 +59,13 @@ final class SettingsModelTests: XCTestCase {
|
||||
let core = FakeCoreGateway()
|
||||
let preferences = Fixtures.preferences()
|
||||
let model = makeModel(core, preferences: preferences)
|
||||
model.setRelayMode(.custom)
|
||||
model.setRelayMode(.strictCustom)
|
||||
model.setRelayURL(" https://relay.example/ ", at: 0)
|
||||
|
||||
model.applyRelayConfiguration()
|
||||
|
||||
await waitUntil { preferences.preferences.relayConfiguration.mode == .custom }
|
||||
let expected = RelayConfiguration(mode: .custom, relayURLs: ["https://relay.example"])
|
||||
await waitUntil { preferences.preferences.relayConfiguration.mode == .strictCustom }
|
||||
let expected = RelayConfiguration(mode: .strictCustom, relayURLs: ["https://relay.example"])
|
||||
XCTAssertEqual(preferences.preferences.relayConfiguration, expected)
|
||||
XCTAssertEqual(core.initializedNetworkConfigurations, [expected])
|
||||
XCTAssertFalse(model.state.relayConfigurationIsDirty)
|
||||
@@ -75,7 +75,7 @@ final class SettingsModelTests: XCTestCase {
|
||||
let core = FakeCoreGateway()
|
||||
let preferences = Fixtures.preferences()
|
||||
let relayURLs = ["https://relay.example", "https://backup.example"]
|
||||
preferences.setRelayConfiguration(RelayConfiguration(mode: .custom, relayURLs: relayURLs))
|
||||
preferences.setRelayConfiguration(RelayConfiguration(mode: .strictCustom, relayURLs: relayURLs))
|
||||
let model = makeModel(core, preferences: preferences)
|
||||
|
||||
model.setRelayMode(.automatic)
|
||||
@@ -86,7 +86,7 @@ final class SettingsModelTests: XCTestCase {
|
||||
XCTAssertEqual(core.initializedNetworkConfigurations, [
|
||||
RelayConfiguration(mode: .automatic, relayURLs: relayURLs),
|
||||
])
|
||||
model.setRelayMode(.custom)
|
||||
model.setRelayMode(.strictCustom)
|
||||
XCTAssertEqual(model.state.relayURLs, relayURLs)
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ final class SettingsModelTests: XCTestCase {
|
||||
isInitialized: true,
|
||||
status: CoreStatus(endpointId: "endpoint", activeTransfers: 0, activeShares: 1)
|
||||
))
|
||||
model.setRelayMode(.custom)
|
||||
model.setRelayMode(.strictCustom)
|
||||
model.setRelayURL("https://relay.example", at: 0)
|
||||
|
||||
model.applyRelayConfiguration()
|
||||
@@ -114,8 +114,8 @@ final class SettingsModelTests: XCTestCase {
|
||||
core.initializeResult = .failure(CoreNetworkLifecycleError.activeNetworkWork)
|
||||
let preferences = Fixtures.preferences()
|
||||
let model = makeModel(core, preferences: preferences)
|
||||
let attempted = RelayConfiguration(mode: .custom, relayURLs: ["https://relay.example"])
|
||||
model.setRelayMode(.custom)
|
||||
let attempted = RelayConfiguration(mode: .strictCustom, relayURLs: ["https://relay.example"])
|
||||
model.setRelayMode(.strictCustom)
|
||||
model.setRelayURL(attempted.relayURLs[0], at: 0)
|
||||
|
||||
model.applyRelayConfiguration()
|
||||
@@ -134,8 +134,8 @@ final class SettingsModelTests: XCTestCase {
|
||||
core.initializeResults = [.failure(TestError.unimplemented), .success(())]
|
||||
let preferences = Fixtures.preferences()
|
||||
let model = makeModel(core, preferences: preferences)
|
||||
let attempted = RelayConfiguration(mode: .custom, relayURLs: ["https://relay.example"])
|
||||
model.setRelayMode(.custom)
|
||||
let attempted = RelayConfiguration(mode: .strictCustom, relayURLs: ["https://relay.example"])
|
||||
model.setRelayMode(.strictCustom)
|
||||
model.setRelayURL(attempted.relayURLs[0], at: 0)
|
||||
|
||||
model.applyRelayConfiguration()
|
||||
|
||||
Reference in New Issue
Block a user