"""Tests for security document templates (Module 3).""" import pytest from unittest.mock import MagicMock, patch from fastapi.testclient import TestClient from fastapi import FastAPI from datetime import datetime from compliance.api.legal_template_routes import router from classroom_engine.database import get_db from compliance.api.tenant_utils import get_tenant_id DEFAULT_TENANT_ID = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e" # ============================================================================= # Test App Setup # ============================================================================= app = FastAPI() app.include_router(router) mock_db = MagicMock() def override_get_db(): yield mock_db def override_tenant(): return DEFAULT_TENANT_ID app.dependency_overrides[get_db] = override_get_db app.dependency_overrides[get_tenant_id] = override_tenant client = TestClient(app) SECURITY_TEMPLATE_TYPES = [ "it_security_concept", "data_protection_concept", "backup_recovery_concept", "logging_concept", "incident_response_plan", "access_control_concept", "risk_management_concept", ] # ============================================================================= # Helpers # ============================================================================= def make_template_row(doc_type, title="Test Template", content="# Test"): row = MagicMock() row._mapping = { "id": "tmpl-001", "tenant_id": DEFAULT_TENANT_ID, "document_type": doc_type, "title": title, "description": f"Test {doc_type}", "content": content, "placeholders": ["COMPANY_NAME", "ISB_NAME"], "language": "de", "jurisdiction": "DE", "status": "published", "license_id": None, "license_name": None, "source_name": None, "inspiration_sources": [], "created_at": datetime(2026, 3, 14), "updated_at": datetime(2026, 3, 14), } return row # ============================================================================= # Tests # ============================================================================= class TestSecurityTemplateTypes: """Verify the 7 security template types are accepted by the API.""" def test_all_security_types_in_valid_set(self): """All 7 security template types are in VALID_DOCUMENT_TYPES.""" from compliance.api.legal_template_routes import VALID_DOCUMENT_TYPES for doc_type in SECURITY_TEMPLATE_TYPES: assert doc_type in VALID_DOCUMENT_TYPES, ( f"{doc_type} not in VALID_DOCUMENT_TYPES" ) def test_security_template_count(self): """There are exactly 7 security template types.""" assert len(SECURITY_TEMPLATE_TYPES) == 7 def test_create_security_template_accepted(self): """Creating a template with a security type is accepted (not 400).""" insert_row = MagicMock() insert_row._mapping = { "id": "new-tmpl", "tenant_id": DEFAULT_TENANT_ID, "document_type": "it_security_concept", "title": "IT-Sicherheitskonzept", "description": "Test", "content": "# IT-Sicherheitskonzept", "placeholders": [], "language": "de", "jurisdiction": "DE", "status": "draft", "license_id": None, "license_name": None, "source_name": None, "inspiration_sources": [], "created_at": datetime(2026, 3, 14), "updated_at": datetime(2026, 3, 14), } mock_db.execute.return_value.fetchone.return_value = insert_row mock_db.commit = MagicMock() resp = client.post("/legal-templates", json={ "document_type": "it_security_concept", "title": "IT-Sicherheitskonzept", "content": "# IT-Sicherheitskonzept\n\n## 1. Managementzusammenfassung", "language": "de", "jurisdiction": "DE", }) # Should NOT be 400 (invalid type) assert resp.status_code != 400 or "Invalid document_type" not in resp.text def test_invalid_type_rejected(self): """A non-existent template type is rejected with 400.""" resp = client.post("/legal-templates", json={ "document_type": "nonexistent_type", "title": "Test", "content": "# Test", }) assert resp.status_code == 400 assert "Invalid document_type" in resp.json()["detail"] class TestSecurityTemplateFilter: """Verify filtering templates by security document types.""" def test_filter_by_security_type(self): """GET /legal-templates?document_type=it_security_concept returns matching templates.""" row = make_template_row("it_security_concept", "IT-Sicherheitskonzept") mock_db.execute.return_value.fetchall.return_value = [row] resp = client.get("/legal-templates?document_type=it_security_concept") assert resp.status_code == 200 data = resp.json() assert "templates" in data or isinstance(data, list) class TestSecurityTemplatePlaceholders: """Verify placeholder structure for security templates.""" def test_common_placeholders_present(self): """Security templates should use standard placeholders.""" common_placeholders = [ "COMPANY_NAME", "GF_NAME", "ISB_NAME", "DOCUMENT_VERSION", "VERSION_DATE", "NEXT_REVIEW_DATE", ] row = make_template_row( "it_security_concept", content="# IT-Sicherheitskonzept\n{{COMPANY_NAME}} {{ISB_NAME}}" ) row._mapping["placeholders"] = common_placeholders mock_db.execute.return_value.fetchone.return_value = row # Verify the mock has all expected placeholders assert all( p in row._mapping["placeholders"] for p in ["COMPANY_NAME", "GF_NAME", "ISB_NAME"] )