passepartout-apple/Passepartout/Library/Tests/CommonLibraryTests/MigrationManagerTests.swift

164 lines
6.0 KiB
Swift

//
// MigrationManagerTests.swift
// Passepartout
//
// Created by Davide De Rosa on 11/21/24.
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of Passepartout.
//
// Passepartout is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Passepartout is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
@testable import CommonLibrary
import CommonUtils
import Foundation
import PassepartoutKit
import XCTest
@MainActor
final class MigrationManagerTests: XCTestCase {
}
extension MigrationManagerTests {
func test_givenStrategy_whenFetchMigratable_thenReturnsMigratable() async throws {
let strategy = MockProfileMigrationStrategy()
strategy.migratableProfiles = [
.init(id: UUID(), name: "one", lastUpdate: nil),
.init(id: UUID(), name: "two", lastUpdate: nil),
.init(id: UUID(), name: "three", lastUpdate: nil)
]
let sut = MigrationManager(profileStrategy: strategy)
let migratable = try await sut.fetchMigratableProfiles()
XCTAssertEqual(migratable, strategy.migratableProfiles)
}
func test_givenStrategy_whenMigrateProfile_thenReturnsMigrated() async throws {
let uuid = UUID()
let expProfile = try {
var builder = Profile.Builder(id: uuid)
builder.name = "foobar"
builder.userInfo = ["user": "info"]
return try builder.tryBuild()
}()
let strategy = MockProfileMigrationStrategy()
strategy.migratableProfiles = [
.init(id: uuid, name: expProfile.name, lastUpdate: nil)
]
strategy.migratedProfiles = [
uuid: expProfile
]
let sut = MigrationManager(profileStrategy: strategy)
let migratable = try await sut.fetchMigratableProfiles()
XCTAssertEqual(migratable.count, 1)
let firstMigratable = try XCTUnwrap(migratable.first)
guard let migrated = try await sut.migratedProfile(withId: firstMigratable.id) else {
XCTFail("Profile not found")
return
}
XCTAssertEqual(migrated.id, uuid)
XCTAssertEqual(migrated.name, "foobar")
XCTAssertEqual(migrated.userInfo?["user"], "info")
}
func test_givenStrategy_whenMigrateProfiles_thenReturnsMigratedWithUpdates() async throws {
let profile1 = try Profile.Builder(name: "one").tryBuild()
let profile2 = try Profile.Builder(name: "two").tryBuild()
let strategy = MockProfileMigrationStrategy()
strategy.migratableProfiles = [
.init(id: profile1.id, name: profile1.name, lastUpdate: nil),
.init(id: profile2.id, name: profile2.name, lastUpdate: nil)
]
strategy.migratedProfiles = [
profile1.id: profile1
]
strategy.failedProfiles = [profile2.id]
let sut = MigrationManager(profileStrategy: strategy)
let migratable = try await sut.fetchMigratableProfiles()
var pending: Set<UUID> = [profile1.id, profile2.id]
let migrated = try await sut.migratedProfiles(migratable) { uuid, status in
if pending.contains(uuid) {
XCTAssertEqual(status, .pending)
pending.remove(uuid)
return
}
switch uuid {
case profile1.id:
XCTAssertEqual(status, .done)
case profile2.id:
XCTAssertEqual(status, .failed)
default:
XCTFail("Unexpected UUID")
}
}
XCTAssertEqual(migrated, [profile1])
}
func test_givenStrategy_whenImportProfiles_thenSavesMigratedWithUpdates() async throws {
let profile1 = try Profile.Builder(name: "one").tryBuild()
let profile2 = try Profile.Builder(name: "two").tryBuild()
let profile3 = try Profile.Builder(name: "three").tryBuild()
let strategy = MockProfileMigrationStrategy()
let sut = MigrationManager(profileStrategy: strategy)
let migrated = [profile1, profile2, profile3]
let importer = MockMigrationManagerImporter(failing: [profile1.id])
var pending = Set(migrated.map(\.id))
await sut.importProfiles(migrated, into: importer) { uuid, status in
if pending.contains(uuid) {
XCTAssertEqual(status, .pending)
pending.remove(uuid)
return
}
switch uuid {
case profile1.id:
XCTAssertEqual(status, .failed)
case profile2.id:
XCTAssertEqual(status, .done)
case profile3.id:
XCTAssertEqual(status, .done)
default:
XCTFail("Unexpected UUID")
}
}
let imported = await importer.importedProfiles()
XCTAssertEqual(imported, [profile2, profile3])
}
func test_givenStrategy_whenDeleteMigratable_thenDeletesMigratable() async throws {
let strategy = MockProfileMigrationStrategy()
let id1 = UUID()
let id2 = UUID()
let id3 = UUID()
strategy.migratableProfiles = [
.init(id: id1, name: "one", lastUpdate: nil),
.init(id: id2, name: "two", lastUpdate: nil),
.init(id: id3, name: "three", lastUpdate: nil)
]
let sut = MigrationManager(profileStrategy: strategy)
try await sut.deleteMigratableProfiles(withIds: [id1, id2])
let migratable = try await sut.fetchMigratableProfiles()
XCTAssertEqual(migratable.map(\.id), [id3])
}
}