import Foundation import Testing @testable import LocalData @Suite struct RouterDomainTests { private let router: StorageRouter private let mockKeychain = MockKeychainHelper() init() { let testBaseURL = FileManager.default.temporaryDirectory.appending(path: "RouterDomainTests-\(UUID().uuidString)") router = StorageRouter( keychain: mockKeychain, encryption: EncryptionHelper(keychain: mockKeychain), file: FileStorageHelper(configuration: FileStorageConfiguration(baseURL: testBaseURL)), defaults: UserDefaultsHelper(defaults: UserDefaults(suiteName: "RouterDomainTests-\(UUID().uuidString)")!) ) } private struct DomainKey: StorageKey { typealias Value = String let name: String let domain: StorageDomain let security: SecurityPolicy let serializer: Serializer = .json let owner: String = "DomainTests" let description: String = "Domain test key" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .never init(name: String, domain: StorageDomain, security: SecurityPolicy = .none) { self.name = name self.domain = domain self.security = security } } @Test func domainUserDefaults() async throws { let key = DomainKey(name: "defaults.key", domain: .userDefaults(suite: nil)) try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) #expect(await (try? router.exists(key)) == false) } @Test func domainAppGroupUserDefaults() async throws { // We use a mock configuration to avoid requiring a real app group await router.updateStorageConfiguration(StorageConfiguration(defaultAppGroupIdentifier: "group.test")) let key = DomainKey(name: "appgroup.defaults.key", domain: .appGroupUserDefaults(identifier: "group.test")) try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) } @Test func domainKeychain() async throws { let key = DomainKey( name: "keychain.key", domain: .keychain(service: "test"), security: .keychain(accessibility: .afterFirstUnlock, accessControl: .none) ) try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) } @Test func domainFileSystem() async throws { let key = DomainKey(name: "file.key", domain: .fileSystem(directory: .documents)) try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) } @Test func domainEncryptedFileSystem() async throws { let key = DomainKey(name: "encfile.key", domain: .encryptedFileSystem(directory: .documents)) try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) } @Test func domainAppGroupFileSystem() async throws { // App blocks usually fail or return nil in tests, but we exercise the path await router.updateStorageConfiguration(StorageConfiguration(defaultAppGroupIdentifier: "group.test")) let key = DomainKey(name: "appgroup.file.key", domain: .appGroupFileSystem(identifier: "group.test", directory: .documents)) do { try await router.set("value", for: key) #expect(try await router.get(key) == "value") try await router.remove(key) } catch StorageError.invalidAppGroupIdentifier { // Path covered } } @Test func resolutionFailureService() async throws { // Clear default service await router.updateStorageConfiguration(StorageConfiguration(defaultKeychainService: nil)) let key = DomainKey( name: "bad.service.key", domain: .keychain(service: nil), security: .keychain(accessibility: .afterFirstUnlock, accessControl: .none) ) await #expect(throws: StorageError.keychainError(errSecBadReq)) { try await router.set("value", for: key) } } @Test func resolutionFailureIdentifier() async throws { // Clear default identifier await router.updateStorageConfiguration(StorageConfiguration(defaultAppGroupIdentifier: nil)) let key = DomainKey(name: "bad.id.key", domain: .appGroupUserDefaults(identifier: nil)) await #expect(throws: StorageError.invalidAppGroupIdentifier("none")) { try await router.set("value", for: key) } } }