chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
import asyncio
|
||||
from types import SimpleNamespace
|
||||
import uuid
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from fastapi import BackgroundTasks, HTTPException
|
||||
from pydantic import ValidationError
|
||||
|
||||
from api.v1.ppt.endpoints.presentation import (
|
||||
check_async_presentation_generation_status,
|
||||
generate_presentation_async,
|
||||
generate_presentation_sync,
|
||||
)
|
||||
from models.generate_presentation_request import GeneratePresentationRequest
|
||||
from models.presentation_and_path import PresentationPathAndEditPath
|
||||
from models.sql.async_task import AsyncTaskModel
|
||||
|
||||
|
||||
class FakeRequest:
|
||||
def __init__(self):
|
||||
self.headers: dict[str, str] = {}
|
||||
self.cookies: dict[str, str] = {}
|
||||
self.state = SimpleNamespace()
|
||||
|
||||
|
||||
class FakeAsyncSession:
|
||||
def __init__(self, get_results=None):
|
||||
self._get_results = get_results or {}
|
||||
self.added = []
|
||||
self.commit_count = 0
|
||||
|
||||
async def get(self, *_args, **_kwargs):
|
||||
if len(_args) >= 2:
|
||||
return self._get_results.get(_args[1])
|
||||
return None
|
||||
|
||||
def add(self, obj, *_args, **_kwargs):
|
||||
self.added.append(obj)
|
||||
return None
|
||||
|
||||
def add_all(self, *_args, **_kwargs):
|
||||
return None
|
||||
|
||||
async def commit(self):
|
||||
self.commit_count += 1
|
||||
return None
|
||||
|
||||
async def refresh(self, *_args, **_kwargs):
|
||||
return None
|
||||
|
||||
|
||||
class TestPresentationGenerationAPI:
|
||||
def test_generate_presentation_export_as_pdf(self):
|
||||
request = GeneratePresentationRequest(
|
||||
content="Create a presentation about artificial intelligence and machine learning",
|
||||
n_slides=5,
|
||||
language="English",
|
||||
export_as="pdf",
|
||||
template="general",
|
||||
)
|
||||
response_payload = PresentationPathAndEditPath(
|
||||
presentation_id=uuid.uuid4(),
|
||||
path="/tmp/exports/test.pdf",
|
||||
edit_path="/presentation?id=test",
|
||||
)
|
||||
|
||||
with patch(
|
||||
"api.v1.ppt.endpoints.presentation.generate_presentation_handler",
|
||||
new=AsyncMock(return_value=response_payload),
|
||||
) as mock_handler:
|
||||
response = asyncio.run(
|
||||
generate_presentation_sync(
|
||||
request_http=FakeRequest(),
|
||||
request=request,
|
||||
sql_session=FakeAsyncSession(),
|
||||
)
|
||||
)
|
||||
|
||||
assert response == response_payload
|
||||
mock_handler.assert_awaited_once()
|
||||
|
||||
def test_generate_presentation_export_as_pptx(self):
|
||||
request = GeneratePresentationRequest(
|
||||
content="Create a presentation about artificial intelligence and machine learning",
|
||||
n_slides=5,
|
||||
language="English",
|
||||
export_as="pptx",
|
||||
template="general",
|
||||
)
|
||||
response_payload = PresentationPathAndEditPath(
|
||||
presentation_id=uuid.uuid4(),
|
||||
path="/tmp/exports/test.pptx",
|
||||
edit_path="/presentation?id=test",
|
||||
)
|
||||
|
||||
with patch(
|
||||
"api.v1.ppt.endpoints.presentation.generate_presentation_handler",
|
||||
new=AsyncMock(return_value=response_payload),
|
||||
) as mock_handler:
|
||||
response = asyncio.run(
|
||||
generate_presentation_sync(
|
||||
request_http=FakeRequest(),
|
||||
request=request,
|
||||
sql_session=FakeAsyncSession(),
|
||||
)
|
||||
)
|
||||
|
||||
assert response == response_payload
|
||||
mock_handler.assert_awaited_once()
|
||||
|
||||
def test_generate_presentation_async_enqueues_async_task(self):
|
||||
request = GeneratePresentationRequest(
|
||||
content="Create a presentation about async task tracking",
|
||||
n_slides=5,
|
||||
language="English",
|
||||
export_as="pptx",
|
||||
template="general",
|
||||
)
|
||||
background_tasks = BackgroundTasks()
|
||||
fake_session = FakeAsyncSession()
|
||||
|
||||
task = asyncio.run(
|
||||
generate_presentation_async(
|
||||
request_http=FakeRequest(),
|
||||
request=request,
|
||||
background_tasks=background_tasks,
|
||||
sql_session=fake_session,
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(task, AsyncTaskModel)
|
||||
assert task.type == "presentation.generate"
|
||||
assert task.status == "pending"
|
||||
assert task.message == "Queued for generation"
|
||||
assert task.data == {"created_slides": 0, "remaining_slides": 5}
|
||||
assert fake_session.added == [task]
|
||||
assert fake_session.commit_count == 1
|
||||
assert len(background_tasks.tasks) == 1
|
||||
|
||||
def test_presentation_status_reads_async_task(self):
|
||||
task = AsyncTaskModel(
|
||||
type="presentation.generate",
|
||||
status="completed",
|
||||
message="Presentation generation completed",
|
||||
data={"created_slides": 5, "remaining_slides": 0},
|
||||
)
|
||||
fake_session = FakeAsyncSession({task.id: task})
|
||||
|
||||
response = asyncio.run(
|
||||
check_async_presentation_generation_status(
|
||||
id=task.id,
|
||||
sql_session=fake_session,
|
||||
)
|
||||
)
|
||||
|
||||
assert response == task
|
||||
|
||||
def test_generate_presentation_with_no_content(self):
|
||||
with pytest.raises(ValidationError):
|
||||
GeneratePresentationRequest.model_validate(
|
||||
{
|
||||
"n_slides": 5,
|
||||
"language": "English",
|
||||
"export_as": "pdf",
|
||||
"template": "general",
|
||||
}
|
||||
)
|
||||
|
||||
def test_generate_presentation_with_n_slides_less_than_one(self):
|
||||
request = GeneratePresentationRequest(
|
||||
content="Create a presentation about artificial intelligence and machine learning",
|
||||
n_slides=0,
|
||||
language="English",
|
||||
export_as="pdf",
|
||||
template="general",
|
||||
)
|
||||
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
asyncio.run(
|
||||
generate_presentation_sync(
|
||||
request_http=FakeRequest(),
|
||||
request=request,
|
||||
sql_session=FakeAsyncSession(),
|
||||
)
|
||||
)
|
||||
|
||||
assert exc.value.status_code == 400
|
||||
assert exc.value.detail == "Number of slides must be greater than 0"
|
||||
|
||||
def test_generate_presentation_with_invalid_export_type(self):
|
||||
with pytest.raises(ValidationError):
|
||||
GeneratePresentationRequest.model_validate(
|
||||
{
|
||||
"content": "Create a presentation about artificial intelligence and machine learning",
|
||||
"n_slides": 5,
|
||||
"language": "English",
|
||||
"export_as": "invalid_type",
|
||||
"template": "general",
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user