262 lines
7.9 KiB
Python
262 lines
7.9 KiB
Python
"""
|
|
Tests for augmentation API routes.
|
|
|
|
TDD Phase 5: RED - Write tests first, then implement to pass.
|
|
"""
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
class TestAugmentationTypesEndpoint:
|
|
"""Tests for GET /admin/augmentation/types endpoint."""
|
|
|
|
def test_list_augmentation_types(
|
|
self, admin_client: TestClient, admin_token: str
|
|
) -> None:
|
|
"""Test listing available augmentation types."""
|
|
response = admin_client.get(
|
|
"/api/v1/admin/augmentation/types",
|
|
headers={"X-Admin-Token": admin_token},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "augmentation_types" in data
|
|
assert len(data["augmentation_types"]) == 12
|
|
|
|
# Check structure
|
|
aug_type = data["augmentation_types"][0]
|
|
assert "name" in aug_type
|
|
assert "description" in aug_type
|
|
assert "affects_geometry" in aug_type
|
|
assert "stage" in aug_type
|
|
|
|
def test_list_augmentation_types_unauthorized(
|
|
self, admin_client: TestClient
|
|
) -> None:
|
|
"""Test that unauthorized request is rejected."""
|
|
response = admin_client.get("/api/v1/admin/augmentation/types")
|
|
|
|
assert response.status_code == 401
|
|
|
|
|
|
class TestAugmentationPresetsEndpoint:
|
|
"""Tests for GET /admin/augmentation/presets endpoint."""
|
|
|
|
def test_list_presets(self, admin_client: TestClient, admin_token: str) -> None:
|
|
"""Test listing available presets."""
|
|
response = admin_client.get(
|
|
"/api/v1/admin/augmentation/presets",
|
|
headers={"X-Admin-Token": admin_token},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "presets" in data
|
|
assert len(data["presets"]) >= 4
|
|
|
|
# Check expected presets exist
|
|
preset_names = [p["name"] for p in data["presets"]]
|
|
assert "conservative" in preset_names
|
|
assert "moderate" in preset_names
|
|
assert "aggressive" in preset_names
|
|
assert "scanned_document" in preset_names
|
|
|
|
|
|
class TestAugmentationPreviewEndpoint:
|
|
"""Tests for POST /admin/augmentation/preview/{document_id} endpoint."""
|
|
|
|
def test_preview_augmentation(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
sample_document_id: str,
|
|
) -> None:
|
|
"""Test previewing augmentation on a document."""
|
|
response = admin_client.post(
|
|
f"/api/v1/admin/augmentation/preview/{sample_document_id}",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"augmentation_type": "gaussian_noise",
|
|
"params": {"std": 15},
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "preview_url" in data
|
|
assert "original_url" in data
|
|
assert "applied_params" in data
|
|
|
|
def test_preview_invalid_augmentation_type(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
sample_document_id: str,
|
|
) -> None:
|
|
"""Test that invalid augmentation type returns error."""
|
|
response = admin_client.post(
|
|
f"/api/v1/admin/augmentation/preview/{sample_document_id}",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"augmentation_type": "nonexistent",
|
|
"params": {},
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
|
|
def test_preview_nonexistent_document(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
) -> None:
|
|
"""Test that nonexistent document returns 404."""
|
|
response = admin_client.post(
|
|
"/api/v1/admin/augmentation/preview/00000000-0000-0000-0000-000000000000",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"augmentation_type": "gaussian_noise",
|
|
"params": {},
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 404
|
|
|
|
|
|
class TestAugmentationPreviewConfigEndpoint:
|
|
"""Tests for POST /admin/augmentation/preview-config/{document_id} endpoint."""
|
|
|
|
def test_preview_config(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
sample_document_id: str,
|
|
) -> None:
|
|
"""Test previewing full config on a document."""
|
|
response = admin_client.post(
|
|
f"/api/v1/admin/augmentation/preview-config/{sample_document_id}",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"gaussian_noise": {"enabled": True, "probability": 1.0},
|
|
"lighting_variation": {"enabled": True, "probability": 1.0},
|
|
"preserve_bboxes": True,
|
|
"seed": 42,
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "preview_url" in data
|
|
assert "original_url" in data
|
|
|
|
|
|
class TestAugmentationBatchEndpoint:
|
|
"""Tests for POST /admin/augmentation/batch endpoint."""
|
|
|
|
def test_create_augmented_dataset(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
sample_dataset_id: str,
|
|
) -> None:
|
|
"""Test creating augmented dataset."""
|
|
response = admin_client.post(
|
|
"/api/v1/admin/augmentation/batch",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"dataset_id": sample_dataset_id,
|
|
"config": {
|
|
"gaussian_noise": {"enabled": True, "probability": 0.5},
|
|
"preserve_bboxes": True,
|
|
},
|
|
"output_name": "test_augmented_dataset",
|
|
"multiplier": 2,
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "task_id" in data
|
|
assert "status" in data
|
|
assert "estimated_images" in data
|
|
|
|
def test_create_augmented_dataset_invalid_multiplier(
|
|
self,
|
|
admin_client: TestClient,
|
|
admin_token: str,
|
|
sample_dataset_id: str,
|
|
) -> None:
|
|
"""Test that invalid multiplier is rejected."""
|
|
response = admin_client.post(
|
|
"/api/v1/admin/augmentation/batch",
|
|
headers={"X-Admin-Token": admin_token},
|
|
json={
|
|
"dataset_id": sample_dataset_id,
|
|
"config": {},
|
|
"output_name": "test",
|
|
"multiplier": 100, # Too high
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 422 # Validation error
|
|
|
|
|
|
class TestAugmentedDatasetsListEndpoint:
|
|
"""Tests for GET /admin/augmentation/datasets endpoint."""
|
|
|
|
def test_list_augmented_datasets(
|
|
self, admin_client: TestClient, admin_token: str
|
|
) -> None:
|
|
"""Test listing augmented datasets."""
|
|
response = admin_client.get(
|
|
"/api/v1/admin/augmentation/datasets",
|
|
headers={"X-Admin-Token": admin_token},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert "total" in data
|
|
assert "limit" in data
|
|
assert "offset" in data
|
|
assert "datasets" in data
|
|
assert isinstance(data["datasets"], list)
|
|
|
|
def test_list_augmented_datasets_pagination(
|
|
self, admin_client: TestClient, admin_token: str
|
|
) -> None:
|
|
"""Test pagination parameters."""
|
|
response = admin_client.get(
|
|
"/api/v1/admin/augmentation/datasets",
|
|
headers={"X-Admin-Token": admin_token},
|
|
params={"limit": 5, "offset": 0},
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
assert data["limit"] == 5
|
|
assert data["offset"] == 0
|
|
|
|
|
|
# Fixtures for tests
|
|
@pytest.fixture
|
|
def sample_document_id() -> str:
|
|
"""Provide a sample document ID for testing."""
|
|
# This would need to be created in test setup
|
|
return "test-document-id"
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_dataset_id() -> str:
|
|
"""Provide a sample dataset ID for testing."""
|
|
# This would need to be created in test setup
|
|
return "test-dataset-id"
|