Summary: - Sources: update Configuration, Helpers, Models (+1 more) - Tests: update tests for AppGroupTests.swift, FileStorageHelperExpansionTests.swift, FileStorageHelperTests.swift (+7 more) Stats: - 18 files changed, 306 insertions(+), 58 deletions(-)
121 lines
4.2 KiB
Swift
121 lines
4.2 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import LocalData
|
|
|
|
private struct LegacyKey: StorageKey {
|
|
typealias Value = String
|
|
let name: String
|
|
let domain: StorageDomain
|
|
let security: SecurityPolicy = .none
|
|
let serializer: Serializer<String> = .json
|
|
let owner: String = "Legacy"
|
|
let description: String = "Legacy key"
|
|
let availability: PlatformAvailability = .all
|
|
let syncPolicy: SyncPolicy = .never
|
|
}
|
|
|
|
private struct ModernKey: StorageKey {
|
|
typealias Value = String
|
|
let name: String
|
|
let domain: StorageDomain
|
|
let security: SecurityPolicy = .keychain(accessibility: .afterFirstUnlock, accessControl: .none)
|
|
let serializer: Serializer<String> = .json
|
|
let owner: String = "Modern"
|
|
let description: String = "Modern key"
|
|
let availability: PlatformAvailability = .all
|
|
let syncPolicy: SyncPolicy = .never
|
|
let migrationSources: [AnyStorageKey]
|
|
|
|
init(name: String, domain: StorageDomain, migrationSources: [AnyStorageKey]) {
|
|
self.name = name
|
|
self.domain = domain
|
|
self.migrationSources = migrationSources
|
|
}
|
|
}
|
|
|
|
@Suite(.serialized)
|
|
struct MigrationTests {
|
|
private let router: StorageRouter
|
|
|
|
init() {
|
|
let testBaseURL = FileManager.default.temporaryDirectory.appending(path: "MigrationTests-\(UUID().uuidString)")
|
|
router = StorageRouter(
|
|
keychain: MockKeychainHelper(),
|
|
encryption: EncryptionHelper(keychain: MockKeychainHelper()),
|
|
file: FileStorageHelper(configuration: FileStorageConfiguration(baseURL: testBaseURL)),
|
|
defaults: UserDefaultsHelper(defaults: UserDefaults(suiteName: "MigrationTests-\(UUID().uuidString)")!)
|
|
)
|
|
}
|
|
|
|
@Test func automaticMigrationFromUserDefaultsToKeychain() async throws {
|
|
let legacyName = "legacy.user.name"
|
|
let modernName = "user.name"
|
|
let suiteName = "MigrationTests.\(UUID().uuidString)"
|
|
let secretValue = "Matt Bruce"
|
|
|
|
defer {
|
|
UserDefaults().removePersistentDomain(forName: suiteName)
|
|
}
|
|
|
|
// 1. Setup legacy data manually in UserDefaults
|
|
let legacyKey = LegacyKey(name: legacyName, domain: .userDefaults(suite: suiteName))
|
|
try await router.set(secretValue, for: legacyKey)
|
|
|
|
// Verify it exists in legacy location
|
|
let existsInLegacy = try await router.exists(legacyKey)
|
|
#expect(existsInLegacy == true)
|
|
|
|
// 2. Setup modern key with legacy source
|
|
let modernKey = ModernKey(
|
|
name: modernName,
|
|
domain: .keychain(service: "test.migration"),
|
|
migrationSources: [.key(legacyKey)]
|
|
)
|
|
|
|
// 3. Trigger automatic migration via GET
|
|
let migratedValue = try await router.get(modernKey)
|
|
#expect(migratedValue == secretValue)
|
|
|
|
// 4. Verify data moved
|
|
// Modern should now exist
|
|
let existsInModern = try await router.exists(modernKey)
|
|
#expect(existsInModern == true)
|
|
|
|
// Legacy should be gone
|
|
let existsInLegacyAfter = try await router.exists(legacyKey)
|
|
#expect(existsInLegacyAfter == false)
|
|
}
|
|
|
|
@Test func manualMigrationSweep() async throws {
|
|
let legacyName = "legacy.manual.key"
|
|
let modernName = "modern.manual.key"
|
|
let suiteName = "MigrationTests.Manual.\(UUID().uuidString)"
|
|
let value = "Manual Data"
|
|
|
|
defer {
|
|
UserDefaults().removePersistentDomain(forName: suiteName)
|
|
}
|
|
|
|
// 1. Setup legacy data
|
|
let legacyKey = LegacyKey(name: legacyName, domain: .userDefaults(suite: suiteName))
|
|
try await router.set(value, for: legacyKey)
|
|
|
|
// 2. Setup modern key
|
|
let modernKey = ModernKey(
|
|
name: modernName,
|
|
domain: .userDefaults(suite: suiteName),
|
|
migrationSources: [.key(legacyKey)]
|
|
)
|
|
|
|
// 3. Trigger manual migration
|
|
try await router.migrate(for: modernKey)
|
|
|
|
// 4. Verify
|
|
let hasModern = try await router.exists(modernKey)
|
|
#expect(hasModern == true)
|
|
|
|
let hasLegacy = try await router.exists(legacyKey)
|
|
#expect(hasLegacy == false)
|
|
}
|
|
}
|