from __future__ import annotations from pathlib import Path FRONTEND = Path(__file__).resolve().parents[1] / "ResearchBee_LibGuides.html" TEXT = FRONTEND.read_text(encoding="utf-8") def between(start: str, end: str) -> str: return TEXT.split(start, 1)[1].split(end, 1)[0] def test_citation_loader_preserves_accordion_container_and_tabs(): loader = between( "window.ResearchBee._loadRelatedWorks = async function(uid)", "// ── Deeper Analysis Strip", ) assert "rwpanel-cited-${uid}" in loader assert "document.getElementById(`rw-${uid}`)" not in loader assert "panel.replaceChildren" not in loader or "renderWorkList(panel" in loader assert "rwpanel-chain-${uid}" in TEXT def test_cover_letter_rendering_has_no_inline_event_handlers(): renderer = between("function renderCoverLetterBtn", "// ── Altmetric badge") generator = between("// ── Cover letter generator", "// ── Subject browse cover letter") subject = between("function renderSubjectQuartileCell", "// ── Export citations") assert "onclick=" not in renderer assert "onclick=" not in generator assert "onclick=" not in subject assert "addEventListener" in renderer assert "textContent" in generator assert "data-cover-id" in renderer def test_related_work_rendering_has_no_inline_handlers_or_raw_html_injection(): related = between("// ── Related works accordion", "// ── Deeper Analysis Strip") citation = between("// ── Citation chaining", "// ── KU Journal Finder Guide card") assert "onclick=" not in related assert "onclick=" not in citation assert "api.openalex.org/works?filter=cites" not in TEXT assert "/api/openalex-cited-by" in citation assert "title.textContent" in related assert "authorLine.textContent" in related def test_subject_table_renders_all_field_quartiles(): assert "function renderSubjectQuartileCell" in TEXT assert "journal.quartiles_by_field" in TEXT assert "Quartile by field" in TEXT assert "subject-q-item" in TEXT