refactor: restructure into package layout and split large modules
This commit is contained in:
@@ -4,7 +4,7 @@ from dataclasses import dataclass, field
|
||||
from typing import Any, cast
|
||||
|
||||
from auditui.app import Auditui
|
||||
from auditui.search_utils import build_search_text, filter_items
|
||||
from auditui.library import build_search_text, filter_items
|
||||
|
||||
|
||||
class StubLibrary:
|
||||
|
||||
@@ -2,24 +2,24 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from auditui import downloads
|
||||
from auditui.downloads import DownloadManager
|
||||
from auditui.constants import MIN_FILE_SIZE
|
||||
|
||||
|
||||
def test_sanitize_filename() -> None:
|
||||
dm = downloads.DownloadManager.__new__(downloads.DownloadManager)
|
||||
dm = DownloadManager.__new__(DownloadManager)
|
||||
assert dm._sanitize_filename('a<>:"/\\|?*b') == "a_________b"
|
||||
|
||||
|
||||
def test_validate_download_url() -> None:
|
||||
dm = downloads.DownloadManager.__new__(downloads.DownloadManager)
|
||||
dm = DownloadManager.__new__(DownloadManager)
|
||||
assert dm._validate_download_url("https://example.com/file") is True
|
||||
assert dm._validate_download_url("http://example.com/file") is True
|
||||
assert dm._validate_download_url("ftp://example.com/file") is False
|
||||
|
||||
|
||||
def test_cached_path_and_remove(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
dm = downloads.DownloadManager.__new__(downloads.DownloadManager)
|
||||
dm = DownloadManager.__new__(DownloadManager)
|
||||
dm.cache_dir = tmp_path
|
||||
|
||||
monkeypatch.setattr(dm, "_get_name_from_asin", lambda asin: "My Book")
|
||||
@@ -37,7 +37,7 @@ def test_cached_path_and_remove(tmp_path: Path, monkeypatch: pytest.MonkeyPatch)
|
||||
|
||||
|
||||
def test_cached_path_ignores_small_file(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
dm = downloads.DownloadManager.__new__(downloads.DownloadManager)
|
||||
dm = DownloadManager.__new__(DownloadManager)
|
||||
dm.cache_dir = tmp_path
|
||||
|
||||
monkeypatch.setattr(dm, "_get_name_from_asin", lambda asin: "My Book")
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from auditui import table_utils
|
||||
from auditui.constants import AUTHOR_NAME_MAX_LENGTH
|
||||
from auditui.library import (
|
||||
create_progress_sort_key,
|
||||
create_title_sort_key,
|
||||
format_item_as_row,
|
||||
truncate_author_name,
|
||||
)
|
||||
|
||||
|
||||
class StubLibrary:
|
||||
@@ -37,22 +43,22 @@ class StubDownloads:
|
||||
|
||||
|
||||
def test_create_title_sort_key_normalizes_accents() -> None:
|
||||
key_fn, _ = table_utils.create_title_sort_key()
|
||||
key_fn, _ = create_title_sort_key()
|
||||
assert key_fn(["École"]) == "ecole"
|
||||
assert key_fn(["Zoo"]) == "zoo"
|
||||
|
||||
|
||||
def test_create_progress_sort_key_parses_percent() -> None:
|
||||
key_fn, _ = table_utils.create_progress_sort_key()
|
||||
key_fn, _ = create_progress_sort_key()
|
||||
assert key_fn(["0", "0", "0", "42.5%"]) == 42.5
|
||||
assert key_fn(["0", "0", "0", "bad"]) == 0.0
|
||||
|
||||
|
||||
def test_truncate_author_name() -> None:
|
||||
long_name = "A" * (table_utils.AUTHOR_NAME_MAX_LENGTH + 5)
|
||||
truncated = table_utils.truncate_author_name(long_name)
|
||||
long_name = "A" * (AUTHOR_NAME_MAX_LENGTH + 5)
|
||||
truncated = truncate_author_name(long_name)
|
||||
assert truncated.endswith("...")
|
||||
assert len(truncated) <= table_utils.AUTHOR_NAME_MAX_LENGTH
|
||||
assert len(truncated) <= AUTHOR_NAME_MAX_LENGTH
|
||||
|
||||
|
||||
def test_format_item_as_row_with_downloaded() -> None:
|
||||
@@ -65,7 +71,7 @@ def test_format_item_as_row_with_downloaded() -> None:
|
||||
"percent": 12.34,
|
||||
"asin": "ASIN123",
|
||||
}
|
||||
title, author, runtime, progress, downloaded = table_utils.format_item_as_row(
|
||||
title, author, runtime, progress, downloaded = format_item_as_row(
|
||||
item, library, cast(Any, downloads)
|
||||
)
|
||||
assert title == "Title"
|
||||
@@ -79,5 +85,5 @@ def test_format_item_as_row_zero_progress() -> None:
|
||||
library = StubLibrary()
|
||||
item = {"title": "Title", "authors": "Author",
|
||||
"minutes": 30, "percent": 0.0}
|
||||
_, _, _, progress, _ = table_utils.format_item_as_row(item, library, None)
|
||||
_, _, _, progress, _ = format_item_as_row(item, library, None)
|
||||
assert progress == "0%"
|
||||
|
||||
@@ -1,63 +1,35 @@
|
||||
import json
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from auditui import ui
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class DummyApp:
|
||||
client: object | None = None
|
||||
auth: object | None = None
|
||||
library_client: object | None = None
|
||||
all_items: list[dict] = field(default_factory=list)
|
||||
BINDINGS: list[tuple[str, str, str]] = field(default_factory=list)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dummy_app() -> DummyApp:
|
||||
return DummyApp()
|
||||
from auditui.stats.email import (
|
||||
find_email_in_data,
|
||||
get_email_from_auth,
|
||||
get_email_from_auth_file,
|
||||
get_email_from_config,
|
||||
)
|
||||
|
||||
|
||||
def test_find_email_in_data() -> None:
|
||||
screen = ui.StatsScreen()
|
||||
data = {"a": {"b": ["nope", "user@example.com"]}}
|
||||
assert screen._find_email_in_data(data) == "user@example.com"
|
||||
assert find_email_in_data(data) == "user@example.com"
|
||||
|
||||
|
||||
def test_get_email_from_config(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, dummy_app: DummyApp
|
||||
) -> None:
|
||||
screen = ui.StatsScreen()
|
||||
def test_get_email_from_config(tmp_path: Path) -> None:
|
||||
config_path = tmp_path / "config.json"
|
||||
config_path.write_text(json.dumps({"email": "config@example.com"}))
|
||||
monkeypatch.setattr(ui, "CONFIG_PATH", config_path)
|
||||
|
||||
email = screen._get_email_from_config(dummy_app)
|
||||
assert email == "config@example.com"
|
||||
assert get_email_from_config(config_path) == "config@example.com"
|
||||
|
||||
|
||||
def test_get_email_from_auth_file(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, dummy_app: DummyApp
|
||||
) -> None:
|
||||
screen = ui.StatsScreen()
|
||||
def test_get_email_from_auth_file(tmp_path: Path) -> None:
|
||||
auth_path = tmp_path / "auth.json"
|
||||
auth_path.write_text(json.dumps({"email": "auth@example.com"}))
|
||||
monkeypatch.setattr(ui, "AUTH_PATH", auth_path)
|
||||
|
||||
email = screen._get_email_from_auth_file(dummy_app)
|
||||
assert email == "auth@example.com"
|
||||
assert get_email_from_auth_file(auth_path) == "auth@example.com"
|
||||
|
||||
|
||||
def test_get_email_from_auth(dummy_app: DummyApp) -> None:
|
||||
screen = ui.StatsScreen()
|
||||
|
||||
def test_get_email_from_auth() -> None:
|
||||
class Auth:
|
||||
username = "user@example.com"
|
||||
login = None
|
||||
email = None
|
||||
|
||||
dummy_app.auth = Auth()
|
||||
assert screen._get_email_from_auth(dummy_app) == "user@example.com"
|
||||
assert get_email_from_auth(Auth()) == "user@example.com"
|
||||
|
||||
Reference in New Issue
Block a user