197 lines
5.5 KiB
Python
197 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Unit tests for list_saved functionality without API access"""
|
|
|
|
import sys
|
|
import os
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
from typing import List
|
|
|
|
from gumyum_npc_client import GumYumClient as AsyncClient, NPC, SpawnedData
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_saved_attaches_client_reference():
|
|
"""Test that list_saved attaches client reference to NPCs"""
|
|
# Mock client
|
|
client = AsyncClient("http://test.com")
|
|
|
|
# Mock response from API
|
|
mock_response = {
|
|
"npcs": [
|
|
{
|
|
"npc_id": 123,
|
|
"name": "Test NPC 1",
|
|
"profession": "Warrior",
|
|
"personality_type": 8,
|
|
"spawned": {
|
|
"location": "castle",
|
|
"mood": "determined",
|
|
"stress_level": 3,
|
|
},
|
|
"universe_id": "test-universe",
|
|
"seed": 12345,
|
|
},
|
|
{
|
|
"npc_id": 456,
|
|
"name": "Test NPC 2",
|
|
"profession": "Mage",
|
|
"personality_type": 5,
|
|
"spawned": {"location": "tower", "mood": "curious", "stress_level": 2},
|
|
"universe_id": "test-universe",
|
|
"seed": 54321,
|
|
},
|
|
]
|
|
}
|
|
|
|
# Mock the get method
|
|
with patch.object(client, "get") as mock_get:
|
|
mock_get.return_value = mock_response
|
|
|
|
# Call list_saved
|
|
npcs = await client.npc.list_saved()
|
|
|
|
# Verify the API was called correctly
|
|
mock_get.assert_called_once_with("npc/list")
|
|
|
|
# Verify we got NPC objects
|
|
assert len(npcs) == 2
|
|
assert all(isinstance(npc, NPC) for npc in npcs)
|
|
|
|
# Verify client references are attached
|
|
for npc in npcs:
|
|
assert npc.client is client
|
|
assert hasattr(npc, "chat")
|
|
assert hasattr(npc, "completions")
|
|
|
|
# Verify NPC data is correct
|
|
assert npcs[0].npc_id == 123
|
|
assert npcs[0].name == "Test NPC 1"
|
|
assert npcs[0].profession == "Warrior"
|
|
assert npcs[0].personality_type == 8
|
|
assert npcs[0].universe_id == "test-universe"
|
|
|
|
assert npcs[1].npc_id == 456
|
|
assert npcs[1].name == "Test NPC 2"
|
|
assert npcs[1].profession == "Mage"
|
|
assert npcs[1].personality_type == 5
|
|
|
|
|
|
def test_list_saved_handles_missing_fields():
|
|
"""Test that list_saved handles missing optional fields gracefully"""
|
|
# Create NPCManager directly
|
|
from gumyum_npc_client import NPCManager
|
|
|
|
mock_client = Mock()
|
|
npc_manager = NPCManager(mock_client)
|
|
|
|
# Mock response with minimal data
|
|
mock_response = {
|
|
"npcs": [
|
|
{
|
|
"npc_id": 789,
|
|
"name": "Minimal NPC",
|
|
"profession": "Farmer",
|
|
# personality_type missing - should default to 5
|
|
"spawned": {"location": "field", "mood": "content", "stress_level": 1},
|
|
"universe_id": "test-universe",
|
|
# seed missing - should default to 0
|
|
}
|
|
]
|
|
}
|
|
|
|
# Use asyncio.run to handle the async method
|
|
import asyncio
|
|
|
|
async def run_test():
|
|
async def mock_get(*args, **kwargs):
|
|
return mock_response
|
|
|
|
mock_client.get = mock_get
|
|
npcs = await npc_manager.list_saved()
|
|
return npcs
|
|
|
|
npcs = asyncio.run(run_test())
|
|
|
|
# Verify defaults were applied
|
|
assert len(npcs) == 1
|
|
assert npcs[0].personality_type == 5 # Default value
|
|
assert npcs[0].seed == 0 # Default value
|
|
assert npcs[0].npc_id == 789
|
|
assert npcs[0].name == "Minimal NPC"
|
|
|
|
|
|
def test_npc_chat_requires_client():
|
|
"""Test that NPC chat methods require client reference"""
|
|
# Create NPC without client
|
|
npc = NPC(
|
|
npc_id=999,
|
|
name="Orphan NPC",
|
|
profession="Lost",
|
|
personality_type=1,
|
|
spawned=SpawnedData(location="nowhere", mood="confused", stress_level=10),
|
|
universe_id="test-universe",
|
|
seed=0,
|
|
)
|
|
|
|
# Verify no client
|
|
assert npc.client is None
|
|
|
|
# Chat proxy should still be created
|
|
assert npc.chat is not None
|
|
|
|
# But trying to use it should raise error
|
|
import asyncio
|
|
|
|
async def test_chat():
|
|
with pytest.raises(ValueError, match="NPC has no client reference"):
|
|
await npc.chat.completions([{"role": "user", "content": "Hello"}])
|
|
|
|
with pytest.raises(ValueError, match="NPC has no client reference"):
|
|
await npc.completions([{"role": "user", "content": "Hello"}])
|
|
|
|
asyncio.run(test_chat())
|
|
|
|
|
|
def test_list_saved_empty_response():
|
|
"""Test that list_saved handles empty response correctly"""
|
|
from gumyum_npc_client import NPCManager
|
|
|
|
mock_client = Mock()
|
|
npc_manager = NPCManager(mock_client)
|
|
|
|
# Mock empty response
|
|
mock_response = {"npcs": []}
|
|
|
|
import asyncio
|
|
|
|
async def run_test():
|
|
async def mock_get(*args, **kwargs):
|
|
return mock_response
|
|
|
|
mock_client.get = mock_get
|
|
npcs = await npc_manager.list_saved()
|
|
return npcs
|
|
|
|
npcs = asyncio.run(run_test())
|
|
|
|
# Should return empty list
|
|
assert isinstance(npcs, list)
|
|
assert len(npcs) == 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import asyncio
|
|
|
|
# Run async test
|
|
asyncio.run(test_list_saved_attaches_client_reference())
|
|
|
|
# Run sync tests
|
|
test_list_saved_handles_missing_fields()
|
|
test_npc_chat_requires_client()
|
|
test_list_saved_empty_response()
|
|
|
|
print("✅ All unit tests passed!")
|