MAC / tests /test_rag.py
Aaryan17's picture
chore: upload MAC codebase to HF Space
0e76632 verified
"""Tests for /rag endpoints (Phase 7)."""
import io
import pytest
from unittest.mock import patch, AsyncMock
@pytest.mark.asyncio
async def test_rag_documents_empty(client, auth_headers):
resp = await client.get("/api/v1/rag/documents", headers=auth_headers)
assert resp.status_code == 200
data = resp.json()
assert "documents" in data
assert len(data["documents"]) == 0
@pytest.mark.asyncio
async def test_rag_documents_unauthenticated(client):
resp = await client.get("/api/v1/rag/documents")
assert resp.status_code == 403
@pytest.mark.asyncio
async def test_rag_ingest_text_file(client, auth_headers):
content = b"This is a test document for RAG ingestion. It contains enough text to be chunked."
with patch("mac.services.rag_service._store_embeddings", new_callable=AsyncMock, return_value=None):
resp = await client.post(
"/api/v1/rag/ingest",
headers=auth_headers,
files={"file": ("test.txt", io.BytesIO(content), "text/plain")},
data={"title": "Test Document"},
)
assert resp.status_code == 200
data = resp.json()
assert data["title"] == "Test Document"
assert data["status"] in ("processing", "ready")
@pytest.mark.asyncio
async def test_rag_ingest_unsupported_type(client, auth_headers):
content = b"\x00\x01\x02\x03"
resp = await client.post(
"/api/v1/rag/ingest",
headers=auth_headers,
files={"file": ("test.exe", io.BytesIO(content), "application/x-executable")},
data={"title": "Bad File"},
)
assert resp.status_code == 400
@pytest.mark.asyncio
async def test_rag_collections_empty(client, auth_headers):
resp = await client.get("/api/v1/rag/collections", headers=auth_headers)
assert resp.status_code == 200
data = resp.json()
assert "collections" in data
@pytest.mark.asyncio
async def test_rag_create_collection_requires_admin(client, auth_headers):
resp = await client.post("/api/v1/rag/collections", headers=auth_headers,
json={"name": "test", "description": "A test collection"})
assert resp.status_code == 403
@pytest.mark.asyncio
async def test_rag_create_collection_as_admin(client, admin_headers):
resp = await client.post("/api/v1/rag/collections", headers=admin_headers,
json={"name": "test-collection", "description": "A test collection"})
assert resp.status_code == 200
data = resp.json()
assert data["name"] == "test-collection"
@pytest.mark.asyncio
async def test_rag_query(client, auth_headers):
with patch("mac.services.rag_service.query_rag", new_callable=AsyncMock, return_value=[]):
with patch("mac.services.llm_service.chat_completion", new_callable=AsyncMock, return_value={
"id": "mac-chat-test", "object": "chat.completion", "created": 0,
"model": "qwen2.5-coder:7b",
"choices": [{"index": 0, "message": {"role": "assistant", "content": "Test answer"}, "finish_reason": "stop"}],
"usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15},
"_latency_ms": 100,
}):
resp = await client.post("/api/v1/rag/query", headers=auth_headers,
json={"question": "What is machine learning?"})
assert resp.status_code == 200
data = resp.json()
assert "answer" in data
assert "sources" in data
@pytest.mark.asyncio
async def test_rag_delete_requires_admin(client, auth_headers):
resp = await client.delete("/api/v1/rag/documents/some-id", headers=auth_headers)
assert resp.status_code == 403