# retoor from tests.api.quizzes._helpers import ( CHOICE, JSON, NUMERIC, add_question, build_published, create_quiz, publish, signup, ) from tests.conftest import BASE_URL def _frozen_quiz(): session, _ = signup() slug = create_quiz(session, "Frozen quiz") add_question(session, slug, CHOICE) question_uid = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json()[ "questions" ][0]["uid"] publish(session, slug) return session, slug, question_uid def test_publishing_an_empty_quiz_is_refused(app_server, seeded_db): session, _ = signup() slug = create_quiz(session, "Empty quiz") response = publish(session, slug) assert response.status_code == 400 assert "question" in response.json()["error"]["message"] def test_a_refused_publish_leaves_the_quiz_a_draft(app_server, seeded_db): session, _ = signup() slug = create_quiz(session, "Still a draft") publish(session, slug) payload = session.get(f"{BASE_URL}/quizzes/{slug}", headers=JSON).json() assert payload["quiz"]["status"] == "draft" def test_the_builder_lists_the_validation_problems(app_server, seeded_db): session, _ = signup() slug = create_quiz(session, "Checklist quiz") payload = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json() assert payload["validation_errors"] def test_a_free_text_without_criteria_blocks_publishing(app_server, seeded_db): from devplacepy.database import get_table, refresh_snapshot session, _ = signup() slug = create_quiz(session, "Incomplete free text quiz") add_question(session, slug, NUMERIC) refresh_snapshot() quiz = get_table("quizzes").find_one(slug=slug) question = get_table("quiz_questions").find_one(quiz_uid=quiz["uid"], deleted_at=None) get_table("quiz_questions").update( {"uid": question["uid"], "kind": "free_text", "expected_answer": "", "grading_criteria": ""}, ["uid"], ) refresh_snapshot() response = publish(session, slug) assert response.status_code == 400 def test_a_single_choice_without_a_correct_option_blocks_publishing(app_server, seeded_db): from devplacepy.database import get_table, refresh_snapshot session, _ = signup() slug = create_quiz(session, "Broken choice quiz") add_question(session, slug, CHOICE) refresh_snapshot() quiz = get_table("quizzes").find_one(slug=slug) get_table("quiz_options").update_many( [ {"uid": row["uid"], "is_correct": 0} for row in get_table("quiz_options").find(quiz_uid=quiz["uid"], deleted_at=None) ], ["uid"], ) refresh_snapshot() assert publish(session, slug).status_code == 400 def test_publishing_a_complete_quiz_succeeds(app_server, seeded_db): session, _ = signup() slug = create_quiz(session, "Complete quiz") add_question(session, slug, CHOICE) response = publish(session, slug) assert response.status_code == 200 assert response.json()["data"]["status"] == "published" def test_publishing_twice_is_harmless(app_server, seeded_db): session, _ = signup() slug = build_published(session, title="Twice published quiz") assert publish(session, slug).status_code == 200 def test_only_the_owner_can_publish(app_server, seeded_db): owner, _ = signup() slug = create_quiz(owner, "Owner only quiz") add_question(owner, slug, CHOICE) other, _ = signup() assert publish(other, slug).status_code == 404 def test_a_published_quiz_refuses_a_settings_edit(app_server, seeded_db): session, slug, _ = _frozen_quiz() response = session.post( f"{BASE_URL}/quizzes/edit/{slug}", data={"title": "Renamed"}, headers=JSON ) assert response.status_code == 400 def test_a_published_quiz_refuses_a_new_question(app_server, seeded_db): session, slug, _ = _frozen_quiz() assert add_question(session, slug, NUMERIC).status_code == 400 def test_a_published_quiz_refuses_a_question_edit(app_server, seeded_db): session, slug, question_uid = _frozen_quiz() response = session.post( f"{BASE_URL}/quizzes/{slug}/questions/{question_uid}", data=CHOICE, headers=JSON ) assert response.status_code == 400 def test_a_published_quiz_refuses_a_question_delete(app_server, seeded_db): session, slug, question_uid = _frozen_quiz() response = session.post( f"{BASE_URL}/quizzes/{slug}/questions/{question_uid}/delete", headers=JSON ) assert response.status_code == 400 def test_a_published_quiz_refuses_a_reorder(app_server, seeded_db): session, slug, question_uid = _frozen_quiz() response = session.post( f"{BASE_URL}/quizzes/{slug}/questions/reorder", data={"order": question_uid}, headers=JSON, ) assert response.status_code == 400 def test_a_refused_write_leaves_the_question_untouched(app_server, seeded_db): session, slug, question_uid = _frozen_quiz() before = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json()["questions"] session.post( f"{BASE_URL}/quizzes/{slug}/questions/{question_uid}", data={**CHOICE, "prompt": "Rewritten"}, headers=JSON, ) after = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json()["questions"] assert before == after def test_there_is_no_unpublish_route(app_server, seeded_db): session, slug, _ = _frozen_quiz() assert session.post(f"{BASE_URL}/quizzes/{slug}/unpublish", headers=JSON).status_code == 404 def test_delete_still_works_on_a_published_quiz(app_server, seeded_db): session, slug, _ = _frozen_quiz() assert session.post(f"{BASE_URL}/quizzes/delete/{slug}", headers=JSON).status_code == 200 def test_the_builder_renders_read_only_after_publishing(app_server, seeded_db): session, slug, _ = _frozen_quiz() page = session.get(f"{BASE_URL}/quizzes/{slug}/edit").text assert "permanently frozen" in page assert "Add a question" not in page def test_the_publish_flag_disappears_from_the_quiz(app_server, seeded_db): session, slug, _ = _frozen_quiz() payload = session.get(f"{BASE_URL}/quizzes/{slug}", headers=JSON).json() assert payload["quiz"]["viewer_can_edit"] is False assert payload["quiz"]["published_at"]