@@ -157,6 +157,66 @@ def test_get_tenant_id_from_auth_context():
157157 auth_context_var .reset (token )
158158
159159
160+ @pytest .mark .anyio
161+ async def test_session_tenant_id_set_from_auth_context_on_first_request (init_options : InitializationOptions ):
162+ """Verify session.tenant_id is populated from auth context on the first request.
163+
164+ The lowlevel server sets session.tenant_id from get_tenant_id() on the
165+ first request that has a tenant. This test simulates that behavior directly.
166+ """
167+ server_to_client_send , server_to_client_recv = anyio .create_memory_object_stream [SessionMessage ](1 )
168+ client_to_server_send , client_to_server_recv = anyio .create_memory_object_stream [SessionMessage | Exception ](1 )
169+
170+ async with server_to_client_send , server_to_client_recv , client_to_server_send , client_to_server_recv :
171+ async with ServerSession (
172+ client_to_server_recv ,
173+ server_to_client_send ,
174+ init_options ,
175+ ) as session :
176+ assert session .tenant_id is None
177+
178+ # Simulate what lowlevel/server.py does: set session.tenant_id
179+ # from auth context on first request
180+ access_token = AccessToken (
181+ token = "token-first" ,
182+ client_id = "client" ,
183+ scopes = ["read" ],
184+ expires_at = int (time .time ()) + 3600 ,
185+ tenant_id = "tenant-first" ,
186+ )
187+ user = AuthenticatedUser (access_token )
188+ context_token = auth_context_var .set (user )
189+ try :
190+ tenant_id = get_tenant_id ()
191+ if tenant_id is not None and session .tenant_id is None :
192+ session .tenant_id = tenant_id
193+ finally :
194+ auth_context_var .reset (context_token )
195+
196+ assert session .tenant_id == "tenant-first"
197+
198+ # Simulate a second request with a different tenant —
199+ # session.tenant_id should NOT change (set-once on first request)
200+ access_token2 = AccessToken (
201+ token = "token-second" ,
202+ client_id = "client" ,
203+ scopes = ["read" ],
204+ expires_at = int (time .time ()) + 3600 ,
205+ tenant_id = "tenant-second" ,
206+ )
207+ user2 = AuthenticatedUser (access_token2 )
208+ context_token2 = auth_context_var .set (user2 )
209+ try :
210+ tenant_id = get_tenant_id ()
211+ if tenant_id is not None and session .tenant_id is None :
212+ session .tenant_id = tenant_id
213+ finally :
214+ auth_context_var .reset (context_token2 )
215+
216+ # Still the first tenant — not overwritten
217+ assert session .tenant_id == "tenant-first"
218+
219+
160220@pytest .mark .anyio
161221async def test_tenant_context_isolation_between_concurrent_requests ():
162222 """Verify tenant_id doesn't leak between concurrent async contexts.
0 commit comments