94 lines
3.7 KiB
Swift
94 lines
3.7 KiB
Swift
|
|
//
|
||
|
|
// PersistenceControllerTest.swift
|
||
|
|
// passKitTests
|
||
|
|
//
|
||
|
|
// Created by Lysann Tranvouez on 9/3/26.
|
||
|
|
// Copyright © 2026 Bob Sun. All rights reserved.
|
||
|
|
//
|
||
|
|
|
||
|
|
import CoreData
|
||
|
|
import XCTest
|
||
|
|
|
||
|
|
@testable import passKit
|
||
|
|
|
||
|
|
final class PersistenceControllerTest: XCTestCase {
|
||
|
|
func testModelLoads() {
|
||
|
|
let controller = PersistenceController.forUnitTests()
|
||
|
|
let context = controller.viewContext()
|
||
|
|
|
||
|
|
let entityNames = context.persistentStoreCoordinator!.managedObjectModel.entities.map(\.name)
|
||
|
|
XCTAssertEqual(entityNames, ["PasswordEntity"])
|
||
|
|
}
|
||
|
|
|
||
|
|
func testInsertAndFetch() {
|
||
|
|
let controller = PersistenceController.forUnitTests()
|
||
|
|
let context = controller.viewContext()
|
||
|
|
XCTAssertEqual(PasswordEntity.fetchAll(in: context).count, 0)
|
||
|
|
|
||
|
|
PasswordEntity.insert(name: "test", path: "test.gpg", isDir: false, into: context)
|
||
|
|
try? context.save()
|
||
|
|
|
||
|
|
XCTAssertEqual(PasswordEntity.fetchAll(in: context).count, 1)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testReinitializePersistentStoreClearsData() {
|
||
|
|
let controller = PersistenceController.forUnitTests()
|
||
|
|
let context = controller.viewContext()
|
||
|
|
|
||
|
|
PasswordEntity.insert(name: "test1", path: "test1.gpg", isDir: false, into: context)
|
||
|
|
PasswordEntity.insert(name: "test2", path: "test2.gpg", isDir: false, into: context)
|
||
|
|
try? context.save()
|
||
|
|
XCTAssertEqual(PasswordEntity.fetchAll(in: context).count, 2)
|
||
|
|
|
||
|
|
controller.reinitializePersistentStore()
|
||
|
|
|
||
|
|
// After reinitialize, old data should be gone
|
||
|
|
// (reinitializePersistentStore calls initPasswordEntityCoreData with the default repo URL,
|
||
|
|
// which won't exist in tests, so the result should be an empty store)
|
||
|
|
let remaining = PasswordEntity.fetchAll(in: context)
|
||
|
|
XCTAssertEqual(remaining.count, 0)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testMultipleControllersAreIndependent() {
|
||
|
|
let controller1 = PersistenceController.forUnitTests()
|
||
|
|
let controller2 = PersistenceController.forUnitTests()
|
||
|
|
|
||
|
|
let context1 = controller1.viewContext()
|
||
|
|
let context2 = controller2.viewContext()
|
||
|
|
|
||
|
|
PasswordEntity.insert(name: "only-in-1", path: "only-in-1.gpg", isDir: false, into: context1)
|
||
|
|
try? context1.save()
|
||
|
|
|
||
|
|
XCTAssertEqual(PasswordEntity.fetchAll(in: context1).count, 1)
|
||
|
|
XCTAssertEqual(PasswordEntity.fetchAll(in: context2).count, 0)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testSaveAndLoadFromFile() throws {
|
||
|
|
let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||
|
|
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
|
||
|
|
defer { try? FileManager.default.removeItem(at: tempDir) }
|
||
|
|
let storeURL = tempDir.appendingPathComponent("test.sqlite")
|
||
|
|
|
||
|
|
// Write
|
||
|
|
let controller1 = PersistenceController(storeURL: storeURL)
|
||
|
|
let context1 = controller1.viewContext()
|
||
|
|
PasswordEntity.insert(name: "saved", path: "saved.gpg", isDir: false, into: context1)
|
||
|
|
PasswordEntity.insert(name: "dir", path: "dir", isDir: true, into: context1)
|
||
|
|
controller1.save()
|
||
|
|
|
||
|
|
// Load in a fresh controller from the same file
|
||
|
|
let controller2 = PersistenceController(storeURL: storeURL)
|
||
|
|
let context2 = controller2.viewContext()
|
||
|
|
let allEntities = PasswordEntity.fetchAll(in: context2)
|
||
|
|
|
||
|
|
XCTAssertEqual(allEntities.count, 2)
|
||
|
|
XCTAssertNotNil(allEntities.first { $0.name == "saved" && !$0.isDir })
|
||
|
|
XCTAssertNotNil(allEntities.first { $0.name == "dir" && $0.isDir })
|
||
|
|
}
|
||
|
|
|
||
|
|
func testSaveError() throws {
|
||
|
|
// NOTE: save() calls fatalError on Core Data save failures, so error propagation
|
||
|
|
// cannot be tested without refactoring save() to throw...
|
||
|
|
}
|
||
|
|
}
|