"""Unit tests for SuperAdmin TOTP session tokens.""" import sys from unittest.mock import AsyncMock, MagicMock import pytest from fastapi import HTTPException sys.modules.setdefault("qrcode", MagicMock()) from app.services.totp_session_service import TotpSessionService @pytest.fixture def actor(): user = MagicMock() user.id = "sa-uuid" user.email = "super@example.com" user.totp_secret = "JBSWY3DPEHPK3PXP" return user @pytest.fixture def redis(): store = {} async def get(key): return store.get(key) async def setex(key, ttl, value): store[key] = value async def delete(key): store.pop(key, None) r = AsyncMock() r.get = get r.setex = setex r.delete = delete r._store = store return r @pytest.mark.asyncio class TestTotpSessionService: async def test_create_session_stores_token(self, actor, redis, monkeypatch): monkeypatch.setattr("app.services.totp_session_service.verify_totp", lambda _s, _c: True) result = await TotpSessionService(redis).create_session(actor, "123456") assert "totp_session_token" in result assert result["expires_in_seconds"] > 0 async def test_is_valid_matches_user(self, actor, redis, monkeypatch): monkeypatch.setattr("app.services.totp_session_service.verify_totp", lambda _s, _c: True) created = await TotpSessionService(redis).create_session(actor, "123456") token = created["totp_session_token"] assert await TotpSessionService(redis).is_valid(actor.id, token) is True assert await TotpSessionService(redis).is_valid("other-user", token) is False async def test_create_rejects_invalid_code(self, actor, redis, monkeypatch): monkeypatch.setattr("app.services.totp_session_service.verify_totp", lambda _s, _c: False) with pytest.raises(HTTPException) as exc: await TotpSessionService(redis).create_session(actor, "000000") assert exc.value.status_code == 400 async def test_revoke_clears_token(self, actor, redis, monkeypatch): monkeypatch.setattr("app.services.totp_session_service.verify_totp", lambda _s, _c: True) created = await TotpSessionService(redis).create_session(actor, "123456") token = created["totp_session_token"] await TotpSessionService(redis).revoke(token) assert await TotpSessionService(redis).is_valid(actor.id, token) is False