File size: 4,588 Bytes
8b6568e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
116
117
118
119
120
121
"""
Tests for the context-aware intent gate (is_continuation_reply).

Verifies that short/vague student replies during active tutoring sessions
are NOT rejected as off-topic, while genuinely off-topic messages still are.
"""

import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import pytest
from unittest.mock import MagicMock
from main import is_continuation_reply


def _make_active_state(active_topic: str = "", current_problem: str = ""):
    """Create a mock WorkingMemoryState."""
    state = MagicMock()
    state.active_topic = active_topic
    state.current_problem = current_problem
    return state


def _make_history(messages: list[tuple[str, str]]) -> list[dict]:
    """Create history list from (role, content) tuples."""
    return [{"role": role, "content": content} for role, content in messages]


# โ”€โ”€โ”€ Tests: Should return True (continuation) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

class TestContinuationPositive:
    def test_di_ko_alam_with_active_topic(self):
        state = _make_active_state(active_topic="Functions and Their Graphs")
        assert is_continuation_reply("di ko alam", state, []) is True

    def test_idk_with_current_problem(self):
        state = _make_active_state(current_problem="Solve x^2 + 3x - 4 = 0")
        assert is_continuation_reply("idk", state, []) is True

    def test_huh_after_tutor_question(self):
        history = _make_history([
            ("user", "what is a function?"),
            ("assistant", "A function maps each input to exactly one output. Can you give me an example?"),
        ])
        assert is_continuation_reply("huh?", None, history) is True

    def test_thanks_with_active_topic(self):
        state = _make_active_state(active_topic="Quadratic Equations")
        assert is_continuation_reply("thanks", state, []) is True

    def test_hindi_ko_gets_no_state_but_phrase_match(self):
        # Filipino phrase match should trigger even without active state
        assert is_continuation_reply("hindi ko gets", None, []) is True

    def test_short_reply_with_active_context(self):
        state = _make_active_state(active_topic="Linear Equations")
        assert is_continuation_reply("I'm confused", state, []) is True

    def test_ano_with_active_problem(self):
        state = _make_active_state(current_problem="Find the derivative of f(x)=3x^2")
        assert is_continuation_reply("ano?", state, []) is True

    def test_paano_po(self):
        assert is_continuation_reply("paano po", None, []) is True

    def test_sige_with_context(self):
        state = _make_active_state(active_topic="Statistics")
        assert is_continuation_reply("sige", state, []) is True

    def test_help_me(self):
        assert is_continuation_reply("help me", None, []) is True

    def test_short_msg_after_solve_prompt(self):
        history = _make_history([
            ("assistant", "Try to solve this: What is 2x + 5 = 11?"),
        ])
        assert is_continuation_reply("what", None, history) is True

    def test_ok_with_active_topic(self):
        state = _make_active_state(active_topic="Trigonometry")
        assert is_continuation_reply("ok", state, []) is True


# โ”€โ”€โ”€ Tests: Should return False (not a continuation) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

class TestContinuationNegative:
    def test_explicit_offtopic_no_context(self):
        assert is_continuation_reply(
            "who is the president of the philippines?", None, []
        ) is False

    def test_write_essay_no_context(self):
        assert is_continuation_reply("write my essay", None, []) is False

    def test_long_offtopic_no_context(self):
        assert is_continuation_reply(
            "can you tell me about the history of the roman empire", None, []
        ) is False

    def test_empty_message(self):
        assert is_continuation_reply("", None, []) is False

    def test_long_non_math_no_state(self):
        assert is_continuation_reply(
            "what is the meaning of life and why are we here on earth",
            None,
            [],
        ) is False

    def test_explicit_offtopic_even_with_history_no_question(self):
        history = _make_history([
            ("assistant", "Great job solving that equation!"),
        ])
        # Long off-topic message, no active state, last assistant msg not a question
        assert is_continuation_reply(
            "tell me about basketball players in the NBA this season",
            None,
            history,
        ) is False