Skip to content

Commit 0a562ab

Browse files
committed
test: add repository tests and fix datetime deprecation warnings
1 parent fd44674 commit 0a562ab

File tree

3 files changed

+170
-5
lines changed

3 files changed

+170
-5
lines changed

chatbot-api/src/chat/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from dataclasses import dataclass
22
from typing import List, Optional, Union, Dict
3-
from datetime import datetime
3+
from datetime import datetime, timezone
44

55

66
@dataclass
@@ -20,11 +20,11 @@ class Message:
2020
role: str
2121
content: Union[str, List[Union[TextContent, ImageContent]]]
2222
model: Optional[str] = None
23-
timestamp: datetime = datetime.utcnow()
23+
timestamp: datetime = datetime.now(timezone.utc)
2424

2525

2626
@dataclass
2727
class ChatResponse:
2828
content: str
2929
model: str
30-
timestamp: datetime = datetime.utcnow()
30+
timestamp: datetime = datetime.now(timezone.utc)

chatbot-api/src/conversation/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from dataclasses import dataclass
2-
from datetime import datetime
2+
from datetime import datetime, timezone
33
from typing import List, Optional
44
from ..chat.models import Message
55

@@ -11,7 +11,7 @@ class Conversation:
1111
conversation_id: str
1212
conversation_name: str
1313
messages: List[Message]
14-
last_updated: datetime = datetime.utcnow()
14+
last_updated: datetime = datetime.now(timezone.utc)
1515

1616

1717
@dataclass
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import os
2+
import pytest
3+
from datetime import datetime, timezone
4+
from src.conversation.repository import SQLiteConversationRepository
5+
from src.conversation.models import Conversation
6+
from src.chat.models import Message
7+
8+
9+
@pytest.fixture
10+
def test_db_path(tmp_path):
11+
"""Create a temporary database file for testing"""
12+
db_file = tmp_path / "test_conversations.db"
13+
yield str(db_file)
14+
# Cleanup after tests
15+
if os.path.exists(db_file):
16+
os.remove(db_file)
17+
18+
19+
@pytest.fixture
20+
def repository(test_db_path):
21+
"""Create a fresh repository instance for each test"""
22+
return SQLiteConversationRepository(db_path=test_db_path)
23+
24+
25+
def test_save_new_conversation(repository):
26+
"""Test saving a new conversation"""
27+
# Create a test conversation
28+
conv = Conversation(
29+
conversation_id="test-id",
30+
conversation_name="Test Conversation",
31+
messages=[
32+
Message(
33+
role="user",
34+
content="Hello",
35+
model="gpt-4",
36+
timestamp=datetime.now(timezone.utc)
37+
)
38+
],
39+
last_updated=datetime.now(timezone.utc)
40+
)
41+
42+
# Save the conversation
43+
repository.save_conversation(conv)
44+
45+
# Retrieve and verify
46+
saved_conv = repository.get_conversation("test-id")
47+
assert saved_conv is not None
48+
assert saved_conv.conversation_id == "test-id"
49+
assert saved_conv.conversation_name == "Test Conversation"
50+
assert len(saved_conv.messages) == 1
51+
assert saved_conv.messages[0].content == "Hello"
52+
53+
54+
def test_update_existing_conversation(repository):
55+
"""Test updating an existing conversation"""
56+
# Create and save initial conversation
57+
initial_conv = Conversation(
58+
conversation_id="test-id",
59+
conversation_name="Initial Name",
60+
messages=[
61+
Message(
62+
role="user",
63+
content="First message",
64+
model="gpt-4",
65+
timestamp=datetime.now(timezone.utc)
66+
)
67+
],
68+
last_updated=datetime.now(timezone.utc)
69+
)
70+
repository.save_conversation(initial_conv)
71+
72+
# Update with new name and messages
73+
updated_conv = Conversation(
74+
conversation_id="test-id",
75+
conversation_name="Updated Name",
76+
messages=[
77+
Message(
78+
role="user",
79+
content="First message",
80+
model="gpt-4",
81+
timestamp=datetime.now(timezone.utc)
82+
),
83+
Message(
84+
role="assistant",
85+
content="Second message",
86+
model="gpt-4",
87+
timestamp=datetime.now(timezone.utc)
88+
)
89+
],
90+
last_updated=datetime.now(timezone.utc)
91+
)
92+
repository.save_conversation(updated_conv)
93+
94+
# Retrieve and verify the update
95+
saved_conv = repository.get_conversation("test-id")
96+
assert saved_conv is not None
97+
assert saved_conv.conversation_id == "test-id"
98+
assert saved_conv.conversation_name == "Updated Name"
99+
assert len(saved_conv.messages) == 2
100+
assert saved_conv.messages[1].content == "Second message"
101+
102+
103+
def test_get_conversations_ordering(repository):
104+
"""Test that conversations are returned in correct order"""
105+
# Create conversations with different timestamps
106+
conv1 = Conversation(
107+
conversation_id="test-id-1",
108+
conversation_name="Test Conversation 1",
109+
messages=[],
110+
last_updated=datetime(2024, 1, 1, tzinfo=timezone.utc)
111+
)
112+
conv2 = Conversation(
113+
conversation_id="test-id-2",
114+
conversation_name="Test Conversation 2",
115+
messages=[],
116+
last_updated=datetime(2024, 1, 2, tzinfo=timezone.utc)
117+
)
118+
119+
# Save in reverse order
120+
repository.save_conversation(conv1)
121+
repository.save_conversation(conv2)
122+
123+
# Get conversations and verify order
124+
conversations = repository.get_conversations()
125+
assert len(conversations) == 2
126+
assert conversations[0].conversation_id == "test-id-2" # Most recent first
127+
assert conversations[1].conversation_id == "test-id-1"
128+
129+
130+
def test_get_nonexistent_conversation(repository):
131+
"""Test getting a conversation that doesn't exist"""
132+
conv = repository.get_conversation("nonexistent-id")
133+
assert conv is None
134+
135+
136+
def test_save_conversation_with_structured_content(repository):
137+
"""Test saving a conversation with structured content"""
138+
# Create a conversation with structured content
139+
conv = Conversation(
140+
conversation_id="test-id",
141+
conversation_name="Test Conversation",
142+
messages=[
143+
Message(
144+
role="user",
145+
content=[
146+
{"type": "text", "text": "Hello with structure"},
147+
{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,test"}}
148+
],
149+
model="gpt-4",
150+
timestamp=datetime.now(timezone.utc)
151+
)
152+
],
153+
last_updated=datetime.now(timezone.utc)
154+
)
155+
156+
# Save and retrieve
157+
repository.save_conversation(conv)
158+
saved_conv = repository.get_conversation("test-id")
159+
160+
assert saved_conv is not None
161+
assert len(saved_conv.messages) == 1
162+
assert isinstance(saved_conv.messages[0].content, list)
163+
assert len(saved_conv.messages[0].content) == 2
164+
assert saved_conv.messages[0].content[0]["type"] == "text"
165+
assert saved_conv.messages[0].content[1]["type"] == "image_url"

0 commit comments

Comments
 (0)