Tussilago/tests/test_control_plane_admin.py
2026-04-27 20:43:26 +02:00

110 lines
3.9 KiB
Python

from __future__ import annotations
from unittest.mock import patch
import pytest
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.test import RequestFactory
from control_plane.models import Deployment
from control_plane.models import HostedSite
from control_plane.models import RuntimeService
from control_plane.models import RuntimeServiceKind
from control_plane.models import RuntimeServiceStatus
from control_plane.models import Tenant
@pytest.mark.django_db
def test_admin_can_view_runtime_service_changelist() -> None:
"""Superusers should see runtime service records in Django admin."""
user_model = get_user_model()
admin_user = user_model.objects.create_superuser(
username="admin",
email="admin@example.com",
password="admin-password",
)
tenant = Tenant.objects.create(slug="acme", display_name="Acme")
hosted_site = HostedSite.objects.create(
tenant=tenant,
slug="portal",
display_name="Portal",
wsgi_module="portal.wsgi:application",
)
deployment = Deployment.objects.create(
hosted_site=hosted_site,
idempotency_key="deploy-admin-001",
source_sha256="c" * 64,
)
RuntimeService.objects.create(
deployment=deployment,
kind=RuntimeServiceKind.POSTGRESQL,
status=RuntimeServiceStatus.READY,
container_name="postgres-acme-portal",
network_name="net-acme-portal",
hostname="postgres.internal",
image_reference="docker.io/library/postgres:17-alpine",
internal_port=5432,
connection_username="portal",
connection_database="portal",
connection_secret_ref="secret://postgres/acme/portal",
)
request = RequestFactory().get("/admin/control_plane/runtimeservice/")
request.user = admin_user
model_admin = admin.site._registry[RuntimeService]
queryset = model_admin.get_queryset(request)
runtime_service = queryset.get()
assert model_admin.has_module_permission(request) is True
assert model_admin.has_view_permission(request) is True
assert runtime_service.container_name == "postgres-acme-portal"
assert model_admin.tenant_slug(runtime_service) == "acme"
assert model_admin.site_slug(runtime_service) == "portal"
@pytest.mark.django_db
def test_admin_registers_control_plane_models() -> None:
"""Admin should expose full control-plane graph for smoke data creation."""
assert Tenant in admin.site._registry
assert HostedSite in admin.site._registry
assert Deployment in admin.site._registry
assert RuntimeService in admin.site._registry
@pytest.mark.django_db
def test_deployment_admin_action_queues_test_container_provisioning() -> None:
"""Deployment admin action should queue Celery-backed test container provisioning."""
user_model = get_user_model()
admin_user = user_model.objects.create_superuser(
username="admin-action",
email="admin-action@example.com",
password="admin-password",
)
tenant = Tenant.objects.create(slug="acme", display_name="Acme")
hosted_site = HostedSite.objects.create(
tenant=tenant,
slug="portal",
display_name="Portal",
wsgi_module="portal.wsgi:application",
)
deployment = Deployment.objects.create(
hosted_site=hosted_site,
idempotency_key="deploy-admin-002",
source_sha256="e" * 64,
)
request = RequestFactory().post("/admin/control_plane/deployment/")
request.user = admin_user
model_admin = admin.site._registry[Deployment]
deployment_queryset = Deployment.objects.filter(pk=deployment.pk)
with (
patch("control_plane.admin.provision_test_runtime_services.delay") as mock_delay,
patch.object(model_admin, "message_user") as mock_message_user,
):
model_admin.create_test_containers(request, deployment_queryset)
mock_delay.assert_called_once_with(str(deployment.id))
mock_message_user.assert_called_once()