Add integration tests
This commit is contained in:
parent
ab6b970063
commit
45643cc594
@ -230,9 +230,7 @@ class GenericMetadata:
|
||||
assign("scan_info", new_md.scan_info)
|
||||
|
||||
assign("tags", new_md.tags)
|
||||
print("before", self.pages, new_md.pages)
|
||||
assign("pages", new_md.pages)
|
||||
print("after", self.pages, new_md.pages)
|
||||
assign("page_count", new_md.page_count)
|
||||
|
||||
assign("characters", new_md.characters)
|
||||
|
@ -172,7 +172,7 @@ class CLI:
|
||||
else:
|
||||
notes = (
|
||||
f"Tagged with ComicTagger {ctversion.version} using info from {self.current_talker().name} on"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
)
|
||||
md.overlay(ct_md.replace(notes=utils.combine_notes(md.notes, notes, "Tagged with ComicTagger")))
|
||||
|
||||
@ -584,7 +584,7 @@ class CLI:
|
||||
|
||||
notes = (
|
||||
f"Tagged with ComicTagger {ctversion.version} using info from {self.current_talker().name} on"
|
||||
+ f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
+ f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
)
|
||||
md.overlay(
|
||||
ct_md.replace(
|
||||
|
@ -36,8 +36,8 @@ def archiver(manager: settngs.Manager) -> None:
|
||||
)
|
||||
|
||||
|
||||
def register_talker_settings(manager: settngs.Manager) -> None:
|
||||
for talker in comictaggerlib.ctsettings.talkers.values():
|
||||
def register_talker_settings(manager: settngs.Manager, talkers: dict[str, ComicTalker]) -> None:
|
||||
for talker in talkers.values():
|
||||
|
||||
def api_options(manager: settngs.Manager) -> None:
|
||||
# The default needs to be unset or None.
|
||||
@ -76,10 +76,10 @@ def validate_archive_settings(config: settngs.Config[ct_ns]) -> settngs.Config[c
|
||||
return config
|
||||
|
||||
|
||||
def validate_talker_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
def validate_talker_settings(config: settngs.Config[ct_ns], talkers: dict[str, ComicTalker]) -> settngs.Config[ct_ns]:
|
||||
# Apply talker settings from config file
|
||||
cfg = settngs.normalize_config(config, True, True)
|
||||
for talker in list(comictaggerlib.ctsettings.talkers.values()):
|
||||
for talker in list(talkers.values()):
|
||||
try:
|
||||
cfg[0][group_for_plugin(talker)] = talker.parse_settings(cfg[0][group_for_plugin(talker)])
|
||||
except Exception as e:
|
||||
@ -90,12 +90,12 @@ def validate_talker_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct
|
||||
return cast(settngs.Config[ct_ns], settngs.get_namespace(cfg, file=True, cmdline=True))
|
||||
|
||||
|
||||
def validate_plugin_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
def validate_plugin_settings(config: settngs.Config[ct_ns], talkers: dict[str, ComicTalker]) -> settngs.Config[ct_ns]:
|
||||
config = validate_archive_settings(config)
|
||||
config = validate_talker_settings(config)
|
||||
config = validate_talker_settings(config, talkers)
|
||||
return config
|
||||
|
||||
|
||||
def register_plugin_settings(manager: settngs.Manager) -> None:
|
||||
def register_plugin_settings(manager: settngs.Manager, talkers: dict[str, ComicTalker]) -> None:
|
||||
manager.add_persistent_group("Archive", archiver, False)
|
||||
register_talker_settings(manager)
|
||||
register_talker_settings(manager, talkers)
|
||||
|
@ -102,7 +102,7 @@ class IssueIdentifier:
|
||||
self.publisher_filter = [s.strip().casefold() for s in config.Issue_Identifier__publisher_filter]
|
||||
|
||||
self.additional_metadata = GenericMetadata()
|
||||
self.output_function: Callable[[str], None] = lambda x: print(x)
|
||||
self.output_function: Callable[[str], None] = print
|
||||
self.progress_callback: Callable[[int, int], None] | None = None
|
||||
self.cover_url_callback: Callable[[bytes], None] | None = None
|
||||
self.search_result = self.result_no_matches
|
||||
@ -271,7 +271,7 @@ class IssueIdentifier:
|
||||
self.output(msg)
|
||||
|
||||
def output(self, *args: Any, file: Any = None, **kwargs: Any) -> None:
|
||||
# We intercept the file argument otherwise everything is passed to self.output_function
|
||||
# We intercept and discard the file argument otherwise everything is passed to self.output_function
|
||||
|
||||
# Ensure args[0] is defined and is a string for logger.info
|
||||
if not args:
|
||||
@ -289,6 +289,7 @@ class IssueIdentifier:
|
||||
if self.config.Runtime_Options__verbose > 0 or self.config.Runtime_Options__quiet:
|
||||
return
|
||||
|
||||
# default output is stdout
|
||||
self.output_function(*args, **kwargs)
|
||||
|
||||
def get_issue_cover_match_score(
|
||||
@ -347,7 +348,6 @@ class IssueIdentifier:
|
||||
if self.cancel:
|
||||
raise IssueIdentifierCancelled
|
||||
|
||||
if use_remote_alternates:
|
||||
self.log_msg(f"[{len(remote_cover_list) - 1} alt. covers]")
|
||||
|
||||
score_list = []
|
||||
|
@ -36,6 +36,7 @@ from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ctversion import version
|
||||
from comictaggerlib.log import setup_logging
|
||||
from comictaggerlib.resulttypes import Action
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
import importlib_metadata
|
||||
@ -107,6 +108,7 @@ class App:
|
||||
self.config: settngs.Config[ct_ns]
|
||||
self.initial_arg_parser = ctsettings.initial_commandline_parser()
|
||||
self.config_load_success = False
|
||||
self.talkers: dict[str, ComicTalker]
|
||||
|
||||
def run(self) -> None:
|
||||
configure_locale()
|
||||
@ -120,7 +122,7 @@ class App:
|
||||
|
||||
def load_plugins(self, opts: argparse.Namespace) -> None:
|
||||
comicapi.comicarchive.load_archive_plugins()
|
||||
ctsettings.talkers = comictalker.get_talkers(version, opts.config.user_cache_dir)
|
||||
self.talkers = comictalker.get_talkers(version, opts.config.user_cache_dir)
|
||||
|
||||
def list_plugins(
|
||||
self, talkers: list[comictalker.ComicTalker], archivers: list[type[comicapi.comicarchive.Archiver]]
|
||||
@ -189,7 +191,7 @@ class App:
|
||||
)
|
||||
ctsettings.register_commandline_settings(self.manager)
|
||||
ctsettings.register_file_settings(self.manager)
|
||||
ctsettings.register_plugin_settings(self.manager)
|
||||
ctsettings.register_plugin_settings(self.manager, getattr(self, "talkers", {}))
|
||||
|
||||
def parse_settings(self, config_paths: ctsettings.ComicTaggerPaths, *args: str) -> settngs.Config[ct_ns]:
|
||||
cfg, self.config_load_success = ctsettings.parse_config(
|
||||
@ -200,7 +202,7 @@ class App:
|
||||
|
||||
config = ctsettings.validate_commandline_settings(config, self.manager)
|
||||
config = ctsettings.validate_file_settings(config)
|
||||
config = ctsettings.validate_plugin_settings(config)
|
||||
config = ctsettings.validate_plugin_settings(config, getattr(self, "talkers", {}))
|
||||
return config
|
||||
|
||||
def initialize_dirs(self, paths: ctsettings.ComicTaggerPaths) -> None:
|
||||
@ -220,10 +222,7 @@ class App:
|
||||
# config already loaded
|
||||
error = None
|
||||
|
||||
talkers = ctsettings.talkers
|
||||
del ctsettings.talkers
|
||||
|
||||
if len(talkers) < 1:
|
||||
if len(self.talkers) < 1:
|
||||
error = error = (
|
||||
"Failed to load any talkers, please re-install and check the log located in '"
|
||||
+ str(self.config[0].Runtime_Options__config.user_log_dir)
|
||||
@ -241,7 +240,7 @@ class App:
|
||||
update_publishers(self.config)
|
||||
|
||||
if self.config[0].Commands__command == Action.list_plugins:
|
||||
self.list_plugins(list(talkers.values()), comicapi.comicarchive.archivers)
|
||||
self.list_plugins(list(self.talkers.values()), comicapi.comicarchive.archivers)
|
||||
return
|
||||
|
||||
if self.config[0].Commands__command == Action.save_config:
|
||||
@ -266,7 +265,7 @@ class App:
|
||||
|
||||
if not gui.qt_available:
|
||||
raise gui.import_error
|
||||
return gui.open_tagger_window(talkers, self.config, error)
|
||||
return gui.open_tagger_window(self.talkers, self.config, error)
|
||||
except ImportError:
|
||||
self.config[0].Runtime_Options__no_gui = True
|
||||
logger.warning("PyQt5 is not available. ComicTagger is limited to command-line mode.")
|
||||
@ -277,7 +276,7 @@ class App:
|
||||
raise SystemExit(1)
|
||||
|
||||
try:
|
||||
cli.CLI(self.config[0], talkers).run()
|
||||
cli.CLI(self.config[0], self.talkers).run()
|
||||
except Exception:
|
||||
logger.exception("CLI mode failed")
|
||||
|
||||
|
@ -265,9 +265,11 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
|
||||
def log_id_output(self, text: str) -> None:
|
||||
if self.iddialog is not None:
|
||||
print(text, end=" ") # noqa: T201
|
||||
self.iddialog.textEdit.append(text.rstrip())
|
||||
self.iddialog.textEdit.ensureCursorVisible()
|
||||
self.iddialog.textEdit.insertPlainText(text)
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
QtCore.QCoreApplication.processEvents()
|
||||
|
||||
def identify_progress(self, cur: int, total: int) -> None:
|
||||
if self.iddialog is not None:
|
||||
|
@ -542,9 +542,7 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
QtWidgets.QDialog.accept(self)
|
||||
|
||||
def update_talkers_config(self) -> None:
|
||||
ctsettings.talkers = self.talkers
|
||||
self.config = ctsettings.plugin.validate_talker_settings(self.config)
|
||||
del ctsettings.talkers
|
||||
self.config = ctsettings.plugin.validate_talker_settings(self.config, self.talkers)
|
||||
|
||||
def select_rar(self) -> None:
|
||||
self.select_file(self.leRarExePath, "RAR")
|
||||
|
@ -1089,7 +1089,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
notes = (
|
||||
f"Tagged with ComicTagger {ctversion.version} using info from {self.current_talker().name} on"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {new_metadata.issue_id}]"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {new_metadata.issue_id}]"
|
||||
)
|
||||
self.metadata.overlay(
|
||||
new_metadata.replace(
|
||||
@ -1698,7 +1698,6 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
return ct_md
|
||||
|
||||
def auto_tag_log(self, text: str) -> None:
|
||||
print(text)
|
||||
if self.atprogdialog is not None:
|
||||
self.atprogdialog.textEdit.append(text.rstrip())
|
||||
self.atprogdialog.textEdit.ensureCursorVisible()
|
||||
@ -1845,7 +1844,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
else:
|
||||
notes = (
|
||||
f"Tagged with ComicTagger {ctversion.version} using info from {self.current_talker().name} on"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
f" {datetime.now():%Y-%m-%d %H:%M:%S}. [Issue ID {ct_md.issue_id}]"
|
||||
)
|
||||
md.overlay(ct_md.replace(notes=utils.combine_notes(md.notes, notes, "Tagged with ComicTagger")))
|
||||
|
||||
|
@ -289,7 +289,7 @@ deps =
|
||||
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
extend-ignore = E203, E501, A003
|
||||
extend-ignore = E203, E501, A003, T202
|
||||
extend-exclude = venv, scripts, build, dist, comictaggerlib/ctversion.py
|
||||
per-file-ignores =
|
||||
comictaggerlib/cli.py: T20
|
||||
|
@ -1,9 +1,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
import io
|
||||
import shutil
|
||||
import unittest.mock
|
||||
from argparse import Namespace
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
|
||||
@ -15,6 +17,7 @@ from pyrate_limiter import Limiter, RequestRate
|
||||
|
||||
import comicapi.comicarchive
|
||||
import comicapi.genericmetadata
|
||||
import comictaggerlib.cli
|
||||
import comictaggerlib.ctsettings
|
||||
import comictalker
|
||||
import comictalker.comiccacher
|
||||
@ -127,10 +130,22 @@ def comicvine_api(monkeypatch, cbz, comic_cache, mock_version, config) -> comict
|
||||
return cv
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_now(monkeypatch):
|
||||
class mydatetime:
|
||||
time = datetime.datetime(2022, 4, 16, 15, 52, 26)
|
||||
|
||||
@classmethod
|
||||
def now(cls):
|
||||
return cls.time
|
||||
|
||||
monkeypatch.setattr(comictaggerlib.cli, "datetime", mydatetime)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_version(monkeypatch):
|
||||
version = "1.4.4a9.dev20"
|
||||
version_tuple = (1, 4, 4, "dev20")
|
||||
version = "1.3.2a5"
|
||||
version_tuple = (1, 3, 2)
|
||||
|
||||
monkeypatch.setattr(comictaggerlib.ctversion, "version", version)
|
||||
monkeypatch.setattr(comictaggerlib.ctversion, "__version__", version)
|
||||
@ -182,6 +197,24 @@ def config(tmp_path):
|
||||
yield defaults
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def plugin_config(tmp_path):
|
||||
from comictaggerlib.main import App
|
||||
|
||||
ns = Namespace(config=comictaggerlib.ctsettings.ComicTaggerPaths(tmp_path / "config"))
|
||||
app = App()
|
||||
app.load_plugins(ns)
|
||||
app.register_settings()
|
||||
|
||||
defaults = app.parse_settings(ns.config, "")
|
||||
defaults[0].Runtime_Options__config.user_data_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].Runtime_Options__config.user_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].Runtime_Options__config.user_cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].Runtime_Options__config.user_state_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].Runtime_Options__config.user_log_dir.mkdir(parents=True, exist_ok=True)
|
||||
yield (defaults, app.talkers)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def comic_cache(config, mock_version) -> Generator[comictalker.comiccacher.ComicCacher, Any, None]:
|
||||
yield comictalker.comiccacher.ComicCacher(config[0].Runtime_Options__config.user_cache_dir, mock_version[0])
|
||||
|
94
tests/integration_test.py
Normal file
94
tests/integration_test.py
Normal file
@ -0,0 +1,94 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import settngs
|
||||
|
||||
import comicapi.comicarchive
|
||||
import comicapi.comicinfoxml
|
||||
import comicapi.genericmetadata
|
||||
import comictaggerlib.resulttypes
|
||||
from comictaggerlib import ctsettings
|
||||
from comictaggerlib.cli import CLI
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
|
||||
def test_save(
|
||||
plugin_config: tuple[settngs.Config[ctsettings.ct_ns], dict[str, ComicTalker]],
|
||||
tmp_comic,
|
||||
comicvine_api,
|
||||
md_saved,
|
||||
mock_now,
|
||||
) -> None:
|
||||
# Overwrite the series so it has definitely changed
|
||||
tmp_comic.write_cix(md_saved.replace(series="nothing"))
|
||||
|
||||
md = tmp_comic.read_cix()
|
||||
|
||||
# Check that it changed
|
||||
assert md != md_saved
|
||||
|
||||
# Clear the cached metadata
|
||||
tmp_comic.reset_cache()
|
||||
|
||||
# Setup the app
|
||||
config = plugin_config[0]
|
||||
talkers = plugin_config[1]
|
||||
|
||||
# Save
|
||||
config[0].Commands__command = comictaggerlib.resulttypes.Action.save
|
||||
|
||||
# Check online, should be intercepted by comicvine_api
|
||||
config[0].Runtime_Options__online = True
|
||||
# Use the temporary comic we created
|
||||
config[0].Runtime_Options__files = [tmp_comic.path]
|
||||
# Save ComicRack tags
|
||||
config[0].Runtime_Options__type = [comicapi.comicarchive.MetaDataStyle.CIX]
|
||||
# Search using the correct series since we just put the wrong series name in the CBZ
|
||||
config[0].Runtime_Options__metadata = comicapi.genericmetadata.GenericMetadata(series=md_saved.series)
|
||||
# Run ComicTagger
|
||||
CLI(config[0], talkers).run()
|
||||
|
||||
# Read the CBZ
|
||||
md = tmp_comic.read_cix()
|
||||
|
||||
# Validate that we got the correct metadata back
|
||||
assert md == md_saved
|
||||
|
||||
|
||||
def test_delete(
|
||||
plugin_config: tuple[settngs.Config[ctsettings.ct_ns], dict[str, ComicTalker]],
|
||||
tmp_comic,
|
||||
comicvine_api,
|
||||
md_saved,
|
||||
mock_now,
|
||||
) -> None:
|
||||
md = tmp_comic.read_cix()
|
||||
|
||||
# Check that the metadata starts correct
|
||||
assert md == md_saved
|
||||
|
||||
# Clear the cached metadata
|
||||
tmp_comic.reset_cache()
|
||||
|
||||
# Setup the app
|
||||
config = plugin_config[0]
|
||||
talkers = plugin_config[1]
|
||||
|
||||
# Delete
|
||||
config[0].Commands__command = comictaggerlib.resulttypes.Action.delete
|
||||
|
||||
# Use the temporary comic we created
|
||||
config[0].Runtime_Options__files = [tmp_comic.path]
|
||||
# Delete ComicRack tags
|
||||
config[0].Runtime_Options__type = [comicapi.comicarchive.MetaDataStyle.CIX]
|
||||
# Run ComicTagger
|
||||
CLI(config[0], talkers).run()
|
||||
|
||||
# Read the CBZ
|
||||
md = tmp_comic.read_cix()
|
||||
|
||||
# Currently we set the default page list on load
|
||||
empty_md = comicapi.genericmetadata.GenericMetadata()
|
||||
empty_md.set_default_page_list(tmp_comic.get_number_of_pages())
|
||||
|
||||
# Validate that we got an empty metadata back
|
||||
assert md == empty_md
|
@ -69,7 +69,6 @@ def test_search(cbz, config, comicvine_api):
|
||||
url_image_hash=1747255366011518976,
|
||||
)
|
||||
for r, e in zip(results, [cv_expected]):
|
||||
# del r["url_image_hash"]
|
||||
assert r == e
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user