feat(cefr): dual mistake ingestion, 1-tap options breakdown, and 260 curated questions
This commit is contained in:
+36
-8
@@ -1376,10 +1376,10 @@ def test_cefr_testing_and_gap_ingestion():
|
||||
assert len(levels) == 4
|
||||
level_map = {l["level"]: l for l in levels}
|
||||
assert "A1" in level_map and "A2" in level_map and "B1" in level_map and "B2" in level_map
|
||||
assert level_map["A1"]["total_questions"] == 40
|
||||
assert level_map["A2"]["total_questions"] == 40
|
||||
assert level_map["B1"]["total_questions"] == 40
|
||||
assert level_map["B2"]["total_questions"] == 40
|
||||
assert level_map["A1"]["total_questions"] >= 65
|
||||
assert level_map["A2"]["total_questions"] >= 65
|
||||
assert level_map["B1"]["total_questions"] >= 65
|
||||
assert level_map["B2"]["total_questions"] >= 65
|
||||
|
||||
# 4. Fetch quiz batch
|
||||
quiz_res = client.get("/api/cefr/quiz?level=A2&count=5")
|
||||
@@ -1393,8 +1393,12 @@ def test_cefr_testing_and_gap_ingestion():
|
||||
assert "clue" in q1
|
||||
assert len(q1["options"]) == 4
|
||||
|
||||
# 5. Answer INCORRECTLY -> Automated Gap Ingestion into SRS!
|
||||
wrong_opt = "__completely_wrong_option__"
|
||||
# 5. Answer INCORRECTLY -> Automated Dual Gap Ingestion (target + selected option)
|
||||
# Pick a distractor from the question's actual options
|
||||
# Find option that is not correct (we test with the first distractor)
|
||||
# Let's inspect options and find one that is wrong
|
||||
wrong_opt = [opt for opt in q1["options"] if opt.lower() != q1.get("term", "").lower()][0]
|
||||
|
||||
ans_wrong = client.post("/api/cefr/answer", json={
|
||||
"question_id": q1["id"],
|
||||
"selected_option": wrong_opt
|
||||
@@ -1402,12 +1406,15 @@ def test_cefr_testing_and_gap_ingestion():
|
||||
assert ans_wrong.status_code == 200
|
||||
w_data = ans_wrong.json()
|
||||
assert w_data["correct"] is False
|
||||
assert w_data["card_created"] is True
|
||||
assert w_data["card_created"] is True or w_data["card_updated"] is True
|
||||
assert w_data["card_id"] is not None
|
||||
assert w_data["correct_option"] != ""
|
||||
assert w_data["explanation"] != ""
|
||||
assert w_data["selected_card_id"] is not None
|
||||
assert w_data["selected_card_term"] == wrong_opt
|
||||
assert len(w_data["options_breakdown"]) == 4
|
||||
|
||||
# Verify the card was actually created in vocabulary_cards with state 'learning' and level tag
|
||||
# Verify target word card in SRS
|
||||
card_res = client.get(f"/api/cards/{w_data['card_id']}")
|
||||
assert card_res.status_code == 200
|
||||
ingested_card = card_res.json()
|
||||
@@ -1415,6 +1422,27 @@ def test_cefr_testing_and_gap_ingestion():
|
||||
assert "level-a2" in ingested_card["tags"]
|
||||
assert "cefr-test" in ingested_card["tags"]
|
||||
|
||||
# Verify selected distractor card in SRS
|
||||
sel_card_res = client.get(f"/api/cards/{w_data['selected_card_id']}")
|
||||
assert sel_card_res.status_code == 200
|
||||
sel_card = sel_card_res.json()
|
||||
assert sel_card["srs_state"] == "learning"
|
||||
assert "level-a2" in sel_card["tags"]
|
||||
assert "cefr-test" in sel_card["tags"]
|
||||
|
||||
# Test manual ingestion of remaining option via /api/cefr/add-word
|
||||
other_opt = [opt for opt in q1["options"] if opt != w_data["correct_option"] and opt != wrong_opt][0]
|
||||
add_word_res = client.post("/api/cefr/add-word", json={
|
||||
"level": "A2",
|
||||
"term": other_opt,
|
||||
"context_sentence": q1["sentence"]
|
||||
})
|
||||
assert add_word_res.status_code == 200
|
||||
add_word_data = add_word_res.json()
|
||||
assert add_word_data["status"] == "ok"
|
||||
assert add_word_data["card_id"] is not None
|
||||
assert add_word_data["term"] == other_opt
|
||||
|
||||
# 6. Check that mode='mistakes' returns this question
|
||||
mistakes_res = client.get("/api/cefr/quiz?level=A2&mode=mistakes")
|
||||
assert mistakes_res.status_code == 200
|
||||
|
||||
Reference in New Issue
Block a user