124 lines
4.3 KiB
Python
124 lines
4.3 KiB
Python
"""
|
|
Pruebas de aislamiento multi-tenant para tickets y usuarios.
|
|
Usa solo los fixtures definidos en conftest.py.
|
|
|
|
Roles en juego:
|
|
client_tenant_a → SUPPORT_MANAGER (aduanasoft) — restringido a su tenant
|
|
client_tenant_b → CLIENT_ADMIN (empresa-test) — restringido a su tenant
|
|
client_admin → ADMIN global (aduanasoft) — acceso a todos los tenants
|
|
"""
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tenant_a_cannot_see_tenant_b_tickets(
|
|
client_tenant_a, create_ticket_tenant_b
|
|
):
|
|
"""
|
|
El usuario del tenant B crea un ticket.
|
|
El usuario del tenant A (SUPPORT_MANAGER) lista sus tickets.
|
|
El ticket de tenant B NO debe aparecer en la respuesta.
|
|
"""
|
|
# El usuario del tenant B crea un ticket
|
|
ticket_b = await create_ticket_tenant_b()
|
|
ticket_b_id = ticket_b["id"]
|
|
|
|
# El usuario del tenant A lista sus tickets
|
|
response = await client_tenant_a.get("/v1/tickets/")
|
|
assert response.status_code == 200
|
|
|
|
ids_visibles = {t["id"] for t in response.json()}
|
|
|
|
# El ticket de tenant B no debe ser visible para tenant A
|
|
assert ticket_b_id not in ids_visibles, (
|
|
f"Fallo de aislamiento: ticket de tenant B ({ticket_b_id}) "
|
|
f"visible para usuario de tenant A"
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tenant_b_cannot_edit_tenant_a_ticket(
|
|
create_ticket_tenant_a, client_tenant_b
|
|
):
|
|
"""
|
|
El usuario del tenant A crea un ticket.
|
|
El usuario del tenant B intenta editar ese ticket vía PATCH.
|
|
Debe recibir 403 (prohibido) o 404 (no encontrado).
|
|
"""
|
|
# El usuario del tenant A crea un ticket
|
|
ticket_a = await create_ticket_tenant_a()
|
|
ticket_a_id = ticket_a["id"]
|
|
|
|
# El usuario del tenant B intenta editar el ticket de tenant A
|
|
response = await client_tenant_b.patch(
|
|
f"/v1/tickets/{ticket_a_id}",
|
|
json={"status": "CLOSED"},
|
|
)
|
|
|
|
# Debe recibir 403 o 404 — nunca 200
|
|
assert response.status_code in (403, 404), (
|
|
f"Fallo de aislamiento: tenant B pudo editar ticket de tenant A "
|
|
f"(HTTP {response.status_code})"
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tenant_a_cannot_see_tenant_b_users(
|
|
client_tenant_a, create_user_tenant_b
|
|
):
|
|
"""
|
|
El usuario del tenant B crea un usuario nuevo.
|
|
El usuario del tenant A (SUPPORT_MANAGER) lista los usuarios.
|
|
El usuario de tenant B NO debe aparecer en la respuesta.
|
|
"""
|
|
# El usuario del tenant B crea un usuario
|
|
user_b = await create_user_tenant_b()
|
|
user_b_id = user_b["id"]
|
|
|
|
# El usuario del tenant A lista los usuarios de su tenant
|
|
response = await client_tenant_a.get("/v1/users/")
|
|
assert response.status_code == 200
|
|
|
|
ids_visibles = {u["id"] for u in response.json()}
|
|
|
|
# El usuario de tenant B no debe ser visible para tenant A
|
|
assert user_b_id not in ids_visibles, (
|
|
f"Fallo de aislamiento: usuario de tenant B ({user_b_id}) "
|
|
f"visible para usuario de tenant A"
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_admin_sees_all_tenant_data(
|
|
client_admin,
|
|
create_ticket_tenant_a,
|
|
create_ticket_tenant_b,
|
|
create_user_tenant_a,
|
|
create_user_tenant_b,
|
|
):
|
|
"""
|
|
El ADMIN global debe poder ver tickets y usuarios de TODOS los tenants.
|
|
- Tickets: vía /v1/tickets/admin/all (endpoint multi-tenant).
|
|
- Usuarios: vía /v1/users/ (ADMIN bypasa el filtro de tenant).
|
|
"""
|
|
# Crear datos en ambos tenants
|
|
ticket_a = await create_ticket_tenant_a()
|
|
ticket_b = await create_ticket_tenant_b()
|
|
user_a = await create_user_tenant_a()
|
|
user_b = await create_user_tenant_b()
|
|
|
|
# El admin lista todos los tickets (endpoint multi-tenant)
|
|
resp_tickets = await client_admin.get("/v1/tickets/admin/all")
|
|
assert resp_tickets.status_code == 200
|
|
ids_tickets = {t["id"] for t in resp_tickets.json()}
|
|
assert ticket_a["id"] in ids_tickets, "El ADMIN no ve el ticket de tenant A"
|
|
assert ticket_b["id"] in ids_tickets, "El ADMIN no ve el ticket de tenant B"
|
|
|
|
# El admin lista todos los usuarios (ADMIN bypasa filtro de tenant)
|
|
resp_users = await client_admin.get("/v1/users/")
|
|
assert resp_users.status_code == 200
|
|
ids_users = {u["id"] for u in resp_users.json()}
|
|
assert user_a["id"] in ids_users, "El ADMIN no ve el usuario de tenant A"
|
|
assert user_b["id"] in ids_users, "El ADMIN no ve el usuario de tenant B"
|
|
|