import pytest from unittest.mock import patch from contextlib import asynccontextmanager from httpx import AsyncClient @pytest.mark.asyncio async def test_transcript_create(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["name"] == "test" assert response.json()["status"] == "idle" assert response.json()["locked"] is False assert response.json()["id"] is not None assert response.json()["created_at"] is not None # ensure some fields are not returned assert "topics" not in response.json() assert "events" not in response.json() @pytest.mark.asyncio async def test_transcript_get_update_name(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["name"] == "test" tid = response.json()["id"] response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["name"] == "test" response = await ac.patch(f"/transcripts/{tid}", json={"name": "test2"}) assert response.status_code == 200 assert response.json()["name"] == "test2" response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["name"] == "test2" @pytest.mark.asyncio async def test_transcript_get_update_locked(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["locked"] is False tid = response.json()["id"] response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["locked"] is False response = await ac.patch(f"/transcripts/{tid}", json={"locked": True}) assert response.status_code == 200 assert response.json()["locked"] is True response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["locked"] is True @pytest.mark.asyncio async def test_transcript_get_update_summary(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["long_summary"] is None assert response.json()["short_summary"] is None tid = response.json()["id"] response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["long_summary"] is None assert response.json()["short_summary"] is None response = await ac.patch( f"/transcripts/{tid}", json={"long_summary": "test_long", "short_summary": "test_short"}, ) assert response.status_code == 200 assert response.json()["long_summary"] == "test_long" assert response.json()["short_summary"] == "test_short" response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["long_summary"] == "test_long" assert response.json()["short_summary"] == "test_short" @pytest.mark.asyncio async def test_transcript_get_update_title(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["title"] is None tid = response.json()["id"] response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["title"] is None response = await ac.patch(f"/transcripts/{tid}", json={"title": "test_title"}) assert response.status_code == 200 assert response.json()["title"] == "test_title" response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["title"] == "test_title" @pytest.mark.asyncio async def test_transcripts_list_anonymous(): # XXX this test is a bit fragile, as it depends on the storage which # is shared between tests from reflector.app import app from reflector.settings import settings async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.get("/transcripts") assert response.status_code == 401 # if public mode, it should be allowed try: settings.PUBLIC_MODE = True async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.get("/transcripts") assert response.status_code == 200 finally: settings.PUBLIC_MODE = False @asynccontextmanager async def authenticated_client_ctx(): from reflector.app import app from reflector.auth import current_user, current_user_optional app.dependency_overrides[current_user] = lambda: { "sub": "randomuserid", "email": "test@mail.com", } app.dependency_overrides[current_user_optional] = lambda: { "sub": "randomuserid", "email": "test@mail.com", } yield del app.dependency_overrides[current_user] del app.dependency_overrides[current_user_optional] @asynccontextmanager async def authenticated_client2_ctx(): from reflector.app import app from reflector.auth import current_user, current_user_optional app.dependency_overrides[current_user] = lambda: { "sub": "randomuserid2", "email": "test@mail.com", } app.dependency_overrides[current_user_optional] = lambda: { "sub": "randomuserid2", "email": "test@mail.com", } yield del app.dependency_overrides[current_user] del app.dependency_overrides[current_user_optional] @pytest.fixture @pytest.mark.asyncio async def authenticated_client(): async with authenticated_client_ctx(): yield @pytest.fixture @pytest.mark.asyncio async def authenticated_client2(): async with authenticated_client2_ctx(): yield @pytest.mark.asyncio async def test_transcripts_list_authenticated(authenticated_client): # XXX this test is a bit fragile, as it depends on the storage which # is shared between tests from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "testxx1"}) assert response.status_code == 200 assert response.json()["name"] == "testxx1" response = await ac.post("/transcripts", json={"name": "testxx2"}) assert response.status_code == 200 assert response.json()["name"] == "testxx2" response = await ac.get("/transcripts") assert response.status_code == 200 assert len(response.json()["items"]) >= 2 names = [t["name"] for t in response.json()["items"]] assert "testxx1" in names assert "testxx2" in names @pytest.mark.asyncio async def test_transcript_delete(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "testdel1"}) assert response.status_code == 200 assert response.json()["name"] == "testdel1" tid = response.json()["id"] response = await ac.delete(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["status"] == "ok" response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 404 @pytest.mark.asyncio async def test_transcript_mark_reviewed(): from reflector.app import app async with AsyncClient(app=app, base_url="http://test/v1") as ac: response = await ac.post("/transcripts", json={"name": "test"}) assert response.status_code == 200 assert response.json()["name"] == "test" assert response.json()["reviewed"] is False tid = response.json()["id"] response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["name"] == "test" assert response.json()["reviewed"] is False response = await ac.patch(f"/transcripts/{tid}", json={"reviewed": True}) assert response.status_code == 200 assert response.json()["reviewed"] is True response = await ac.get(f"/transcripts/{tid}") assert response.status_code == 200 assert response.json()["reviewed"] is True @asynccontextmanager async def patch_migrate_user(): with patch( "reflector.db.migrate_user.users_to_migrate", [["test@mail.com", "randomuserid", None]], ): yield @pytest.mark.asyncio async def test_transcripts_list_authenticated_migration(): # XXX this test is a bit fragile, as it depends on the storage which # is shared between tests from reflector.app import app testx1 = "testmigration1" testx2 = "testmigration2" async with patch_migrate_user(), AsyncClient( app=app, base_url="http://test/v1" ) as ac: # first ensure client 2 does not have any transcripts related to this test async with authenticated_client2_ctx(): response = await ac.get("/transcripts") assert response.status_code == 200 # assert len(response.json()["items"]) == 0 names = [t["name"] for t in response.json()["items"]] assert testx1 not in names assert testx2 not in names # create 2 transcripts with client 1 async with authenticated_client_ctx(): response = await ac.post("/transcripts", json={"name": testx1}) assert response.status_code == 200 assert response.json()["name"] == testx1 response = await ac.post("/transcripts", json={"name": testx2}) assert response.status_code == 200 assert response.json()["name"] == testx2 response = await ac.get("/transcripts") assert response.status_code == 200 assert len(response.json()["items"]) >= 2 names = [t["name"] for t in response.json()["items"]] assert testx1 in names assert testx2 in names # now going back to client 2, migration should happen async with authenticated_client2_ctx(): response = await ac.get("/transcripts") assert response.status_code == 200 names = [t["name"] for t in response.json()["items"]] assert testx1 in names assert testx2 in names # and client 1 should have nothing now async with authenticated_client_ctx(): response = await ac.get("/transcripts") assert response.status_code == 200 names = [t["name"] for t in response.json()["items"]] assert testx1 not in names assert testx2 not in names