Files
discord_bot/tests/test_spec_env.py
T

57 lines
2.6 KiB
Python

"""Unit coverage for SPEC-001 test-class requirements (ENV-10..12)."""
import json
import time
import unittest
from fjerkroa_bot.ai_responder import AIMessage, AIResponder
from .test_bdd_envelope import FakeModelResponder
def entry(channel: str, text: str = "x"):
return {"role": "user", "content": json.dumps({"message": text, "channel": channel})}
class TestSystemPromptTemplate(unittest.TestCase):
def test_dynamic_context_in_suffix(self):
"""ENV-10: date/memory reach the system message via the context suffix (ENV-20)."""
config = {"system": "Date {date} memory {memory} news {news}", "history-limit": 5, "news": "/nonexistent/news.txt"}
responder = AIResponder(config, "chat")
responder.memory = "MEMSTR"
messages = responder.message(AIMessage("alice", "hei"))
system = messages[0]["content"]
self.assertIn(time.strftime("%Y-%m-%d"), system)
self.assertIn("MEMSTR", system)
self.assertNotIn("{news}", system) # placeholders stripped since ENV-20
class TestHistoryShrink(unittest.TestCase):
def test_shrink_prefers_busy_channel(self):
"""ENV-11: entry from the channel exceeding history-per-channel is removed first."""
config = {"system": "s", "history-limit": 4}
responder = AIResponder(config, "chat")
responder.history = [entry("a", "a0"), entry("a", "a1"), entry("a", "a2"), entry("a", "a3"), entry("b", "b0")]
responder.shrink_history_by_one()
self.assertEqual(len(responder.history), 4)
self.assertNotIn("a0", responder.history[0]["content"]) # oldest busy-channel entry gone
def test_shrink_falls_back_to_oldest(self):
"""ENV-11: when no channel exceeds the cap, the oldest entry overall is removed."""
config = {"system": "s", "history-limit": 4}
responder = AIResponder(config, "chat")
responder.history = [entry("a", "a0"), entry("b", "b0"), entry("c", "c0")]
responder.shrink_history_by_one()
self.assertEqual(len(responder.history), 2)
self.assertNotIn("a0", responder.history[0]["content"])
class TestRetriesExhausted(unittest.IsolatedAsyncioTestCase):
async def test_send_raises_after_three_failures(self):
"""ENV-12: three model failures -> RuntimeError (revision pending in FDB-004/D1)."""
responder = FakeModelResponder({"system": "s", "history-limit": 5}, "chat")
# scripted list empty -> chat() returns None every attempt
with self.assertRaises(RuntimeError):
await responder.send(AIMessage("alice", "hei", "chat"))
self.assertEqual(responder.chat_calls, 3)