gateway/modules/features/commcoach/tests/test_serviceAi.py
2026-03-02 00:51:27 +01:00

193 lines
7 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Tests for CommCoach AI service (prompt building and response parsing).
These tests don't require AI calls -- they test the prompt construction and JSON parsing.
"""
import pytest
import json
from ..serviceCommcoachAi import (
buildCoachingSystemPrompt,
buildSummaryPrompt,
buildScoringPrompt,
buildTaskExtractionPrompt,
buildEarlierConversationSummaryPrompt,
prepareMessagesForPrompt,
parseJsonResponse,
)
class TestBuildCoachingSystemPrompt:
def test_basicPrompt(self):
context = {"title": "Conflict Resolution", "category": "conflict"}
prompt = buildCoachingSystemPrompt(context, [], [])
assert "Conflict Resolution" in prompt
assert "conflict" in prompt
assert "coach" in prompt.lower()
def test_withGoals(self):
context = {
"title": "Leadership",
"category": "leadership",
"goals": json.dumps([{"text": "Improve delegation"}]),
}
prompt = buildCoachingSystemPrompt(context, [], [])
assert "Improve delegation" in prompt
def test_withInsights(self):
context = {
"title": "Test",
"category": "custom",
"insights": json.dumps([{"text": "User shows progress in empathy"}]),
}
prompt = buildCoachingSystemPrompt(context, [], [])
assert "empathy" in prompt
def test_withPreviousMessages(self):
context = {"title": "Test", "category": "custom"}
messages = [
{"role": "user", "content": "I had a conflict with my team"},
{"role": "assistant", "content": "Tell me more about that"},
]
prompt = buildCoachingSystemPrompt(context, messages, [])
assert "conflict" in prompt.lower()
def test_withTasks(self):
context = {"title": "Test", "category": "custom"}
tasks = [
{"title": "Practice listening", "status": "open"},
{"title": "Read book", "status": "done"},
]
prompt = buildCoachingSystemPrompt(context, [], tasks)
assert "Practice listening" in prompt
def test_promptLanguageIsGerman(self):
context = {"title": "Test", "category": "custom"}
prompt = buildCoachingSystemPrompt(context, [], [])
assert "Fuehrungskraefte" in prompt or "Coach" in prompt
def test_withEarlierSummary(self):
context = {"title": "Test", "category": "custom"}
messages = [{"role": "user", "content": "Recent question"}]
earlierSummary = "User discussed delegation. Coach suggested practice."
prompt = buildCoachingSystemPrompt(context, messages, [], earlierSummary=earlierSummary)
assert "Aelterer Gespraechsverlauf" in prompt
assert "delegation" in prompt.lower()
assert "Recent question" in prompt
def test_withRollingOverview(self):
context = {"title": "Test", "category": "custom"}
prompt = buildCoachingSystemPrompt(
context, [], [], rollingOverview="User arbeitet an Delegation. Fortschritt sichtbar."
)
assert "Gesamtueberblick" in prompt
assert "Delegation" in prompt
def test_withRetrievedSession(self):
context = {"title": "Test", "category": "custom"}
retrieved = {"summary": "Delegation und Feedback besprochen", "startedAt": "2026-02-01T10:00:00Z"}
prompt = buildCoachingSystemPrompt(context, [], [], retrievedSession=retrieved)
assert "angefragte Session" in prompt
assert "Delegation" in prompt
class TestPrepareMessagesForPrompt:
def test_underThreshold(self):
messages = [{"role": "user", "content": f"msg {i}"} for i in range(10)]
earlier, recent = prepareMessagesForPrompt(messages, None, None)
assert earlier is None
assert len(recent) == 10
def test_overThresholdWithCachedSummary(self):
messages = [{"role": "user", "content": f"msg {i}"} for i in range(40)]
cached = "Summary of first 25 messages"
earlier, recent = prepareMessagesForPrompt(messages, cached, 25)
assert earlier == cached
assert len(recent) == 15
def test_overThresholdNeedsRegenerate(self):
messages = [{"role": "user", "content": f"msg {i}"} for i in range(40)]
earlier, recent = prepareMessagesForPrompt(messages, "old summary", 20)
assert earlier is None
assert len(recent) == 40
class TestBuildEarlierConversationSummaryPrompt:
def test_basic(self):
messages = [
{"role": "user", "content": "I have a conflict"},
{"role": "assistant", "content": "Tell me more"},
]
prompt = buildEarlierConversationSummaryPrompt(messages)
assert "Fasse" in prompt
assert "conflict" in prompt
class TestBuildSummaryPrompt:
def test_basic(self):
messages = [
{"role": "user", "content": "I need help with delegation"},
{"role": "assistant", "content": "Let's work on that"},
]
prompt = buildSummaryPrompt(messages, "Delegation")
assert "Delegation" in prompt
assert "Zusammenfassung" in prompt
def test_emptyMessages(self):
prompt = buildSummaryPrompt([], "Test")
assert "Test" in prompt
class TestBuildScoringPrompt:
def test_basic(self):
messages = [{"role": "user", "content": "I tried active listening today"}]
prompt = buildScoringPrompt(messages, "leadership")
assert "empathy" in prompt
assert "clarity" in prompt
assert "JSON" in prompt
def test_containsScaleInfo(self):
prompt = buildScoringPrompt([{"role": "user", "content": "test"}], "custom")
assert "0-100" in prompt
class TestBuildTaskExtractionPrompt:
def test_basic(self):
messages = [
{"role": "assistant", "content": "You should try practicing active listening this week"},
]
prompt = buildTaskExtractionPrompt(messages)
assert "JSON" in prompt
assert "Aufgaben" in prompt or "Aufgabe" in prompt
def test_limitedMessages(self):
messages = [{"role": "user", "content": f"msg {i}"} for i in range(35)]
prompt = buildTaskExtractionPrompt(messages)
assert "msg 34" in prompt
assert "msg 0" not in prompt
class TestParseJsonResponse:
def test_validJson(self):
result = parseJsonResponse('[{"dimension": "empathy", "score": 70}]')
assert isinstance(result, list)
assert result[0]["score"] == 70
def test_codeBlockWrapped(self):
result = parseJsonResponse('```json\n[{"title": "task1"}]\n```')
assert isinstance(result, list)
assert result[0]["title"] == "task1"
def test_invalidJson(self):
result = parseJsonResponse('not json at all', fallback=[])
assert result == []
def test_emptyString(self):
result = parseJsonResponse('', fallback=None)
assert result is None
def test_nestedCodeBlock(self):
text = '```\n{"key": "value"}\n```'
result = parseJsonResponse(text)
assert result["key"] == "value"