109 lines
3.1 KiB
Python
109 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock
|
|
|
|
import pytest
|
|
|
|
from cpv3.modules.tasks.schemas import CaptionsGenerateRequest, TaskWebhookEvent
|
|
from cpv3.modules.tasks.service import TaskService
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_submit_captions_generate_reuses_existing_active_job() -> None:
|
|
service = TaskService(session=AsyncMock())
|
|
existing_job_id = uuid.uuid4()
|
|
existing_job = SimpleNamespace(
|
|
id=existing_job_id,
|
|
status="RUNNING",
|
|
)
|
|
|
|
service._find_duplicate_active_job = AsyncMock(return_value=existing_job)
|
|
service._submit_task = AsyncMock()
|
|
|
|
response = await service.submit_captions_generate(
|
|
requester=SimpleNamespace(id=uuid.uuid4()),
|
|
request=CaptionsGenerateRequest(
|
|
video_s3_path="projects/test/video.mp4",
|
|
folder="output_files",
|
|
transcription_id=uuid.uuid4(),
|
|
project_id=uuid.uuid4(),
|
|
preset_id=uuid.uuid4(),
|
|
),
|
|
)
|
|
|
|
assert response.job_id == existing_job_id
|
|
assert response.status == "RUNNING"
|
|
assert response.webhook_url.endswith(f"/api/tasks/webhook/{existing_job_id}/")
|
|
service._submit_task.assert_not_awaited()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_record_webhook_event_ignores_cancelled_job() -> None:
|
|
cancelled_job = SimpleNamespace(
|
|
id=uuid.uuid4(),
|
|
status="CANCELLED",
|
|
)
|
|
job_repo = SimpleNamespace(
|
|
get_by_id=AsyncMock(return_value=cancelled_job),
|
|
update=AsyncMock(),
|
|
)
|
|
event_repo = SimpleNamespace(create=AsyncMock())
|
|
|
|
service = TaskService(session=AsyncMock())
|
|
service._job_repo = job_repo
|
|
service._event_repo = event_repo
|
|
|
|
result = await service.record_webhook_event(
|
|
job_id=cancelled_job.id,
|
|
event=TaskWebhookEvent(
|
|
status="DONE",
|
|
current_message="Готово",
|
|
output_data={"output_path": "projects/test/output.mp4"},
|
|
),
|
|
)
|
|
|
|
assert result is cancelled_job
|
|
job_repo.update.assert_not_awaited()
|
|
event_repo.create.assert_not_awaited()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_cancel_job_marks_job_cancelled_and_keeps_record() -> None:
|
|
job_id = uuid.uuid4()
|
|
user_id = uuid.uuid4()
|
|
job = SimpleNamespace(
|
|
id=job_id,
|
|
status="PENDING",
|
|
broker_id="default:redis-message-id",
|
|
job_type="CAPTIONS_GENERATE",
|
|
user_id=user_id,
|
|
)
|
|
cancelled_job = SimpleNamespace(
|
|
id=job_id,
|
|
status="CANCELLED",
|
|
broker_id="default:redis-message-id",
|
|
job_type="CAPTIONS_GENERATE",
|
|
user_id=user_id,
|
|
current_message="Отменено пользователем",
|
|
)
|
|
|
|
service = TaskService(session=AsyncMock())
|
|
service._job_repo = SimpleNamespace(update=AsyncMock(return_value=cancelled_job))
|
|
service._event_repo = SimpleNamespace(create=AsyncMock())
|
|
service._cancel_dramatiq_message = AsyncMock()
|
|
service._cancel_caption_render = AsyncMock()
|
|
service._create_cancellation_notification = AsyncMock()
|
|
|
|
result = await service.cancel_job(job)
|
|
|
|
assert result is cancelled_job
|
|
service._job_repo.update.assert_awaited_once()
|
|
service._event_repo.create.assert_awaited_once()
|
|
service._cancel_dramatiq_message.assert_awaited_once_with(job.broker_id)
|
|
service._cancel_caption_render.assert_awaited_once_with(job)
|
|
service._create_cancellation_notification.assert_awaited_once_with(
|
|
cancelled_job
|
|
)
|