from pathlib import Path import rdb_discovery.discovery as discovery_mod def test_core_questions_returns_at_least_10_items() -> None: questions = discovery_mod.core_questions() assert len(questions) >= 10 def test_append_creates_file_when_missing(tmp_path: Path) -> None: log_path = tmp_path / "context" / "discovery-log.md" assert not log_path.exists() discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="What problem are we solving?", answer="A great app", confidence="High", follow_up_needed="No", ) assert log_path.exists() def test_append_records_all_fields(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="What problem are we solving?", answer="A great app", confidence="High", follow_up_needed="No", ) content = (tmp_path / "context" / "discovery-log.md").read_text(encoding="utf-8") assert "| Q-001 |" in content assert "What problem are we solving?" in content assert "A great app" in content assert "High" in content assert "No" in content def test_append_escapes_pipe_in_answer(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="What | is this?", answer="A | B", confidence="High", follow_up_needed="No", ) content = (tmp_path / "context" / "discovery-log.md").read_text(encoding="utf-8") # Piped answers should be escaped so the table row doesn't break assert "\\|" in content def test_append_escapes_newline_in_answer(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="Multi\nline?", answer="A\nB\nC", confidence="High", follow_up_needed="No", ) content = (tmp_path / "context" / "discovery-log.md").read_text(encoding="utf-8") # Data rows should each be a single line — no embedded newlines data_lines = [l for l in content.splitlines() if l.startswith("| Q-")] assert len(data_lines) == 1 assert "\n" not in data_lines[0] def test_append_preserves_existing_history(tmp_path: Path) -> None: log_path = tmp_path / "context" / "discovery-log.md" discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="First?", answer="Ans 1", confidence="High", follow_up_needed="No", ) assert log_path.read_text(encoding="utf-8").count("Ans 1") == 1 discovery_mod.append_discovery_answer( tmp_path, question_id="Q-002", question="Second?", answer="Ans 2", confidence="Low", follow_up_needed="Yes", ) content = log_path.read_text(encoding="utf-8") assert "Ans 1" in content assert "Ans 2" in content # Two data rows, not one data_rows = [l for l in content.splitlines() if l.startswith("| Q-")] assert len(data_rows) == 2 def test_read_discovery_answers_returns_dicts(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="What is this?", answer="A thing", confidence="High", follow_up_needed="No", ) answers = discovery_mod.read_discovery_answers(tmp_path) assert len(answers) == 1 assert answers[0]["id"] == "Q-001" assert answers[0]["question"] == "What is this?" assert answers[0]["answer"] == "A thing" assert answers[0]["confidence"] == "High" assert answers[0]["follow_up_needed"] == "No" assert answers[0]["needs_followup"] is False assert answers[0]["low_confidence"] is False def test_read_discovery_answers_returns_empty_when_no_log(tmp_path: Path) -> None: log_path = tmp_path / "context" / "discovery-log.md" assert not log_path.exists() answers = discovery_mod.read_discovery_answers(tmp_path) assert answers == [] def test_read_discovery_answers_detects_low_confidence(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-002", question="How much?", answer="About half", confidence="Low", follow_up_needed="No", ) answers = discovery_mod.read_discovery_answers(tmp_path) low_conf_rows = [a for a in answers if a["low_confidence"]] assert len(low_conf_rows) == 1 assert low_conf_rows[0]["id"] == "Q-002" def test_read_discovery_answers_detects_followup_flag(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-003", question="What next?", answer="TBD", confidence="High", follow_up_needed="Yes", ) answers = discovery_mod.read_discovery_answers(tmp_path) fu_rows = [a for a in answers if a["needs_followup"]] assert len(fu_rows) == 1 assert fu_rows[0]["id"] == "Q-003" def test_append_followup_appends_row(tmp_path: Path) -> None: # First create the log with an existing entry discovery_mod.append_discovery_answer( tmp_path, question_id="Q-010", question="Original?", answer="Original answer", confidence="High", follow_up_needed="No", ) original_count = len(discovery_mod.read_discovery_answers(tmp_path)) discovery_mod.append_followup_answer( tmp_path, question_id="Q-010", follow_up_question="Can you elaborate?", answer="Yes, it's bigger than expected.", confidence="Medium", ) answers = discovery_mod.read_discovery_answers(tmp_path) assert len(answers) == original_count + 1 # The new row should have the original Q-010 id and follow-up data new_row = [a for a in answers if a["question"] == "Can you elaborate?"][0] assert new_row["follow_up_needed"] == "Yes" assert new_row["confidence"] == "Medium" def test_header_is_written_on_create(tmp_path: Path) -> None: discovery_mod.append_discovery_answer( tmp_path, question_id="Q-001", question="Test?", answer="T", confidence="High", follow_up_needed="No", ) content = (tmp_path / "context" / "discovery-log.md").read_text(encoding="utf-8") assert "# Discovery Log" in content assert "| ID | Question | Answer | Confidence | Follow-up needed | Linked decision | Linked task | Date |" in content