"""Changes that the user makes to the chapters of a story while a job runs for it.""" import pytest from test_deliver import CHAPTER, linked_story, site, titles, update from test_deliver import fake as fake from test_deliver import jobs as jobs from test_deliver import story_epub as story_epub from bindery import fff, orchestrator from bindery.jobs import DownloadMode from bindery.store import Store THREE = [(1, "One", "a"), (2, "Two", "b"), (3, "Three", "c")] def during_download(monkeypatch, number, action): """Run `action` when the job downloads the chapter with this number.""" fetch = fff.fetch_chapter def fetch_and_act(adapter, url, index): if url == CHAPTER.format(number): action() return fetch(adapter, url, index) monkeypatch.setattr(fff, "fetch_chapter", fetch_and_act) def chapter_id(story_id, title): return next(c["id"] for c in orchestrator.store.list_chapters(story_id) if c["title"] == title) def test_a_move_during_a_download_stays(fake, jobs, monkeypatch): story_id = linked_story(THREE) site(monkeypatch, [*THREE, (4, "Four", "d"), (5, "Five", "e")]) during_download(monkeypatch, 4, lambda: orchestrator.move_chapters(story_id, [chapter_id(story_id, "Three")], None)) assert "2 new chapters" in update(story_id) assert titles(story_id) == ["Three", "One", "Two", "Four", "Five"] def test_a_new_chapter_in_the_middle_goes_after_its_moved_predecessor(fake, jobs, monkeypatch): story_id = linked_story(THREE) site(monkeypatch, [(1, "One", "a"), (9, "Nine", "x"), (2, "Two", "b"), (3, "Three", "c")]) during_download( monkeypatch, 9, lambda: orchestrator.move_chapters(story_id, [chapter_id(story_id, "One")], chapter_id(story_id, "Three")), ) update(story_id) assert titles(story_id) == ["Two", "Three", "One", "Nine"] def test_a_delete_during_a_download_stays(fake, jobs, monkeypatch): story_id = linked_story(THREE) site(monkeypatch, [*THREE, (4, "Four", "d")]) during_download(monkeypatch, 4, lambda: orchestrator.delete_chapters(story_id, [chapter_id(story_id, "Two")])) assert "1 new chapter" in update(story_id) assert titles(story_id) == ["One", "Three", "Four"] def test_a_delete_during_a_recheck_does_not_stop_the_job(fake, jobs, monkeypatch): story_id = linked_story(THREE) site(monkeypatch, [(1, "One", "a2"), (2, "Two", "b2"), (3, "Three", "c2")]) during_download(monkeypatch, 2, lambda: orchestrator.delete_chapters(story_id, [chapter_id(story_id, "Two")])) assert "2 of 3 rechecked chapters changed" in update(story_id, DownloadMode.RECHECK_ALL) assert titles(story_id) == ["One", "Three"] def test_the_order_function_of_add_chapters_sees_the_stored_order(tmp_path): store = Store(tmp_path / "db.sqlite") sid = store.create_story("u", "s", "T", "A", []) for n, url in enumerate(["u2", "u1"]): store.add_chapter(sid, url, url, "

", "h", "new", n) new = [{"url": "u3", "title": "u3", "html": "

", "text_hash": "h"}] seen = [] store.add_chapters(sid, new, "new", lambda stored: seen.append(stored) or [*stored, "u3"]) assert seen == [["u2", "u1"]] assert [c["url"] for c in store.list_chapters(sid)] == ["u2", "u1", "u3"] def test_a_refused_reorder_changes_nothing(tmp_path): store = Store(tmp_path / "db.sqlite") sid = store.create_story("u", "s", "T", "A", []) ids = [store.add_chapter(sid, f"u{n}", str(n), "

", "h", "new", n) for n in range(3)] def refuse(order): raise ValueError("no") with pytest.raises(ValueError, match="no"): store.reorder_chapters(sid, refuse) assert [c["id"] for c in store.list_chapters(sid)] == ids store.reorder_chapters(sid, lambda order: order[::-1]) assert [c["id"] for c in store.list_chapters(sid)] == ids[::-1]