Files
bindery/tests/test_store.py
T
tim 6c2574cf0f Store chapters, merge chapter lists, diff and apply rules
The SQLite store keeps every chapter revision, so a chapter that the site
removes stays in the book. The merge puts new chapters after the chapter
that comes before them on the site. Diffs compare text, not HTML, and
replacement rules run on chapter HTML when a book is built.
2026-09-27 21:23:20 +02:00

72 lines
3.3 KiB
Python

from bindery.store import Store
def test_chapters_revisions_and_rules(tmp_path):
store = Store(tmp_path / "db.sqlite")
sid = store.create_story("https://example/s/1", "example", "T", "A", ["title"])
c1 = store.add_chapter(sid, "u1", "One", "<p>1</p>", "h1", "new", 0)
c2 = store.add_chapter(sid, "u2", "Two", "<p>2</p>", "h2", "new", 1)
store.set_positions(sid, [c2, c1])
assert [c["url"] for c in store.chapters_for_build(sid)] == ["u2", "u1"]
assert store.add_revision(c1, "<p>1b</p>", "h1b", "recheck") == 2
assert store.current_revisions(sid)[c1] == {"rev": 2, "text_hash": "h1b", "source": "recheck"}
store.replace_revision(c1, 2, "<p>1c</p>", "h1c")
assert store.current_revisions(sid)[c1]["text_hash"] == "h1c"
assert store.revision_html(c1, 1) == "<p>1</p>"
store.update_chapter(c1, current_rev=1, included=0)
assert [c["url"] for c in store.chapters_for_build(sid)] == ["u2"]
store.set_rules(None, [{"pattern": "g"}])
store.set_rules(sid, [{"pattern": "s", "flags": "i"}])
assert [r["pattern"] for r in store.rules(None)] == ["g"]
assert store.rules(sid)[0]["flags"] == "i"
story = store.get_story(sid)
assert story["locked_fields"] == ["title"] and story["pinned"] == {}
store.update_story(sid, pinned={"title": "Kept"})
assert store.get_story_by_url("https://example/s/1")["pinned"] == {"title": "Kept"}
store.delete_story(sid)
assert store.get_chapter(c1) is None
assert store.rules(sid) == []
assert store.rules(None) != []
def test_cover_replaces_previous_cover(tmp_path):
store = Store(tmp_path / "db.sqlite")
sid = store.create_story("u", "s", "T", "A", [])
store.put_image(sid, "c1", "jpg", "image/jpeg", b"1", is_cover=True)
store.put_image(sid, "c2", "jpg", "image/jpeg", b"2", is_cover=True)
store.put_image(sid, "i1", "png", "image/png", b"3")
assert store.cover(sid)["url"] == "c2"
assert [i["url"] for i in store.images(sid)] == ["i1"]
def test_add_chapters_places_them_in_one_step(tmp_path):
store = Store(tmp_path / "db.sqlite")
sid = store.create_story("u", "s", "T", "A", [])
store.add_chapter(sid, "u1", "One", "<p>1</p>", "h1", "new", 0)
store.add_chapter(sid, "u3", "Three", "<p>3</p>", "h3", "new", 1)
store.add_chapter(sid, "u9", "Nine", "<p>9</p>", "h9", "new", 2)
new = [{"url": u, "title": u, "html": "<p/>", "text_hash": "h"} for u in ("u2", "u4")]
ids = store.add_chapters(sid, new, "import", ["u1", "u2", "u3", "u4"])
chapters = store.list_chapters(sid)
assert [c["url"] for c in chapters] == ["u1", "u2", "u3", "u4", "u9"]
assert [c["position"] for c in chapters] == [0, 1, 2, 3, 4]
assert [c["id"] for c in chapters if c["url"] in ("u2", "u4")] == ids
def test_settings(tmp_path):
store = Store(tmp_path / "db.sqlite")
sid = store.create_story("u", "s", "T", "A", [])
assert store.get_setting(None, "paragraphs") is None
store.set_setting(None, "paragraphs", True)
store.set_setting(sid, "paragraphs", False)
assert (store.get_setting(None, "paragraphs"), store.get_setting(sid, "paragraphs")) == (True, False)
store.set_setting(sid, "paragraphs", None)
assert store.get_setting(sid, "paragraphs") is None
store.set_setting(sid, "paragraphs", True)
store.delete_story(sid)
assert store.get_setting(sid, "paragraphs") is None