chore: something changed, commit before reorg

This commit is contained in:
Daniil
2026-04-27 23:19:04 +03:00
parent 259d3da89f
commit b9030a863e
19 changed files with 2753 additions and 146 deletions
@@ -0,0 +1,212 @@
from __future__ import annotations
import uuid
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from cpv3.modules.files.models import File
from cpv3.modules.projects.models import Project
from cpv3.modules.tasks.schemas import TaskSubmitResponse
from cpv3.modules.tasks.service import TaskService
from cpv3.modules.users.models import User
pytest.importorskip("greenlet")
@pytest.fixture
async def workflow_project(test_db_session: AsyncSession, test_user: User) -> Project:
project = Project(
id=uuid.uuid4(),
owner_id=test_user.id,
name="Workflow Project",
description="Typed workflow test project",
language="ru",
status="DRAFT",
is_active=True,
)
test_db_session.add(project)
await test_db_session.commit()
await test_db_session.refresh(project)
return project
@pytest.fixture
async def source_file(
test_db_session: AsyncSession,
test_user: User,
workflow_project: Project,
) -> File:
file = File(
id=uuid.uuid4(),
owner_id=test_user.id,
project_id=workflow_project.id,
original_filename="source.mp4",
path="users/test/source.mp4",
storage_backend="S3",
mime_type="video/mp4",
size_bytes=1024,
file_format="mp4",
is_uploaded=True,
is_deleted=False,
)
test_db_session.add(file)
await test_db_session.commit()
await test_db_session.refresh(file)
return file
class TestProjectWorkspaceEndpoints:
async def test_get_workspace_returns_default_state(
self,
auth_client: AsyncClient,
workflow_project: Project,
) -> None:
response = await auth_client.get(f"/api/projects/{workflow_project.id}/workspace")
assert response.status_code == 200
data = response.json()
assert data["project_id"] == str(workflow_project.id)
assert data["revision"] == 0
assert data["version"] == 1
assert data["phase"] == "INGEST"
assert data["current_screen"] == "upload"
assert data["source_file_id"] is None
assert data["active_job"] is None
assert data["workspace_view"] == {
"used_file_ids": [],
"selected_file_id": None,
}
async def test_get_workspace_forbidden_for_other_users_project(
self,
auth_client: AsyncClient,
test_db_session: AsyncSession,
other_user: User,
) -> None:
foreign_project = Project(
id=uuid.uuid4(),
owner_id=other_user.id,
name="Other Project",
description=None,
language="ru",
status="DRAFT",
is_active=True,
)
test_db_session.add(foreign_project)
await test_db_session.commit()
response = await auth_client.get(f"/api/projects/{foreign_project.id}/workspace")
assert response.status_code == 403
async def test_set_source_file_action_updates_workspace(
self,
auth_client: AsyncClient,
workflow_project: Project,
source_file: File,
) -> None:
response = await auth_client.post(
f"/api/projects/{workflow_project.id}/workflow/actions",
json={
"type": "SET_SOURCE_FILE",
"revision": 0,
"file_id": str(source_file.id),
},
)
assert response.status_code == 200
data = response.json()
assert data["revision"] == 1
assert data["phase"] == "VERIFY"
assert data["current_screen"] == "verify"
assert data["source_file_id"] == str(source_file.id)
assert data["workspace_view"] == {
"used_file_ids": [str(source_file.id)],
"selected_file_id": str(source_file.id),
}
async def test_action_returns_conflict_on_stale_revision(
self,
auth_client: AsyncClient,
workflow_project: Project,
source_file: File,
) -> None:
first_response = await auth_client.post(
f"/api/projects/{workflow_project.id}/workflow/actions",
json={
"type": "SET_SOURCE_FILE",
"revision": 0,
"file_id": str(source_file.id),
},
)
assert first_response.status_code == 200
response = await auth_client.post(
f"/api/projects/{workflow_project.id}/workflow/actions",
json={
"type": "RESET_SOURCE_FILE",
"revision": 0,
},
)
assert response.status_code == 409
async def test_start_media_convert_action_sets_active_job(
self,
auth_client: AsyncClient,
workflow_project: Project,
source_file: File,
monkeypatch: pytest.MonkeyPatch,
) -> None:
async def fake_submit_media_convert(
self,
*,
requester: User,
request,
) -> TaskSubmitResponse:
assert requester.id == workflow_project.owner_id
assert request.file_key == source_file.path
assert request.project_id == workflow_project.id
return TaskSubmitResponse(
job_id=uuid.UUID("00000000-0000-4000-a000-000000000123"),
webhook_url=("http://test/api/tasks/webhook/00000000-0000-4000-a000-000000000123/"),
status="PENDING",
)
monkeypatch.setattr(
TaskService,
"submit_media_convert",
fake_submit_media_convert,
)
set_source_response = await auth_client.post(
f"/api/projects/{workflow_project.id}/workflow/actions",
json={
"type": "SET_SOURCE_FILE",
"revision": 0,
"file_id": str(source_file.id),
},
)
assert set_source_response.status_code == 200
response = await auth_client.post(
f"/api/projects/{workflow_project.id}/workflow/actions",
json={
"type": "START_MEDIA_CONVERT",
"revision": 1,
"output_format": "mp4",
"out_folder": "output_files",
},
)
assert response.status_code == 200
data = response.json()
assert data["revision"] == 2
assert data["phase"] == "VERIFY"
assert data["current_screen"] == "verify"
assert data["active_job"] == {
"job_id": "00000000-0000-4000-a000-000000000123",
"job_type": "MEDIA_CONVERT",
}