Files

140 lines
4.7 KiB
Python
Raw Permalink Normal View History

"""Tests for the mail signature PATCH/DELETE and label DELETE endpoints (I-D fix).
Proves the previously missing routes now work end-to-end:
- PATCH /api/v1/mail/signatures/{id} -> 200 with updated values
- DELETE /api/v1/mail/signatures/{id} -> 204, row gone
- DELETE /api/v1/mail/labels/{id} -> 204, row gone
- 404 for unknown IDs
"""
from __future__ import annotations
import pytest
import pytest_asyncio
from httpx import ASGITransport, AsyncClient
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
from app.core.db import close_engine, reset_engine_for_testing
from app.core.permission_registry import init_permission_registry
from app.core.service_container import get_container
from app.main import create_app
from app.plugins.builtins.mail import MailPlugin
from app.plugins.registry import reset_registry_for_testing
from app.services.plugin_service import reset_plugin_service_for_testing
from tests.conftest import ORIGIN_HEADER, login_client, seed_tenant_and_users
@pytest_asyncio.fixture
async def mail_app(engine: AsyncEngine, redis_client):
"""FastAPI app with Mail plugin registered."""
reset_engine_for_testing(engine)
app = create_app()
registry = reset_registry_for_testing()
registry.initialize(engine, app)
init_permission_registry(active_plugin_names={"mail"})
container = get_container()
await container.initialize()
registry.register_plugin(MailPlugin())
reset_plugin_service_for_testing(registry)
sf = async_sessionmaker(bind=engine, expire_on_commit=False, class_=AsyncSession)
async with sf() as session:
await registry.install(session, "mail")
await registry.activate(session, "mail")
await session.commit()
yield app
await close_engine()
@pytest_asyncio.fixture
async def mail_client(mail_app) -> AsyncClient:
transport = ASGITransport(app=mail_app)
async with AsyncClient(transport=transport, base_url="http://test") as c:
yield c
@pytest_asyncio.fixture
async def authed_client(
mail_client: AsyncClient, db_session: AsyncSession
) -> AsyncClient:
seed = await seed_tenant_and_users(db_session)
assert seed is not None
await login_client(mail_client, "admin@tenanta.com")
return mail_client
async def _create_signature(client: AsyncClient) -> dict:
resp = await client.post(
"/api/v1/mail/signatures",
json={"name": "Old Name", "body_html": "<p>old</p>", "is_default": False},
headers=ORIGIN_HEADER,
)
assert resp.status_code == 201, resp.text
return resp.json()
async def _create_label(client: AsyncClient) -> dict:
resp = await client.post(
"/api/v1/mail/labels",
json={"name": "Temp Label", "color": "#ff0000"},
headers=ORIGIN_HEADER,
)
assert resp.status_code == 201, resp.text
return resp.json()
@pytest.mark.asyncio
async def test_update_signature(authed_client: AsyncClient):
sig = await _create_signature(authed_client)
resp = await authed_client.patch(
f"/api/v1/mail/signatures/{sig['id']}",
json={"name": "New Name", "body_html": "<p>new</p>", "is_default": True},
headers=ORIGIN_HEADER,
)
assert resp.status_code == 200, resp.text
data = resp.json()
assert data["name"] == "New Name"
assert data["body_html"] == "<p>new</p>"
assert data["is_default"] is True
@pytest.mark.asyncio
async def test_delete_signature(authed_client: AsyncClient):
sig = await _create_signature(authed_client)
resp = await authed_client.delete(
f"/api/v1/mail/signatures/{sig['id']}",
headers=ORIGIN_HEADER,
)
assert resp.status_code == 204, resp.text
lst = await authed_client.get("/api/v1/mail/signatures", headers=ORIGIN_HEADER)
assert all(s["id"] != sig["id"] for s in lst.json())
@pytest.mark.asyncio
async def test_delete_label(authed_client: AsyncClient):
label = await _create_label(authed_client)
resp = await authed_client.delete(
f"/api/v1/mail/labels/{label['id']}",
headers=ORIGIN_HEADER,
)
assert resp.status_code == 204, resp.text
lst = await authed_client.get("/api/v1/mail/labels", headers=ORIGIN_HEADER)
assert all(lb["id"] != label["id"] for lb in lst.json())
@pytest.mark.asyncio
async def test_delete_unknown_signature_404(authed_client: AsyncClient):
resp = await authed_client.delete(
"/api/v1/mail/signatures/00000000-0000-0000-0000-000000000000",
headers=ORIGIN_HEADER,
)
assert resp.status_code == 404, resp.text
@pytest.mark.asyncio
async def test_delete_unknown_label_404(authed_client: AsyncClient):
resp = await authed_client.delete(
"/api/v1/mail/labels/00000000-0000-0000-0000-000000000000",
headers=ORIGIN_HEADER,
)
assert resp.status_code == 404, resp.text