|
13 | 13 | 4. switch_profile(process_wide=False) does NOT mutate process globals |
14 | 14 | 5. Concurrent requests on different threads see independent profiles |
15 | 15 | """ |
| 16 | +import logging |
16 | 17 | import os |
17 | 18 | import threading |
18 | 19 | from pathlib import Path |
@@ -230,6 +231,60 @@ def test_configured_profile_cookie_ignores_default_cookie_name(self, monkeypatch |
230 | 231 | assert get_profile_cookie(handler) is None |
231 | 232 |
|
232 | 233 |
|
| 234 | +# ── 1b. Profile cookie name resolution (env > legacy env > default) ─────────── |
| 235 | + |
| 236 | +class TestProfileCookieNameResolution: |
| 237 | + |
| 238 | + def test_default_when_unset(self, monkeypatch): |
| 239 | + from api.helpers import PROFILE_COOKIE_NAME, get_profile_cookie_name |
| 240 | + monkeypatch.delenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', raising=False) |
| 241 | + monkeypatch.delenv('WEBUI_PROFILE_COOKIE_NAME', raising=False) |
| 242 | + assert get_profile_cookie_name() == PROFILE_COOKIE_NAME |
| 243 | + |
| 244 | + def test_canonical_env_overrides_default(self, monkeypatch): |
| 245 | + from api.helpers import get_profile_cookie_name |
| 246 | + monkeypatch.delenv('WEBUI_PROFILE_COOKIE_NAME', raising=False) |
| 247 | + monkeypatch.setenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', 'hermes_profile_alt') |
| 248 | + assert get_profile_cookie_name() == 'hermes_profile_alt' |
| 249 | + |
| 250 | + def test_legacy_env_still_honoured(self, monkeypatch): |
| 251 | + from api.helpers import get_profile_cookie_name |
| 252 | + monkeypatch.delenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', raising=False) |
| 253 | + monkeypatch.setenv('WEBUI_PROFILE_COOKIE_NAME', 'hermes_profile_legacy') |
| 254 | + assert get_profile_cookie_name() == 'hermes_profile_legacy' |
| 255 | + |
| 256 | + def test_canonical_takes_precedence_over_legacy(self, monkeypatch): |
| 257 | + from api.helpers import get_profile_cookie_name |
| 258 | + monkeypatch.setenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', 'canonical') |
| 259 | + monkeypatch.setenv('WEBUI_PROFILE_COOKIE_NAME', 'legacy') |
| 260 | + assert get_profile_cookie_name() == 'canonical' |
| 261 | + |
| 262 | + def test_blank_canonical_falls_back_to_legacy(self, monkeypatch): |
| 263 | + from api.helpers import get_profile_cookie_name |
| 264 | + monkeypatch.setenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', ' ') |
| 265 | + monkeypatch.setenv('WEBUI_PROFILE_COOKIE_NAME', 'hermes_profile_legacy') |
| 266 | + assert get_profile_cookie_name() == 'hermes_profile_legacy' |
| 267 | + |
| 268 | + def test_blank_envs_fall_back_to_default(self, monkeypatch): |
| 269 | + from api.helpers import PROFILE_COOKIE_NAME, get_profile_cookie_name |
| 270 | + monkeypatch.setenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', ' ') |
| 271 | + monkeypatch.setenv('WEBUI_PROFILE_COOKIE_NAME', '') |
| 272 | + assert get_profile_cookie_name() == PROFILE_COOKIE_NAME |
| 273 | + |
| 274 | + def test_legacy_deprecation_warns_only_once(self, monkeypatch, caplog): |
| 275 | + # get_profile_cookie_name() runs on every request, so the deprecation |
| 276 | + # warning for the legacy env var must be emitted once per process. |
| 277 | + import api.helpers as helpers |
| 278 | + monkeypatch.delenv('HERMES_WEBUI_PROFILE_COOKIE_NAME', raising=False) |
| 279 | + monkeypatch.setenv('WEBUI_PROFILE_COOKIE_NAME', 'hermes_profile_legacy') |
| 280 | + monkeypatch.setattr(helpers, '_legacy_profile_cookie_warned', False) |
| 281 | + with caplog.at_level(logging.WARNING, logger='api.helpers'): |
| 282 | + for _ in range(3): |
| 283 | + assert helpers.get_profile_cookie_name() == 'hermes_profile_legacy' |
| 284 | + warned = [r for r in caplog.records if 'deprecated' in r.getMessage()] |
| 285 | + assert len(warned) == 1 |
| 286 | + |
| 287 | + |
233 | 288 | # ── 2. Thread-local request context ────────────────────────────────────────── |
234 | 289 |
|
235 | 290 | class TestThreadLocalProfileContext: |
|
0 commit comments