diff --git a/beets/test/helper.py b/beets/test/helper.py index 718652686..3132026c6 100644 --- a/beets/test/helper.py +++ b/beets/test/helper.py @@ -53,6 +53,7 @@ import beets import beets.plugins from beets import autotag, config, importer, logging, util from beets.autotag.hooks import AlbumInfo, TrackInfo +from beets.importer import ImportSession from beets.library import Album, Item, Library from beets.test import _common from beets.ui.commands import TerminalImportSession @@ -498,13 +499,26 @@ class PluginTestCase(PluginMixin, BeetsTestCase): pass -class ImportHelper: +class ImportHelper(TestHelper): """Provides tools to setup a library, a directory containing files that are to be imported and an import session. The class also provides stubs for the autotagging library and several assertions for the library. """ - importer: importer.ImportSession + resource_path = syspath(os.path.join(_common.RSRC, b"full.mp3")) + default_import_config = { + "autotag": True, + "copy": True, + "hardlink": False, + "link": False, + "move": False, + "resume": False, + "singletons": False, + "timid": True, + } + + lib: Library + importer: ImportSession @cached_property def import_dir(self): @@ -512,130 +526,87 @@ class ImportHelper: os.makedirs(syspath(import_dir), exist_ok=True) return import_dir - def setup_beets(self): - super().setup_beets() + def setUp(self): + super().setUp() + self.import_media = [] self.lib.path_formats = [ ("default", os.path.join("$artist", "$album", "$title")), ("singleton:true", os.path.join("singletons", "$title")), ("comp:true", os.path.join("compilations", "$album", "$title")), ] - def prepare_album_for_import(self, count=3): - """Creates a directory with media files to import. - Sets ``self.import_dir`` to the path of the directory. Also sets - ``self.import_media`` to a list :class:`MediaFile` for all the files in - the directory. + def prepare_track_for_import( + self, + track_id: int, + album_path: bytes, + album_id: int | None = None, + ) -> MediaFile: + filename = bytestring_path(f"track_{track_id}.mp3") + medium_path = os.path.join(album_path, filename) + shutil.copy(self.resource_path, syspath(medium_path)) + medium = MediaFile(medium_path) + medium.update( + { + "album": "Tag Album" + (f" {album_id}" if album_id else ""), + "albumartist": None, + "mb_albumid": None, + "comp": None, + "artist": "Tag Artist", + "title": f"Tag Track {track_id}", + "track": track_id, + "mb_trackid": None, + } + ) + medium.save() + return medium + + def prepare_album_for_import( + self, item_count: int, album_id: int | None = None + ) -> None: + """Create an album directory with media files to import. The directory has following layout - the_album/ + album/ track_1.mp3 track_2.mp3 track_3.mp3 - - :param count: Number of files to create """ - album_path = os.path.join(self.import_dir, b"the_album") + album_path = os.path.join( + self.import_dir, + bytestring_path(f"album_{album_id}" if album_id else "album"), + ) os.makedirs(syspath(album_path), exist_ok=True) - resource_path = os.path.join(_common.RSRC, b"full.mp3") + mediums = [ + self.prepare_track_for_import(tid, album_path, album_id=album_id) + for tid in range(1, item_count + 1) + ] + self.import_media.extend(mediums) - album = bytestring_path("album") - album_path = os.path.join(self.import_dir, album) - os.makedirs(syspath(album_path), exist_ok=True) + def prepare_albums_for_import(self, count: int = 1) -> None: + album_dirs = Path(os.fsdecode(self.import_dir)).glob("album_*") + base_idx = int(str(max(album_dirs, default="0")).split("_")[-1]) + 1 - self.import_media = [] - for track_id in range(1, count + 1): - medium_path = os.path.join( - album_path, bytestring_path(f"track_{track_id}.mp3") - ) - shutil.copy(syspath(resource_path), syspath(medium_path)) - medium = MediaFile(medium_path) - medium.update( - { - "album": "Tag Album", - "albumartist": None, - "mb_albumid": None, - "comp": None, - "artist": "Tag Artist", - "title": f"Tag Track {track_id}", - "track": track_id, - "mb_trackid": None, - } - ) - medium.save() - self.import_media.append(medium) + for album_id in range(base_idx, count + base_idx): + self.prepare_album_for_import(1, album_id=album_id) - def _get_import_session(self, import_dir: str) -> None: - self.importer = ImportSessionFixture( + def _get_import_session(self, import_dir: str) -> ImportSession: + return ImportSessionFixture( self.lib, loghandler=None, query=None, paths=[import_dir], ) - def _setup_import_session( - self, - import_dir=None, - singletons=False, - move=False, - autotag=True, - ): - config["import"]["copy"] = True - config["import"]["delete"] = False - config["import"]["timid"] = True - config["threaded"] = False - config["import"]["singletons"] = singletons - config["import"]["move"] = move - config["import"]["autotag"] = autotag - config["import"]["resume"] = False - config["import"]["link"] = False - config["import"]["hardlink"] = False + def setup_importer( + self, import_dir: str | None = None, **kwargs + ) -> ImportSession: + config["import"].set_args({**self.default_import_config, **kwargs}) + self.importer = self._get_import_session(import_dir or self.import_dir) + return self.importer - self._get_import_session(import_dir or self.import_dir) - - def create_importer(self, item_count=1, album_count=1): - """Create files to import and return corresponding session. - - Copies the specified number of files to a subdirectory of - `self.temp_dir` and creates a `ImportSessionFixture` for this path. - """ - resource_path = os.path.join(_common.RSRC, b"full.mp3") - - album_dirs = Path(os.fsdecode(self.import_dir)).glob("album_*") - base_idx = int(str(max(album_dirs, default="0")).split("_")[-1]) + 1 - - for album_id in range(base_idx, album_count + base_idx): - album = bytestring_path(f"album_{album_id}") - album_path = os.path.join(self.import_dir, album) - os.makedirs(syspath(album_path), exist_ok=True) - - for track_id in range(1, item_count + 1): - medium_path = os.path.join( - album_path, bytestring_path(f"track_{track_id}.mp3") - ) - shutil.copy(syspath(resource_path), syspath(medium_path)) - medium = MediaFile(medium_path) - medium.update( - { - "album": f"Tag Album {album_id}", - "albumartist": None, - "mb_albumid": None, - "comp": None, - "artist": "Tag Artist", - "title": f"Tag Track {track_id}", - "track": track_id, - "mb_trackid": None, - } - ) - medium.save() - - config["import"]["quiet"] = True - config["import"]["autotag"] = False - config["import"]["resume"] = False - - return ImportSessionFixture( - self.lib, loghandler=None, query=None, paths=[self.import_dir] - ) + def setup_singleton_importer(self, **kwargs) -> ImportSession: + return self.setup_importer(singletons=True, **kwargs) def assert_file_in_lib(self, *segments): """Join the ``segments`` and assert that this path exists in the @@ -657,7 +628,7 @@ class ImportTestCase(ImportHelper, BeetsTestCase): pass -class ImportSessionFixture(importer.ImportSession): +class ImportSessionFixture(ImportSession): """ImportSession that can be controlled programaticaly. >>> lib = Library(':memory:') @@ -771,9 +742,11 @@ class TerminalImportSessionFixture(TerminalImportSession): class TerminalImportMixin(ImportHelper): """Provides_a terminal importer for the import session.""" - def _get_import_session(self, import_dir: str) -> None: + io: _common.DummyIO + + def _get_import_session(self, import_dir: str) -> importer.ImportSession: self.io.install() - self.importer = TerminalImportSessionFixture( + return TerminalImportSessionFixture( self.lib, loghandler=None, query=None, diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 9076bea30..64a20722d 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -434,7 +434,7 @@ def displayable_path( return path.decode("utf-8", "ignore") -def syspath(path: Bytes_or_String, prefix: bool = True) -> Bytes_or_String: +def syspath(path: Bytes_or_String, prefix: bool = True) -> str: """Convert a path for use by the operating system. In particular, paths on Windows must receive a magic prefix and must be converted to Unicode before they are sent to the OS. To disable the magic diff --git a/test/plugins/test_convert.py b/test/plugins/test_convert.py index 67b513bb9..eca953c43 100644 --- a/test/plugins/test_convert.py +++ b/test/plugins/test_convert.py @@ -98,7 +98,8 @@ class ConvertTestCase(ConvertMixin, PluginTestCase): class ImportConvertTest(ImportHelper, ConvertTestCase): def setUp(self): super().setUp() - self.importer = self.create_importer() + self.prepare_album_for_import(1) + self.importer = self.setup_importer(autotag=False) self.config["convert"] = { "dest": os.path.join(self.temp_dir, b"convert"), diff --git a/test/plugins/test_edit.py b/test/plugins/test_edit.py index fc1798445..ba068e90d 100644 --- a/test/plugins/test_edit.py +++ b/test/plugins/test_edit.py @@ -13,7 +13,6 @@ # included in all copies or substantial portions of the Software. import codecs -from typing import ClassVar from unittest.mock import patch from beets.dbcore.query import TrueQuery @@ -329,17 +328,14 @@ class EditDuringImporterTestCase( """TODO""" IGNORED = ["added", "album_id", "id", "mtime", "path"] - singletons: ClassVar[bool] def setUp(self): super().setUp() # Create some mediafiles, and store them for comparison. - self.prepare_album_for_import() - self._setup_import_session(singletons=self.singletons) + self.prepare_album_for_import(1) self.items_orig = [Item.from_path(f.path) for f in self.import_media] self.matcher = AutotagStub().install() self.matcher.matching = AutotagStub.GOOD - self.config["import"]["timid"] = True def tearDown(self): EditPlugin.listeners = None @@ -349,7 +345,9 @@ class EditDuringImporterTestCase( @_common.slow_test() class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase): - singletons = False + def setUp(self): + super().setUp() + self.importer = self.setup_importer() def test_edit_apply_asis(self): """Edit the album field for all items in the library, apply changes, @@ -497,7 +495,9 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase): @_common.slow_test() class EditDuringImporterSingletonTest(EditDuringImporterTestCase): - singletons = True + def setUp(self): + super().setUp() + self.importer = self.setup_singleton_importer() def test_edit_apply_asis_singleton(self): """Edit the album field for all items in the library, apply changes, diff --git a/test/plugins/test_filefilter.py b/test/plugins/test_filefilter.py index 79aedb53e..abf2b4c62 100644 --- a/test/plugins/test_filefilter.py +++ b/test/plugins/test_filefilter.py @@ -18,7 +18,6 @@ import os import shutil -from typing import ClassVar from mediafile import MediaFile @@ -30,17 +29,9 @@ from beetsplug.filefilter import FileFilterPlugin class FileFilterPluginMixin(ImportTestCase): - singletons: ClassVar[bool] - def setUp(self): super().setUp() self.__create_import_dir(2) - self._setup_import_session() - config["import"]["pretend"] = True - - import_files = [self.import_dir] - self._setup_import_session(singletons=self.singletons) - self.importer.paths = import_files def tearDown(self): self.unload_plugins() @@ -112,7 +103,9 @@ class FileFilterPluginMixin(ImportTestCase): class FileFilterPluginNonSingletonTest(FileFilterPluginMixin): - singletons = False + def setUp(self): + super().setUp() + self.importer = self.setup_importer(pretend=True) def test_import_default(self): """The default configuration should import everything.""" @@ -189,7 +182,9 @@ class FileFilterPluginNonSingletonTest(FileFilterPluginMixin): class FileFilterPluginSingletonTest(FileFilterPluginMixin): - singletons = True + def setUp(self): + super().setUp() + self.importer = self.setup_singleton_importer(pretend=True) def test_import_global(self): config["filefilter"]["path"] = ".*track_1.*\\.mp3" diff --git a/test/plugins/test_importadded.py b/test/plugins/test_importadded.py index fe8f0466b..b055e16cc 100644 --- a/test/plugins/test_importadded.py +++ b/test/plugins/test_importadded.py @@ -56,7 +56,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase): ) self.matcher = AutotagStub().install() self.matcher.macthin = AutotagStub.GOOD - self._setup_import_session() + self.importer = self.setup_importer() self.importer.add_choice(importer.action.APPLY) def tearDown(self): @@ -113,7 +113,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase): # Newer Item path mtimes as if Beets had modified them modify_mtimes(items_added_before.keys(), offset=10000) # Reimport - self._setup_import_session(import_dir=album.path) + self.setup_importer(import_dir=self.libdir) self.importer.run() # Verify the reimported items album = self.lib.albums().get() @@ -154,8 +154,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase): # Newer Item path mtimes as if Beets had modified them modify_mtimes(items_added_before.keys(), offset=10000) # Reimport - import_dir = os.path.dirname(list(items_added_before.keys())[0]) - self._setup_import_session(import_dir=import_dir, singletons=True) + self.setup_importer(import_dir=self.libdir, singletons=True) self.importer.run() # Verify the reimported items items_added_after = {item.path: item.added for item in self.lib.items()} diff --git a/test/plugins/test_keyfinder.py b/test/plugins/test_keyfinder.py index d941df3ca..0517c7011 100644 --- a/test/plugins/test_keyfinder.py +++ b/test/plugins/test_keyfinder.py @@ -39,8 +39,8 @@ class KeyFinderTest(PluginMixin, ImportTestCase): def test_add_key_on_import(self, command_output): command_output.return_value = util.CommandOutput(b"dbm", b"") - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() item = self.lib.items().get() self.assertEqual(item["initial_key"], "C#m") diff --git a/test/plugins/test_mbsubmit.py b/test/plugins/test_mbsubmit.py index f2151736b..01ef522c6 100644 --- a/test/plugins/test_mbsubmit.py +++ b/test/plugins/test_mbsubmit.py @@ -29,7 +29,7 @@ class MBSubmitPluginTest(PluginMixin, TerminalImportMixin, ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(2) - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() def tearDown(self): diff --git a/test/plugins/test_permissions.py b/test/plugins/test_permissions.py index c54bb9b83..b28ee46d5 100644 --- a/test/plugins/test_permissions.py +++ b/test/plugins/test_permissions.py @@ -22,6 +22,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): super().setUp() self.config["permissions"] = {"file": "777", "dir": "777"} + self.prepare_album_for_import(1) def test_permissions_on_album_imported(self): self.do_thing(True) @@ -44,10 +45,10 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): & 0o777 ) - self.importer = self.create_importer() + self.importer = self.setup_importer(autotag=False) typs = ["file", "dir"] - track_file = (b"album_1", b"track_1.mp3") + track_file = (b"album", b"track_1.mp3") self.exp_perms = { True: { k: convert_perm(self.config["permissions"][k].get()) @@ -93,8 +94,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): def do_set_art(self, expect_success): if platform.system() == "Windows": self.skipTest("permissions not available on Windows") - self.importer = self.create_importer() - self.importer.run() + self.setup_importer(autotag=False).run() album = self.lib.albums().get() artpath = os.path.join(self.temp_dir, b"cover.jpg") touch(artpath) diff --git a/test/plugins/test_replaygain.py b/test/plugins/test_replaygain.py index 342902a63..d0532caed 100644 --- a/test/plugins/test_replaygain.py +++ b/test/plugins/test_replaygain.py @@ -68,7 +68,8 @@ class ReplayGainTestCase(ImportTestCase): except Exception: self.tearDown() - self.importer = self.create_importer() + self.prepare_album_for_import(1) + self.importer = self.setup_importer(autotag=False) def tearDown(self): self.unload_plugins() diff --git a/test/test_importer.py b/test/test_importer.py index bf2ef2b11..d0100688b 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -51,8 +51,8 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase): def setUp(self): super().setUp() - self.prepare_album_for_import(2) - self._setup_import_session(autotag=False) + self.prepare_album_for_import(1) + self.setup_importer(autotag=False) def test_tags_not_scrubbed(self): config["plugins"] = ["scrub"] @@ -103,8 +103,8 @@ class NonAutotaggedImportTest(ImportTestCase): def setUp(self): super().setUp() - self.prepare_album_for_import(2) - self._setup_import_session(autotag=False) + self.prepare_album_for_import(1) + self.setup_importer(autotag=False) def test_album_created_with_track_artist(self): self.importer.run() @@ -285,7 +285,7 @@ class RmTempTest(ImportTestCase): archive_task = importer.ArchiveImportTask(zip_path) archive_task.extract() tmp_path = archive_task.toppath - self._setup_import_session(autotag=False, import_dir=tmp_path) + self.setup_importer(autotag=False, import_dir=tmp_path) self.assertExists(tmp_path) archive_task.finalize(self) self.assertNotExists(tmp_path) @@ -297,7 +297,7 @@ class ImportZipTest(ImportTestCase): self.assertEqual(len(self.lib.items()), 0) self.assertEqual(len(self.lib.albums()), 0) - self._setup_import_session(autotag=False, import_dir=zip_path) + self.setup_importer(autotag=False, import_dir=zip_path) self.importer.run() self.assertEqual(len(self.lib.items()), 1) self.assertEqual(len(self.lib.albums()), 1) @@ -341,8 +341,7 @@ class ImportSingletonTest(ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(1) - self._setup_import_session() - config["import"]["singletons"] = True + self.setup_importer(singletons=True) self.matcher = AutotagStub().install() def tearDown(self): @@ -410,7 +409,7 @@ class ImportSingletonTest(ImportTestCase): os.path.join(self.import_dir, b"album"), single_path, ] - self._setup_import_session(singletons=False) + self.setup_importer() self.importer.paths = import_files self.importer.add_choice(importer.action.ASIS) @@ -462,7 +461,7 @@ class ImportTest(ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(1) - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() self.matcher.macthin = AutotagStub.GOOD @@ -581,7 +580,7 @@ class ImportTest(ImportTestCase): def test_empty_directory_warning(self): import_dir = os.path.join(self.temp_dir, b"empty") self.touch(b"non-audio", dir=import_dir) - self._setup_import_session(import_dir=import_dir) + self.setup_importer(import_dir=import_dir) with capture_log() as logs: self.importer.run() @@ -591,7 +590,7 @@ class ImportTest(ImportTestCase): def test_empty_directory_singleton_warning(self): import_dir = os.path.join(self.temp_dir, b"empty") self.touch(b"non-audio", dir=import_dir) - self._setup_import_session(import_dir=import_dir, singletons=True) + self.setup_importer(import_dir=import_dir, singletons=True) with capture_log() as logs: self.importer.run() @@ -672,7 +671,7 @@ class ImportTracksTest(ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(1) - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() def tearDown(self): @@ -706,7 +705,7 @@ class ImportCompilationTest(ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(3) - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() def tearDown(self): @@ -827,55 +826,52 @@ class ImportExistingTest(ImportTestCase): self.prepare_album_for_import(1) self.matcher = AutotagStub().install() - self._setup_import_session() - self.setup_importer = self.importer - self.setup_importer.default_choice = importer.action.APPLY - - self._setup_import_session(import_dir=self.libdir) + self.reimporter = self.setup_importer(import_dir=self.libdir) + self.importer = self.setup_importer() def tearDown(self): super().tearDown() self.matcher.restore() def test_does_not_duplicate_item(self): - self.setup_importer.run() + self.importer.run() self.assertEqual(len(self.lib.items()), 1) - self.importer.add_choice(importer.action.APPLY) - self.importer.run() + self.reimporter.add_choice(importer.action.APPLY) + self.reimporter.run() self.assertEqual(len(self.lib.items()), 1) def test_does_not_duplicate_album(self): - self.setup_importer.run() - self.assertEqual(len(self.lib.albums()), 1) - - self.importer.add_choice(importer.action.APPLY) self.importer.run() self.assertEqual(len(self.lib.albums()), 1) - def test_does_not_duplicate_singleton_track(self): - self.setup_importer.add_choice(importer.action.TRACKS) - self.setup_importer.add_choice(importer.action.APPLY) - self.setup_importer.run() - self.assertEqual(len(self.lib.items()), 1) + self.reimporter.add_choice(importer.action.APPLY) + self.reimporter.run() + self.assertEqual(len(self.lib.albums()), 1) + def test_does_not_duplicate_singleton_track(self): self.importer.add_choice(importer.action.TRACKS) self.importer.add_choice(importer.action.APPLY) self.importer.run() self.assertEqual(len(self.lib.items()), 1) + self.reimporter.add_choice(importer.action.TRACKS) + self.reimporter.add_choice(importer.action.APPLY) + self.reimporter.run() + self.assertEqual(len(self.lib.items()), 1) + def test_asis_updates_metadata(self): - self.setup_importer.run() + self.importer.run() medium = MediaFile(self.lib.items().get().path) medium.title = "New Title" medium.save() - self.importer.add_choice(importer.action.ASIS) - self.importer.run() + self.reimporter.add_choice(importer.action.ASIS) + self.reimporter.run() self.assertEqual(self.lib.items().get().title, "New Title") def test_asis_updated_moves_file(self): - self.setup_importer.run() + self.importer.run() medium = MediaFile(self.lib.items().get().path) medium.title = "New Title" medium.save() @@ -885,15 +881,15 @@ class ImportExistingTest(ImportTestCase): ) self.assert_file_in_lib(old_path) - self.importer.add_choice(importer.action.ASIS) - self.importer.run() + self.reimporter.add_choice(importer.action.ASIS) + self.reimporter.run() self.assert_file_in_lib( b"Applied Artist", b"Applied Album", b"New Title.mp3" ) self.assert_file_not_in_lib(old_path) def test_asis_updated_without_copy_does_not_move_file(self): - self.setup_importer.run() + self.importer.run() medium = MediaFile(self.lib.items().get().path) medium.title = "New Title" medium.save() @@ -904,8 +900,8 @@ class ImportExistingTest(ImportTestCase): self.assert_file_in_lib(old_path) config["import"]["copy"] = False - self.importer.add_choice(importer.action.ASIS) - self.importer.run() + self.reimporter.add_choice(importer.action.ASIS) + self.reimporter.run() self.assert_file_not_in_lib( b"Applied Artist", b"Applied Album", b"New Title.mp3" ) @@ -913,15 +909,14 @@ class ImportExistingTest(ImportTestCase): def test_outside_file_is_copied(self): config["import"]["copy"] = False - self.setup_importer.run() + self.importer.run() self.assert_equal_path( self.lib.items().get().path, self.import_media[0].path ) - config["import"]["copy"] = True - self._setup_import_session() - self.importer.add_choice(importer.action.APPLY) - self.importer.run() + self.reimporter = self.setup_importer() + self.reimporter.add_choice(importer.action.APPLY) + self.reimporter.run() new_path = os.path.join( b"Applied Artist", b"Applied Album", b"Applied Track 1.mp3" ) @@ -933,14 +928,14 @@ class ImportExistingTest(ImportTestCase): def test_outside_file_is_moved(self): config["import"]["copy"] = False - self.setup_importer.run() + self.importer.run() self.assert_equal_path( self.lib.items().get().path, self.import_media[0].path ) - self._setup_import_session(move=True) - self.importer.add_choice(importer.action.APPLY) - self.importer.run() + self.reimporter = self.setup_importer(move=True) + self.reimporter.add_choice(importer.action.APPLY) + self.reimporter.run() self.assertNotExists(self.import_media[0].path) @@ -950,7 +945,7 @@ class GroupAlbumsImportTest(ImportTestCase): self.prepare_album_for_import(3) self.matcher = AutotagStub().install() self.matcher.matching = AutotagStub.NONE - self._setup_import_session() + self.setup_importer() # Split tracks into two albums and use both as-is self.importer.add_choice(importer.action.ALBUMS) @@ -1020,7 +1015,7 @@ class ChooseCandidateTest(ImportTestCase): def setUp(self): super().setUp() self.prepare_album_for_import(1) - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() self.matcher.matching = AutotagStub.BAD @@ -1163,9 +1158,10 @@ class ImportDuplicateAlbumTest(ImportTestCase): self.add_album_fixture(albumartist="artist", album="album") # Create import session - self.importer = self.create_importer() - config["import"]["autotag"] = True - config["import"]["duplicate_keys"]["album"] = "albumartist album" + self.prepare_album_for_import(1) + self.importer = self.setup_importer( + duplicate_keys={"album": "albumartist album"} + ) def test_remove_duplicate_album(self): item = self.lib.items().get() @@ -1190,7 +1186,7 @@ class ImportDuplicateAlbumTest(ImportTestCase): # Imported item has the same artist and album as the one in the # library. import_file = os.path.join( - self.importer.paths[0], b"album_1", b"track_1.mp3" + self.importer.paths[0], b"album", b"track_1.mp3" ) import_file = MediaFile(import_file) import_file.artist = item["artist"] @@ -1238,7 +1234,7 @@ class ImportDuplicateAlbumTest(ImportTestCase): item = self.lib.items().get() import_file = MediaFile( - os.path.join(self.importer.paths[0], b"album_1", b"track_1.mp3") + os.path.join(self.importer.paths[0], b"album", b"track_1.mp3") ) import_file.artist = item["artist"] import_file.albumartist = item["artist"] @@ -1284,10 +1280,10 @@ class ImportDuplicateSingletonTest(ImportTestCase): ) # Import session - self.importer = self.create_importer() - config["import"]["autotag"] = True - config["import"]["singletons"] = True - config["import"]["duplicate_keys"]["item"] = "artist title" + self.prepare_album_for_import(1) + self.importer = self.setup_importer( + duplicate_keys={"album": "artist title"}, singletons=True + ) def test_remove_duplicate(self): item = self.lib.items().get() @@ -1363,8 +1359,8 @@ class TagLogTest(BeetsTestCase): class ResumeImportTest(ImportTestCase): @patch("beets.plugins.send") def test_resume_album(self, plugins_send): - self.importer = self.create_importer(album_count=2) - self.config["import"]["resume"] = True + self.prepare_albums_for_import(2) + self.importer = self.setup_importer(autotag=False, resume=True) # Aborts import after one album. This also ensures that we skip # the first album in the second try. @@ -1384,9 +1380,10 @@ class ResumeImportTest(ImportTestCase): @patch("beets.plugins.send") def test_resume_singleton(self, plugins_send): - self.importer = self.create_importer(item_count=2) - self.config["import"]["resume"] = True - self.config["import"]["singletons"] = True + self.prepare_album_for_import(2) + self.importer = self.setup_importer( + autotag=False, resume=True, singletons=True + ) # Aborts import after one track. This also ensures that we skip # the first album in the second try. @@ -1408,10 +1405,10 @@ class ResumeImportTest(ImportTestCase): class IncrementalImportTest(ImportTestCase): def setUp(self): super().setUp() - self.config["import"]["incremental"] = True + self.prepare_album_for_import(1) def test_incremental_album(self): - importer = self.create_importer(album_count=1) + importer = self.setup_importer(autotag=False, incremental=True) importer.run() # Change album name so the original file would be imported again @@ -1420,13 +1417,13 @@ class IncrementalImportTest(ImportTestCase): album["album"] = "edited album" album.store() - importer = self.create_importer(album_count=1) importer.run() self.assertEqual(len(self.lib.albums()), 2) def test_incremental_item(self): - self.config["import"]["singletons"] = True - importer = self.create_importer(item_count=1) + importer = self.setup_importer( + autotag=False, incremental=True, singletons=True + ) importer.run() # Change track name so the original file would be imported again @@ -1435,12 +1432,11 @@ class IncrementalImportTest(ImportTestCase): item["artist"] = "edited artist" item.store() - importer = self.create_importer(item_count=1) importer.run() self.assertEqual(len(self.lib.items()), 2) def test_invalid_state_file(self): - importer = self.create_importer() + importer = self.setup_importer(autotag=False, incremental=True) with open(self.config["statefile"].as_filename(), "wb") as f: f.write(b"000") importer.run() @@ -1648,7 +1644,7 @@ class ReimportTest(ImportTestCase): self.matcher.restore() def _setup_session(self, singletons=False): - self._setup_import_session(self._album().path, singletons=singletons) + self.setup_importer(import_dir=self.libdir, singletons=singletons) self.importer.add_choice(importer.action.APPLY) def _album(self): @@ -1732,8 +1728,7 @@ class ImportPretendTest(ImportTestCase): super().setUp() self.__create_import_dir() self.__create_empty_import_dir() - self._setup_import_session() - config["import"]["pretend"] = True + self.setup_importer(pretend=True) self.matcher = AutotagStub().install() self.io.install() @@ -1763,7 +1758,7 @@ class ImportPretendTest(ImportTestCase): self.empty_path = path def __run(self, import_paths, singletons=True): - self._setup_import_session(singletons=singletons) + self.setup_importer(singletons=singletons) self.importer.paths = import_paths with capture_log() as logs: @@ -1929,21 +1924,21 @@ class ImportMusicBrainzIdTest(ImportTestCase): self.prepare_album_for_import(1) def test_one_mbid_one_album(self): - self.config["import"]["search_ids"] = [ - self.MB_RELEASE_PREFIX + self.ID_RELEASE_0 - ] - self._setup_import_session() + self.setup_importer( + search_ids=[self.MB_RELEASE_PREFIX + self.ID_RELEASE_0] + ) self.importer.add_choice(importer.action.APPLY) self.importer.run() self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_0") def test_several_mbid_one_album(self): - self.config["import"]["search_ids"] = [ - self.MB_RELEASE_PREFIX + self.ID_RELEASE_0, - self.MB_RELEASE_PREFIX + self.ID_RELEASE_1, - ] - self._setup_import_session() + self.setup_importer( + search_ids=[ + self.MB_RELEASE_PREFIX + self.ID_RELEASE_0, + self.MB_RELEASE_PREFIX + self.ID_RELEASE_1, + ] + ) self.importer.add_choice(2) # Pick the 2nd best match (release 1). self.importer.add_choice(importer.action.APPLY) @@ -1951,21 +1946,23 @@ class ImportMusicBrainzIdTest(ImportTestCase): self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_1") def test_one_mbid_one_singleton(self): - self.config["import"]["search_ids"] = [ - self.MB_RECORDING_PREFIX + self.ID_RECORDING_0 - ] - self._setup_import_session(singletons=True) + self.setup_importer( + search_ids=[self.MB_RECORDING_PREFIX + self.ID_RECORDING_0], + singletons=True, + ) self.importer.add_choice(importer.action.APPLY) self.importer.run() self.assertEqual(self.lib.items().get().title, "VALID_RECORDING_0") def test_several_mbid_one_singleton(self): - self.config["import"]["search_ids"] = [ - self.MB_RECORDING_PREFIX + self.ID_RECORDING_0, - self.MB_RECORDING_PREFIX + self.ID_RECORDING_1, - ] - self._setup_import_session(singletons=True) + self.setup_importer( + search_ids=[ + self.MB_RECORDING_PREFIX + self.ID_RECORDING_0, + self.MB_RECORDING_PREFIX + self.ID_RECORDING_1, + ], + singletons=True, + ) self.importer.add_choice(2) # Pick the 2nd best match (recording 1). self.importer.add_choice(importer.action.APPLY) diff --git a/test/test_logging.py b/test/test_logging.py index 2919e6030..29579fdb2 100644 --- a/test/test_logging.py +++ b/test/test_logging.py @@ -135,8 +135,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level0(self): self.config["verbose"] = 0 with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() self.assertIn("dummy: warning import_stage", logs) self.assertNotIn("dummy: info import_stage", logs) self.assertNotIn("dummy: debug import_stage", logs) @@ -144,8 +144,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level1(self): self.config["verbose"] = 1 with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() self.assertIn("dummy: warning import_stage", logs) self.assertIn("dummy: info import_stage", logs) self.assertNotIn("dummy: debug import_stage", logs) @@ -153,8 +153,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level2(self): self.config["verbose"] = 2 with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() self.assertIn("dummy: warning import_stage", logs) self.assertIn("dummy: info import_stage", logs) self.assertIn("dummy: debug import_stage", logs) @@ -264,20 +264,20 @@ class ConcurrentEventsTest(ImportTestCase): blog.getLogger("beets").set_global_level(blog.WARNING) with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() self.assertEqual(logs, []) blog.getLogger("beets").set_global_level(blog.INFO) with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() for l in logs: self.assertIn("import", l) self.assertIn("album", l) blog.getLogger("beets").set_global_level(blog.DEBUG) with helper.capture_log() as logs: - importer = self.create_importer() - importer.run() + self.prepare_album_for_import(1) + self.setup_importer(autotag=False).run() self.assertIn("Sending event: database_change", logs) diff --git a/test/test_plugins.py b/test/test_plugins.py index 4415bebbc..709727d0a 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -160,12 +160,9 @@ class ItemTypeConflictTest(PluginLoaderTestCase): class EventsTest(PluginImportTestCase): def setUp(self): super().setUp() - config["import"]["pretend"] = True def test_import_task_created(self): - import_files = [self.import_dir] - self._setup_import_session(singletons=False) - self.importer.paths = import_files + self.importer = self.setup_importer(pretend=True) with helper.capture_log() as logs: self.importer.run() @@ -212,9 +209,7 @@ class EventsTest(PluginImportTestCase): to_singleton_plugin = ToSingletonPlugin self.register_plugin(to_singleton_plugin) - import_files = [self.import_dir] - self._setup_import_session(singletons=False) - self.importer.paths = import_files + self.importer = self.setup_importer(pretend=True) with helper.capture_log() as logs: self.importer.run() @@ -371,7 +366,7 @@ class ListenersTest(PluginLoaderTestCase): class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): def setUp(self): super().setUp() - self._setup_import_session() + self.setup_importer() self.matcher = AutotagStub().install() # keep track of ui.input_option() calls self.input_options_patcher = patch(