Skip to content

Commit 8f9b0d4

Browse files
Johan Brobergclaude
andcommitted
test(tooling): add whitespace and empty list validation tests
Add tests for whitespace-only string validation in ChatHistoryMessage and ChatMessageRequest (CRM-012). Add test for empty chat_history list validation in send_chat_history (CRM-011). Update HTTP error test to match new aiohttp.ClientResponseError format. Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 6f22dde commit 8f9b0d4

File tree

3 files changed

+105
-3
lines changed

3 files changed

+105
-3
lines changed

tests/tooling/models/test_chat_history_message.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,48 @@ def test_chat_history_message_preserves_timestamp_precision(self):
9494
# Assert
9595
assert message.timestamp == timestamp
9696
assert "2024-01-15T10:30:45.123000" in message_dict["timestamp"]
97+
98+
def test_chat_history_message_rejects_whitespace_only_id(self):
99+
"""Test that ChatHistoryMessage rejects whitespace-only id."""
100+
# Arrange
101+
timestamp = datetime.now(timezone.utc)
102+
103+
# Act & Assert
104+
with pytest.raises(ValueError, match="id cannot be empty"):
105+
ChatHistoryMessage(" ", "user", "Content", timestamp)
106+
107+
def test_chat_history_message_rejects_whitespace_only_role(self):
108+
"""Test that ChatHistoryMessage rejects whitespace-only role."""
109+
# Arrange
110+
timestamp = datetime.now(timezone.utc)
111+
112+
# Act & Assert
113+
with pytest.raises(ValueError, match="role cannot be empty"):
114+
ChatHistoryMessage("msg-1", " ", "Content", timestamp)
115+
116+
def test_chat_history_message_rejects_whitespace_only_content(self):
117+
"""Test that ChatHistoryMessage rejects whitespace-only content."""
118+
# Arrange
119+
timestamp = datetime.now(timezone.utc)
120+
121+
# Act & Assert
122+
with pytest.raises(ValueError, match="content cannot be empty"):
123+
ChatHistoryMessage("msg-1", "user", " ", timestamp)
124+
125+
def test_chat_history_message_rejects_tab_only_id(self):
126+
"""Test that ChatHistoryMessage rejects tab-only id."""
127+
# Arrange
128+
timestamp = datetime.now(timezone.utc)
129+
130+
# Act & Assert
131+
with pytest.raises(ValueError, match="id cannot be empty"):
132+
ChatHistoryMessage("\t", "user", "Content", timestamp)
133+
134+
def test_chat_history_message_rejects_newline_only_content(self):
135+
"""Test that ChatHistoryMessage rejects newline-only content."""
136+
# Arrange
137+
timestamp = datetime.now(timezone.utc)
138+
139+
# Act & Assert
140+
with pytest.raises(ValueError, match="content cannot be empty"):
141+
ChatHistoryMessage("msg-1", "user", "\n\n", timestamp)

tests/tooling/models/test_chat_message_request.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,49 @@ def test_chat_message_request_with_multiple_messages(self):
103103
assert result["chatHistory"][0]["id"] == "msg-1"
104104
assert result["chatHistory"][1]["id"] == "msg-2"
105105
assert result["chatHistory"][2]["id"] == "msg-3"
106+
107+
def test_chat_message_request_rejects_whitespace_only_conversation_id(self):
108+
"""Test that ChatMessageRequest rejects whitespace-only conversation_id."""
109+
# Arrange
110+
timestamp = datetime.now(timezone.utc)
111+
message = ChatHistoryMessage("msg-1", "user", "Hello", timestamp)
112+
113+
# Act & Assert
114+
with pytest.raises(ValueError, match="conversation_id cannot be empty"):
115+
ChatMessageRequest(" ", "msg-456", "How are you?", [message])
116+
117+
def test_chat_message_request_rejects_whitespace_only_message_id(self):
118+
"""Test that ChatMessageRequest rejects whitespace-only message_id."""
119+
# Arrange
120+
timestamp = datetime.now(timezone.utc)
121+
message = ChatHistoryMessage("msg-1", "user", "Hello", timestamp)
122+
123+
# Act & Assert
124+
with pytest.raises(ValueError, match="message_id cannot be empty"):
125+
ChatMessageRequest("conv-123", " ", "How are you?", [message])
126+
127+
def test_chat_message_request_rejects_whitespace_only_user_message(self):
128+
"""Test that ChatMessageRequest rejects whitespace-only user_message."""
129+
# Arrange
130+
timestamp = datetime.now(timezone.utc)
131+
message = ChatHistoryMessage("msg-1", "user", "Hello", timestamp)
132+
133+
# Act & Assert
134+
with pytest.raises(ValueError, match="user_message cannot be empty"):
135+
ChatMessageRequest("conv-123", "msg-456", " ", [message])
136+
137+
def test_chat_message_request_rejects_tab_only_conversation_id(self):
138+
"""Test that ChatMessageRequest rejects tab-only conversation_id."""
139+
# Arrange
140+
timestamp = datetime.now(timezone.utc)
141+
message = ChatHistoryMessage("msg-1", "user", "Hello", timestamp)
142+
143+
# Act & Assert
144+
with pytest.raises(ValueError, match="conversation_id cannot be empty"):
145+
ChatMessageRequest("\t\t", "msg-456", "How are you?", [message])
146+
147+
def test_chat_message_request_rejects_none_chat_history(self):
148+
"""Test that ChatMessageRequest rejects None chat_history."""
149+
# Act & Assert
150+
with pytest.raises(ValueError, match="chat_history cannot be empty"):
151+
ChatMessageRequest("conv-123", "msg-456", "How are you?", None)

tests/tooling/services/test_send_chat_history.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ async def test_send_chat_history_http_error(
9292
# Assert
9393
assert result.succeeded is False
9494
assert len(result.errors) == 1
95-
assert "HTTP 500" in str(result.errors[0].message)
95+
# Error now uses aiohttp.ClientResponseError which formats as "status, message=..."
96+
assert "500" in str(result.errors[0].message)
97+
assert "Internal Server Error" in str(result.errors[0].message)
9698

9799
@pytest.mark.asyncio
98100
async def test_send_chat_history_with_options(
@@ -128,7 +130,7 @@ async def test_send_chat_history_with_options(
128130
async def test_send_chat_history_validates_turn_context(self, service, chat_history_messages):
129131
"""Test that send_chat_history validates turn_context parameter."""
130132
# Act & Assert
131-
with pytest.raises(ValueError, match="turn_context cannot be empty or None"):
133+
with pytest.raises(ValueError, match="turn_context cannot be None"):
132134
await service.send_chat_history(None, chat_history_messages)
133135

134136
@pytest.mark.asyncio
@@ -137,9 +139,18 @@ async def test_send_chat_history_validates_chat_history_messages(
137139
):
138140
"""Test that send_chat_history validates chat_history_messages parameter."""
139141
# Act & Assert
140-
with pytest.raises(ValueError, match="chat_history_messages cannot be empty or None"):
142+
with pytest.raises(ValueError, match="chat_history_messages cannot be None or empty"):
141143
await service.send_chat_history(mock_turn_context, None)
142144

145+
@pytest.mark.asyncio
146+
async def test_send_chat_history_validates_empty_chat_history_list(
147+
self, service, mock_turn_context
148+
):
149+
"""Test that send_chat_history validates empty chat_history list."""
150+
# Act & Assert
151+
with pytest.raises(ValueError, match="chat_history_messages cannot be None or empty"):
152+
await service.send_chat_history(mock_turn_context, [])
153+
143154
@pytest.mark.asyncio
144155
async def test_send_chat_history_validates_activity(self, service, chat_history_messages):
145156
"""Test that send_chat_history validates turn_context.activity."""

0 commit comments

Comments
 (0)