import os
import unittest


os.environ.setdefault("DATABASE_URL", "mysql+pymysql://test:test@127.0.0.1/documenta")
os.environ.setdefault("REDIS_URL", "redis://127.0.0.1:6379/0")
os.environ.setdefault("APP_ENCRYPTION_KEY", "test-encryption-key")
os.environ.setdefault("PII_HMAC_KEY", "test-pii-key")
os.environ.setdefault("ACCESS_TOKEN_HMAC_KEY", "test-access-key")

from pydantic import ValidationError

from app.api.portal_routes import PortalEventIn, PortalPageIn
from app.main import app


class H5PublicPortalContractTests(unittest.TestCase):
    def test_public_and_admin_routes_are_registered(self):
        paths = {route.path for route in app.routes}
        self.assertIn("/api/v1/portal/home", paths)
        self.assertIn("/api/v1/portal/events", paths)
        self.assertIn("/api/v1/panel/admin/portal-content", paths)

    def test_analytics_accepts_only_allowlisted_events(self):
        self.assertEqual(PortalEventIn(evento="page_view", ruta="/", sesion="123456789012").evento, "PAGE_VIEW")
        with self.assertRaises(ValidationError):
            PortalEventIn(evento="ARBITRARY_EVENT", ruta="/", sesion="123456789012")

    def test_cms_rejects_duplicate_blocks(self):
        block = {"codigo":"HERO","tipo":"HERO","titulo":"Título válido","contenido":{},"orden":10}
        with self.assertRaises(ValidationError):
            PortalPageIn(titulo="Inicio", meta_titulo="Título público Documenta",
                         meta_descripcion="Descripción suficientemente extensa para el portal.",
                         estado="PUBLICADA", bloques=[block, block])

    def test_cms_rejects_unsafe_links(self):
        with self.assertRaises(ValidationError):
            PortalPageIn(titulo="Inicio", meta_titulo="Título público Documenta",
                         meta_descripcion="Descripción suficientemente extensa para el portal.",
                         estado="PUBLICADA", bloques=[{
                             "codigo":"HERO","tipo":"HERO","titulo":"Título válido",
                             "contenido":{"primary_url":"javascript:alert(1)"},"orden":10,
                         }])

if __name__ == "__main__":
    unittest.main()
