124 lines
3.9 KiB
Python
124 lines
3.9 KiB
Python
"""Session review public share regression tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from starlette.requests import Request
|
|
|
|
from . import session_persistence
|
|
from .deps import Principal, Role
|
|
from .routes import sessions
|
|
from .routes import share as share_routes
|
|
from .services import persona as persona_service, state_machine
|
|
from .store import InProcSession, TurnRecord, store
|
|
|
|
|
|
def _principal() -> Principal:
|
|
return Principal(
|
|
user_id="00000000-0000-0000-0000-000000000201",
|
|
role=Role.LEARNER,
|
|
cohort_ids=[],
|
|
email="share-test@hs.ac.kr",
|
|
display_name="Share Test",
|
|
consent_at=1.0,
|
|
)
|
|
|
|
|
|
def _request(path: str = "/sessions/share-test-session/share") -> Request:
|
|
return Request(
|
|
{
|
|
"type": "http",
|
|
"method": "POST",
|
|
"path": path,
|
|
"scheme": "https",
|
|
"server": ("api.test", 443),
|
|
"headers": [(b"host", b"api.test")],
|
|
}
|
|
)
|
|
|
|
|
|
def _ended_session(principal: Principal) -> InProcSession:
|
|
card = persona_service.P1
|
|
sess = InProcSession(
|
|
session_id="share-test-session",
|
|
case_id="share-test-case",
|
|
learner_id=principal.user_id,
|
|
persona_code=card.code,
|
|
theory_mode="humanistic",
|
|
persona=card,
|
|
state=state_machine.SessionState(
|
|
resistance=card.base_resistance(),
|
|
ideation_stage=card.ideation_baseline(),
|
|
),
|
|
ended=True,
|
|
ended_at=1_800_000_100,
|
|
)
|
|
sess.turns.extend(
|
|
[
|
|
TurnRecord(
|
|
turn_seq=1,
|
|
speaker="counselor",
|
|
stage="라포",
|
|
text="원문 학습자 민감 발화",
|
|
text_masked="원문 학습자 민감 발화",
|
|
created_at=1_800_000_000,
|
|
),
|
|
TurnRecord(
|
|
turn_seq=2,
|
|
speaker="client",
|
|
stage="라포",
|
|
text="내담자 응답",
|
|
text_masked="내담자 응답",
|
|
created_at=1_800_000_030,
|
|
),
|
|
]
|
|
)
|
|
store.put(sess)
|
|
return sess
|
|
|
|
|
|
class SessionShareTest(unittest.IsolatedAsyncioTestCase):
|
|
async def asyncSetUp(self) -> None:
|
|
store._sessions.clear()
|
|
session_persistence._SESSION_SHARE_CACHE.clear()
|
|
session_persistence._SESSION_SHARE_TOKEN_INDEX.clear()
|
|
|
|
async def asyncTearDown(self) -> None:
|
|
store._sessions.clear()
|
|
session_persistence._SESSION_SHARE_CACHE.clear()
|
|
session_persistence._SESSION_SHARE_TOKEN_INDEX.clear()
|
|
|
|
async def test_create_share_returns_public_summary_without_transcript(self) -> None:
|
|
principal = _principal()
|
|
_ended_session(principal)
|
|
|
|
response = await sessions.create_session_share(
|
|
"share-test-session",
|
|
_request(),
|
|
principal,
|
|
)
|
|
self.assertTrue(response.shareUrl.startswith("https://api.test/share/session/"))
|
|
token = response.shareUrl.rsplit("/", 1)[-1]
|
|
|
|
summary = await share_routes._load_share_or_404(token)
|
|
self.assertIn("Vignette 회기 리뷰", summary.title)
|
|
self.assertNotIn("원문 학습자 민감 발화", summary.model_dump_json())
|
|
self.assertIn("저장된 실제 축어록 2개", summary.summary)
|
|
|
|
async def test_revoke_share_blocks_public_lookup(self) -> None:
|
|
principal = _principal()
|
|
_ended_session(principal)
|
|
|
|
response = await sessions.create_session_share(
|
|
"share-test-session",
|
|
_request(),
|
|
principal,
|
|
)
|
|
token = response.shareUrl.rsplit("/", 1)[-1]
|
|
revoked = await sessions.revoke_session_share("share-test-session", principal)
|
|
self.assertTrue(revoked.revoked)
|
|
|
|
with self.assertRaises(share_routes.HTTPException) as caught:
|
|
await share_routes._load_share_or_404(token)
|
|
self.assertEqual(caught.exception.status_code, 404)
|