From 5cae8e4b19c18cf4b2382a0db4668f61bdbaa7ff Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Sat, 1 Feb 2025 22:11:01 +0000 Subject: [PATCH] File importer - more tests --- app/config.py | 2 +- app/file_importer.py | 33 +++++++++++++++++---------------- tests/test_file_importer.py | 13 ++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/config.py b/app/config.py index ff946d2..7344c01 100644 --- a/app/config.py +++ b/app/config.py @@ -124,5 +124,5 @@ class Config(object): # These rely on earlier definitions HIDE_PLAYED_MODE = HIDE_PLAYED_MODE_SECTIONS - IMPORT_DESTINATION = "/tmp/mm" # os.path.join(ROOT, "Singles") + IMPORT_DESTINATION = os.path.join(ROOT, "Singles") REPLACE_FILES_DEFAULT_DESTINATION = os.path.dirname(REPLACE_FILES_DEFAULT_SOURCE) diff --git a/app/file_importer.py b/app/file_importer.py index b88cbdb..bca3d4e 100644 --- a/app/file_importer.py +++ b/app/file_importer.py @@ -367,6 +367,8 @@ class FileImporter: Set up to replace an existing file. """ + log.debug(f"replace_file({tfd=}, {track_id=})") + if track_id < 1: raise ApplicationError(f"No track ID: replace_file({tfd=}, {track_id=})") @@ -435,8 +437,9 @@ class FileImporter: ) # If destination path is the same as file_path_to_remove, that's - # OK, otherwise if this is a new import then check check + # OK, otherwise if this is a new import then check that # destination path doesn't already exists + if tfd.track_id == 0 and tfd.destination_path != tfd.file_path_to_remove: while os.path.exists(tfd.destination_path): msg = ( @@ -497,7 +500,7 @@ class FileImporter: try: tfd = self.import_files_data.pop() filename = os.path.basename(tfd.source_path) - log.debug(f"_import_next_file: {filename}") + log.debug(f"Processing {filename}") log.debug( f"remaining files: {[a.source_path for a in self.import_files_data]}" ) @@ -520,6 +523,7 @@ class FileImporter: tags=tfd.tags, destination_path=tfd.destination_path, track_id=tfd.track_id, + file_path_to_remove=tfd.file_path_to_remove ) log.debug(f"{self.workers[tfd.source_path]=} created") @@ -539,7 +543,7 @@ class FileImporter: if tfd.source_path in self.workers: del self.workers[tfd.source_path] else: - log.debug(f"Couldn't find entry in self.workers: {tfd.source_path=}") + log.error(f"Couldn't find {tfd.source_path=} in {self.workers.keys()=}") log.debug(f"After cleanup_thread: {self.workers.keys()=}") @@ -573,6 +577,7 @@ class DoTrackImport(QThread): tags: Tags, destination_path: str, track_id: int, + file_path_to_remove: Optional[str] = None ) -> None: """ Save parameters @@ -583,6 +588,7 @@ class DoTrackImport(QThread): self.tags = tags self.destination_track_path = destination_path self.track_id = track_id + self.file_path_to_remove = file_path_to_remove self.signals = MusicMusterSignals() @@ -597,24 +603,19 @@ class DoTrackImport(QThread): And add to visible playlist or update playlist if track already present. """ - temp_file: Optional[str] = None + self.signals.status_message_signal.emit( + f"Importing {os.path.basename(self.import_file_path)}", 5000 + ) # Get audio metadata in this thread rather than calling function to save interactive time self.audio_metadata = helpers.get_audio_metadata(self.import_file_path) - # If destination exists, move it out of the way - if os.path.exists(self.destination_track_path): - temp_file = self.destination_track_path + ".TMP" - shutil.move(self.destination_track_path, temp_file) - # Move file to destination - shutil.move(self.import_file_path, self.destination_track_path) - # Clean up - if temp_file and os.path.exists(temp_file): - os.unlink(temp_file) + # Remove old file if so requested + if self.file_path_to_remove and os.path.exists(self.file_path_to_remove): + os.unlink(self.file_path_to_remove) - self.signals.status_message_signal.emit( - f"Importing {os.path.basename(self.import_file_path)}", 5000 - ) + # Move new file to destination + shutil.move(self.import_file_path, self.destination_track_path) with db.Session() as session: if self.track_id == 0: diff --git a/tests/test_file_importer.py b/tests/test_file_importer.py index 2d06a5a..0e2076d 100644 --- a/tests/test_file_importer.py +++ b/tests/test_file_importer.py @@ -12,7 +12,8 @@ import unittest from unittest.mock import MagicMock, patch # PyQt imports -from PyQt6.QtWidgets import QDialog +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import QApplication, QDialog, QPushButton # Third party imports import pytest @@ -26,7 +27,7 @@ from app.models import ( Tracks, ) from config import Config -from file_importer import FileImporter +from file_importer import FileImporter, PickMatch # Custom fixture to adapt qtbot for use with unittest.TestCase @@ -224,7 +225,7 @@ class MyTestCase(unittest.TestCase): assert os.listdir(self.import_source) == [] def test_005_replace_file(self): - """Import the same file again""" + """Import the same file again and update existing track""" test_track_path = "testdata/lovecats.mp3" shutil.copy(test_track_path, self.import_source) @@ -236,7 +237,7 @@ class MyTestCase(unittest.TestCase): # Simulate the user clicking OK in the dialog mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted - mock_dialog_instance.selected_track_id = 1 # Simulated return value + mock_dialog_instance.selected_track_id = 2 # Simulated return value self.widget.import_files_wrapper() @@ -255,9 +256,6 @@ class MyTestCase(unittest.TestCase): # Verify exec() was called mock_dialog_instance.exec.assert_called_once() - # Ensure selected_track_id was accessed after dialog.exec() - assert mock_dialog_instance.selected_track_id == 1 - # Allow time for import thread to run self.qtbot.wait(3000) @@ -268,6 +266,7 @@ class MyTestCase(unittest.TestCase): track = tracks[1] assert track.title == "The Lovecats" assert track.artist == "The Cure" + assert track.id == 2 track_file = os.path.join( self.musicstore, os.path.basename(test_track_path) )