Files
2026-07-13 13:08:41 +08:00

115 lines
3.2 KiB
Python

import asyncio
from datetime import datetime, timezone
from typing import Any
import pytest
from fastapi import HTTPException
from sqlalchemy.dialects import sqlite
from api.v1.async_tasks.router import (
API_V1_ASYNC_TASKS_ROUTER,
check_async_task_status,
list_async_tasks,
)
from models.sql.async_task import AsyncTaskModel
class _RowsResult:
def __init__(self, rows: list[Any]):
self._rows = rows
def scalars(self):
return self
def all(self):
return self._rows
class _FakeAsyncSession:
def __init__(self, get_results: dict[Any, Any] | None = None):
self._get_results = get_results or {}
self.executed_statement = None
async def get(self, _model: Any, key: Any):
return self._get_results.get(key)
async def execute(self, statement: Any):
self.executed_statement = statement
return _RowsResult(list(self._get_results.values()))
def test_async_tasks_routes_use_hyphenated_endpoint():
paths = {route.path for route in API_V1_ASYNC_TASKS_ROUTER.routes}
assert "/api/v1/async-tasks" in paths
assert "/api/v1/async-tasks/status/{id}" in paths
assert "/api/v1/async_tasks" not in paths
def test_check_async_task_status_returns_task():
task = AsyncTaskModel(
type="template.create",
status="pending",
message="Queued for template creation",
)
response = asyncio.run(
check_async_task_status(
id=task.id,
sql_session=_FakeAsyncSession({task.id: task}),
)
)
assert response == task
def test_check_async_task_status_returns_404_for_missing_task():
with pytest.raises(HTTPException) as exc:
asyncio.run(
check_async_task_status(
id="task-missing",
sql_session=_FakeAsyncSession(),
)
)
assert exc.value.status_code == 404
assert exc.value.detail == "No async task found"
def test_list_async_tasks_filters_and_orders_tasks():
task = AsyncTaskModel(
type="template.create",
status="completed",
message="Template creation completed",
)
session = _FakeAsyncSession({task.id: task})
response = asyncio.run(
list_async_tasks(
task_type="template.create",
status="completed",
created_at=datetime(2026, 6, 1, tzinfo=timezone.utc),
created_at_from=None,
created_at_to=datetime(2026, 6, 30, tzinfo=timezone.utc),
order_by="updated_at",
order="asc",
limit=25,
offset=5,
sql_session=session,
)
)
assert response == [task]
compiled = str(
session.executed_statement.compile(
dialect=sqlite.dialect(),
compile_kwargs={"literal_binds": True},
)
)
assert "WHERE async_tasks.type = 'template.create'" in compiled
assert "async_tasks.status = 'completed'" in compiled
assert "async_tasks.created_at >= '2026-06-01 00:00:00.000000'" in compiled
assert "async_tasks.created_at <= '2026-06-30 00:00:00.000000'" in compiled
assert "ORDER BY async_tasks.updated_at ASC" in compiled
assert "LIMIT 25 OFFSET 5" in compiled