세션 평가와 교수자 분석 보강
This commit is contained in:
parent
5c4ac04e06
commit
fe2796f05a
51 changed files with 4928 additions and 240 deletions
|
|
@ -160,6 +160,152 @@ class LearnerSessionIdorTest(unittest.IsolatedAsyncioTestCase):
|
|||
self.assertIn("does not belong", caught.exception.detail)
|
||||
review_ready.assert_not_awaited()
|
||||
|
||||
async def test_super_admin_primary_learner_can_review_other_learner_session(self) -> None:
|
||||
owner = _principal(
|
||||
user_id="00000000-0000-0000-0000-000000000103",
|
||||
)
|
||||
super_admin = Principal(
|
||||
user_id="00000000-0000-0000-0000-000000000303",
|
||||
role=Role.LEARNER,
|
||||
admin_access=True,
|
||||
super_admin=True,
|
||||
email="yunchan@twentyoz.kr",
|
||||
display_name="Yun Chan",
|
||||
)
|
||||
sess = _session(
|
||||
session_id="00000000-0000-0000-0000-00000000a103",
|
||||
learner_id=owner.user_id,
|
||||
)
|
||||
store.put(sess)
|
||||
|
||||
with (
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_session",
|
||||
AsyncMock(return_value=None),
|
||||
) as load_session,
|
||||
patch.object(sessions.turn_runtime, "runtime_fallback_allowed", return_value=True),
|
||||
):
|
||||
loaded, review_principal = await sessions._load_review_session_or_404(
|
||||
sess.session_id,
|
||||
super_admin,
|
||||
)
|
||||
|
||||
self.assertIs(loaded, sess)
|
||||
self.assertEqual(review_principal.role, Role.ADMIN)
|
||||
self.assertEqual(load_session.await_count, 2)
|
||||
|
||||
async def test_super_admin_primary_learner_review_loaders_use_admin_principal(self) -> None:
|
||||
owner = _principal(
|
||||
user_id="00000000-0000-0000-0000-000000000105",
|
||||
)
|
||||
super_admin = Principal(
|
||||
user_id="00000000-0000-0000-0000-000000000305",
|
||||
role=Role.LEARNER,
|
||||
admin_access=True,
|
||||
super_admin=True,
|
||||
email="yunchan@twentyoz.kr",
|
||||
display_name="Yun Chan",
|
||||
)
|
||||
sess = _session(
|
||||
session_id="00000000-0000-0000-0000-00000000a105",
|
||||
learner_id=owner.user_id,
|
||||
)
|
||||
sess.ended = True
|
||||
sess.ended_at = 1_800_000_120.0
|
||||
sess.turns.extend(
|
||||
[
|
||||
_turn(seq=1, speaker="counselor", text="admin-visible learner turn"),
|
||||
_turn(seq=2, speaker="client", text="admin-visible client turn"),
|
||||
]
|
||||
)
|
||||
store.put(sess)
|
||||
|
||||
with (
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_session",
|
||||
AsyncMock(return_value=None),
|
||||
),
|
||||
patch.object(sessions.turn_runtime, "runtime_fallback_allowed", return_value=True),
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_session_evaluation",
|
||||
AsyncMock(return_value=(None, False)),
|
||||
) as load_session_evaluation,
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_case_worksheet",
|
||||
AsyncMock(return_value=(None, False)),
|
||||
) as load_case_worksheet,
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_session_review_status",
|
||||
AsyncMock(
|
||||
return_value=(
|
||||
{
|
||||
"status": "viewed",
|
||||
"reviewer_id": "00000000-0000-0000-0000-000000000999",
|
||||
},
|
||||
True,
|
||||
)
|
||||
),
|
||||
) as load_session_review_status,
|
||||
):
|
||||
response = await sessions.get_session_review(sess.session_id, super_admin)
|
||||
|
||||
load_session_evaluation.assert_awaited_once()
|
||||
load_case_worksheet.assert_awaited_once()
|
||||
load_session_review_status.assert_awaited_once()
|
||||
|
||||
evaluation_principal = load_session_evaluation.await_args.args[1]
|
||||
worksheet_principal = load_case_worksheet.await_args.args[1]
|
||||
review_status_principal = load_session_review_status.await_args.args[1]
|
||||
|
||||
self.assertEqual(load_session_evaluation.await_args.args[0], sess.session_id)
|
||||
self.assertEqual(load_case_worksheet.await_args.args[0], sess.session_id)
|
||||
self.assertEqual(load_session_review_status.await_args.args[0], sess.session_id)
|
||||
self.assertIs(evaluation_principal, worksheet_principal)
|
||||
self.assertIs(evaluation_principal, review_status_principal)
|
||||
self.assertEqual(evaluation_principal.user_id, super_admin.user_id)
|
||||
self.assertEqual(evaluation_principal.role, Role.ADMIN)
|
||||
self.assertTrue(evaluation_principal.super_admin)
|
||||
self.assertEqual(response.session_id, sess.session_id)
|
||||
self.assertIsNotNone(response.teacherReview)
|
||||
self.assertEqual(response.teacherReview.status, "viewed")
|
||||
|
||||
async def test_admin_access_flag_alone_does_not_review_other_learner_session(self) -> None:
|
||||
owner = _principal(
|
||||
user_id="00000000-0000-0000-0000-000000000104",
|
||||
)
|
||||
delegated_admin = Principal(
|
||||
user_id="00000000-0000-0000-0000-000000000304",
|
||||
role=Role.LEARNER,
|
||||
admin_access=True,
|
||||
super_admin=False,
|
||||
email="delegate@example.test",
|
||||
display_name="Delegated Admin",
|
||||
)
|
||||
sess = _session(
|
||||
session_id="00000000-0000-0000-0000-00000000a104",
|
||||
learner_id=owner.user_id,
|
||||
)
|
||||
store.put(sess)
|
||||
|
||||
with (
|
||||
patch.object(
|
||||
sessions.session_persistence,
|
||||
"load_session",
|
||||
AsyncMock(return_value=None),
|
||||
),
|
||||
patch.object(sessions.turn_runtime, "runtime_fallback_allowed", return_value=True),
|
||||
):
|
||||
with self.assertRaises(HTTPException) as caught:
|
||||
await sessions._load_review_session_or_404(sess.session_id, delegated_admin)
|
||||
|
||||
self.assertEqual(caught.exception.status_code, 403)
|
||||
self.assertIn("does not belong", caught.exception.detail)
|
||||
|
||||
async def test_session_detail_filters_evaluator_only_turns(self) -> None:
|
||||
owner = _principal(
|
||||
user_id="00000000-0000-0000-0000-000000000111",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue