dataloader/tests/integration_tests/test_api_endpoints.py

173 lines
4.9 KiB
Python

# tests/integration_tests/test_api_endpoints.py
from __future__ import annotations
import pytest
from httpx import AsyncClient
@pytest.mark.integration
class TestJobsAPI:
"""
Интеграционные тесты для API endpoints.
"""
async def test_trigger_job_creates_new_job(
self,
client: AsyncClient,
clean_queue_tables,
queue_name: str,
task_name: str,
):
"""
Тест создания новой задачи через API.
"""
payload = {
"queue": queue_name,
"task": task_name,
"args": {"test_key": "test_value"},
"lock_key": "lock_api_1",
"partition_key": "part1",
"priority": 100,
"max_attempts": 5,
"lease_ttl_sec": 60,
}
response = await client.post("/api/v1/jobs/trigger", json=payload)
assert response.status_code == 200
data = response.json()
assert "job_id" in data
assert data["status"] == "queued"
async def test_trigger_job_with_idempotency_key(
self,
client: AsyncClient,
clean_queue_tables,
queue_name: str,
task_name: str,
):
"""
Тест идемпотентности через idempotency_key.
"""
payload = {
"queue": queue_name,
"task": task_name,
"args": {},
"idempotency_key": "unique_key_123",
"lock_key": "lock_idem",
"priority": 100,
"max_attempts": 5,
"lease_ttl_sec": 60,
}
response1 = await client.post("/api/v1/jobs/trigger", json=payload)
response2 = await client.post("/api/v1/jobs/trigger", json=payload)
assert response1.status_code == 200
assert response2.status_code == 200
data1 = response1.json()
data2 = response2.json()
assert data1["job_id"] == data2["job_id"]
assert data1["status"] == data2["status"] == "queued"
async def test_get_status_returns_job_status(
self,
client: AsyncClient,
clean_queue_tables,
queue_name: str,
task_name: str,
):
"""
Тест получения статуса задачи через API.
"""
payload = {
"queue": queue_name,
"task": task_name,
"args": {},
"lock_key": "lock_status",
"priority": 100,
"max_attempts": 5,
"lease_ttl_sec": 60,
}
create_response = await client.post("/api/v1/jobs/trigger", json=payload)
job_id = create_response.json()["job_id"]
status_response = await client.get(f"/api/v1/jobs/{job_id}/status")
assert status_response.status_code == 200
data = status_response.json()
assert data["job_id"] == job_id
assert data["status"] == "queued"
assert data["attempt"] == 0
async def test_get_status_returns_404_for_nonexistent_job(
self,
client: AsyncClient,
clean_queue_tables,
):
"""
Тест получения статуса несуществующей задачи.
"""
fake_job_id = "00000000-0000-0000-0000-000000000000"
response = await client.get(f"/api/v1/jobs/{fake_job_id}/status")
assert response.status_code == 404
async def test_cancel_job_sets_cancel_flag(
self,
client: AsyncClient,
clean_queue_tables,
queue_name: str,
task_name: str,
):
"""
Тест отмены задачи через API.
"""
payload = {
"queue": queue_name,
"task": task_name,
"args": {},
"lock_key": "lock_cancel",
"priority": 100,
"max_attempts": 5,
"lease_ttl_sec": 60,
}
create_response = await client.post("/api/v1/jobs/trigger", json=payload)
job_id = create_response.json()["job_id"]
cancel_response = await client.post(f"/api/v1/jobs/{job_id}/cancel")
assert cancel_response.status_code == 200
data = cancel_response.json()
assert data["job_id"] == job_id
async def test_cancel_nonexistent_job_returns_404(
self,
client: AsyncClient,
clean_queue_tables,
):
"""
Тест отмены несуществующей задачи.
"""
fake_job_id = "00000000-0000-0000-0000-000000000000"
response = await client.post(f"/api/v1/jobs/{fake_job_id}/cancel")
assert response.status_code == 404
async def test_health_endpoint_returns_200(
self,
client: AsyncClient,
):
"""
Тест health check endpoint.
"""
response = await client.get("/health")
assert response.status_code == 200