Files
vnidrop/apple/Tests/AppPreferencesRepositoryTests.swift
Hammed Abass cbace73908 feat(network): support custom relay servers
Add strict custom Iroh relay profiles with safe restart and rollback across the Rust core, Compose apps, and Apple apps. Preserve multi-relay invitations and fail closed on configuration or recovery mismatches.
2026-07-23 14:27:40 +02:00

91 lines
3.3 KiB
Swift

import XCTest
@testable import VniDrop
/// Ports `preferences/AppPreferencesRepositoryTest.kt` values persist to the
/// backing store and reload identically.
@MainActor
final class AppPreferencesRepositoryTests: XCTestCase {
private func defaults() -> UserDefaults { UserDefaults(suiteName: "vnidrop.prefs.\(UUID().uuidString)")! }
private func fallback() -> AppPreferencesDefaults {
AppPreferencesDefaults(
username: "Default",
receiveFolder: ReceiveFolder(kind: .fileSystemPath, value: "/tmp", displayName: "Downloads"),
themeMode: .system
)
}
func testMissingRelayProfileDefaultsToAutomatic() {
let repo = AppPreferencesRepository(defaults: defaults(), fallback: fallback())
XCTAssertEqual(repo.preferences.username, "Default")
XCTAssertEqual(repo.preferences.themeMode, .system)
XCTAssertFalse(repo.preferences.notificationsEnabled)
XCTAssertEqual(repo.preferences.relayConfiguration, .automatic)
}
func testValuesPersistAndReload() {
let store = defaults()
let fb = fallback()
let repo = AppPreferencesRepository(defaults: store, fallback: fb)
repo.setUsername("Bob")
repo.setThemeMode(.dark)
repo.setNotificationsEnabled(true)
repo.setReceiveFolder(ReceiveFolder(kind: .iosSecurityScopedUrl, value: "file:///x", displayName: "Custom"))
repo.setRelayConfiguration(RelayConfiguration(
mode: .custom,
relayURLs: ["https://relay-one.example", "https://relay-two.example:443"]
))
// A fresh repository over the same store reflects the persisted values.
let reloaded = AppPreferencesRepository(defaults: store, fallback: fb)
XCTAssertEqual(reloaded.preferences.username, "Bob")
XCTAssertEqual(reloaded.preferences.themeMode, .dark)
XCTAssertTrue(reloaded.preferences.notificationsEnabled)
XCTAssertEqual(reloaded.preferences.receiveFolder.displayName, "Custom")
XCTAssertEqual(reloaded.preferences.receiveFolder.kind, .iosSecurityScopedUrl)
XCTAssertEqual(reloaded.preferences.relayConfiguration, RelayConfiguration(
mode: .custom,
relayURLs: ["https://relay-one.example", "https://relay-two.example:443"]
))
XCTAssertNotNil(store.data(forKey: "relay_configuration"))
XCTAssertNil(store.object(forKey: "relay_mode"))
XCTAssertNil(store.object(forKey: "relay_urls"))
}
func testCorruptedRelayProfileFailsClosed() {
let store = defaults()
store.set(Data("{".utf8), forKey: "relay_configuration")
let repo = AppPreferencesRepository(defaults: store, fallback: fallback())
XCTAssertEqual(
repo.preferences.relayConfiguration,
RelayConfiguration(mode: .custom, relayURLs: [])
)
}
func testUnknownRelayModeFailsClosed() {
let store = defaults()
store.set(
Data(#"{"mode":"future-mode","relayURLs":["https://relay.example"]}"#.utf8),
forKey: "relay_configuration"
)
let repo = AppPreferencesRepository(defaults: store, fallback: fallback())
XCTAssertEqual(
repo.preferences.relayConfiguration,
RelayConfiguration(mode: .custom, relayURLs: [])
)
}
func testResetReceiveFolderRestoresFallback() {
let store = defaults()
let fb = fallback()
let repo = AppPreferencesRepository(defaults: store, fallback: fb)
repo.setReceiveFolder(ReceiveFolder(kind: .fileSystemPath, value: "/custom", displayName: "Custom"))
repo.resetReceiveFolder()
XCTAssertEqual(repo.preferences.receiveFolder.value, "/tmp")
}
}