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""" 1.1 1 marcxml xml -----nam a22 PPN123 Example Title Subtitle 2001 Example Publisher 1 1.1 pica.tit=Example 10 xml marcxml """ 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"}