From e7a413e745ae73bce545771b184d309bb2ea958a Mon Sep 17 00:00:00 2001 From: Marian Date: Mon, 20 Jul 2026 13:40:30 +0000 Subject: [PATCH] feat(oidc): apply the env provider during startup Placed after init_db(): is_env_managed only exists once run_migrations has added it, so an upsert before that would fail on every existing installation. The wiring gets its own tests because the apply tests cannot cover it -- they call apply_env_oidc_provider() directly, so deleting this call would leave the feature dead with a fully green suite. Verified: removing the call fails the three startup tests while all seven apply tests still pass. They assert against the lifespan's source rather than running it. The function is ~460 lines and starts printer connections, MQTT and schedulers; executing it would exercise everything except the line in question. The docstring says plainly that this proves the call exists and runs after migrations, and proves nothing about its behaviour. Refs #2593 --- backend/app/main.py | 8 ++++ .../integration/test_oidc_env_startup.py | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 backend/tests/integration/test_oidc_env_startup.py diff --git a/backend/app/main.py b/backend/app/main.py index 378feb178..c39358880 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -6194,6 +6194,14 @@ async def lifespan(app: FastAPI): await init_db() + # After migrations, so the is_env_managed column exists. Never raises -- + # a bad BAMBUDDY_OIDC_* value is logged and skipped rather than blocking + # startup (see apply_env_oidc_provider). + from backend.app.core.oidc_env import apply_env_oidc_provider + + async with async_session() as oidc_db: + await apply_env_oidc_provider(oidc_db) + # Register an app-scoped httpx client for Bambu Cloud services so # per-request BambuCloudService instances reuse the same connection pool # (important for routes like /cloud/filament-info that chain many diff --git a/backend/tests/integration/test_oidc_env_startup.py b/backend/tests/integration/test_oidc_env_startup.py new file mode 100644 index 000000000..d75c61c00 --- /dev/null +++ b/backend/tests/integration/test_oidc_env_startup.py @@ -0,0 +1,43 @@ +"""The env provider is applied on startup, not merely appliable (#2593). + +test_oidc_env_apply.py calls apply_env_oidc_provider() directly, so it stays +green even if nothing ever calls it -- deleting the lifespan call would leave +the feature dead with a fully passing suite. These tests pin the call site. + +They read the lifespan's source rather than running it: the function is ~460 +lines and starts printer connections, MQTT and schedulers, so executing it +here would test everything except the one line in question. That makes this a +wiring check, not a behavioural one -- it proves the call exists and runs +after migrations, and deliberately proves nothing about what it does. The +behaviour is covered by test_oidc_env_apply.py. +""" + +from __future__ import annotations + +import inspect + +from backend.app.main import lifespan + + +def _lifespan_source() -> str: + return inspect.getsource(lifespan) + + +def test_lifespan_applies_the_env_oidc_provider(): + assert "apply_env_oidc_provider(" in _lifespan_source() + + +def test_it_runs_after_the_migrations(): + """is_env_managed does not exist until run_migrations has added it, so an + upsert before init_db() would fail on every existing installation.""" + source = _lifespan_source() + assert source.index("await init_db()") < source.index("apply_env_oidc_provider(") + + +def test_the_apply_call_is_awaited(): + """apply_env_oidc_provider is a coroutine; calling it without await would + return an un-awaited coroutine and silently apply nothing.""" + source = _lifespan_source() + call = source.index("apply_env_oidc_provider(") + line_start = source.rindex("\n", 0, call) + 1 + assert source[line_start:call].strip().endswith("await")