Refactor code structure for improved readability and maintainability
This commit is contained in:
108
tests/conftest.py
Normal file
108
tests/conftest.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from typing import Callable, Optional
|
||||
|
||||
import pytest
|
||||
|
||||
from bibapi import sru
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_sru_xml() -> bytes:
|
||||
"""Return a small SRU searchRetrieveResponse (MARCXML) as bytes.
|
||||
|
||||
Tests can use this raw bytes payload to simulate SRU responses.
|
||||
"""
|
||||
xml = b"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<zs:searchRetrieveResponse xmlns:zs="http://www.loc.gov/zing/srw/"
|
||||
xmlns:marc="http://www.loc.gov/MARC21/slim">
|
||||
<zs:version>1.1</zs:version>
|
||||
<zs:numberOfRecords>1</zs:numberOfRecords>
|
||||
<zs:records>
|
||||
<zs:record>
|
||||
<zs:recordSchema>marcxml</zs:recordSchema>
|
||||
<zs:recordPacking>xml</zs:recordPacking>
|
||||
<zs:recordData>
|
||||
<marc:record>
|
||||
<marc:leader>-----nam a22</marc:leader>
|
||||
<marc:controlfield tag="001">PPN123</marc:controlfield>
|
||||
<marc:datafield tag="245" ind1=" " ind2=" ">
|
||||
<marc:subfield code="a">Example Title</marc:subfield>
|
||||
<marc:subfield code="b">Subtitle</marc:subfield>
|
||||
</marc:datafield>
|
||||
<marc:datafield tag="264" ind1=" " ind2="1">
|
||||
<marc:subfield code="c">2001</marc:subfield>
|
||||
<marc:subfield code="b">Example Publisher</marc:subfield>
|
||||
</marc:datafield>
|
||||
</marc:record>
|
||||
</zs:recordData>
|
||||
<zs:recordPosition>1</zs:recordPosition>
|
||||
</zs:record>
|
||||
</zs:records>
|
||||
<zs:echoedSearchRetrieveRequest>
|
||||
<zs:version>1.1</zs:version>
|
||||
<zs:query>pica.tit=Example</zs:query>
|
||||
<zs:maximumRecords>10</zs:maximumRecords>
|
||||
<zs:recordPacking>xml</zs:recordPacking>
|
||||
<zs:recordSchema>marcxml</zs:recordSchema>
|
||||
</zs:echoedSearchRetrieveRequest>
|
||||
</zs:searchRetrieveResponse>
|
||||
"""
|
||||
return xml
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sru_api_factory(monkeypatch) -> Callable[[str, Optional[bytes]], sru.Api]:
|
||||
"""Factory to create an `sru.Api` (or subclass) with network calls mocked.
|
||||
|
||||
Usage:
|
||||
def test_x(sru_api_factory, sample_sru_xml):
|
||||
api = sru_api_factory('SWB', sample_sru_xml)
|
||||
books = api.getBooks(['pica.tit=Example'])
|
||||
|
||||
The fixture monkeypatches requests.Session.get on the Api instance to return
|
||||
a fake Response with the provided bytes payload. If `response_bytes` is
|
||||
None the real network call will be performed (not recommended in unit tests).
|
||||
"""
|
||||
|
||||
def _make(site: str, response_bytes: Optional[bytes] = None) -> sru.Api:
|
||||
mapping = {"SWB": sru.SWB, "DNB": sru.Api}
|
||||
if site == "SWB":
|
||||
api = sru.SWB()
|
||||
elif site == "DNB":
|
||||
# DNB Api class is the base Api configured differently in sru module
|
||||
api = sru.Api(
|
||||
sru.DNBData.NAME.value,
|
||||
sru.DNBData.URL.value,
|
||||
sru.DNBData.ARGSCHEMA.value,
|
||||
)
|
||||
else:
|
||||
# allow custom site/url/prefix via tuple passed as site: (site, url, prefix)
|
||||
if isinstance(site, tuple) and len(site) == 3:
|
||||
api = sru.Api(site[0], site[1], site[2])
|
||||
else:
|
||||
raise ValueError("Unknown site for factory: %r" % (site,))
|
||||
|
||||
if response_bytes is not None:
|
||||
|
||||
class FakeResp:
|
||||
status_code = 200
|
||||
|
||||
def __init__(self, content: bytes):
|
||||
self.content = content
|
||||
|
||||
def fake_get(url, headers=None, timeout=None):
|
||||
return FakeResp(response_bytes)
|
||||
|
||||
# Patch only this instance's session.get
|
||||
monkeypatch.setattr(api._session, "get", fake_get)
|
||||
|
||||
return api
|
||||
|
||||
return _make
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sru_data():
|
||||
return {"bib_id": 20735, "sigil": "Frei129"}
|
||||
Reference in New Issue
Block a user