Add more tests

This commit is contained in:
Timmy Welch 2022-07-13 19:56:34 -07:00
parent 9ba8b2876c
commit a00891f622
10 changed files with 177 additions and 56 deletions

View File

@ -399,7 +399,7 @@ class ComicVineTalker:
"filter": flt,
}
cv_response = self.get_cv_content(self.api_base_url + "/issues", params)
cv_response = self.get_cv_content(self.api_base_url + "/issues/", params)
current_result_count = cv_response["number_of_page_results"]
total_result_count = cv_response["number_of_total_results"]
@ -429,7 +429,7 @@ class ComicVineTalker:
f_record = None
for record in issues_list_results:
if IssueString(issue_number).as_string() is None:
if not IssueString(issue_number).as_string():
issue_number = "1"
if (
IssueString(record["issue_number"]).as_string().casefold()

View File

@ -90,17 +90,9 @@ class MetadataFormatter(string.Formatter):
field_name = field_name.casefold()
# this is some markup, find the object and do the formatting
# handle arg indexing when empty field_names are given.
if field_name == "":
if auto_arg_index is False:
raise ValueError("cannot switch from manual field specification to automatic field numbering")
field_name = str(auto_arg_index)
auto_arg_index += 1
elif field_name.isdigit():
if auto_arg_index:
raise ValueError("cannot switch from manual field specification to automatic field numbering")
# disable auto arg incrementing, if it gets used later on, then an exception will be raised
auto_arg_index = False
# handle arg indexing when digit field_names are given.
if field_name.isdigit():
raise ValueError("cannot use a number as a field name")
# given the field_name, find the object it references
# and the argument it came from
@ -111,8 +103,8 @@ class MetadataFormatter(string.Formatter):
obj = self.convert_field(obj, conversion) # type: ignore
# expand the format spec, if needed
format_spec, auto_arg_index = self._vformat(
cast(str, format_spec), args, kwargs, used_args, recursion_depth - 1, auto_arg_index=auto_arg_index
format_spec, _ = self._vformat(
cast(str, format_spec), args, kwargs, used_args, recursion_depth - 1, auto_arg_index=False
)
# format the object and append to the result
@ -128,7 +120,7 @@ class MetadataFormatter(string.Formatter):
fmt_obj = str(sanitize_filename(fmt_obj, platform=self.platform))
result.append(fmt_obj)
return "".join(result), auto_arg_index
return "".join(result), False
class FileRenamer:

View File

@ -19,7 +19,7 @@ import itertools
import logging
from collections import deque
from PyQt5 import QtCore, QtWidgets, uic
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import pyqtSignal
from comicapi import utils
@ -452,15 +452,16 @@ class VolumeSelectionWindow(QtWidgets.QDialog):
self.twList.selectRow(0)
self.twList.resizeColumnsToContents()
if not self.cv_search_results:
QtCore.QCoreApplication.processEvents()
QtWidgets.QMessageBox.information(self, "Search Result", "No matches found!")
QtCore.QTimer.singleShot(200, self.close_me)
def showEvent(self, event: QtGui.QShowEvent):
if not self.cv_search_results:
QtCore.QCoreApplication.processEvents()
QtWidgets.QMessageBox.information(self, "Search Result", "No matches found!")
QtCore.QTimer.singleShot(200, self.close_me)
if self.immediate_autoselect and self.cv_search_results:
# defer the immediate autoselect so this dialog has time to pop up
QtCore.QCoreApplication.processEvents()
QtCore.QTimer.singleShot(10, self.do_immediate_autoselect)
elif self.immediate_autoselect:
# defer the immediate autoselect so this dialog has time to pop up
QtCore.QCoreApplication.processEvents()
QtCore.QTimer.singleShot(10, self.do_immediate_autoselect)
def do_immediate_autoselect(self) -> None:
self.immediate_autoselect = False

View File

@ -5,6 +5,14 @@ from typing import Any
import comicapi.genericmetadata
import comictaggerlib.comicvinetalker
def filter_field_list(cv_result, kwargs):
if "field_list" in kwargs["params"]:
for key in list(cv_result.keys()):
if key not in kwargs["params"]["field_list"]:
del cv_result[key]
cv_issue_result: dict[str, Any] = {
"error": "OK",
"limit": 1,
@ -99,6 +107,15 @@ cv_volume_result: dict[str, Any] = {
},
"version": "1.0",
}
cv_not_found = {
"error": "Object Not Found",
"limit": 0,
"offset": 0,
"number_of_page_results": 0,
"number_of_total_results": 0,
"status_code": 101,
"results": [],
}
date = comictaggerlib.comicvinetalker.ComicVineTalker().parse_date_str(cv_issue_result["results"]["cover_date"])
cv_md = comicapi.genericmetadata.GenericMetadata(

View File

@ -11,6 +11,16 @@ format is
"""
from __future__ import annotations
import os
import os.path
import pathlib
from contextlib import nullcontext as does_not_raise
import pytest
datadir = pathlib.Path(__file__).parent / "data"
cbz_path = datadir / "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz"
fnames = [
(
"batman 3 title (DC).cbz",
@ -731,89 +741,125 @@ rnames = [
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series} #{issue} - {title} ({year})({price})", # price should be none, test no space between ')('
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series} #{issue} - {title} ({year}) ({price})", # price should be none, test double space ') ('
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series} #{issue} - {title} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series}: {title} #{issue} ({year})", # on windows the ':' is replaced
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
does_not_raise(),
),
(
"{series}: {title} #{issue} ({year})", # on linux the ':' is preserved
False,
"Linux",
"Cory Doctorow's Futuristic Tales of the Here and Now: Anda's Game #001 (2007).cbz",
does_not_raise(),
),
(
"{publisher}/ {series} #{issue} - {title} ({year})", # leading whitespace is removed when moving
True,
"universal",
"IDW Publishing/Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{publisher}/ {series} #{issue} - {title} ({year})", # leading whitespace is removed when only renaming
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
r"{publisher}\ {series} #{issue} - {title} ({year})", # backslashes separate directories
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series} # {issue} - {title} ({year})", # double spaces are reduced to one
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now # 001 - Anda's Game (2007).cbz",
does_not_raise(),
),
(
"{series} # {issue} - {locations} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now # 001 - lonely cottage (2007).cbz",
does_not_raise(),
),
(
"{series} #{issue} - {title} - {WriteR}, {EDITOR} ({year})", # fields are case in-sensitive
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game - Dara Naraghi, Ted Adams (2007).cbz",
does_not_raise(),
),
(
"{series} v{price} #{issue} ({year})", # Remove previous text if value is ""
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 (2007).cbz",
does_not_raise(),
),
(
"{series} {price} #{issue} ({year})", # Ensure that a single space remains
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 (2007).cbz",
does_not_raise(),
),
(
"{series} - {title}{price} #{issue} ({year})", # Ensure removal before None values only impacts literal text
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
does_not_raise(),
),
(
"{series} - {title} {test} #{issue} ({year})", # Test non-existent key
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game {test} #001 (2007).cbz",
does_not_raise(),
),
(
"{series} - {title} {1} #{issue} ({year})", # Test numeric key
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game {test} #001 (2007).cbz",
pytest.raises(ValueError),
),
]
rfnames = [
(None, lambda x: x.path.parent.absolute()),
("", lambda x: pathlib.Path(os.getcwd())),
("test", lambda x: (pathlib.Path(os.getcwd()) / "test")),
(pathlib.Path(os.getcwd()) / "test", lambda x: pathlib.Path(os.getcwd()) / "test"),
]

View File

@ -1,16 +1,12 @@
from __future__ import annotations
import pathlib
import shutil
import pytest
import comicapi.comicarchive
import comicapi.genericmetadata
import testing
datadir = pathlib.Path(testing.__file__).parent / "data"
cbz_path = datadir / "Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz"
from testing.filenames import cbz_path, datadir
@pytest.mark.xfail(not comicapi.comicarchive.rar_support, reason="rar support")
@ -28,25 +24,14 @@ def test_getPageNameList():
]
def test_set_default_page_list(tmp_path):
md = comicapi.genericmetadata.GenericMetadata()
md.overlay(comicapi.genericmetadata.md_test)
md.pages = []
md.set_default_page_list(len(comicapi.genericmetadata.md_test.pages))
assert isinstance(md.pages[0]["Image"], int)
def test_page_type_read():
c = comicapi.comicarchive.ComicArchive(cbz_path)
md = c.read_cix()
def test_page_type_read(cbz):
md = cbz.read_cix()
assert isinstance(md.pages[0]["Type"], str)
def test_metadata_read():
c = comicapi.comicarchive.ComicArchive(cbz_path)
md = c.read_cix()
def test_metadata_read(cbz):
md = cbz.read_cix()
assert md == comicapi.genericmetadata.md_test
@ -101,10 +86,9 @@ archivers = [
@pytest.mark.parametrize("archiver", archivers)
def test_copy_to_archive(archiver, tmp_path):
comic_path = tmp_path / cbz_path.with_suffix("").name
def test_copy_to_archive(archiver, tmp_path, cbz):
comic_path = tmp_path / cbz.path.with_suffix("").name
cbz = comicapi.comicarchive.ComicArchive(cbz_path)
archive = archiver(comic_path)
assert archive.copy_from_archive(cbz.archiver)

View File

@ -2,6 +2,7 @@ from __future__ import annotations
import pytest
import comicapi.genericmetadata
import comictaggerlib.comicvinetalker
import testing.comicvine
from testing.comicdata import select_details
@ -16,12 +17,60 @@ def test_fetch_volume_data(comicvine_api, settings, mock_now, comic_cache):
assert volume == comic_cache.get_volume_info(23437, ct.source_name)
def test_fetch_issues_by_volume(comicvine_api, settings, comic_cache):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()
issues = ct.fetch_issues_by_volume(23437)
cache_issues = comic_cache.get_volume_issues_info(23437, ct.source_name)
issues[0]["image"] = {"super_url": issues[0]["image"]["super_url"], "thumb_url": issues[0]["image"]["thumb_url"]}
del issues[0]["volume"]
assert issues == cache_issues
def test_fetch_issue_data_by_issue_id(comicvine_api, settings, mock_now, mock_version):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()
md = ct.fetch_issue_data_by_issue_id(311811, settings)
assert md == testing.comicvine.cv_md
def test_fetch_issues_by_volume_issue_num_and_year(comicvine_api):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()
cv = ct.fetch_issues_by_volume_issue_num_and_year([23437], "3", None)
cv_expected = testing.comicvine.cv_issue_result["results"].copy()
testing.comicvine.filter_field_list(
cv_expected,
{"params": {"field_list": "id,volume,issue_number,name,image,cover_date,site_detail_url,description"}},
)
assert cv[0] == cv_expected
cv_issue = [
(23437, "3", testing.comicvine.cv_md),
(23437, "", comicapi.genericmetadata.GenericMetadata()),
(23437, "0", comicapi.genericmetadata.GenericMetadata()),
]
@pytest.mark.parametrize("volume_id, issue_number, result_md", cv_issue)
def test_fetch_issue_data(comicvine_api, settings, mock_now, mock_version, volume_id, issue_number, result_md):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()
md = ct.fetch_issue_data(volume_id, issue_number, settings)
assert md == result_md
# @pytest.mark.parametrize("volume_id, issue_number, result_md", cv_issue)
def test_fetch_issue_select_details(comicvine_api, settings, mock_now, mock_version):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()
md = ct.fetch_issue_select_details(311811)
res = {
"cover_date": testing.comicvine.cv_issue_result["results"]["cover_date"],
"site_detail_url": testing.comicvine.cv_issue_result["results"]["site_detail_url"],
"image_url": testing.comicvine.cv_issue_result["results"]["image"]["super_url"],
"thumb_image_url": testing.comicvine.cv_issue_result["results"]["image"]["thumb_url"],
}
assert md == res
@pytest.mark.parametrize("details", select_details)
def test_issue_select_details(comic_cache, details):
ct = comictaggerlib.comicvinetalker.ComicVineTalker()

View File

@ -8,15 +8,21 @@ from typing import Any, Generator
import pytest
import requests
import comicapi.comicarchive
import comicapi.genericmetadata
import comictaggerlib.comiccacher
import comictaggerlib.comicvinetalker
import comictaggerlib.settings
from comicapi import utils
from testing import comicvine
from testing import comicvine, filenames
from testing.comicdata import all_seed_imprints, seed_imprints
@pytest.fixture
def cbz():
yield comicapi.comicarchive.ComicArchive(filenames.cbz_path)
@pytest.fixture(autouse=True)
def no_requests(monkeypatch) -> None:
"""Remove requests.sessions.Session.request for all tests."""
@ -35,7 +41,18 @@ def comicvine_api(monkeypatch) -> unittest.mock.Mock:
return comicvine.MockResponse(comicvine.cv_volume_result)
if args[0].startswith("https://comicvine.gamespot.com/api/issue/4000-311811"):
return comicvine.MockResponse(comicvine.cv_issue_result)
return comicvine.MockResponse({})
if (
args[0].startswith("https://comicvine.gamespot.com/api/issues/")
and "params" in kwargs
and "filter" in kwargs["params"]
and "23437" in kwargs["params"]["filter"]
):
cv_list = comicvine.cv_issue_result.copy()
cv_list["results"] = cv_list["results"].copy()
comicvine.filter_field_list(cv_list["results"], kwargs)
cv_list["results"] = [cv_list["results"]]
return comicvine.MockResponse(cv_list)
return comicvine.MockResponse(comicvine.cv_not_found)
m_get = unittest.mock.Mock(side_effect=mock_get)

View File

@ -6,6 +6,15 @@ import comicapi.genericmetadata
from testing.comicdata import credits, metadata
def test_set_default_page_list(tmp_path):
md = comicapi.genericmetadata.GenericMetadata()
md.overlay(comicapi.genericmetadata.md_test)
md.pages = []
md.set_default_page_list(len(comicapi.genericmetadata.md_test.pages))
assert isinstance(md.pages[0]["Image"], int)
@pytest.mark.parametrize("replaced, expected", metadata)
def test_metadata_overlay(md: comicapi.genericmetadata.GenericMetadata, replaced, expected):
md.overlay(replaced)

View File

@ -5,13 +5,19 @@ import pathlib
import pytest
from comicapi.genericmetadata import md_test
from comictaggerlib.filerenamer import FileRenamer
from testing.filenames import rnames
from comictaggerlib import filerenamer
from testing.filenames import rfnames, rnames
@pytest.mark.parametrize("template, move, platform, expected", rnames)
def test_rename(template, platform, move, expected):
fr = FileRenamer(md_test, platform=platform)
@pytest.mark.parametrize("template, move, platform, expected, exception", rnames)
def test_rename(template, platform, move, expected, exception):
fr = filerenamer.FileRenamer(md_test, platform=platform)
fr.move = move
fr.set_template(template)
assert str(pathlib.PureWindowsPath(fr.determine_name(".cbz"))) == str(pathlib.PureWindowsPath(expected))
with exception:
assert str(pathlib.PureWindowsPath(fr.determine_name(".cbz"))) == str(pathlib.PureWindowsPath(expected))
@pytest.mark.parametrize("inp, result", rfnames)
def test_get_rename_dir(inp, result, cbz):
assert result(cbz) == filerenamer.get_rename_dir(cbz, inp)