// // 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... } }