import logging from typing import Any, Callable, Optional, cast import pytest from utils.sharepoint.sharepoint_client import ( ResourceNotFoundError, api_call_decorator, # pyright: ignore[reportUnknownVariableType] ) # The legacy decorator is untyped; cast so this module stays pyright-strict. _decorate = cast( Callable[[Callable[..., Any]], Callable[..., Any]], api_call_decorator ) class _FakeResponse: def __init__(self, status_code: int, error_code: str, message: str) -> None: self.status_code = status_code self._error_code = error_code self._message = message self.headers: dict[str, str] = {} def json(self) -> dict[str, Any]: return {"error": {"code": self._error_code, "message": self._message}} class _FakeClient: headers: Optional[dict[str, str]] = {} def is_access_token_expired(self) -> bool: return False @_decorate def fetch(self, path: str) -> Any: return "GET", f"https://graph.example.invalid/root:/{path}:/children", None def _patch_response( monkeypatch: pytest.MonkeyPatch, response: _FakeResponse ) -> None: def fake_request(*args: Any, **kwargs: Any) -> _FakeResponse: return response monkeypatch.setattr( "utils.sharepoint.sharepoint_client.requests.request", fake_request ) def test_404_raises_resource_not_found_without_error_logs( monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture ) -> None: # Arrange _patch_response( monkeypatch, _FakeResponse(404, "itemNotFound", "The resource could not be found."), ) # Act with pytest.raises(ResourceNotFoundError): _FakeClient().fetch("missing/folder") # Assert error_records = [r for r in caplog.records if r.levelno >= logging.ERROR] assert error_records == [] def test_other_client_errors_still_log_at_error_level( monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture ) -> None: # Arrange _patch_response( monkeypatch, _FakeResponse(403, "accessDenied", "Access denied.") ) # Act with pytest.raises(ValueError): _FakeClient().fetch("forbidden/folder") # Assert assert any(r.levelno >= logging.ERROR for r in caplog.records)