from src.domain.app_blocks.canonical import CANONICAL_BLOCK_IDS
from src.domain.app_blocks.catalogs import FEATURE_PACK_ALIASES, default_known_packs
from src.domain.app_blocks.job_packs import JOB_FEATURE_PACKS
from src.domain.app_blocks.registry import load_default_registry
from src.domain.starter_library.archetypes import ARCHETYPE_STARTERS, starter_id_for_recipe


def test_generic_application_portal_is_composable_without_vertical_backend():
    required = {
        "forms.contact",
        "case.management",
        "requirements.checklist",
        "collaboration.conversation",
        "collaboration.comment",
        "files.attachments",
        "notifications.in_app",
        "workflow.assignment",
        "task.management",
        "activity.timeline",
    }
    assert required <= CANONICAL_BLOCK_IDS
    assert FEATURE_PACK_ALIASES["requirements.fulfillment"] == "requirements-fulfillment"
    assert FEATURE_PACK_ALIASES["record.conversations"] == "messaging"
    assert {"requirements-fulfillment", "messaging"} <= default_known_packs()
    assert starter_id_for_recipe("application_portal") == "application_portal"

    starter = ARCHETYPE_STARTERS["application_portal"]
    assert "requirements.checklist" in starter.required_capabilities
    assert "collaboration.conversation" in starter.required_capabilities
    assert "student_admissions_backend" in starter.forbidden_implicit_capabilities
    assert "student_consultancy_backend" in starter.forbidden_implicit_capabilities
    portal_pack = JOB_FEATURE_PACKS["application_portal_operations"]
    assert "declarative-event-reactions" in portal_pack.architecture_gaps
    assert "task-management" in portal_pack.required_backend_packs
    assert "activity-timeline" in portal_pack.required_backend_packs

    registry = load_default_registry()
    requirements = registry.require("requirements.checklist")
    conversation = registry.require("collaboration.conversation")
    assert {slot.component_contract for slot in requirements.slots if slot.component_contract} >= {
        "record.table", "record.detail", "record.create", "record.edit"
    }
    assert {slot.component_contract for slot in conversation.slots if slot.component_contract} >= {
        "record.table", "record.detail", "record.create", "record.edit"
    }
