mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 05:40:26 +02:00
Reformat using black
This commit is contained in:
+345
-314
@@ -1,4 +1,10 @@
|
||||
from abogen.integrations.calibre_opds import CalibreOPDSClient, OPDSEntry, OPDSFeed, OPDSLink, feed_to_dict
|
||||
from abogen.integrations.calibre_opds import (
|
||||
CalibreOPDSClient,
|
||||
OPDSEntry,
|
||||
OPDSFeed,
|
||||
OPDSLink,
|
||||
feed_to_dict,
|
||||
)
|
||||
|
||||
|
||||
def test_calibre_opds_feed_exposes_series_metadata() -> None:
|
||||
@@ -158,25 +164,33 @@ This is the detailed summary text.</summary>
|
||||
|
||||
|
||||
def test_calibre_opds_relative_urls_keep_catalog_prefix() -> None:
|
||||
client = CalibreOPDSClient("http://example.com/opds/")
|
||||
client = CalibreOPDSClient("http://example.com/opds/")
|
||||
|
||||
assert client._make_url("search") == "http://example.com/opds/search"
|
||||
assert client._make_url("books/sample.epub") == "http://example.com/opds/books/sample.epub"
|
||||
assert client._make_url("/cover/1") == "http://example.com/cover/1"
|
||||
assert client._make_url("?page=2") == "http://example.com/opds?page=2"
|
||||
assert client._make_url("search") == "http://example.com/opds/search"
|
||||
assert (
|
||||
client._make_url("books/sample.epub")
|
||||
== "http://example.com/opds/books/sample.epub"
|
||||
)
|
||||
assert client._make_url("/cover/1") == "http://example.com/cover/1"
|
||||
assert client._make_url("?page=2") == "http://example.com/opds?page=2"
|
||||
|
||||
|
||||
def test_calibre_opds_base_url_without_trailing_slash() -> None:
|
||||
"""Ensure the client works with base URLs that don't have trailing slashes."""
|
||||
client = CalibreOPDSClient("http://example.com/api/v1/opds")
|
||||
"""Ensure the client works with base URLs that don't have trailing slashes."""
|
||||
client = CalibreOPDSClient("http://example.com/api/v1/opds")
|
||||
|
||||
# Base URL should be stored without trailing slash
|
||||
assert client._base_url == "http://example.com/api/v1/opds"
|
||||
# Relative paths should resolve as siblings to the base URL
|
||||
assert client._make_url("catalog") == "http://example.com/api/v1/opds/catalog"
|
||||
assert client._make_url("search?q=test") == "http://example.com/api/v1/opds/search?q=test"
|
||||
assert client._make_url("/api/v1/opds/books") == "http://example.com/api/v1/opds/books"
|
||||
assert client._make_url("?page=2") == "http://example.com/api/v1/opds?page=2"
|
||||
# Base URL should be stored without trailing slash
|
||||
assert client._base_url == "http://example.com/api/v1/opds"
|
||||
# Relative paths should resolve as siblings to the base URL
|
||||
assert client._make_url("catalog") == "http://example.com/api/v1/opds/catalog"
|
||||
assert (
|
||||
client._make_url("search?q=test")
|
||||
== "http://example.com/api/v1/opds/search?q=test"
|
||||
)
|
||||
assert (
|
||||
client._make_url("/api/v1/opds/books") == "http://example.com/api/v1/opds/books"
|
||||
)
|
||||
assert client._make_url("?page=2") == "http://example.com/api/v1/opds?page=2"
|
||||
|
||||
|
||||
def test_calibre_opds_filters_out_unsupported_formats() -> None:
|
||||
@@ -253,365 +267,382 @@ def test_calibre_opds_navigation_entries_without_download_are_preserved() -> Non
|
||||
|
||||
|
||||
def test_calibre_opds_search_filters_by_title_and_author() -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(id="1", title="The Long Journey", authors=["Alice Smith"]),
|
||||
OPDSEntry(id="2", title="Hidden Worlds", authors=["Bob Johnson"]),
|
||||
OPDSEntry(id="3", title="Side Stories", authors=["Cara Nguyen"], series="Journey Tales"),
|
||||
],
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(id="1", title="The Long Journey", authors=["Alice Smith"]),
|
||||
OPDSEntry(id="2", title="Hidden Worlds", authors=["Bob Johnson"]),
|
||||
OPDSEntry(
|
||||
id="3",
|
||||
title="Side Stories",
|
||||
authors=["Cara Nguyen"],
|
||||
series="Journey Tales",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
filtered = client._filter_feed_entries(feed, "journey alice")
|
||||
assert [entry.id for entry in filtered.entries] == ["1"]
|
||||
filtered = client._filter_feed_entries(feed, "journey alice")
|
||||
assert [entry.id for entry in filtered.entries] == ["1"]
|
||||
|
||||
filtered = client._filter_feed_entries(feed, "bob")
|
||||
assert [entry.id for entry in filtered.entries] == ["2"]
|
||||
filtered = client._filter_feed_entries(feed, "bob")
|
||||
assert [entry.id for entry in filtered.entries] == ["2"]
|
||||
|
||||
filtered = client._filter_feed_entries(feed, "journey tales")
|
||||
assert [entry.id for entry in filtered.entries] == ["3"]
|
||||
filtered = client._filter_feed_entries(feed, "journey tales")
|
||||
assert [entry.id for entry in filtered.entries] == ["3"]
|
||||
|
||||
filtered = client._filter_feed_entries(feed, "missing")
|
||||
assert filtered.entries == []
|
||||
filtered = client._filter_feed_entries(feed, "missing")
|
||||
assert filtered.entries == []
|
||||
|
||||
|
||||
def test_calibre_opds_local_search_follows_next(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
page_one = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Unrelated", authors=["Alice Smith"])],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
page_two = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="2", title="The Journey Continues", authors=["Bob Johnson"])],
|
||||
links={},
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
page_one = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Unrelated", authors=["Alice Smith"])],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
page_two = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(id="2", title="The Journey Continues", authors=["Bob Johnson"])
|
||||
],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return page_two
|
||||
return page_one
|
||||
def fake_fetch(href=None, params=None):
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return page_two
|
||||
return page_one
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client._local_search("journey", seed_feed=page_one)
|
||||
assert [entry.id for entry in result.entries] == ["2"]
|
||||
result = client._local_search("journey", seed_feed=page_one)
|
||||
assert [entry.id for entry in result.entries] == ["2"]
|
||||
|
||||
|
||||
def test_calibre_opds_local_search_traverses_navigation(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-authors",
|
||||
title="Browse Authors",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-authors",
|
||||
title="Browse Authors",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
links={},
|
||||
)
|
||||
authors_feed = OPDSFeed(
|
||||
id="authors",
|
||||
title="Authors",
|
||||
entries=[
|
||||
OPDSEntry(id="book-42", title="The Count of Monte Cristo", authors=["Alexandre Dumas"])
|
||||
],
|
||||
links={},
|
||||
)
|
||||
links={},
|
||||
)
|
||||
authors_feed = OPDSFeed(
|
||||
id="authors",
|
||||
title="Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="book-42",
|
||||
title="The Count of Monte Cristo",
|
||||
authors=["Alexandre Dumas"],
|
||||
)
|
||||
],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
if href == "http://example.com/catalog/authors":
|
||||
return authors_feed
|
||||
return root_feed
|
||||
def fake_fetch(href=None, params=None):
|
||||
if href == "http://example.com/catalog/authors":
|
||||
return authors_feed
|
||||
return root_feed
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client._local_search("monte cristo", seed_feed=root_feed)
|
||||
assert [entry.id for entry in result.entries] == ["book-42"]
|
||||
result = client._local_search("monte cristo", seed_feed=root_feed)
|
||||
assert [entry.id for entry in result.entries] == ["book-42"]
|
||||
|
||||
|
||||
def test_calibre_opds_search_falls_back_to_local_search(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
search_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Unrelated", authors=["Alice Smith"])],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
next_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="2", title="Journey in Space", authors=["Cara Nguyen"])],
|
||||
links={},
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
search_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Unrelated", authors=["Alice Smith"])],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
next_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="2", title="Journey in Space", authors=["Cara Nguyen"])],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return search_page
|
||||
if path == "http://example.com/catalog?page=2":
|
||||
return next_page
|
||||
return search_page
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return search_page
|
||||
if path == "http://example.com/catalog?page=2":
|
||||
return next_page
|
||||
return search_page
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.search("journey")
|
||||
assert [entry.id for entry in result.entries] == ["2"]
|
||||
result = client.search("journey")
|
||||
assert [entry.id for entry in result.entries] == ["2"]
|
||||
|
||||
|
||||
def test_calibre_opds_search_collects_next_page_results(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
first_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Ryan's Adventure")],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
second_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="2", title="Return of Ryan")],
|
||||
links={},
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
first_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="1", title="Ryan's Adventure")],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
second_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[OPDSEntry(id="2", title="Return of Ryan")],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return first_page
|
||||
if path == "http://example.com/catalog?page=2":
|
||||
return second_page
|
||||
if path is None and params is None:
|
||||
return first_page
|
||||
return first_page
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return first_page
|
||||
if path == "http://example.com/catalog?page=2":
|
||||
return second_page
|
||||
if path is None and params is None:
|
||||
return first_page
|
||||
return first_page
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.search("ryan")
|
||||
assert [entry.id for entry in result.entries] == ["1", "2"]
|
||||
result = client.search("ryan")
|
||||
assert [entry.id for entry in result.entries] == ["1", "2"]
|
||||
|
||||
|
||||
def test_calibre_opds_search_supplements_with_local_navigation(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
search_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="Ryan's First Mission"),
|
||||
OPDSEntry(
|
||||
id="nav-authors",
|
||||
title="Browse Authors",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
search_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Catalog",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="Ryan's First Mission"),
|
||||
OPDSEntry(
|
||||
id="nav-authors",
|
||||
title="Browse Authors",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
links={},
|
||||
)
|
||||
authors_feed = OPDSFeed(
|
||||
id="authors",
|
||||
title="Authors",
|
||||
entries=[OPDSEntry(id="book-2", title="Chronicles of Ryan")],
|
||||
links={},
|
||||
)
|
||||
links={},
|
||||
)
|
||||
authors_feed = OPDSFeed(
|
||||
id="authors",
|
||||
title="Authors",
|
||||
entries=[OPDSEntry(id="book-2", title="Chronicles of Ryan")],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return search_feed
|
||||
if path == "http://example.com/catalog/authors":
|
||||
return authors_feed
|
||||
if path is None and params is None:
|
||||
return search_feed
|
||||
return search_feed
|
||||
def fake_fetch(path=None, params=None):
|
||||
if path == "search":
|
||||
return search_feed
|
||||
if path == "http://example.com/catalog/authors":
|
||||
return authors_feed
|
||||
if path is None and params is None:
|
||||
return search_feed
|
||||
return search_feed
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.search("ryan")
|
||||
assert [entry.id for entry in result.entries] == ["book-1", "book-2"]
|
||||
result = client.search("ryan")
|
||||
assert [entry.id for entry in result.entries] == ["book-1", "book-2"]
|
||||
|
||||
|
||||
def test_calibre_opds_browse_letter_traverses_next(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-a",
|
||||
title="A",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/a",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-a",
|
||||
title="A",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/a",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
page_two = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-c",
|
||||
title="C",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/c",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
page_two = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-c",
|
||||
title="C",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/c",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
links={},
|
||||
)
|
||||
letter_feed = OPDSFeed(
|
||||
id="authors-c",
|
||||
title="Authors starting with C",
|
||||
entries=[OPDSEntry(id="author-1", title="Clarke, Arthur C.")],
|
||||
links={},
|
||||
)
|
||||
links={},
|
||||
)
|
||||
letter_feed = OPDSFeed(
|
||||
id="authors-c",
|
||||
title="Authors starting with C",
|
||||
entries=[OPDSEntry(id="author-1", title="Clarke, Arthur C.")],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return root_feed
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return page_two
|
||||
if href == "http://example.com/catalog/authors/c":
|
||||
return letter_feed
|
||||
return root_feed
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return root_feed
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return page_two
|
||||
if href == "http://example.com/catalog/authors/c":
|
||||
return letter_feed
|
||||
return root_feed
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.browse_letter("C")
|
||||
assert [entry.id for entry in result.entries] == ["author-1"]
|
||||
result = client.browse_letter("C")
|
||||
assert [entry.id for entry in result.entries] == ["author-1"]
|
||||
|
||||
|
||||
def test_calibre_opds_browse_letter_filters_when_missing_navigation(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
titles_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="The Moon is a Harsh Mistress"),
|
||||
OPDSEntry(id="book-2", title="Another Story"),
|
||||
],
|
||||
links={},
|
||||
)
|
||||
def test_calibre_opds_browse_letter_filters_when_missing_navigation(
|
||||
monkeypatch,
|
||||
) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
titles_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="The Moon is a Harsh Mistress"),
|
||||
OPDSEntry(id="book-2", title="Another Story"),
|
||||
],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
return titles_feed
|
||||
def fake_fetch(href=None, params=None):
|
||||
return titles_feed
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.browse_letter("M")
|
||||
assert [entry.id for entry in result.entries] == ["book-1"]
|
||||
result = client.browse_letter("M")
|
||||
assert [entry.id for entry in result.entries] == ["book-1"]
|
||||
|
||||
|
||||
def test_calibre_opds_browse_letter_collects_paginated_entries(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
first_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="Ryan's First Adventure"),
|
||||
OPDSEntry(id="book-2", title="Another Tale"),
|
||||
],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
second_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[OPDSEntry(id="book-3", title="Return of Ryan")],
|
||||
links={},
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
first_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[
|
||||
OPDSEntry(id="book-1", title="Ryan's First Adventure"),
|
||||
OPDSEntry(id="book-2", title="Another Tale"),
|
||||
],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog?page=2", rel="next")},
|
||||
)
|
||||
second_page = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Titles",
|
||||
entries=[OPDSEntry(id="book-3", title="Return of Ryan")],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return first_page
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return second_page
|
||||
return first_page
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return first_page
|
||||
if href == "http://example.com/catalog?page=2":
|
||||
return second_page
|
||||
return first_page
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.browse_letter("R")
|
||||
assert [entry.id for entry in result.entries] == ["book-1", "book-3"]
|
||||
result = client.browse_letter("R")
|
||||
assert [entry.id for entry in result.entries] == ["book-1", "book-3"]
|
||||
|
||||
|
||||
def test_calibre_opds_browse_letter_collects_paginated_navigation(monkeypatch) -> None:
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-a",
|
||||
title="A",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/a",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
client = CalibreOPDSClient("http://example.com/catalog")
|
||||
root_feed = OPDSFeed(
|
||||
id="catalog",
|
||||
title="Browse Authors",
|
||||
entries=[
|
||||
OPDSEntry(
|
||||
id="nav-a",
|
||||
title="A",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/a",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
),
|
||||
OPDSEntry(
|
||||
id="nav-r",
|
||||
title="R",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/r",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
OPDSEntry(
|
||||
id="nav-r",
|
||||
title="R",
|
||||
links=[
|
||||
OPDSLink(
|
||||
href="http://example.com/catalog/authors/r",
|
||||
rel="http://opds-spec.org/navigation",
|
||||
type="application/atom+xml;profile=opds-catalog",
|
||||
)
|
||||
links={},
|
||||
)
|
||||
letter_feed = OPDSFeed(
|
||||
id="authors-r",
|
||||
title="Authors — R",
|
||||
entries=[
|
||||
OPDSEntry(id="author-1", title="Ryan, Alice"),
|
||||
],
|
||||
),
|
||||
],
|
||||
links={},
|
||||
)
|
||||
letter_feed = OPDSFeed(
|
||||
id="authors-r",
|
||||
title="Authors — R",
|
||||
entries=[
|
||||
OPDSEntry(id="author-1", title="Ryan, Alice"),
|
||||
],
|
||||
links={"next": OPDSLink(href="http://example.com/catalog/authors/r?page=2", rel="next")},
|
||||
)
|
||||
letter_page_two = OPDSFeed(
|
||||
id="authors-r",
|
||||
title="Authors — R",
|
||||
entries=[OPDSEntry(id="author-2", title="Ryan, Bob")],
|
||||
links={},
|
||||
)
|
||||
links={
|
||||
"next": OPDSLink(
|
||||
href="http://example.com/catalog/authors/r?page=2", rel="next"
|
||||
)
|
||||
},
|
||||
)
|
||||
letter_page_two = OPDSFeed(
|
||||
id="authors-r",
|
||||
title="Authors — R",
|
||||
entries=[OPDSEntry(id="author-2", title="Ryan, Bob")],
|
||||
links={},
|
||||
)
|
||||
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return root_feed
|
||||
if href == "http://example.com/catalog/authors/r":
|
||||
return letter_feed
|
||||
if href == "http://example.com/catalog/authors/r?page=2":
|
||||
return letter_page_two
|
||||
return root_feed
|
||||
def fake_fetch(href=None, params=None):
|
||||
if not href:
|
||||
return root_feed
|
||||
if href == "http://example.com/catalog/authors/r":
|
||||
return letter_feed
|
||||
if href == "http://example.com/catalog/authors/r?page=2":
|
||||
return letter_page_two
|
||||
return root_feed
|
||||
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
monkeypatch.setattr(client, "fetch_feed", fake_fetch)
|
||||
|
||||
result = client.browse_letter("R")
|
||||
assert [entry.id for entry in result.entries] == ["author-1", "author-2"]
|
||||
result = client.browse_letter("R")
|
||||
assert [entry.id for entry in result.entries] == ["author-1", "author-2"]
|
||||
|
||||
Reference in New Issue
Block a user