Leave a single source of truth for importer setup

This commit is contained in:
Šarūnas Nejus 2024-07-12 22:11:48 +01:00
parent 8065ff0461
commit f042f5ad32
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
13 changed files with 212 additions and 251 deletions

View file

@ -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,47 +526,28 @@ 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.
The directory has following layout
the_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")
os.makedirs(syspath(album_path), exist_ok=True)
resource_path = os.path.join(_common.RSRC, b"full.mp3")
album = bytestring_path("album")
album_path = os.path.join(self.import_dir, album)
os.makedirs(syspath(album_path), exist_ok=True)
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))
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",
"album": "Tag Album" + (f" {album_id}" if album_id else ""),
"albumartist": None,
"mb_albumid": None,
"comp": None,
@ -563,79 +558,55 @@ class ImportHelper:
}
)
medium.save()
self.import_media.append(medium)
return medium
def _get_import_session(self, import_dir: str) -> None:
self.importer = ImportSessionFixture(
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
album/
track_1.mp3
track_2.mp3
track_3.mp3
"""
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)
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)
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
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) -> 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,

View file

@ -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

View file

@ -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"),

View file

@ -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,

View file

@ -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"

View file

@ -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()}

View file

@ -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")

View file

@ -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):

View file

@ -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)

View file

@ -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()

View file

@ -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.setup_importer(
search_ids=[
self.MB_RELEASE_PREFIX + self.ID_RELEASE_0,
self.MB_RELEASE_PREFIX + self.ID_RELEASE_1,
]
self._setup_import_session()
)
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.setup_importer(
search_ids=[
self.MB_RECORDING_PREFIX + self.ID_RECORDING_0,
self.MB_RECORDING_PREFIX + self.ID_RECORDING_1,
]
self._setup_import_session(singletons=True)
],
singletons=True,
)
self.importer.add_choice(2) # Pick the 2nd best match (recording 1).
self.importer.add_choice(importer.action.APPLY)

View file

@ -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)

View file

@ -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(