LocalData/Tests/LocalDataTests/MigrationAdditionalTests.swift
Matt Bruce b1bf6020f3 fixed tests
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
2026-01-17 09:18:04 -06:00

170 lines
5.9 KiB
Swift

import Foundation
import Testing
@testable import LocalData
private func makeLegacyStringKey(name: String, domain: StorageDomain) -> StorageKey<String> {
StorageKey(
name: name,
domain: domain,
security: .none,
owner: "Legacy",
description: "Legacy string key"
)
}
private func makeModernStringKey(
name: String,
domain: StorageDomain,
legacyKey: AnyStorageKey?
) -> StorageKey<String> {
StorageKey(
name: name,
domain: domain,
security: .none,
owner: "Modern",
description: "Modern string key",
migration: { destinationKey in
guard let legacyKey else { return nil }
return AnyStorageMigration(
SimpleLegacyMigration(destinationKey: destinationKey, sourceKey: legacyKey)
)
}
)
}
private func makePhoneOnlyKey(name: String, domain: StorageDomain) -> StorageKey<String> {
StorageKey(
name: name,
domain: domain,
security: .none,
owner: "PhoneOnly",
description: "Phone-only key",
availability: .phoneOnly
)
}
private func makeSourceStringKey(name: String, domain: StorageDomain) -> StorageKey<String> {
StorageKey(
name: name,
domain: domain,
security: .none,
owner: "Source",
description: "Source key"
)
}
private func makeDestinationIntKey(name: String, domain: StorageDomain) -> StorageKey<Int> {
StorageKey(
name: name,
domain: domain,
security: .none,
owner: "Destination",
description: "Destination int key"
)
}
@Suite(.serialized)
struct MigrationAdditionalTests {
private let router: StorageRouter
init() {
let testBaseURL = FileManager.default.temporaryDirectory.appending(path: "MigrationAdditionalTests-\(UUID().uuidString)")
router = StorageRouter(
keychain: MockKeychainHelper(),
encryption: EncryptionHelper(keychain: MockKeychainHelper()),
file: FileStorageHelper(configuration: FileStorageConfiguration(baseURL: testBaseURL)),
defaults: UserDefaultsHelper(defaults: UserDefaults(suiteName: "MigrationAdditionalTests.\(UUID().uuidString)")!)
)
}
@Test func migrationHistoryTrackingTest() async throws {
let legacyKey = makeLegacyStringKey(name: "legacy.history", domain: .userDefaults(suite: nil))
let modernKey = makeModernStringKey(
name: "modern.history",
domain: .userDefaults(suite: nil),
legacyKey: .key(legacyKey)
)
try await router.set("history", for: legacyKey)
_ = try await router.forceMigration(for: modernKey)
let history = await router.migrationHistory(for: modernKey)
#expect(history != nil)
}
@Test func migrationFailureKeepsSourceTest() async throws {
let sourceKey = makeSourceStringKey(name: "legacy.rollback", domain: .userDefaults(suite: nil))
let destinationKey = makeDestinationIntKey(name: "modern.rollback", domain: .userDefaults(suite: nil))
try await router.set("not-a-number", for: sourceKey)
let migration = DefaultTransformingMigration(
destinationKey: destinationKey,
sourceKey: sourceKey
) { _ in
throw MigrationError.transformationFailed("Invalid integer")
}
let result = try await migration.migrate(using: router, context: MigrationContext())
#expect(result.success == false)
#expect(try await router.exists(sourceKey) == true)
#expect(try await router.exists(destinationKey) == false)
}
@Test func watchAvailabilityBlocksMigrationTest() async throws {
let legacyKey = makeLegacyStringKey(name: "legacy.watch", domain: .userDefaults(suite: nil))
let destinationKey = makePhoneOnlyKey(name: "modern.watch", domain: .userDefaults(suite: nil))
let migration = SimpleLegacyMigration(destinationKey: destinationKey, sourceKey: .key(legacyKey))
let deviceInfo = DeviceInfo(
platform: .watchOS,
systemVersion: "10.0",
model: "Watch",
isSimulator: true
)
let context = MigrationContext(deviceInfo: deviceInfo)
let shouldMigrate = try await migration.shouldMigrate(using: router, context: context)
#expect(shouldMigrate == false)
}
@Test func largeDataMigrationTest() async throws {
let legacyKey = makeLegacyStringKey(name: "legacy.large", domain: .userDefaults(suite: nil))
let modernKey = makeModernStringKey(
name: "modern.large",
domain: .userDefaults(suite: nil),
legacyKey: .key(legacyKey)
)
let largeValue = String(repeating: "a", count: 1_200_000)
try await router.set(largeValue, for: legacyKey)
let migration = SimpleLegacyMigration(destinationKey: modernKey, sourceKey: .key(legacyKey))
let result = try await migration.migrate(using: router, context: MigrationContext())
#expect(result.success == true)
let migratedValue = try await router.get(modernKey)
#expect(migratedValue == largeValue)
}
@Test func typeErasureMigrationTest() async throws {
let legacyKey = makeLegacyStringKey(name: "legacy.erased", domain: .userDefaults(suite: nil))
let modernKey = makeModernStringKey(
name: "modern.erased",
domain: .userDefaults(suite: nil),
legacyKey: .key(legacyKey)
)
try await router.set("erased", for: legacyKey)
let migration = AnyStorageMigration(
SimpleLegacyMigration(destinationKey: modernKey, sourceKey: .key(legacyKey))
)
let shouldMigrate = try await migration.shouldMigrate(using: router, context: MigrationContext())
#expect(shouldMigrate == true)
let result = try await migration.migrate(using: router, context: MigrationContext())
#expect(result.success == true)
}
}