45 lines
2.0 KiB
Python
45 lines
2.0 KiB
Python
"""Unit coverage for SPEC-008 (CFG-01..03)."""
|
|
|
|
import unittest
|
|
from unittest.mock import mock_open, patch
|
|
|
|
import toml
|
|
|
|
from fjerkroa_bot import FjerkroaBot
|
|
from fjerkroa_bot.ai_responder import AIMessage, AIResponder
|
|
|
|
|
|
class TestConfigLoad(unittest.TestCase):
|
|
def test_load_config_parses_toml(self):
|
|
"""CFG-01: load_config parses the TOML file into a plain dict."""
|
|
data = {"system": "prompt", "history-limit": 7, "additional-responders": []}
|
|
with patch("builtins.open", mock_open(read_data=toml.dumps(data))):
|
|
result = FjerkroaBot.load_config("config.toml")
|
|
self.assertEqual(result, data)
|
|
|
|
|
|
class TestPerChannelPrompt(unittest.TestCase):
|
|
def test_channel_override_wins(self):
|
|
"""CFG-02: responder bound to a channel uses config[channel] over config['system']."""
|
|
config = {"system": "Default prompt", "kitchen": "Kitchen prompt", "history-limit": 5}
|
|
responder = AIResponder(config, "kitchen")
|
|
system = responder.message(AIMessage("alice", "hei", "kitchen"))[0]["content"]
|
|
self.assertTrue(system.startswith("Kitchen prompt"))
|
|
|
|
def test_fallback_to_system(self):
|
|
"""CFG-02: without a channel key the shared system prompt is used."""
|
|
config = {"system": "Default prompt", "history-limit": 5}
|
|
responder = AIResponder(config, "kitchen")
|
|
system = responder.message(AIMessage("alice", "hei", "kitchen"))[0]["content"]
|
|
self.assertTrue(system.startswith("Default prompt"))
|
|
|
|
|
|
class TestNewsFileMissing(unittest.TestCase):
|
|
def test_missing_news_file_degrades_silently(self):
|
|
"""CFG-03 (revised): nonexistent news file -> no news section, no literal, no crash."""
|
|
config = {"system": "N: {news}", "history-limit": 5, "news": "/nonexistent/news.txt"}
|
|
responder = AIResponder(config, "chat")
|
|
system = responder.message(AIMessage("alice", "hei"))[0]["content"]
|
|
self.assertNotIn("{news}", system)
|
|
self.assertNotIn("news:", system)
|