Spaces:
Sleeping
Sleeping
File size: 6,315 Bytes
e86dfae | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | """
Integration Tests: Chat API
Tests for chat session CRUD and message flow.
"""
import pytest
from fastapi.testclient import TestClient
class TestChatSessions:
"""Chat session CRUD tests."""
@pytest.mark.integration
def test_list_sessions_returns_200(self, client: TestClient):
"""List sessions returns HTTP 200."""
response = client.get("/api/v1/chat/sessions")
assert response.status_code == 200
@pytest.mark.integration
def test_list_sessions_empty_for_new_user(self, client: TestClient):
"""New user has no chat sessions."""
response = client.get("/api/v1/chat/sessions")
data = response.json()
assert isinstance(data, list)
assert len(data) == 0
@pytest.mark.integration
def test_create_session_returns_201_or_200(self, client: TestClient):
"""Creating a session returns success status."""
response = client.post(
"/api/v1/chat/sessions",
json={"title": "Test Mining Chat", "document_ids": []},
)
assert response.status_code in (200, 201)
@pytest.mark.integration
def test_create_session_has_required_fields(self, client: TestClient):
"""Created session has id, title, message_count."""
response = client.post("/api/v1/chat/sessions", json={"title": "Test Session"})
data = response.json()
assert "id" in data
assert "title" in data
assert "message_count" in data
assert data["title"] == "Test Session"
assert data["message_count"] == 0
@pytest.mark.integration
def test_get_session_returns_200(self, client: TestClient, sample_chat_session):
"""Get session by ID returns HTTP 200."""
response = client.get(f"/api/v1/chat/sessions/{sample_chat_session.id}")
assert response.status_code == 200
@pytest.mark.integration
def test_get_session_has_messages_list(
self, client: TestClient, sample_chat_session
):
"""Session detail response includes messages list."""
response = client.get(f"/api/v1/chat/sessions/{sample_chat_session.id}")
data = response.json()
assert "messages" in data
assert isinstance(data["messages"], list)
@pytest.mark.integration
def test_get_nonexistent_session_returns_404(self, client: TestClient):
"""Non-existent session ID returns 404."""
fake_id = "00000000-0000-0000-0000-000000000000"
response = client.get(f"/api/v1/chat/sessions/{fake_id}")
assert response.status_code == 404
@pytest.mark.integration
def test_update_session_title(self, client: TestClient, sample_chat_session):
"""PATCH session updates title."""
response = client.patch(
f"/api/v1/chat/sessions/{sample_chat_session.id}",
json={"title": "Updated Title"},
)
assert response.status_code == 200
data = response.json()
assert data["title"] == "Updated Title"
@pytest.mark.integration
def test_delete_session_returns_200(self, client: TestClient, sample_chat_session):
"""Delete session returns success."""
response = client.delete(f"/api/v1/chat/sessions/{sample_chat_session.id}")
assert response.status_code == 200
assert response.json()["success"] is True
@pytest.mark.integration
def test_delete_makes_session_not_found(
self, client: TestClient, sample_chat_session
):
"""After deletion, GET returns 404."""
session_id = str(sample_chat_session.id)
client.delete(f"/api/v1/chat/sessions/{session_id}")
response = client.get(f"/api/v1/chat/sessions/{session_id}")
assert response.status_code == 404
class TestSendMessage:
"""Tests for the /chat/send endpoint."""
@pytest.mark.integration
def test_send_creates_new_session_when_no_session_id(self, client: TestClient):
"""Sending without session_id creates a new session."""
from unittest.mock import AsyncMock, patch
with patch(
"app.services.chat_service.ChatService.generate_response",
new_callable=AsyncMock,
) as mock_gen:
mock_gen.return_value = (
"According to [Mining_site.pdf, Page 12], methane limits are below 1%.",
[],
)
response = client.post(
"/api/v1/chat/send",
json={
"content": "What are the methane limits?",
"include_sources": True,
},
)
assert response.status_code == 200
data = response.json()
assert "session_id" in data
assert "message" in data
@pytest.mark.integration
def test_send_message_has_assistant_role(self, client: TestClient):
"""AI response message has role='assistant'."""
from unittest.mock import AsyncMock, patch
with patch(
"app.services.chat_service.ChatService.generate_response",
new_callable=AsyncMock,
) as mock_gen:
mock_gen.return_value = ("Test answer with [doc.pdf, Page 5] citation.", [])
response = client.post(
"/api/v1/chat/send",
json={
"content": "Test question",
},
)
data = response.json()
assert data["message"]["role"] == "assistant"
@pytest.mark.integration
def test_send_message_with_existing_session(
self, client: TestClient, sample_chat_session
):
"""Sending with existing session_id appends to that session."""
from unittest.mock import AsyncMock, patch
with patch(
"app.services.chat_service.ChatService.generate_response",
new_callable=AsyncMock,
) as mock_gen:
mock_gen.return_value = ("Response text.", [])
response = client.post(
"/api/v1/chat/send",
json={
"content": "Question about mining",
"session_id": str(sample_chat_session.id),
},
)
assert response.status_code == 200
data = response.json()
assert data["session_id"] == str(sample_chat_session.id)
|