NoteProjetMigrationTest.swift 75 lignes · 2913 octets
import XCTest
import SQLite3
@testable import Card2vcf

/// Verifies additive migration v4 → v5 :
/// - la table `notes_projet` est cr\u{e9}\u{e9}e
/// - les donn\u{e9}es existantes (table `projets`) sont pr\u{e9}serv\u{e9}es.
final class NoteProjetMigrationTest: XCTestCase {

    private var dbPath: String!

    override func setUp() {
        super.setUp()
        dbPath = FileManager.default.temporaryDirectory
            .appendingPathComponent("migration_v4v5_\(UUID().uuidString).sqlite")
            .path
    }

    override func tearDown() {
        try? FileManager.default.removeItem(atPath: dbPath)
        super.tearDown()
    }

    func testMigrationV4ToV5PreservesDataAndAddsNotesTable() async throws {
        // --- 1. Cr\u{e9}er une base v4 avec donn\u{e9}es ---
        var rawHandle: OpaquePointer?
        guard sqlite3_open(dbPath, &rawHandle) == SQLITE_OK, let rawHandle else {
            XCTFail("Cannot open test database at \(dbPath!)")
            return
        }

        let v4SQL = """
            CREATE TABLE projets (
                localId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                serverId TEXT,
                nom TEXT NOT NULL,
                description TEXT NOT NULL,
                workflowServerId TEXT NOT NULL,
                membresJson TEXT NOT NULL,
                creePar TEXT NOT NULL,
                createdAt INTEGER NOT NULL,
                updatedAt INTEGER NOT NULL
            );
            INSERT INTO projets
                (serverId, nom, description, workflowServerId, membresJson, creePar, createdAt, updatedAt)
            VALUES
                ('srv-p1', 'Salon', '', 'wf-1', '[]', 'alice', 1000, 1000);
            PRAGMA user_version = 4;
            """
        var errMsg: UnsafeMutablePointer<CChar>? = nil
        let rc = sqlite3_exec(rawHandle, v4SQL, nil, nil, &errMsg)
        if rc != SQLITE_OK {
            let msg = errMsg.map { String(cString: $0) } ?? "unknown"
            sqlite3_free(errMsg)
            sqlite3_close_v2(rawHandle)
            XCTFail("v4 setup failed: \(msg)")
            return
        }
        sqlite3_close_v2(rawHandle)

        // --- 2. Ouvrir avec SqliteDatabase (d\u{e9}clenche la migration v4 → v5) ---
        let db = SqliteDatabase(filePath: dbPath)
        let noteDao = SqliteNoteProjetDao(db: db)
        let projetDao = SqliteProjetDao(db: db)

        // --- 3. La table notes_projet existe et est vide ---
        let notes = try await noteDao.listAll()
        XCTAssertTrue(notes.isEmpty, "notes_projet doit exister et \u{ea}tre vide apr\u{e8}s migration")

        // --- 4. Les donn\u{e9}es v4 sont pr\u{e9}serv\u{e9}es ---
        let projets = try await projetDao.listAll()
        XCTAssertEqual(1, projets.count, "Le projet Salon doit \u{ea}tre pr\u{e9}serv\u{e9} apr\u{e8}s migration")
        XCTAssertEqual("Salon", projets.first?.nom)
    }
}