import Foundation import Testing @testable import bitchat /// The built-in relay set is four well-known hostnames, so a filter blocking /// four names ends internet-delivered private messages. These cover the /// hand-added relays that make that recoverable without shipping a build. struct NostrRelaySettingsTests { /// Each case gets its own suite so nothing touches the real preferences or /// races another case. private func makeDefaults() -> UserDefaults { let suite = "bitchat.tests.relays.\(UUID().uuidString)" return UserDefaults(suiteName: suite)! } private let builtIn: Set = [ "wss://relay.damus.io", "wss://nos.lol" ] @Test func addNormalizesABareHostname() { let defaults = makeDefaults() // A bare hostname is how relays are usually quoted; wss is the only // sensible assumption. let result = NostrRelaySettings.add("relay.example.com", builtIn: builtIn, in: defaults) #expect(result == .success("wss://relay.example.com")) #expect(NostrRelaySettings.customRelays(in: defaults) == ["wss://relay.example.com"]) } @Test func addAcceptsAnOnionAddress() { let defaults = makeDefaults() // The reason this feature exists: an onion relay is not blockable by // hostname or SNI filtering. let result = NostrRelaySettings.add( "wss://exampleonionaddressxyz234567.onion", builtIn: builtIn, in: defaults ) #expect(result == .success("wss://exampleonionaddressxyz234567.onion")) } @Test func addRejectsMalformedInput() { let defaults = makeDefaults() #expect(NostrRelaySettings.add("", builtIn: builtIn, in: defaults) == .failure(.malformed)) #expect(NostrRelaySettings.add(" ", builtIn: builtIn, in: defaults) == .failure(.malformed)) // A scheme the relay layer cannot dial must not be stored. #expect(NostrRelaySettings.add("ftp://relay.example.com", builtIn: builtIn, in: defaults) == .failure(.malformed)) #expect(NostrRelaySettings.customRelays(in: defaults).isEmpty) } @Test func addRejectsDuplicatesAndBuiltIns() { let defaults = makeDefaults() #expect(NostrRelaySettings.add("wss://relay.example.com", builtIn: builtIn, in: defaults) == .success("wss://relay.example.com")) // Same relay written differently still normalizes to the same URL. #expect(NostrRelaySettings.add("relay.example.com", builtIn: builtIn, in: defaults) == .failure(.alreadyPresent)) #expect(NostrRelaySettings.add("WSS://Relay.Example.com", builtIn: builtIn, in: defaults) == .failure(.alreadyPresent)) // Re-adding a built-in would double-count it in the target list. #expect(NostrRelaySettings.add("wss://nos.lol", builtIn: builtIn, in: defaults) == .failure(.alreadyPresent)) #expect(NostrRelaySettings.customRelays(in: defaults) == ["wss://relay.example.com"]) } @Test func addStopsAtTheLimit() { let defaults = makeDefaults() for index in 0..