Files
bindery/tests/test_metadata.py
tim 49cd18a09f Run download jobs and deliver books to CWA
Jobs download new chapters, recheck chapters, replace the book, update
metadata or rebuild from stored chapters. Locked metadata fields keep
their values. A scheduler queues updates. An update finds the library
book of a story through CWA, and fails with an error if it cannot, so
that it never makes a duplicate book.
2026-09-27 23:38:28 +02:00

75 lines
2.8 KiB
Python

import pytest
from bindery import orchestrator as backend
SITE = {
"title": "Site Title",
"authors": ["Writer"],
"comments": "<p>New blurb</p>",
"tags": ["Fantasy", "Completed"],
"series": "Saga",
"series_index": 2.0,
"pubdate": "2020-01-01T00:00:00",
"languages": "en",
}
def story(**extra):
base = {"locked_fields": ["title"], "pinned": {}, "site_values": {}}
base.update(extra)
return base
def test_first_download_keeps_site_value():
assert backend._resolve_metadata(story(), SITE, []) == {"title": "Site Title"}
def test_locked_field_keeps_its_value():
assert backend._resolve_metadata(story(pinned={"title": "Old"}), SITE, []) == {"title": "Old"}
def test_forced_field_takes_site_value_and_stays_locked():
s = story(pinned={"title": "Old"})
assert backend._resolve_metadata(s, SITE, ["title"]) == {"title": "Site Title"}
def test_edited_unlocked_field_stays_until_the_site_changes_it():
s = story(pinned={"title": "Old", "tags": ["mine"]}, site_values=SITE)
assert backend._resolve_metadata(s, SITE, []) == {"title": "Old", "tags": ["mine"]}
changed = {**SITE, "tags": ["Fantasy", "Completed", "LitRPG"]}
assert backend._resolve_metadata(s, changed, []) == {"title": "Old"}
# A change to another field keeps the edit.
assert backend._resolve_metadata(s, {**SITE, "comments": "<p>x</p>"}, []) == {"title": "Old", "tags": ["mine"]}
def test_forced_update_replaces_an_edited_unlocked_field():
s = story(pinned={"tags": ["mine"]}, site_values=SITE)
assert backend._resolve_metadata(s, SITE, ["tags"]) == {"title": "Site Title"}
def test_edit_before_the_first_site_values_stays():
s = story(pinned={"tags": ["mine"]})
assert backend._resolve_metadata(s, SITE, []) == {"title": "Site Title", "tags": ["mine"]}
def test_edited_values_are_checked_and_normalized():
assert backend._edited_value("authors", "A & B ") == ["A", "B"]
assert backend._edited_value("tags", "x, y,,") == ["x", "y"]
assert backend._edited_value("series", "Saga [2]") == ["Saga", 2.0]
assert backend._edited_value("series", ["Saga", "3"]) == ["Saga", 3.0]
assert backend._edited_value("series", "") == ["", None]
assert backend._edited_value("pubdate", "2024-01-31") == "2024-01-31"
assert backend._edited_value("title", " New ") == "New"
for field, value in (("title", " "), ("authors", "&"), ("pubdate", "soon")):
with pytest.raises(ValueError):
backend._edited_value(field, value)
def test_series_keeps_name_and_index():
s = story(locked_fields=["series"])
assert backend._resolve_metadata(s, SITE, []) == {"series": ["Saga", 2.0]}
def test_resolve_without_site_values_does_not_fail():
assert backend._resolve_metadata(story(pinned={"title": "Old"}), {}, []) == {"title": "Old"}