"""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