Files
ss-tools/backend/tests/api/test_dashboard_action_routes.py
busya 977f3d6d75 chore: checkpoint working tree onto master
Carried over from 042-dashboard-scenario-registry:
- dashboard/migration backend changes + tests (dataset_key_sync)
- specs updates; drop generated doxygen artifacts
- research notes, integration artifacts, session log
2026-08-18 12:20:42 +03:00

158 lines
5.3 KiB
Python

# #region Test.Api.DashboardActionRoutes [C:3] [TYPE Module] [SEMANTICS test,dashboard,action,backup]
# @BRIEF Unit tests for dashboard action routes — backup.
# @RELATION BINDS_TO -> [Api.ActionRoutes.DashboardActionRoutes]
# @TEST_EDGE: empty_dashboard_ids -> 400
# @TEST_EDGE: env_not_found_backup -> 404
# @TEST_EDGE: task_creation_fail -> 503
import os
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-tests")
from pathlib import Path
import sys
from unittest.mock import AsyncMock, MagicMock
from fastapi import FastAPI
from fastapi.testclient import TestClient
_src = str(Path(__file__).resolve().parent.parent.parent / "src")
if _src not in sys.path:
sys.path.insert(0, _src)
def _make_client(overrides: dict | None = None) -> TestClient:
from src.api.routes.dashboards._action_routes import router
from src.dependencies import get_current_user
from src.schemas.auth import RoleSchema, User
app = FastAPI()
app.include_router(router)
mock_user = User(
id="admin-1", username="admin", email="admin@x.com",
auth_source="LOCAL",
created_at=__import__("datetime").datetime.now(),
roles=[RoleSchema(id="r1", name="Admin", description="", is_admin=True, permissions=[])],
)
defaults = {
get_current_user: lambda: mock_user,
}
if overrides:
defaults.update(overrides)
for dep, mock_fn in defaults.items():
app.dependency_overrides[dep] = mock_fn
return TestClient(app)
# ── backup_dashboards ──
class TestBackupDashboards:
"""POST /api/dashboards/backup"""
def test_backup_success(self):
"""Happy path: backup task created."""
env = MagicMock()
env.id = "env-1"
mock_config = MagicMock()
mock_config.get_environments.return_value = [env]
mock_task = MagicMock()
mock_task.id = "task-backup-1"
mock_task_manager = AsyncMock()
mock_task_manager.create_task.return_value = mock_task
from src.dependencies import get_config_manager, get_task_manager
client = _make_client({
get_config_manager: lambda: mock_config,
get_task_manager: lambda: mock_task_manager,
})
resp = client.post("/api/dashboards/backup", json={
"env_id": "env-1",
"dashboard_ids": [10, 20],
})
assert resp.status_code == 200
assert resp.json()["task_id"] == "task-backup-1"
def test_backup_empty_dashboard_ids(self):
"""Empty dashboard_ids returns 400."""
mock_config = MagicMock()
from src.dependencies import get_config_manager, get_task_manager
client = _make_client({
get_config_manager: lambda: mock_config,
get_task_manager: lambda: MagicMock(),
})
resp = client.post("/api/dashboards/backup", json={
"env_id": "env-1",
"dashboard_ids": [],
})
assert resp.status_code == 400
assert "At least one dashboard ID" in resp.text
def test_backup_env_not_found(self):
"""Non-existent env returns 404."""
mock_config = MagicMock()
mock_config.get_environments.return_value = []
from src.dependencies import get_config_manager, get_task_manager
client = _make_client({
get_config_manager: lambda: mock_config,
get_task_manager: lambda: MagicMock(),
})
resp = client.post("/api/dashboards/backup", json={
"env_id": "env-ghost",
"dashboard_ids": [1],
})
assert resp.status_code == 404
assert "Environment not found" in resp.text
def test_backup_with_schedule(self):
"""Backup with schedule."""
env = MagicMock()
env.id = "env-1"
mock_config = MagicMock()
mock_config.get_environments.return_value = [env]
mock_task = MagicMock()
mock_task.id = "task-sched"
mock_task_manager = AsyncMock()
mock_task_manager.create_task.return_value = mock_task
from src.dependencies import get_config_manager, get_task_manager
client = _make_client({
get_config_manager: lambda: mock_config,
get_task_manager: lambda: mock_task_manager,
})
resp = client.post("/api/dashboards/backup", json={
"env_id": "env-1",
"dashboard_ids": [1, 2],
"schedule": "0 0 * * *",
})
assert resp.status_code == 200
def test_backup_task_creation_fail(self):
"""Task creation failure returns 503."""
env = MagicMock()
env.id = "env-1"
mock_config = MagicMock()
mock_config.get_environments.return_value = [env]
mock_task_manager = AsyncMock()
mock_task_manager.create_task.side_effect = Exception("Queue full")
from src.dependencies import get_config_manager, get_task_manager
client = _make_client({
get_config_manager: lambda: mock_config,
get_task_manager: lambda: mock_task_manager,
})
resp = client.post("/api/dashboards/backup", json={
"env_id": "env-1",
"dashboard_ids": [1],
})
assert resp.status_code == 503
# #endregion Test.Api.DashboardActionRoutes