Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions tests/unit/app/endpoints/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Unit tests for the /config REST API endpoint."""

import pytest
from pytest_mock import MockerFixture

from fastapi import HTTPException, Request, status
from app.endpoints.config import config_endpoint_handler
Expand All @@ -9,7 +10,7 @@


@pytest.mark.asyncio
async def test_config_endpoint_handler_configuration_not_loaded(mocker):
async def test_config_endpoint_handler_configuration_not_loaded(mocker: MockerFixture):
"""Test the config endpoint handler."""
mock_authorization_resolvers(mocker)

Expand All @@ -34,7 +35,7 @@ async def test_config_endpoint_handler_configuration_not_loaded(mocker):


@pytest.mark.asyncio
async def test_config_endpoint_handler_configuration_loaded(mocker):
async def test_config_endpoint_handler_configuration_loaded(mocker: MockerFixture):
"""Test the config endpoint handler."""
mock_authorization_resolvers(mocker)

Expand Down
67 changes: 41 additions & 26 deletions tests/unit/app/endpoints/test_conversations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from fastapi import HTTPException, status, Request
import pytest
from pytest_mock import MockerFixture
from llama_stack_client import APIConnectionError, NotFoundError

from app.endpoints.conversations import (
Expand Down Expand Up @@ -42,7 +43,7 @@ def dummy_request() -> Request:


def create_mock_conversation(
mocker,
mocker: MockerFixture,
conversation_id,
created_at,
last_message_at,
Expand All @@ -65,7 +66,7 @@ def create_mock_conversation(
return mock_conversation


def mock_database_session(mocker, query_result=None):
def mock_database_session(mocker: MockerFixture, query_result=None):
"""Helper function to mock get_session with proper context manager support."""
mock_session = mocker.Mock()
if query_result is not None:
Expand Down Expand Up @@ -266,7 +267,7 @@ class TestGetConversationEndpoint:
"""Test cases for the GET /conversations/{conversation_id} endpoint."""

@pytest.mark.asyncio
async def test_configuration_not_loaded(self, mocker, dummy_request):
async def test_configuration_not_loaded(self, mocker: MockerFixture, dummy_request):
"""Test the endpoint when configuration is not loaded."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations.configuration", None)
Expand All @@ -283,7 +284,7 @@ async def test_configuration_not_loaded(self, mocker, dummy_request):

@pytest.mark.asyncio
async def test_invalid_conversation_id_format(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint with an invalid conversation ID format."""
mock_authorization_resolvers(mocker)
Expand All @@ -303,7 +304,7 @@ async def test_invalid_conversation_id_format(

@pytest.mark.asyncio
async def test_llama_stack_connection_error(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when LlamaStack connection fails."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -333,7 +334,7 @@ async def test_llama_stack_connection_error(

@pytest.mark.asyncio
async def test_llama_stack_not_found_error(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when LlamaStack returns NotFoundError."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -366,7 +367,7 @@ async def test_llama_stack_not_found_error(

@pytest.mark.asyncio
async def test_session_retrieve_exception(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when session retrieval raises an exception."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -398,7 +399,11 @@ async def test_session_retrieve_exception(

@pytest.mark.asyncio
async def test_get_conversation_forbidden(
self, mocker, setup_configuration, dummy_request, mock_conversation
self,
mocker: MockerFixture,
setup_configuration,
dummy_request,
mock_conversation,
):
"""Test forbidden access when user lacks permission to read conversation."""
mocker.patch("app.endpoints.conversations.configuration", setup_configuration)
Expand Down Expand Up @@ -443,7 +448,7 @@ async def test_get_conversation_forbidden(
@pytest.mark.asyncio
async def test_get_others_conversations_allowed_for_authorized_user(
self,
mocker,
mocker: MockerFixture,
setup_configuration,
mock_conversation,
dummy_request,
Expand Down Expand Up @@ -486,7 +491,7 @@ async def test_get_others_conversations_allowed_for_authorized_user(
@pytest.mark.asyncio
async def test_successful_conversation_retrieval(
self,
mocker,
mocker: MockerFixture,
setup_configuration,
mock_session_data,
expected_chat_history,
Expand Down Expand Up @@ -531,7 +536,7 @@ class TestDeleteConversationEndpoint:
"""Test cases for the DELETE /conversations/{conversation_id} endpoint."""

@pytest.mark.asyncio
async def test_configuration_not_loaded(self, mocker, dummy_request):
async def test_configuration_not_loaded(self, mocker: MockerFixture, dummy_request):
"""Test the endpoint when configuration is not loaded."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations.configuration", None)
Expand All @@ -548,7 +553,7 @@ async def test_configuration_not_loaded(self, mocker, dummy_request):

@pytest.mark.asyncio
async def test_invalid_conversation_id_format(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint with an invalid conversation ID format."""
mock_authorization_resolvers(mocker)
Expand All @@ -568,7 +573,7 @@ async def test_invalid_conversation_id_format(

@pytest.mark.asyncio
async def test_llama_stack_connection_error(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when LlamaStack connection fails."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -597,7 +602,7 @@ async def test_llama_stack_connection_error(

@pytest.mark.asyncio
async def test_llama_stack_not_found_error(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when LlamaStack returns NotFoundError."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -630,7 +635,7 @@ async def test_llama_stack_not_found_error(

@pytest.mark.asyncio
async def test_session_deletion_exception(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test the endpoint when session deletion raises an exception."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -665,7 +670,11 @@ async def test_session_deletion_exception(

@pytest.mark.asyncio
async def test_delete_conversation_forbidden(
self, mocker, setup_configuration, dummy_request, mock_conversation
self,
mocker: MockerFixture,
setup_configuration,
dummy_request,
mock_conversation,
):
"""Test forbidden deletion when user lacks permission to delete conversation."""
mocker.patch("app.endpoints.conversations.configuration", setup_configuration)
Expand Down Expand Up @@ -709,7 +718,11 @@ async def test_delete_conversation_forbidden(

@pytest.mark.asyncio
async def test_delete_others_conversations_allowed_for_authorized_user(
self, mocker, setup_configuration, mock_conversation, dummy_request
self,
mocker: MockerFixture,
setup_configuration,
mock_conversation,
dummy_request,
):
"""Test allowed deletion of another user's conversation for authorized user."""
mocker.patch(
Expand Down Expand Up @@ -752,7 +765,7 @@ async def test_delete_others_conversations_allowed_for_authorized_user(

@pytest.mark.asyncio
async def test_successful_conversation_deletion(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test successful conversation deletion."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -794,7 +807,7 @@ class TestGetConversationsListEndpoint:
"""Test cases for the GET /conversations endpoint."""

@pytest.mark.asyncio
async def test_configuration_not_loaded(self, mocker, dummy_request):
async def test_configuration_not_loaded(self, mocker: MockerFixture, dummy_request):
"""Test the endpoint when configuration is not loaded."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations.configuration", None)
Expand All @@ -809,7 +822,7 @@ async def test_configuration_not_loaded(self, mocker, dummy_request):

@pytest.mark.asyncio
async def test_successful_conversations_list_retrieval(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test successful retrieval of conversations list."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -869,7 +882,7 @@ async def test_successful_conversations_list_retrieval(

@pytest.mark.asyncio
async def test_empty_conversations_list(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test when user has no conversations."""
mock_authorization_resolvers(mocker)
Expand All @@ -887,7 +900,9 @@ async def test_empty_conversations_list(
assert response.conversations == []

@pytest.mark.asyncio
async def test_database_exception(self, mocker, setup_configuration, dummy_request):
async def test_database_exception(
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test when database query raises an exception."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations.configuration", setup_configuration)
Expand All @@ -906,7 +921,7 @@ async def test_database_exception(self, mocker, setup_configuration, dummy_reque

@pytest.mark.asyncio
async def test_conversations_list_with_none_topic_summary(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test conversations list when topic_summary is None."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -940,7 +955,7 @@ async def test_conversations_list_with_none_topic_summary(

@pytest.mark.asyncio
async def test_conversations_list_with_mixed_topic_summaries(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test conversations list with mixed topic_summary values (some None, some not)."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -1005,7 +1020,7 @@ async def test_conversations_list_with_mixed_topic_summaries(

@pytest.mark.asyncio
async def test_conversations_list_with_empty_topic_summary(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test conversations list when topic_summary is an empty string."""
mock_authorization_resolvers(mocker)
Expand Down Expand Up @@ -1039,7 +1054,7 @@ async def test_conversations_list_with_empty_topic_summary(

@pytest.mark.asyncio
async def test_conversations_list_topic_summary_field_presence(
self, mocker, setup_configuration, dummy_request
self, mocker: MockerFixture, setup_configuration, dummy_request
):
"""Test that topic_summary field is always present in ConversationDetails objects."""
mock_authorization_resolvers(mocker)
Expand Down
19 changes: 12 additions & 7 deletions tests/unit/app/endpoints/test_conversations_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from unittest.mock import Mock
import pytest
from pytest_mock import MockerFixture
from fastapi import HTTPException, status

from app.endpoints.conversations_v2 import (
Expand Down Expand Up @@ -71,13 +72,13 @@ def mock_configuration():
class TestCheckValidConversationId:
"""Test cases for the check_valid_conversation_id function."""

def test_valid_conversation_id(self, mocker):
def test_valid_conversation_id(self, mocker: MockerFixture):
"""Test with a valid conversation ID."""
mocker.patch("app.endpoints.conversations_v2.check_suid", return_value=True)
# Should not raise an exception
check_valid_conversation_id(VALID_CONVERSATION_ID)

def test_invalid_conversation_id(self, mocker):
def test_invalid_conversation_id(self, mocker: MockerFixture):
"""Test with an invalid conversation ID."""
mocker.patch("app.endpoints.conversations_v2.check_suid", return_value=False)

Expand Down Expand Up @@ -117,7 +118,7 @@ class TestUpdateConversationEndpoint:
"""Test cases for the PUT /conversations/{conversation_id} endpoint."""

@pytest.mark.asyncio
async def test_configuration_not_loaded(self, mocker):
async def test_configuration_not_loaded(self, mocker: MockerFixture):
"""Test the endpoint when configuration is not loaded."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations_v2.configuration", None)
Expand All @@ -134,7 +135,9 @@ async def test_configuration_not_loaded(self, mocker):
assert exc_info.value.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR

@pytest.mark.asyncio
async def test_invalid_conversation_id_format(self, mocker, mock_configuration):
async def test_invalid_conversation_id_format(
self, mocker: MockerFixture, mock_configuration
):
"""Test the endpoint with an invalid conversation ID format."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations_v2.configuration", mock_configuration)
Expand All @@ -153,7 +156,7 @@ async def test_invalid_conversation_id_format(self, mocker, mock_configuration):
assert "Invalid conversation ID format" in exc_info.value.detail["response"]

@pytest.mark.asyncio
async def test_conversation_cache_not_configured(self, mocker):
async def test_conversation_cache_not_configured(self, mocker: MockerFixture):
"""Test the endpoint when conversation cache is not configured."""
mock_authorization_resolvers(mocker)
mock_config = Mock()
Expand All @@ -176,7 +179,9 @@ async def test_conversation_cache_not_configured(self, mocker):
)

@pytest.mark.asyncio
async def test_conversation_not_found(self, mocker, mock_configuration):
async def test_conversation_not_found(
self, mocker: MockerFixture, mock_configuration
):
"""Test the endpoint when conversation does not exist."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations_v2.configuration", mock_configuration)
Expand All @@ -196,7 +201,7 @@ async def test_conversation_not_found(self, mocker, mock_configuration):
assert "Conversation not found" in exc_info.value.detail["response"]

@pytest.mark.asyncio
async def test_successful_update(self, mocker, mock_configuration):
async def test_successful_update(self, mocker: MockerFixture, mock_configuration):
"""Test successful topic summary update."""
mock_authorization_resolvers(mocker)
mocker.patch("app.endpoints.conversations_v2.configuration", mock_configuration)
Expand Down
Loading
Loading