Skip to content
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "folioclient"
version = "1.0.4"
version = "1.0.5"
description = "An API wrapper over the FOLIO LSP API Suite (Formerly OKAPI)."
authors = [
{ name = "Theodor Tolstoy", email = "github.teddes@tolstoy.se" },
Expand Down
1 change: 1 addition & 0 deletions src/folioclient/FolioClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ def __exit__(self, exc_type, exc_value, traceback):
and not self.httpx_client.is_closed
):
logger.info("logging out...")
self.folio_auth.reset_tenant_id()
logout = self.httpx_client.post(
urljoin(self.gateway_url, "authn/logout"),
)
Expand Down
17 changes: 17 additions & 0 deletions tests/integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
FolioPermissionError,
FolioResourceNotFoundError,
FolioValidationError,
FolioClientClosed,
)


Expand Down Expand Up @@ -451,6 +452,22 @@ def test_ecs_members_property(self, folio_client):
assert isinstance(member, dict)
assert "id" in member

def test_context_manager_logout_after_tenant_switch(self, folio_client_ecs):
"""Verify __exit__ logs out cleanly after switching to a member tenant."""
members = folio_client_ecs.ecs_members
if not members:
pytest.skip("No ECS member tenants available for logout test")

member_tenant = members[0]["id"]

with folio_client_ecs as client:
client.tenant_id = member_tenant
assert client.tenant_id == member_tenant

assert client.is_closed is True
with pytest.raises(FolioClientClosed):
_ = client.cookies

@pytest.mark.skip(reason="ECS functionality not available in snapshot environment")
def test_ecs_central_tenant_id_setter(self, folio_client):
"""Test setting ecs_central_tenant_id."""
Expand Down
23 changes: 23 additions & 0 deletions tests/test_folio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pytest
from httpx import HTTPError, UnsupportedProtocol
from unittest.mock import Mock, patch, MagicMock, AsyncMock
from urllib.parse import urljoin
import httpx

# Import shared test utilities
Expand Down Expand Up @@ -280,6 +281,28 @@ def test_context_manager_closes_client():
assert fc.is_closed is True


@patch.object(FolioClient, '_initial_ecs_check')
def test_context_manager_logs_out_on_exit(mock_ecs_check):
with folio_auth_patcher():
mock_logout_response = Mock()
mock_logout_response.raise_for_status.return_value = None

mock_httpx_client = Mock()
mock_httpx_client.is_closed = False
mock_httpx_client.post.return_value = mock_logout_response
mock_httpx_client.close = Mock()

logout_url = urljoin("https://example.com", "authn/logout")

with patch.object(FolioClient, 'get_folio_http_client', return_value=mock_httpx_client):
with FolioClient("https://example.com", "tenant", "user", "pass") as fc:
fc.folio_auth.reset_tenant_id = Mock()

mock_httpx_client.post.assert_called_once_with(logout_url)
mock_httpx_client.close.assert_called_once()
fc.folio_auth.reset_tenant_id.assert_called_once()


@pytest.mark.asyncio
async def test_async_context_manager_closes_client():
with folio_auth_patcher() as mock_folio_auth:
Expand Down