from __future__ import annotations import pytest from fastapi import HTTPException from investibook.api import workspaces as workspaces_api from investibook.db import queries as dbq from investibook.models.requests import SessionPayload @pytest.fixture def workspace_session_db(tmp_path, monkeypatch): monkeypatch.setattr(workspaces_api, "schedule_session_prewarm", lambda **_: True) monkeypatch.setattr(dbq, "DB_PATH", tmp_path / "workspace-session.db") dbq._db_init() owner = dbq._db_get_or_create_user("workspace-owner@example.com") viewer = dbq._db_get_or_create_user("workspace-viewer@example.com") now = dbq._utc_now() dbq._db_upsert_workspace( "ws-readonly-session", owner["id"], "Readonly session workspace", "", False, now, now, ) return owner, viewer @pytest.mark.asyncio async def test_readonly_workspace_viewer_can_load_session(workspace_session_db): owner, viewer = workspace_session_db owner_session = await workspaces_api.get_session("ws-readonly-session", owner) viewer_session = await workspaces_api.get_session("ws-readonly-session", viewer) assert owner_session["session_id"].startswith("ses_") assert viewer_session["session_id"] == owner_session["session_id"] with dbq._db_lock: conn = dbq._db_connect() row = conn.execute( "SELECT user_id FROM agent_sessions WHERE id = ?", (owner_session["session_id"],), ).fetchone() conn.close() assert row["user_id"] == owner["id"] @pytest.mark.asyncio async def test_readonly_workspace_viewer_can_load_without_existing_session( workspace_session_db, ): _, viewer = workspace_session_db session = await workspaces_api.get_session("ws-readonly-session", viewer) assert session == {"session_id": ""} @pytest.mark.asyncio async def test_readonly_workspace_viewer_cannot_write_session(workspace_session_db): _, viewer = workspace_session_db with pytest.raises(HTTPException) as exc: await workspaces_api.post_session( "ws-readonly-session", SessionPayload(session_id="ses_viewer_attempt"), viewer, ) assert exc.value.status_code == 403