Spaces:
Paused
Paused
| def create_lesson(client): | |
| response = client.post( | |
| "/api/v1/sessions", | |
| json={"topic": "Gravity", "learner_level": "beginner"}, | |
| ) | |
| assert response.status_code == 201 | |
| return response.json()["id"] | |
| def test_complete_teaching_flow(client): | |
| session_id = create_lesson(client) | |
| with client.stream( | |
| "POST", | |
| f"/api/v1/sessions/{session_id}/teach", | |
| json={"text": "Why do things fall?"}, | |
| ) as response: | |
| body = "".join(response.iter_text()) | |
| assert response.status_code == 200 | |
| assert "event: text_delta" in body | |
| assert "event: lesson_payload" in body | |
| assert "event: audio_ready" in body | |
| assert "event: done" in body | |
| session = client.get(f"/api/v1/sessions/{session_id}").json() | |
| assert len(session["messages"]) == 2 | |
| assert len(session["artifacts"]) == 1 | |
| quiz_id = session["artifacts"][0]["quiz"][0]["id"] | |
| answer = client.post( | |
| f"/api/v1/sessions/{session_id}/quiz/{quiz_id}/answer", | |
| json={"answer": "Attracts"}, | |
| ) | |
| assert answer.status_code == 200 | |
| assert answer.json()["is_correct"] is True | |
| assert answer.json()["score"] == 1.0 | |
| def test_input_validation_and_missing_resources(client): | |
| session_id = create_lesson(client) | |
| empty = client.post( | |
| f"/api/v1/sessions/{session_id}/teach", json={"text": " "} | |
| ) | |
| assert empty.status_code == 422 | |
| assert empty.json()["detail"]["code"] == "EMPTY_TRANSCRIPT" | |
| missing = client.get("/api/v1/sessions/not-real") | |
| assert missing.status_code == 404 | |
| def test_audio_and_session_deletion(client): | |
| session_id = create_lesson(client) | |
| client.post( | |
| f"/api/v1/sessions/{session_id}/teach", | |
| json={"text": "Explain gravity."}, | |
| ) | |
| audio_id = "11111111-1111-1111-1111-111111111111" | |
| audio = client.get(f"/api/v1/audio/{audio_id}") | |
| assert audio.status_code == 200 | |
| assert audio.headers["content-type"] == "audio/mpeg" | |
| deleted = client.delete(f"/api/v1/sessions/{session_id}") | |
| assert deleted.status_code == 204 | |
| assert client.get(f"/api/v1/sessions/{session_id}").status_code == 404 | |
| assert client.get(f"/api/v1/audio/{audio_id}").status_code == 404 | |
| def test_live_websocket_voice_turn(client): | |
| session_id = create_lesson(client) | |
| with client.websocket_connect( | |
| f"/api/v1/sessions/{session_id}/live" | |
| ) as websocket: | |
| ready = websocket.receive_json() | |
| assert ready["type"] == "ready" | |
| assert ready["input_audio"]["sample_rate"] == 16000 | |
| assert ready["output_audio"]["sample_rate"] == 24000 | |
| websocket.send_bytes(b"fake-microphone-pcm") | |
| input_transcription = websocket.receive_json() | |
| output_transcription = websocket.receive_json() | |
| audio = websocket.receive_bytes() | |
| lesson_payload = websocket.receive_json() | |
| turn_complete = websocket.receive_json() | |
| assert input_transcription["type"] == "input_transcription" | |
| assert output_transcription["type"] == "output_transcription" | |
| assert audio == b"fake-live-pcm" | |
| assert lesson_payload["type"] == "lesson_payload" | |
| assert turn_complete["type"] == "turn_complete" | |
| session = client.get(f"/api/v1/sessions/{session_id}").json() | |
| assert [message["role"] for message in session["messages"]] == [ | |
| "student", | |
| "teacher", | |
| ] | |
| assert len(session["artifacts"]) == 1 | |