feat(listening): interactive listening comprehension trainer with neural voiceover and auto-evaluation
This commit is contained in:
@@ -2280,6 +2280,76 @@ def test_piper_tts_endpoints_and_caching():
|
||||
assert "/api/audio/" in card_data["context_audio_url"]
|
||||
|
||||
|
||||
def test_listening_exercise_and_check():
|
||||
login_resp = client.post("/api/login", json={"username": "testadmin", "password": "testpass12345"})
|
||||
assert login_resp.status_code == 200
|
||||
token = login_resp.cookies.get(config.SESSION_COOKIE_NAME)
|
||||
auth_headers = {"Cookie": f"{config.SESSION_COOKIE_NAME}={token}"}
|
||||
|
||||
# 1. Fetch listening exercise for tech topic
|
||||
resp = client.get("/api/listening/exercise?topic=tech&level=B1", headers=auth_headers)
|
||||
assert resp.status_code == 200
|
||||
ex = resp.json()
|
||||
assert "id" in ex
|
||||
assert ex["topic"] == "tech"
|
||||
assert "story" in ex
|
||||
assert "question" in ex
|
||||
assert "/api/audio/" in ex["story_audio_url"]
|
||||
assert "/api/audio/" in ex["question_audio_url"]
|
||||
# Check that client cannot inspect ideal_answer or keywords before submitting
|
||||
assert "ideal_answer" not in ex
|
||||
assert "keywords" not in ex
|
||||
|
||||
# 2. Check evaluation: correct answer for tech-01
|
||||
check_resp = client.post(
|
||||
"/api/listening/check",
|
||||
json={
|
||||
"scenario_id": "tech-01",
|
||||
"user_answer": "At midnight to minimize downtime",
|
||||
},
|
||||
headers=auth_headers,
|
||||
)
|
||||
assert check_resp.status_code == 200
|
||||
res = check_resp.json()
|
||||
assert res["is_correct"] is True
|
||||
assert res["score"] == 100
|
||||
assert "midnight" in res["ideal_answer"].lower()
|
||||
assert "story" in res
|
||||
assert "story_ru" in res
|
||||
|
||||
# 3. Check evaluation: wrong answer for tech-01
|
||||
check_wrong = client.post(
|
||||
"/api/listening/check",
|
||||
json={
|
||||
"scenario_id": "tech-01",
|
||||
"user_answer": "Tomorrow morning at sunrise",
|
||||
},
|
||||
headers=auth_headers,
|
||||
)
|
||||
assert check_wrong.status_code == 200
|
||||
res_wrong = check_wrong.json()
|
||||
assert res_wrong["is_correct"] is False
|
||||
assert res_wrong["score"] < 50
|
||||
|
||||
# 4. Check exercise from user's vocabulary cards
|
||||
# First ensure a card with context sentence exists
|
||||
client.post(
|
||||
"/api/cards",
|
||||
json={
|
||||
"term": "refactoring",
|
||||
"translation": "рефакторинг",
|
||||
"context_sentence": "Clean architecture requires continuous refactoring of legacy components.",
|
||||
},
|
||||
headers=auth_headers,
|
||||
)
|
||||
card_ex_resp = client.get("/api/listening/exercise?topic=cards", headers=auth_headers)
|
||||
assert card_ex_resp.status_code == 200
|
||||
card_ex = card_ex_resp.json()
|
||||
assert card_ex["topic"] == "cards"
|
||||
assert "/api/audio/" in card_ex["story_audio_url"]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user