|
|
@@ -13,6 +13,7 @@ from backend.app.cli import DEFAULT_KIOSK_KEY_NAME, KioskBootstrapError, kiosk_b
|
|
|
from backend.app.core.auth import _validate_api_key
|
|
|
from backend.app.core.database import Base
|
|
|
from backend.app.models.api_key import APIKey
|
|
|
+from backend.app.models.settings import Settings
|
|
|
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
|
@@ -113,6 +114,45 @@ async def test_bootstrap_force_rotates_existing_key(session_maker):
|
|
|
assert validated.name == DEFAULT_KIOSK_KEY_NAME
|
|
|
|
|
|
|
|
|
+@pytest.mark.asyncio
|
|
|
+@pytest.mark.unit
|
|
|
+async def test_bootstrap_marks_setup_completed(session_maker):
|
|
|
+ """Bootstrap must set setup_completed=true so AuthContext doesn't redirect the kiosk to /setup."""
|
|
|
+ await kiosk_bootstrap(
|
|
|
+ DEFAULT_KIOSK_KEY_NAME,
|
|
|
+ force=False,
|
|
|
+ session_maker=session_maker,
|
|
|
+ ensure_schema=False,
|
|
|
+ )
|
|
|
+
|
|
|
+ async with session_maker() as db:
|
|
|
+ setting = (await db.execute(select(Settings).where(Settings.key == "setup_completed"))).scalar_one()
|
|
|
+ assert setting.value == "true"
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+@pytest.mark.unit
|
|
|
+async def test_bootstrap_setup_idempotent_on_rotate(session_maker):
|
|
|
+ """Re-running with --force must not duplicate the setup_completed row."""
|
|
|
+ await kiosk_bootstrap(
|
|
|
+ DEFAULT_KIOSK_KEY_NAME,
|
|
|
+ force=False,
|
|
|
+ session_maker=session_maker,
|
|
|
+ ensure_schema=False,
|
|
|
+ )
|
|
|
+ await kiosk_bootstrap(
|
|
|
+ DEFAULT_KIOSK_KEY_NAME,
|
|
|
+ force=True,
|
|
|
+ session_maker=session_maker,
|
|
|
+ ensure_schema=False,
|
|
|
+ )
|
|
|
+
|
|
|
+ async with session_maker() as db:
|
|
|
+ rows = (await db.execute(select(Settings).where(Settings.key == "setup_completed"))).scalars().all()
|
|
|
+ assert len(rows) == 1
|
|
|
+ assert rows[0].value == "true"
|
|
|
+
|
|
|
+
|
|
|
@pytest.mark.asyncio
|
|
|
@pytest.mark.unit
|
|
|
async def test_bootstrap_custom_name(session_maker):
|