110 lines
3.9 KiB
Python
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()
|