#!/usr/bin/env python3 """ Test d'intégration : export + import des cues Mixxx via les modules mixxx_export et mixxx_import. Nécessite que mixxx_export.py et mixxx_import_gui.py (ou mixxx_import.py) soient dans le même répertoire, ou ajustez les imports. """ import sqlite3 import tempfile import os import json from pathlib import Path import subprocess import sys # ------------------------------------------------------------ # 1. Créer une base Mixxx temporaire avec les bonnes tables # ------------------------------------------------------------ def create_temp_db(db_path: Path): con = sqlite3.connect(db_path) con.executescript(""" CREATE TABLE track_locations ( id INTEGER PRIMARY KEY, location TEXT, filename TEXT, directory TEXT, filesize INTEGER, fs_deleted INTEGER DEFAULT 0, needs_verification INTEGER DEFAULT 0 ); CREATE TABLE library ( id INTEGER PRIMARY KEY, artist TEXT, title TEXT, album TEXT, genre TEXT, tracknumber INTEGER, year INTEGER, duration REAL, samplerate INTEGER, bitrate INTEGER, channels INTEGER, bpm REAL, key TEXT, rating INTEGER, comment TEXT, location INTEGER REFERENCES track_locations(id) -- clé manquante dans l'exemple précédent ); CREATE TABLE cues ( id INTEGER PRIMARY KEY, track_id INTEGER, type INTEGER, position REAL, length REAL, hotcue INTEGER, label TEXT, color INTEGER ); CREATE TABLE IF NOT EXISTS Playlists ( id INTEGER PRIMARY KEY, name TEXT, position INTEGER, hidden INTEGER DEFAULT 0, date_created TEXT, date_modified TEXT ); CREATE TABLE IF NOT EXISTS PlaylistTracks ( id INTEGER PRIMARY KEY, playlist_id INTEGER, track_id INTEGER, position INTEGER, pl_datetime_added TEXT ); """) con.commit() return con # ------------------------------------------------------------ # 2. Insérer des données de test # ------------------------------------------------------------ def populate_test_data(con, audio_file_path: Path): # Une piste "test.flac" tl_id = 1 con.execute(""" INSERT INTO track_locations (id, location, filename, directory, filesize) VALUES (?, ?, ?, ?, ?) """, (tl_id, str(audio_file_path), audio_file_path.name, str(audio_file_path.parent), 12345)) con.execute(""" INSERT INTO library (id, artist, title, album, genre, year, duration, location) VALUES (?, 'Test', 'Ma Chanson', '', '', 2025, 200, ?) """, (tl_id, tl_id)) # location pointe vers track_locations.id # Deux hot cues con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,1,10.5,0,1,'Intro',16744448)", (tl_id,)) con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,1,45.0,0,2,'Drop',0xFF8000)", (tl_id,)) # Une boucle (type=4) con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,4,60.0,15.0,-1,'',0)", (tl_id,)) con.commit() # ------------------------------------------------------------ # 3. Fonctions de test # ------------------------------------------------------------ def run_export(db_path: Path, output_dir: Path): # Utiliser le module mixxx_export directement import mixxx_export mixxx_export.export_cues(db_path, output_dir) def run_import(music_dir: Path, db_path: Path, dry_run=False): # Utiliser le module mixxx_import (v2) import mixxx_import mixxx_import.import_cues_v2(music_dir, db_path, dry_run=dry_run, log_callback=print) def main(): with tempfile.TemporaryDirectory() as tmpdir: tmp = Path(tmpdir) db_path = tmp / "test_mixxxdb.sqlite" audio_dir = tmp / "music" audio_dir.mkdir() audio_file = audio_dir / "test.flac" audio_file.write_text("fake audio") # fichier factice # 1. Créer DB et peupler con = create_temp_db(db_path) populate_test_data(con, audio_file) con.close() # 2. Exporter les cues dans un sous-dossier export_dir = tmp / "export" export_dir.mkdir() run_export(db_path, export_dir) expected_json = export_dir / "test.flac.mixxx" assert expected_json.exists(), "Le fichier .mixxx n'a pas été créé" with open(expected_json, "r") as f: data = json.load(f) assert data["version"] == 1 assert data["filename"] == "test.flac" assert len(data["cues"]) == 3 print("[PASS] Export OK") # 3. Préparer l'import : copier le .mixxx dans le dossier audio import_audio_dir = tmp / "import" import_audio_dir.mkdir() import_audio_file = import_audio_dir / "test.flac" import_audio_file.write_text("fake audio") # recréer le fichier audio import_json = import_audio_dir / "test.flac.mixxx" import_json.write_text(expected_json.read_text()) # Créer une nouvelle DB vierge pour l'import (même structure) fresh_db = tmp / "fresh_mixxxdb.sqlite" create_temp_db(fresh_db).close() # 4. Importer run_import(import_audio_dir, fresh_db, dry_run=False) # 5. Vérifier que les cues ont été insérés con = sqlite3.connect(fresh_db) con.row_factory = sqlite3.Row # Vérifier la piste tl = con.execute("SELECT * FROM track_locations WHERE filename='test.flac'").fetchone() assert tl is not None, "Piste non importée" track_id = tl["id"] # Vérifier les cues cues = con.execute("SELECT * FROM cues WHERE track_id=?", (track_id,)).fetchall() assert len(cues) == 3, f"Nombre de cues incorrect : {len(cues)} au lieu de 3" # Vérifier les types types = {c["type"] for c in cues} assert types == {1, 4}, f"Types de cues inattendus: {types}" print("[PASS] Import OK") # 6. Test dry-run # Créer une autre DB vide pour simuler dry_db = tmp / "dry_db.sqlite" create_temp_db(dry_db).close() run_import(import_audio_dir, dry_db, dry_run=True) con = sqlite3.connect(dry_db) cues_dry = con.execute("SELECT count(*) FROM cues").fetchone()[0] assert cues_dry == 0, "Le dry-run a écrit des données !" print("[PASS] Dry-run OK") print("\n✅ Tous les tests ont réussi !") if __name__ == "__main__": main()