File size: 4,771 Bytes
c05106c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""Self-check for the public widget.

The important one is test_unpublished_content_never_leaks: this endpoint is
unauthenticated, so the state/access filter is a trust boundary, not a detail.

Run: python3 test_answer.py
"""
import answer
import mesh

TERMS = ["lunch", "price"]


def test_keywords_drop_question_noise():
    assert answer.keywords("How much is the student lunch?") == ["student", "lunch"]
    assert answer.keywords("Who is the superintendent") == ["superintendent"]
    # A question made entirely of stopwords still yields something to search.
    assert answer.keywords("who is it") == ["who", "is", "it"]


def test_intent_detection():
    for q, want in [("who is the principal", "who"),
                    ("when is spring break", "when"),
                    ("how much does lunch cost", "cost"),
                    ("where is the school", "where"),
                    ("what is the phone number", "contact"),
                    ("is there a lunch menu", "menu"),
                    ("tell me about robotics", "what")]:
        got, _ = answer.intent_of(q)
        assert got == want, f"{q!r} → {got}, expected {want}"


def test_markdown_never_reaches_a_visitor():
    assert answer.clean("**Student Lunch:** $2.85") == "Student Lunch: $2.85"
    assert "**" not in answer.clean("a **b** c **d**")
    assert answer.clean("spaced   out\n\ntext") == "spaced out text"


def test_bare_headings_lose_to_real_sentences():
    """'Superintendent' repeats the question; it must not win as an answer."""
    heading = answer.score_sentence("Superintendent", ["superintendent"], "who")
    real = answer.score_sentence(
        "The superintendent leads the district and reports to the school board.",
        ["superintendent"], "who")
    assert real > heading


def test_fragments_lose_to_complete_sentences():
    frag = answer.score_sentence("For school-specific contacts, visit the", TERMS, "contact")
    whole = answer.score_sentence("For school-specific contacts, visit the office page.",
                                  TERMS, "contact")
    assert whole > frag


def test_intent_boosts_matching_shapes():
    money = answer.score_sentence("Student lunch costs $2.85 each day.", TERMS, "cost")
    plain = answer.score_sentence("Student lunch is served every day here.", TERMS, "cost")
    assert money > plain

    dated = answer.score_sentence("Spring break runs March 24 through March 28.", ["spring"], "when")
    vague = answer.score_sentence("Spring break is a scheduled district holiday.", ["spring"], "when")
    assert dated > vague


def test_unknown_question_says_so_instead_of_guessing():
    r = answer.ask("do you sell unicorns and dragons here")
    assert r["ok"] is False
    assert "could not find" in r["answer"].lower()
    assert r["sources"] == []


def test_real_question_quotes_the_site():
    r = answer.ask("how much is student lunch")
    assert r["ok"] is True
    assert "$" in r["answer"], f"a pricing question should quote a price: {r['answer']!r}"
    assert r["source"]["article_id"] > 0
    assert "**" not in r["answer"]


def test_unpublished_content_never_leaks():
    """Insert an unpublished node, confirm the public search refuses it."""
    db = mesh.grid()
    secret = "zzqx-unpublished-marker"
    rows = [("test.unpub", 999901, "Draft Page", "0", "text", f"{secret} draft", "", 1, 0, 1),
            ("test.private", 999902, "Private Page", "0", "text", f"{secret} private", "", 1, 1, 3),
            ("test.public", 999903, "Public Page", "0", "text", f"{secret} public", "", 1, 1, 1)]
    try:
        for r in rows:
            db.execute("INSERT OR REPLACE INTO nodes VALUES (?,?,?,?,?,?,?,?,?,?)", r)
            db.execute("INSERT INTO nodes_fts(coord,article,type,text,media) VALUES (?,?,?,?,?)",
                       (r[0], r[2], r[4], r[5], r[6]))
        db.commit()

        titles = {h["article"] for h in mesh.public_search(secret)}
        assert "Public Page" in titles, "published public content must be findable"
        assert "Draft Page" not in titles, "UNPUBLISHED CONTENT LEAKED"
        assert "Private Page" not in titles, "ACCESS-RESTRICTED CONTENT LEAKED"

        served = answer.ask(f"{secret} information")
        for bad in ("draft", "private"):
            assert bad not in served["answer"].lower(), f"{bad} content reached the answer"
    finally:
        for r in rows:
            db.execute("DELETE FROM nodes WHERE coord = ?", (r[0],))
            db.execute("DELETE FROM nodes_fts WHERE coord = ?", (r[0],))
        db.commit()


if __name__ == "__main__":
    tests = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
    for t in tests:
        t()
        print(f"  ok  {t.__name__}")
    print(f"\n{len(tests)} checks passed")