diff --git a/src/palace/manager/api/controller/opds_feed.py b/src/palace/manager/api/controller/opds_feed.py index f13f67fa0..b331fd725 100644 --- a/src/palace/manager/api/controller/opds_feed.py +++ b/src/palace/manager/api/controller/opds_feed.py @@ -34,6 +34,7 @@ SearchFacets, WorkList, ) +from palace.manager.util.flask_util import OPDSFeedResponse from palace.manager.util.problem_detail import ProblemDetail @@ -243,7 +244,7 @@ def crawlable_list_feed(self, list_name): def _crawlable_feed( self, title, url, worklist, annotator=None, feed_class=OPDSAcquisitionFeed - ): + ) -> OPDSFeedResponse | ProblemDetail: """Helper method to create a crawlable feed. :param title: The title to use for the feed. @@ -270,6 +271,8 @@ def _crawlable_feed( worklist=worklist, base_class=CrawlableFacets, ) + if isinstance(facets, ProblemDetail): + return facets annotator = annotator or self.manager.annotator(worklist, facets=facets) return feed_class.page( diff --git a/tests/manager/api/controller/test_crawlfeed.py b/tests/manager/api/controller/test_crawlfeed.py index 80385c9f4..df3d07f0a 100644 --- a/tests/manager/api/controller/test_crawlfeed.py +++ b/tests/manager/api/controller/test_crawlfeed.py @@ -1,7 +1,7 @@ import json from contextlib import contextmanager from typing import Any -from unittest.mock import MagicMock +from unittest.mock import MagicMock, create_autospec import feedparser from flask import url_for @@ -13,7 +13,11 @@ CrawlableFacets, DynamicLane, ) -from palace.manager.api.problem_details import NO_SUCH_COLLECTION, NO_SUCH_LIST +from palace.manager.api.problem_details import ( + NO_SUCH_COLLECTION, + NO_SUCH_LANE, + NO_SUCH_LIST, +) from palace.manager.core.problem_details import INVALID_INPUT from palace.manager.feed.acquisition import OPDSAcquisitionFeed from palace.manager.feed.annotator.circulation import CirculationManagerAnnotator @@ -226,6 +230,21 @@ def works(self, _db, facets, pagination, *args, **kwargs): title="Lane title", url="Lane URL", worklist=mock_lane, feed_class=MockFeed ) + # Lane that cannot be accessed -> problem detail + inaccessible_lane = MockLane() + inaccessible_lane.accessible_to = create_autospec( + mock_lane.accessible_to, return_value=False + ) + with circulation_fixture.request_context_with_library("/"): + response = circulation_fixture.manager.opds_feeds._crawlable_feed( + title="Lane title", + url="Lane URL", + worklist=inaccessible_lane, + feed_class=MockFeed, + ) + assert isinstance(response, ProblemDetail) + assert NO_SUCH_LANE.uri == response.uri + # Bad pagination data -> problem detail with circulation_fixture.app.test_request_context("/?size=a"): response = circulation_fixture.manager.opds_feeds._crawlable_feed(