OpenHands / tests /unit /test_file_conversation_store.py
Backup-bdg's picture
Upload 964 files
51ff9e5 verified
raw
history blame
7.19 kB
import json
import pytest
from openhands.storage.conversation.file_conversation_store import FileConversationStore
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
from openhands.storage.locations import get_conversation_metadata_filename
from openhands.storage.memory import InMemoryFileStore
@pytest.mark.asyncio
async def test_load_store():
store = FileConversationStore(InMemoryFileStore({}))
expected = ConversationMetadata(
conversation_id='some-conversation-id',
user_id='some-user-id',
selected_repository='some-repo',
title="Let's talk about trains",
)
await store.save_metadata(expected)
found = await store.get_metadata('some-conversation-id')
assert expected == found
@pytest.mark.asyncio
async def test_load_int_user_id():
store = FileConversationStore(
InMemoryFileStore(
{
get_conversation_metadata_filename('some-conversation-id'): json.dumps(
{
'conversation_id': 'some-conversation-id',
'user_id': '67890',
'selected_repository': 'some-repo',
'title': "Let's talk about trains",
'created_at': '2025-01-16T19:51:04.886331Z',
}
)
}
)
)
found = await store.get_metadata('some-conversation-id')
assert found.user_id == '67890'
@pytest.mark.asyncio
async def test_search_empty():
store = FileConversationStore(InMemoryFileStore({}))
result = await store.search()
assert len(result.results) == 0
assert result.next_page_id is None
@pytest.mark.asyncio
async def test_search_basic():
# Create test data with 3 conversations at different dates
store = FileConversationStore(
InMemoryFileStore(
{
get_conversation_metadata_filename('conv1'): json.dumps(
{
'conversation_id': 'conv1',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'First conversation',
'created_at': '2025-01-16T19:51:04Z',
}
),
get_conversation_metadata_filename('conv2'): json.dumps(
{
'conversation_id': 'conv2',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'Second conversation',
'created_at': '2025-01-17T19:51:04Z',
}
),
get_conversation_metadata_filename('conv3'): json.dumps(
{
'conversation_id': 'conv3',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'Third conversation',
'created_at': '2025-01-15T19:51:04Z',
}
),
}
)
)
result = await store.search()
assert len(result.results) == 3
# Should be sorted by date, newest first
assert result.results[0].conversation_id == 'conv2'
assert result.results[1].conversation_id == 'conv1'
assert result.results[2].conversation_id == 'conv3'
assert result.next_page_id is None
@pytest.mark.asyncio
async def test_search_pagination():
# Create test data with 5 conversations
store = FileConversationStore(
InMemoryFileStore(
{
get_conversation_metadata_filename(f'conv{i}'): json.dumps(
{
'conversation_id': f'conv{i}',
'user_id': '123',
'selected_repository': 'repo1',
'title': f'ServerConversation {i}',
'created_at': f'2025-01-{15 + i}T19:51:04Z',
}
)
for i in range(1, 6)
}
)
)
# Test with limit of 2
result = await store.search(limit=2)
assert len(result.results) == 2
assert result.results[0].conversation_id == 'conv5' # newest first
assert result.results[1].conversation_id == 'conv4'
assert result.next_page_id is not None
# Get next page using the next_page_id
result2 = await store.search(page_id=result.next_page_id, limit=2)
assert len(result2.results) == 2
assert result2.results[0].conversation_id == 'conv3'
assert result2.results[1].conversation_id == 'conv2'
assert result2.next_page_id is not None
# Get last page
result3 = await store.search(page_id=result2.next_page_id, limit=2)
assert len(result3.results) == 1
assert result3.results[0].conversation_id == 'conv1'
assert result3.next_page_id is None
@pytest.mark.asyncio
async def test_search_with_invalid_conversation():
# Test handling of invalid conversation data
store = FileConversationStore(
InMemoryFileStore(
{
get_conversation_metadata_filename('conv1'): json.dumps(
{
'conversation_id': 'conv1',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'Valid conversation',
'created_at': '2025-01-16T19:51:04Z',
}
),
get_conversation_metadata_filename(
'conv2'
): 'invalid json', # Invalid conversation
}
)
)
result = await store.search()
# Should return only the valid conversation
assert len(result.results) == 1
assert result.results[0].conversation_id == 'conv1'
assert result.next_page_id is None
@pytest.mark.asyncio
async def test_get_all_metadata():
store = FileConversationStore(
InMemoryFileStore(
{
get_conversation_metadata_filename('conv1'): json.dumps(
{
'conversation_id': 'conv1',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'First conversation',
'created_at': '2025-01-16T19:51:04Z',
}
),
get_conversation_metadata_filename('conv2'): json.dumps(
{
'conversation_id': 'conv2',
'user_id': '123',
'selected_repository': 'repo1',
'title': 'Second conversation',
'created_at': '2025-01-17T19:51:04Z',
}
),
}
)
)
results = await store.get_all_metadata(['conv1', 'conv2'])
assert len(results) == 2
assert results[0].conversation_id == 'conv1'
assert results[0].title == 'First conversation'
assert results[1].conversation_id == 'conv2'
assert results[1].title == 'Second conversation'