"""Community forum: categories, sorting, search, safe body rendering, and the in-place migration for boards created before categories existed.""" import sqlite3 import pytest import forum @pytest.fixture(autouse=True) def board(tmp_path, monkeypatch): monkeypatch.setattr(forum, "_DB_PATH", str(tmp_path / "forum.db")) def test_categories_filter_and_validate(): forum.create_thread("a", "x", "body", "mining") forum.create_thread("b", "x", "body", "wallets") assert [t["title"] for t in forum.list_threads(category="mining")["threads"]] == ["a"] assert forum.stats()["per_category"]["wallets"] == 1 with pytest.raises(ValueError): forum.create_thread("c", "x", "body", "not-a-category") def test_sorts_and_unanswered(): quiet = forum.create_thread("quiet", "x", "body") busy = forum.create_thread("busy", "x", "body") forum.add_reply(busy["id"], "y", "one") forum.add_reply(busy["id"], "z", "two") assert forum.list_threads(sort="top")["threads"][0]["id"] == busy["id"] forum.vote("t", busy["id"], "v", "n", 1) unanswered = forum.list_threads(sort="unanswered") assert [t["id"] for t in unanswered["threads"]] == [quiet["id"]] top = forum.list_threads(sort="top")["threads"][0] assert top["last_author"] == "z" and top["voice_count"] == 3 def test_search_treats_wildcards_literally(): forum.create_thread("100% uptime", "x", "body") forum.create_thread("plain", "x", "body") assert forum.list_threads(q="100%")["total"] == 1 assert forum.list_threads(q="%")["total"] == 1 assert forum.list_threads(q="_")["total"] == 0 def test_render_body_escapes_and_formats(): html = str(forum.render_body("\n\n> said `y`\nhttp://e.x/a?b=1&c=2.")) assert "