TorbatYar/backend/services/experience/app/tests/test_bundles.py
Mortezakoohjani 203671a7bf feat(experience): ship Experience Platform phases 11.0-11.10
Add the experience service with sites through analytics/AI hooks, migrations through 0011, and phase docs/manifests marking the track complete.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:43:10 +03:30

84 lines
3.2 KiB
Python

"""Bundles, licensing refs and feature-toggle API tests — Phase 11.8."""
import pytest
from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers
async def _workspace(client, code="bundle"):
response = await client.post(
"/api/v1/workspaces",
json={"code": code, "name": "Bundles", "status": "active"},
headers=tenant_headers(TENANT_A),
)
assert response.status_code == 201, response.text
return response.json()
@pytest.mark.asyncio
async def test_bundle_activation_license_and_toggle(client):
caps = (await client.get("/capabilities")).json()
assert caps["phase"] == "11.10"
assert caps["features"]["bundle_licensing_shell"] is True
ws = await _workspace(client)
headers = tenant_headers(TENANT_A)
definition = await client.post(
"/api/v1/bundle-definitions",
json={"workspace_id": ws["id"], "code": "mini", "bundle_key": "mini_site",
"name": "Mini Site", "status": "available", "feature_keys": ["pages.mini"]},
headers=headers,
)
assert definition.status_code == 201, definition.text
bundle = await client.post(
"/api/v1/tenant-bundles",
json={"workspace_id": ws["id"], "bundle_definition_id": definition.json()["id"],
"status": "active", "core_entitlement_ref": "core-entitlement-1"},
headers=headers,
)
assert bundle.status_code == 201, bundle.text
assert bundle.json()["bundle_key"] == "mini_site"
license_binding = await client.post(
"/api/v1/license-bindings",
json={"workspace_id": ws["id"], "tenant_bundle_id": bundle.json()["id"],
"core_entitlement_ref": "core-entitlement-1", "status": "active"},
headers=headers,
)
assert license_binding.status_code == 201, license_binding.text
toggle = await client.post(
"/api/v1/feature-toggles",
json={"workspace_id": ws["id"], "feature_key": "pages.mini",
"enabled": True, "bundle_key": "mini_site"},
headers=headers,
)
assert toggle.status_code == 201, toggle.text
assert (await client.get(
f"/api/v1/feature-toggles/{toggle.json()['id']}", headers=tenant_headers(TENANT_B)
)).status_code == 404
@pytest.mark.asyncio
async def test_rejects_core_plan_metadata_and_inactive_activation(client):
ws = await _workspace(client, "bundle-rules")
headers = tenant_headers(TENANT_A)
rejected = await client.post(
"/api/v1/bundle-definitions",
json={"workspace_id": ws["id"], "code": "bad", "bundle_key": "custom",
"name": "Bad", "metadata_json": {"plan_engine": "local"}},
headers=headers,
)
assert rejected.status_code == 422
draft = await client.post(
"/api/v1/bundle-definitions",
json={"workspace_id": ws["id"], "code": "draft", "bundle_key": "forms", "name": "Draft"},
headers=headers,
)
assert draft.status_code == 201, draft.text
activation = await client.post(
"/api/v1/tenant-bundles",
json={"workspace_id": ws["id"], "bundle_definition_id": draft.json()["id"], "status": "active"},
headers=headers,
)
assert activation.status_code == 409