File importer - more tests

This commit is contained in:
Keith Edmunds 2025-02-01 22:11:01 +00:00
parent 8177e03387
commit 5cae8e4b19
3 changed files with 24 additions and 24 deletions

View File

@ -124,5 +124,5 @@ class Config(object):
# These rely on earlier definitions # These rely on earlier definitions
HIDE_PLAYED_MODE = HIDE_PLAYED_MODE_SECTIONS 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) REPLACE_FILES_DEFAULT_DESTINATION = os.path.dirname(REPLACE_FILES_DEFAULT_SOURCE)

View File

@ -367,6 +367,8 @@ class FileImporter:
Set up to replace an existing file. Set up to replace an existing file.
""" """
log.debug(f"replace_file({tfd=}, {track_id=})")
if track_id < 1: if track_id < 1:
raise ApplicationError(f"No track ID: replace_file({tfd=}, {track_id=})") 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 # 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 # destination path doesn't already exists
if tfd.track_id == 0 and tfd.destination_path != tfd.file_path_to_remove: if tfd.track_id == 0 and tfd.destination_path != tfd.file_path_to_remove:
while os.path.exists(tfd.destination_path): while os.path.exists(tfd.destination_path):
msg = ( msg = (
@ -497,7 +500,7 @@ class FileImporter:
try: try:
tfd = self.import_files_data.pop() tfd = self.import_files_data.pop()
filename = os.path.basename(tfd.source_path) filename = os.path.basename(tfd.source_path)
log.debug(f"_import_next_file: {filename}") log.debug(f"Processing {filename}")
log.debug( log.debug(
f"remaining files: {[a.source_path for a in self.import_files_data]}" f"remaining files: {[a.source_path for a in self.import_files_data]}"
) )
@ -520,6 +523,7 @@ class FileImporter:
tags=tfd.tags, tags=tfd.tags,
destination_path=tfd.destination_path, destination_path=tfd.destination_path,
track_id=tfd.track_id, track_id=tfd.track_id,
file_path_to_remove=tfd.file_path_to_remove
) )
log.debug(f"{self.workers[tfd.source_path]=} created") log.debug(f"{self.workers[tfd.source_path]=} created")
@ -539,7 +543,7 @@ class FileImporter:
if tfd.source_path in self.workers: if tfd.source_path in self.workers:
del self.workers[tfd.source_path] del self.workers[tfd.source_path]
else: 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()=}") log.debug(f"After cleanup_thread: {self.workers.keys()=}")
@ -573,6 +577,7 @@ class DoTrackImport(QThread):
tags: Tags, tags: Tags,
destination_path: str, destination_path: str,
track_id: int, track_id: int,
file_path_to_remove: Optional[str] = None
) -> None: ) -> None:
""" """
Save parameters Save parameters
@ -583,6 +588,7 @@ class DoTrackImport(QThread):
self.tags = tags self.tags = tags
self.destination_track_path = destination_path self.destination_track_path = destination_path
self.track_id = track_id self.track_id = track_id
self.file_path_to_remove = file_path_to_remove
self.signals = MusicMusterSignals() self.signals = MusicMusterSignals()
@ -597,24 +603,19 @@ class DoTrackImport(QThread):
And add to visible playlist or update playlist if track already present. 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 # 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) self.audio_metadata = helpers.get_audio_metadata(self.import_file_path)
# If destination exists, move it out of the way # Remove old file if so requested
if os.path.exists(self.destination_track_path): if self.file_path_to_remove and os.path.exists(self.file_path_to_remove):
temp_file = self.destination_track_path + ".TMP" os.unlink(self.file_path_to_remove)
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)
self.signals.status_message_signal.emit( # Move new file to destination
f"Importing {os.path.basename(self.import_file_path)}", 5000 shutil.move(self.import_file_path, self.destination_track_path)
)
with db.Session() as session: with db.Session() as session:
if self.track_id == 0: if self.track_id == 0:

View File

@ -12,7 +12,8 @@ import unittest
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
# PyQt imports # PyQt imports
from PyQt6.QtWidgets import QDialog from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QDialog, QPushButton
# Third party imports # Third party imports
import pytest import pytest
@ -26,7 +27,7 @@ from app.models import (
Tracks, Tracks,
) )
from config import Config 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 # Custom fixture to adapt qtbot for use with unittest.TestCase
@ -224,7 +225,7 @@ class MyTestCase(unittest.TestCase):
assert os.listdir(self.import_source) == [] assert os.listdir(self.import_source) == []
def test_005_replace_file(self): 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" test_track_path = "testdata/lovecats.mp3"
shutil.copy(test_track_path, self.import_source) shutil.copy(test_track_path, self.import_source)
@ -236,7 +237,7 @@ class MyTestCase(unittest.TestCase):
# Simulate the user clicking OK in the dialog # Simulate the user clicking OK in the dialog
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted 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() self.widget.import_files_wrapper()
@ -255,9 +256,6 @@ class MyTestCase(unittest.TestCase):
# Verify exec() was called # Verify exec() was called
mock_dialog_instance.exec.assert_called_once() 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 # Allow time for import thread to run
self.qtbot.wait(3000) self.qtbot.wait(3000)
@ -268,6 +266,7 @@ class MyTestCase(unittest.TestCase):
track = tracks[1] track = tracks[1]
assert track.title == "The Lovecats" assert track.title == "The Lovecats"
assert track.artist == "The Cure" assert track.artist == "The Cure"
assert track.id == 2
track_file = os.path.join( track_file = os.path.join(
self.musicstore, os.path.basename(test_track_path) self.musicstore, os.path.basename(test_track_path)
) )