# tests/integrations/test_api_v1.py import pytest from httpx import AsyncClient @pytest.mark.anyio async def test_trigger_and_get_status_ok(client: AsyncClient): """ Тест проверяет успешное создание задачи и получение её статуса. """ # 1. Триггер задачи trigger_payload = { "queue": "test_queue", "task": "test_task", "lock_key": "lock_123", } response = await client.post("/api/v1/jobs/trigger", json=trigger_payload) # Проверки ответа на триггер assert response.status_code == 200 response_data = response.json() assert "job_id" in response_data assert response_data["status"] == "queued" job_id = response_data["job_id"] # 2. Получение статуса response = await client.get(f"/api/v1/jobs/{job_id}/status") # Проверки ответа на статус assert response.status_code == 200 status_data = response.json() assert status_data["job_id"] == job_id assert status_data["status"] == "queued" assert status_data["attempt"] == 0 @pytest.mark.anyio async def test_cancel_job_ok(client: AsyncClient): """ Тест проверяет успешную отмену задачи. """ # 1. Триггер задачи trigger_payload = { "queue": "cancel_queue", "task": "cancel_task", "lock_key": "lock_cancel", } response = await client.post("/api/v1/jobs/trigger", json=trigger_payload) assert response.status_code == 200 job_id = response.json()["job_id"] # 2. Запрос на отмену response = await client.post(f"/api/v1/jobs/{job_id}/cancel") assert response.status_code == 200 cancel_data = response.json() assert cancel_data["job_id"] == job_id # Воркер еще не взял задачу, поэтому статус queued, но cancel_requested уже true assert cancel_data["status"] == "queued" # 3. Проверка статуса после отмены response = await client.get(f"/api/v1/jobs/{job_id}/status") assert response.status_code == 200 status_data = response.json() assert status_data["job_id"] == job_id # Задача еще не отменена, а только запрошена к отмене assert status_data["status"] == "queued" @pytest.mark.anyio async def test_trigger_duplicate_idempotency_key(client: AsyncClient): """ Тест проверяет, что повторная отправка с тем же ключом идемпотентности возвращает ту же самую задачу. """ idempotency_key = "idem_key_123" trigger_payload = { "queue": "idempotent_queue", "task": "idempotent_task", "lock_key": "lock_idem", "idempotency_key": idempotency_key, } # 1. Первый запрос response1 = await client.post("/api/v1/jobs/trigger", json=trigger_payload) assert response1.status_code == 200 job_id1 = response1.json()["job_id"] # 2. Второй запрос с тем же ключом response2 = await client.post("/api/v1/jobs/trigger", json=trigger_payload) assert response2.status_code == 200 job_id2 = response2.json()["job_id"] # ID задач должны совпадать assert job_id1 == job_id2