helix.fhir.client.sdk 4.2.15__py3-none-any.whl → 4.2.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,155 @@
1
+ """
2
+ Tests for RetryableAioHttpClient session lifecycle management.
3
+
4
+ This module tests that sessions are properly closed or kept open depending on
5
+ whether they were created internally or provided by the user.
6
+ """
7
+
8
+ import aiohttp
9
+ import pytest
10
+
11
+ from helix_fhir_client_sdk.utilities.retryable_aiohttp_client import RetryableAioHttpClient
12
+
13
+
14
+ @pytest.mark.asyncio
15
+ async def test_internal_session_is_closed_after_exit() -> None:
16
+ """Test that internally created sessions are closed when context exits"""
17
+ client = RetryableAioHttpClient(
18
+ retries=1,
19
+ refresh_token_func=None,
20
+ tracer_request_func=None,
21
+ fn_get_session=None, # No custom factory - SDK will create session
22
+ use_data_streaming=False,
23
+ access_token=None,
24
+ access_token_expiry_date=None,
25
+ )
26
+
27
+ async with client:
28
+ # Session should be created
29
+ assert client.session is not None
30
+ assert not client.session.closed
31
+ session_ref = client.session
32
+
33
+ # After exiting context, the internal session should be closed
34
+ assert session_ref.closed
35
+
36
+
37
+ @pytest.mark.asyncio
38
+ async def test_user_provided_session_is_not_closed_after_exit() -> None:
39
+ """Test that user-provided sessions are NOT closed when context exits"""
40
+ # User creates their own session
41
+ user_session = aiohttp.ClientSession()
42
+
43
+ try:
44
+ # Provide a factory that returns the user's session
45
+ # Since fn_get_session is provided, SDK will NOT close the session
46
+ client = RetryableAioHttpClient(
47
+ retries=1,
48
+ refresh_token_func=None,
49
+ tracer_request_func=None,
50
+ fn_get_session=lambda: user_session, # User provides a custom factory
51
+ use_data_streaming=False,
52
+ access_token=None,
53
+ access_token_expiry_date=None,
54
+ )
55
+
56
+ async with client:
57
+ # Session should be the user's session
58
+ assert client.session is user_session
59
+ assert not client.session.closed
60
+
61
+ # After exiting context, the user's session should still be open
62
+ # because fn_get_session was provided (caller manages session lifecycle)
63
+ assert not user_session.closed
64
+
65
+ finally:
66
+ # User closes their own session
67
+ await user_session.close()
68
+ assert user_session.closed
69
+
70
+
71
+ @pytest.mark.asyncio
72
+ async def test_multiple_clients_can_share_user_session() -> None:
73
+ """Test that multiple RetryableAioHttpClient instances can share the same user session"""
74
+ # User creates a persistent session
75
+ shared_session = aiohttp.ClientSession()
76
+
77
+ try:
78
+ # Multiple clients share the same session
79
+ async with RetryableAioHttpClient(
80
+ retries=1,
81
+ refresh_token_func=None,
82
+ tracer_request_func=None,
83
+ fn_get_session=lambda: shared_session,
84
+ use_data_streaming=False,
85
+ access_token=None,
86
+ access_token_expiry_date=None,
87
+ ) as client1:
88
+ assert client1.session is shared_session
89
+ assert not shared_session.closed
90
+
91
+ # Session should still be open after the first client exits
92
+ assert not shared_session.closed
93
+
94
+ # The second client can reuse the same session
95
+ async with RetryableAioHttpClient(
96
+ retries=1,
97
+ refresh_token_func=None,
98
+ tracer_request_func=None,
99
+ fn_get_session=lambda: shared_session,
100
+ use_data_streaming=False,
101
+ access_token=None,
102
+ access_token_expiry_date=None,
103
+ ) as client2:
104
+ assert client2.session is shared_session
105
+ assert not shared_session.closed
106
+
107
+ # Session should still be open after the second client exits
108
+ assert not shared_session.closed
109
+
110
+ finally:
111
+ # User closes the shared session when done
112
+ await shared_session.close()
113
+ assert shared_session.closed
114
+
115
+
116
+ @pytest.mark.asyncio
117
+ async def test_user_can_recreate_closed_session_via_factory() -> None:
118
+ """Test that a user's factory can be called multiple times if session gets closed"""
119
+ call_count = 0
120
+
121
+ def session_factory() -> aiohttp.ClientSession:
122
+ nonlocal call_count
123
+ call_count += 1
124
+ return aiohttp.ClientSession()
125
+
126
+ created_sessions = []
127
+
128
+ try:
129
+ # First client call
130
+ async with RetryableAioHttpClient(
131
+ retries=1,
132
+ refresh_token_func=None,
133
+ tracer_request_func=None,
134
+ fn_get_session=session_factory,
135
+ use_data_streaming=False,
136
+ access_token=None,
137
+ access_token_expiry_date=None,
138
+ ) as client1:
139
+ assert client1.session is not None
140
+ created_sessions.append(client1.session)
141
+ assert call_count == 1 # Factory called once in __aenter__
142
+
143
+ # SDK doesn't close session (caller provided fn_get_session)
144
+ assert created_sessions[0] is not None
145
+ assert not created_sessions[0].closed
146
+
147
+ # User could manually close and recreate via factory if needed
148
+ # (This demonstrates the pattern, though in practice the factory
149
+ # would handle closed session detection)
150
+
151
+ finally:
152
+ # Clean up all created sessions
153
+ for session in created_sessions:
154
+ if session is not None and not session.closed:
155
+ await session.close()