133 lines
4.0 KiB
Python
133 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from chat.app import app
|
|
|
|
|
|
@pytest.fixture
|
|
def client(tmp_path, monkeypatch):
|
|
config_path = tmp_path / "config.toml"
|
|
config_path.write_text('featherless_api_key = "test"\n')
|
|
monkeypatch.setenv("CHAT_CONFIG_PATH", str(config_path))
|
|
monkeypatch.setenv("CHAT_DB_PATH", str(tmp_path / "test.db"))
|
|
with TestClient(app) as c:
|
|
yield c
|
|
|
|
|
|
def test_get_new_bot_form_renders(client):
|
|
response = client.get("/bots/new")
|
|
assert response.status_code == 200
|
|
body = response.text.lower()
|
|
assert "<form" in body
|
|
assert "name" in body
|
|
assert "persona" in body
|
|
assert "kickoff" in body
|
|
|
|
|
|
def test_post_new_bot_appends_event_and_redirects(client, tmp_path):
|
|
response = client.post(
|
|
"/bots/new",
|
|
data={
|
|
"id": "bot_a",
|
|
"name": "BotA",
|
|
"persona": "thoughtful, observant",
|
|
"voice_samples": "first sample\n---\nsecond sample",
|
|
"traits": "shy, quick to anger",
|
|
"backstory": "grew up in a small town",
|
|
"initial_relationship_to_you": "coworker",
|
|
"kickoff_prose": "you stay late at the office",
|
|
},
|
|
follow_redirects=False,
|
|
)
|
|
assert response.status_code == 303
|
|
assert response.headers["location"] == "/bots/bot_a/kickoff"
|
|
|
|
from chat.db.connection import open_db
|
|
from chat.state.entities import get_bot
|
|
|
|
with open_db(tmp_path / "test.db") as conn:
|
|
bot = get_bot(conn, "bot_a")
|
|
assert bot is not None
|
|
assert bot["name"] == "BotA"
|
|
assert bot["voice_samples"] == ["first sample", "second sample"]
|
|
assert bot["traits"] == ["shy", "quick to anger"]
|
|
assert bot["backstory"] == "grew up in a small town"
|
|
assert bot["initial_relationship_to_you"] == "coworker"
|
|
assert bot["kickoff_prose"] == "you stay late at the office"
|
|
|
|
# Confirm event was actually appended (state goes through event log).
|
|
cur = conn.execute(
|
|
"SELECT kind, payload_json FROM event_log WHERE kind = 'bot_authored'"
|
|
)
|
|
rows = cur.fetchall()
|
|
assert len(rows) == 1
|
|
|
|
|
|
def test_post_new_bot_rejects_missing_required(client):
|
|
response = client.post(
|
|
"/bots/new",
|
|
data={"id": "bot_b"},
|
|
follow_redirects=False,
|
|
)
|
|
assert response.status_code == 400
|
|
|
|
|
|
def test_get_bots_list_renders(client):
|
|
response = client.get("/bots")
|
|
assert response.status_code == 200
|
|
|
|
|
|
def test_post_new_bot_empty_traits_parses_to_empty_list(client, tmp_path):
|
|
response = client.post(
|
|
"/bots/new",
|
|
data={
|
|
"id": "bot_c",
|
|
"name": "BotC",
|
|
"persona": "stoic",
|
|
"voice_samples": "",
|
|
"traits": "",
|
|
"backstory": "",
|
|
"initial_relationship_to_you": "stranger",
|
|
"kickoff_prose": "the rain begins",
|
|
},
|
|
follow_redirects=False,
|
|
)
|
|
assert response.status_code == 303
|
|
|
|
from chat.db.connection import open_db
|
|
from chat.state.entities import get_bot
|
|
|
|
with open_db(tmp_path / "test.db") as conn:
|
|
bot = get_bot(conn, "bot_c")
|
|
assert bot is not None
|
|
assert bot["voice_samples"] == []
|
|
assert bot["traits"] == []
|
|
|
|
|
|
def test_post_new_bot_traits_split_by_newlines(client, tmp_path):
|
|
response = client.post(
|
|
"/bots/new",
|
|
data={
|
|
"id": "bot_d",
|
|
"name": "BotD",
|
|
"persona": "curious",
|
|
"voice_samples": "",
|
|
"traits": "calm\nthoughtful\nguarded",
|
|
"backstory": "",
|
|
"initial_relationship_to_you": "neighbor",
|
|
"kickoff_prose": "morning light",
|
|
},
|
|
follow_redirects=False,
|
|
)
|
|
assert response.status_code == 303
|
|
|
|
from chat.db.connection import open_db
|
|
from chat.state.entities import get_bot
|
|
|
|
with open_db(tmp_path / "test.db") as conn:
|
|
bot = get_bot(conn, "bot_d")
|
|
assert bot is not None
|
|
assert bot["traits"] == ["calm", "thoughtful", "guarded"]
|