Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Enki integration URL generation (PP-1876) #2155

Merged
merged 1 commit into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/palace/manager/api/enki.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@


class EnkiConstants:
PRODUCTION_BASE_URL = "https://enkilibrary.org/API/"
PRODUCTION_BASE_URL = "https://enkilibrary.org/API"


class EnkiSettings(BaseCirculationApiSettings):
Expand Down Expand Up @@ -148,7 +148,7 @@ def label(cls) -> str:
def description(cls) -> str:
return cls.DESCRIPTION # type: ignore[no-any-return]

def __init__(self, _db: Session, collection: Collection):
def __init__(self, _db: Session, collection: Collection) -> None:
self._db = _db
if collection.protocol != self.ENKI:
raise ValueError(
Expand All @@ -158,7 +158,10 @@ def __init__(self, _db: Session, collection: Collection):
super().__init__(_db, collection)

self.collection_id = collection.id
self.base_url = self.settings.url or self.PRODUCTION_BASE_URL
self.base_url = self.settings.url

def _url(self, endpoint: str) -> str:
return f"{self.base_url}/{endpoint}"

def enki_library_id(self, library: Library) -> str | None:
"""Find the Enki library ID for the given library."""
Expand Down Expand Up @@ -300,7 +303,7 @@ def recent_activity(
start_int = int((start - epoch).total_seconds())
end_int = int((end - epoch).total_seconds())

url = self.base_url + self.item_endpoint
url = self._url(self.item_endpoint)
args = dict(
method="getRecentActivityTime", stime=str(start_int), etime=str(end_int)
)
Expand Down Expand Up @@ -328,7 +331,7 @@ def updated_titles(self, since: datetime.datetime) -> Generator[Metadata]:
:yield: A sequence of Metadata objects.
"""
minutes = self._minutes_since(since)
url = self.base_url + self.list_endpoint
url = self._url(self.list_endpoint)
args = dict(
method="getUpdateTitles",
minutes=minutes,
Expand All @@ -348,7 +351,7 @@ def get_item(self, enki_id: str | None) -> Metadata | None:
:return: If the book is in the library's collection, a
Metadata object with attached CirculationData. Otherwise, None.
"""
url = self.base_url + self.item_endpoint
url = self._url(self.item_endpoint)
args = dict(
method="getItem",
recordid=enki_id,
Expand Down Expand Up @@ -381,7 +384,7 @@ def get_all_titles(self, strt: int = 0, qty: int = 10) -> Generator[Metadata]:
self.log.debug(
"requesting : " + str(qty) + " books starting at econtentRecord" + str(strt)
)
url = str(self.base_url) + str(self.list_endpoint)
url = self._url(self.list_endpoint)
args = {"method": "getAllTitles", "id": "secontent", "strt": strt, "qty": qty}
response = self.request(url, params=args)
yield from BibliographicParser().process_all(response.content)
Expand Down Expand Up @@ -447,7 +450,7 @@ def loan_request(
enki_library_id: str | None,
) -> RequestsResponse:
self.log.debug("Sending checkout request for %s" % book_id)
url = str(self.base_url) + str(self.user_endpoint)
url = self._url(self.user_endpoint)
args = {
"method": "getSELink",
"username": barcode,
Expand Down Expand Up @@ -552,7 +555,7 @@ def patron_request(
self, patron: str | None, pin: str | None, enki_library_id: str | None
) -> RequestsResponse:
self.log.debug("Querying Enki for information on patron %s" % patron)
url = str(self.base_url) + str(self.user_endpoint)
url = self._url(self.user_endpoint)
args = {
"method": "getSEPatronData",
"username": patron,
Expand Down
43 changes: 40 additions & 3 deletions tests/manager/api/test_enki.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
EnkiCollectionReaper,
EnkiImport,
EnkiLibrarySettings,
EnkiSettings,
)
from palace.manager.api.overdrive import OverdriveAPI
from palace.manager.core.metadata_layer import CirculationData, Metadata, TimestampData
Expand Down Expand Up @@ -94,6 +95,42 @@ def test_constructor(self, enki_test_fixture: EnkiTestFixure):
collection.protocol = EnkiAPI.label()
EnkiAPI(db.session, collection)

@pytest.mark.parametrize(
"base_url, endpoint, expected",
[
(
"https://enkilibrary.org/API",
"ItemAPI",
"https://enkilibrary.org/API/ItemAPI",
),
(
"https://enkilibrary.org/API/",
"UserAPI",
"https://enkilibrary.org/API/UserAPI",
),
(
"https://other.test.url/TEST//",
"ListAPI",
"https://other.test.url/TEST/ListAPI",
),
],
)
def test__url(
self,
db: DatabaseTransactionFixture,
base_url: str,
endpoint: str,
expected: str,
) -> None:
self.collection = db.collection(
name="Test Enki Collection",
protocol=EnkiAPI,
library=db.default_library(),
settings=EnkiSettings(url=base_url),
)
api = EnkiAPI(db.session, self.collection)
assert api._url(endpoint) == expected

def test_enki_library_id(self, enki_test_fixture: EnkiTestFixure):
db = enki_test_fixture.db
# The default library has already had this value set on its
Expand Down Expand Up @@ -441,7 +478,7 @@ def test_checkout_success(self, enki_test_fixture: EnkiTestFixure):
kwargs,
] = enki_test_fixture.api.requests.pop()
assert "get" == method
assert enki_test_fixture.api.base_url + "UserAPI" == url
assert enki_test_fixture.api._url("UserAPI") == url
assert "getSELink" == params["method"]
assert "123" == params["username"]
assert "pin" == params["password"]
Expand Down Expand Up @@ -537,7 +574,7 @@ def test_fulfill_success_acsm(self, enki_test_fixture: EnkiTestFixure):
kwargs,
] = enki_test_fixture.api.requests.pop()
assert "get" == method
assert enki_test_fixture.api.base_url + "UserAPI" == url
assert enki_test_fixture.api._url("UserAPI") == url
assert "getSELink" == params["method"]
assert "123" == params["username"]
assert "pin" == params["password"]
Expand Down Expand Up @@ -589,7 +626,7 @@ def test_patron_activity(self, enki_test_fixture: EnkiTestFixure):
kwargs,
] = enki_test_fixture.api.requests.pop()
assert "get" == method
assert enki_test_fixture.api.base_url + "UserAPI" == url
assert enki_test_fixture.api._url("UserAPI") == url
assert "getSEPatronData" == params["method"]
assert "123" == params["username"]
assert "pin" == params["password"]
Expand Down