209 lines
7.0 KiB
Python
209 lines
7.0 KiB
Python
# [DEF:backend.src.api.routes.__tests__.test_datasets:Module]
|
|
# @TIER: STANDARD
|
|
# @PURPOSE: Unit tests for Datasets API endpoints
|
|
# @LAYER: API
|
|
# @RELATION: TESTS -> backend.src.api.routes.datasets
|
|
|
|
import pytest
|
|
from unittest.mock import MagicMock, patch, AsyncMock
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
from src.api.routes.datasets import DatasetsResponse, DatasetDetailResponse
|
|
|
|
client = TestClient(app)
|
|
|
|
|
|
# [DEF:test_get_datasets_success:Function]
|
|
# @TEST: GET /api/datasets returns 200 and valid schema
|
|
# @PRE: env_id exists
|
|
# @POST: Response matches DatasetsResponse schema
|
|
def test_get_datasets_success():
|
|
with patch("src.api.routes.datasets.get_config_manager") as mock_config, \
|
|
patch("src.api.routes.datasets.get_resource_service") as mock_service, \
|
|
patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
|
|
# Mock environment
|
|
mock_env = MagicMock()
|
|
mock_env.id = "prod"
|
|
mock_config.return_value.get_environments.return_value = [mock_env]
|
|
|
|
# Mock resource service response
|
|
mock_service.return_value.get_datasets_with_status.return_value = AsyncMock()(
|
|
return_value=[
|
|
{
|
|
"id": 1,
|
|
"table_name": "sales_data",
|
|
"schema": "public",
|
|
"database": "sales_db",
|
|
"mapped_fields": {"total": 10, "mapped": 5},
|
|
"last_task": {"task_id": "task-1", "status": "SUCCESS"}
|
|
}
|
|
]
|
|
)
|
|
|
|
# Mock permission
|
|
mock_perm.return_value = lambda: True
|
|
|
|
response = client.get("/api/datasets?env_id=prod")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "datasets" in data
|
|
assert len(data["datasets"]) >= 0
|
|
# Validate against Pydantic model
|
|
DatasetsResponse(**data)
|
|
|
|
|
|
# [/DEF:test_get_datasets_success:Function]
|
|
|
|
|
|
# [DEF:test_get_datasets_env_not_found:Function]
|
|
# @TEST: GET /api/datasets returns 404 if env_id missing
|
|
# @PRE: env_id does not exist
|
|
# @POST: Returns 404 error
|
|
def test_get_datasets_env_not_found():
|
|
with patch("src.api.routes.datasets.get_config_manager") as mock_config, \
|
|
patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
|
|
mock_config.return_value.get_environments.return_value = []
|
|
mock_perm.return_value = lambda: True
|
|
|
|
response = client.get("/api/datasets?env_id=nonexistent")
|
|
|
|
assert response.status_code == 404
|
|
assert "Environment not found" in response.json()["detail"]
|
|
|
|
|
|
# [/DEF:test_get_datasets_env_not_found:Function]
|
|
|
|
|
|
# [DEF:test_get_datasets_invalid_pagination:Function]
|
|
# @TEST: GET /api/datasets returns 400 for invalid page/page_size
|
|
# @PRE: page < 1 or page_size > 100
|
|
# @POST: Returns 400 error
|
|
def test_get_datasets_invalid_pagination():
|
|
with patch("src.api.routes.datasets.get_config_manager") as mock_config, \
|
|
patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
|
|
mock_env = MagicMock()
|
|
mock_env.id = "prod"
|
|
mock_config.return_value.get_environments.return_value = [mock_env]
|
|
mock_perm.return_value = lambda: True
|
|
|
|
# Invalid page
|
|
response = client.get("/api/datasets?env_id=prod&page=0")
|
|
assert response.status_code == 400
|
|
assert "Page must be >= 1" in response.json()["detail"]
|
|
|
|
# Invalid page_size
|
|
response = client.get("/api/datasets?env_id=prod&page_size=0")
|
|
assert response.status_code == 400
|
|
assert "Page size must be between 1 and 100" in response.json()["detail"]
|
|
|
|
|
|
# [/DEF:test_get_datasets_invalid_pagination:Function]
|
|
|
|
|
|
# [DEF:test_map_columns_success:Function]
|
|
# @TEST: POST /api/datasets/map-columns creates mapping task
|
|
# @PRE: Valid env_id, dataset_ids, source_type
|
|
# @POST: Returns task_id
|
|
def test_map_columns_success():
|
|
with patch("src.api.routes.datasets.get_config_manager") as mock_config, \
|
|
patch("src.api.routes.datasets.get_task_manager") as mock_task_mgr, \
|
|
patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
|
|
# Mock environment
|
|
mock_env = MagicMock()
|
|
mock_env.id = "prod"
|
|
mock_config.return_value.get_environments.return_value = [mock_env]
|
|
|
|
# Mock task manager
|
|
mock_task = MagicMock()
|
|
mock_task.id = "task-123"
|
|
mock_task_mgr.return_value.create_task = AsyncMock(return_value=mock_task)
|
|
|
|
# Mock permission
|
|
mock_perm.return_value = lambda: True
|
|
|
|
response = client.post(
|
|
"/api/datasets/map-columns",
|
|
json={
|
|
"env_id": "prod",
|
|
"dataset_ids": [1, 2, 3],
|
|
"source_type": "postgresql"
|
|
}
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "task_id" in data
|
|
|
|
|
|
# [/DEF:test_map_columns_success:Function]
|
|
|
|
|
|
# [DEF:test_map_columns_invalid_source_type:Function]
|
|
# @TEST: POST /api/datasets/map-columns returns 400 for invalid source_type
|
|
# @PRE: source_type is not 'postgresql' or 'xlsx'
|
|
# @POST: Returns 400 error
|
|
def test_map_columns_invalid_source_type():
|
|
with patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
mock_perm.return_value = lambda: True
|
|
|
|
response = client.post(
|
|
"/api/datasets/map-columns",
|
|
json={
|
|
"env_id": "prod",
|
|
"dataset_ids": [1],
|
|
"source_type": "invalid"
|
|
}
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
assert "Source type must be 'postgresql' or 'xlsx'" in response.json()["detail"]
|
|
|
|
|
|
# [/DEF:test_map_columns_invalid_source_type:Function]
|
|
|
|
|
|
# [DEF:test_generate_docs_success:Function]
|
|
# @TEST: POST /api/datasets/generate-docs creates doc generation task
|
|
# @PRE: Valid env_id, dataset_ids, llm_provider
|
|
# @POST: Returns task_id
|
|
def test_generate_docs_success():
|
|
with patch("src.api.routes.datasets.get_config_manager") as mock_config, \
|
|
patch("src.api.routes.datasets.get_task_manager") as mock_task_mgr, \
|
|
patch("src.api.routes.datasets.has_permission") as mock_perm:
|
|
|
|
# Mock environment
|
|
mock_env = MagicMock()
|
|
mock_env.id = "prod"
|
|
mock_config.return_value.get_environments.return_value = [mock_env]
|
|
|
|
# Mock task manager
|
|
mock_task = MagicMock()
|
|
mock_task.id = "task-456"
|
|
mock_task_mgr.return_value.create_task = AsyncMock(return_value=mock_task)
|
|
|
|
# Mock permission
|
|
mock_perm.return_value = lambda: True
|
|
|
|
response = client.post(
|
|
"/api/datasets/generate-docs",
|
|
json={
|
|
"env_id": "prod",
|
|
"dataset_ids": [1],
|
|
"llm_provider": "openai"
|
|
}
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "task_id" in data
|
|
|
|
|
|
# [/DEF:test_generate_docs_success:Function]
|
|
|
|
|
|
# [/DEF:backend.src.api.routes.__tests__.test_datasets:Module] |