"""Tests for Vendor Compliance routes (vendor_compliance_routes.py).

Includes:
  - Vendors: CRUD (5) + Stats (1) + Status-Patch (1) + Filter (2)
  - Contracts: CRUD (5) + Filter (1)
  - Findings: CRUD (5) + Filter (2)
  - Control Instances: CRUD (5) + Filter (1)
  - Controls Library: List + Create + Delete (3)
  - Export Stubs: 3 × 501
  - Response-Format: success/data/timestamp wrapper (2)
  - camelCase/snake_case round-trip (2)
"""

import pytest
import uuid
import os
import sys
from datetime import datetime, timezone

from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy import create_engine, text, event
from sqlalchemy.orm import sessionmaker

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from classroom_engine.database import get_db
from compliance.api.vendor_compliance_routes import router as vendor_compliance_router

# =============================================================================
# Test App + SQLite Setup
# =============================================================================

SQLALCHEMY_DATABASE_URL = "sqlite:///./test_vendor_compliance.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
_RawSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

TENANT_ID = "default"


@event.listens_for(engine, "connect")
def _register_sqlite_functions(dbapi_conn, connection_record):
    dbapi_conn.create_function("NOW", 0, lambda: datetime.now(timezone.utc).isoformat())


class _DictRow(dict):
    pass


class _DictSession:
    def __init__(self, session):
        self._session = session

    def execute(self, stmt, params=None):
        import re
        if hasattr(stmt, 'text'):
            rewritten = re.sub(r'CAST\((:[\w]+)\s+AS\s+jsonb\)', r'\1', stmt.text)
            # Remove FILTER (WHERE ...) for SQLite — replace with CASE/SUM
            # Simple approach: rewrite COUNT(*) FILTER (WHERE cond) → SUM(CASE WHEN cond THEN 1 ELSE 0 END)
            filter_re = r'COUNT\(\*\)\s+FILTER\s*\(\s*WHERE\s+([^)]+)\)'
            rewritten = re.sub(filter_re, r'SUM(CASE WHEN \1 THEN 1 ELSE 0 END)', rewritten)
            # ILIKE → LIKE for SQLite
            rewritten = rewritten.replace(' ILIKE ', ' LIKE ')
            if rewritten != stmt.text:
                stmt = text(rewritten)
        result = self._session.execute(stmt, params)
        return _DictResult(result)

    def flush(self):
        self._session.flush()

    def commit(self):
        self._session.commit()

    def rollback(self):
        self._session.rollback()

    def close(self):
        self._session.close()


class _DictResult:
    def __init__(self, result):
        self._result = result
        try:
            self._keys = list(result.keys())
            self._returns_rows = True
        except Exception:
            self._keys = []
            self._returns_rows = False

    def fetchone(self):
        if not self._returns_rows:
            return None
        row = self._result.fetchone()
        if row is None:
            return None
        return _DictRow(zip(self._keys, row))

    def fetchall(self):
        if not self._returns_rows:
            return []
        rows = self._result.fetchall()
        return [_DictRow(zip(self._keys, r)) for r in rows]

    @property
    def rowcount(self):
        return self._result.rowcount


app = FastAPI()
app.include_router(vendor_compliance_router, prefix="/api/compliance")


def override_get_db():
    session = _RawSessionLocal()
    db = _DictSession(session)
    try:
        yield db
    finally:
        db.close()


app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)


# =============================================================================
# SQLite Table Creation
# =============================================================================

CREATE_VENDORS = """
CREATE TABLE IF NOT EXISTS vendor_vendors (
    id TEXT PRIMARY KEY,
    tenant_id TEXT NOT NULL DEFAULT 'default',
    name TEXT NOT NULL DEFAULT '',
    legal_form TEXT DEFAULT '',
    country TEXT DEFAULT '',
    address TEXT DEFAULT '',
    website TEXT DEFAULT '',
    role TEXT DEFAULT 'PROCESSOR',
    service_description TEXT DEFAULT '',
    service_category TEXT DEFAULT 'OTHER',
    data_access_level TEXT DEFAULT 'NONE',
    processing_locations TEXT DEFAULT '[]',
    transfer_mechanisms TEXT DEFAULT '[]',
    certifications TEXT DEFAULT '[]',
    primary_contact TEXT DEFAULT '{}',
    dpo_contact TEXT DEFAULT '{}',
    security_contact TEXT DEFAULT '{}',
    contract_types TEXT DEFAULT '[]',
    inherent_risk_score INTEGER DEFAULT 50,
    residual_risk_score INTEGER DEFAULT 50,
    manual_risk_adjustment INTEGER,
    risk_justification TEXT DEFAULT '',
    review_frequency TEXT DEFAULT 'ANNUAL',
    last_review_date TIMESTAMP,
    next_review_date TIMESTAMP,
    status TEXT DEFAULT 'ACTIVE',
    processing_activity_ids TEXT DEFAULT '[]',
    notes TEXT DEFAULT '',
    contact_name TEXT DEFAULT '',
    contact_email TEXT DEFAULT '',
    contact_phone TEXT DEFAULT '',
    contact_department TEXT DEFAULT '',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by TEXT DEFAULT 'system'
)
"""

CREATE_CONTRACTS = """
CREATE TABLE IF NOT EXISTS vendor_contracts (
    id TEXT PRIMARY KEY,
    tenant_id TEXT NOT NULL DEFAULT 'default',
    vendor_id TEXT NOT NULL DEFAULT '',
    file_name TEXT DEFAULT '',
    original_name TEXT DEFAULT '',
    mime_type TEXT DEFAULT '',
    file_size INTEGER DEFAULT 0,
    storage_path TEXT DEFAULT '',
    document_type TEXT DEFAULT 'AVV',
    version INTEGER DEFAULT 1,
    previous_version_id TEXT,
    parties TEXT DEFAULT '[]',
    effective_date TIMESTAMP,
    expiration_date TIMESTAMP,
    auto_renewal INTEGER DEFAULT 0,
    renewal_notice_period TEXT DEFAULT '',
    termination_notice_period TEXT DEFAULT '',
    review_status TEXT DEFAULT 'PENDING',
    review_completed_at TIMESTAMP,
    compliance_score INTEGER,
    status TEXT DEFAULT 'DRAFT',
    extracted_text TEXT DEFAULT '',
    page_count INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by TEXT DEFAULT 'system'
)
"""

CREATE_FINDINGS = """
CREATE TABLE IF NOT EXISTS vendor_findings (
    id TEXT PRIMARY KEY,
    tenant_id TEXT NOT NULL DEFAULT 'default',
    vendor_id TEXT NOT NULL DEFAULT '',
    contract_id TEXT,
    finding_type TEXT DEFAULT 'UNKNOWN',
    category TEXT DEFAULT '',
    severity TEXT DEFAULT 'MEDIUM',
    title TEXT DEFAULT '',
    description TEXT DEFAULT '',
    recommendation TEXT DEFAULT '',
    citations TEXT DEFAULT '[]',
    status TEXT DEFAULT 'OPEN',
    assignee TEXT DEFAULT '',
    due_date TIMESTAMP,
    resolution TEXT DEFAULT '',
    resolved_at TIMESTAMP,
    resolved_by TEXT DEFAULT '',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by TEXT DEFAULT 'system'
)
"""

CREATE_CONTROL_INSTANCES = """
CREATE TABLE IF NOT EXISTS vendor_control_instances (
    id TEXT PRIMARY KEY,
    tenant_id TEXT NOT NULL DEFAULT 'default',
    vendor_id TEXT NOT NULL DEFAULT '',
    control_id TEXT DEFAULT '',
    control_domain TEXT DEFAULT '',
    status TEXT DEFAULT 'PLANNED',
    evidence_ids TEXT DEFAULT '[]',
    notes TEXT DEFAULT '',
    last_assessed_at TIMESTAMP,
    last_assessed_by TEXT DEFAULT '',
    next_assessment_date TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    created_by TEXT DEFAULT 'system'
)
"""

CREATE_CONTROLS = """
CREATE TABLE IF NOT EXISTS vendor_compliance_controls (
    id TEXT PRIMARY KEY,
    tenant_id TEXT NOT NULL DEFAULT 'default',
    domain TEXT DEFAULT '',
    control_code TEXT DEFAULT '',
    title TEXT DEFAULT '',
    description TEXT DEFAULT '',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""


def _setup_tables():
    with engine.connect() as conn:
        for sql in [CREATE_VENDORS, CREATE_CONTRACTS, CREATE_FINDINGS,
                    CREATE_CONTROL_INSTANCES, CREATE_CONTROLS]:
            conn.execute(text(sql))
        conn.commit()


def _teardown_tables():
    with engine.connect() as conn:
        for t in ["vendor_vendors", "vendor_contracts", "vendor_findings",
                  "vendor_control_instances", "vendor_compliance_controls"]:
            conn.execute(text(f"DELETE FROM {t}"))
        conn.commit()


_setup_tables()


# =============================================================================
# Fixtures
# =============================================================================

@pytest.fixture(autouse=True)
def clean_tables():
    _teardown_tables()
    yield
    _teardown_tables()


def _create_vendor(**kwargs):
    payload = {
        "name": kwargs.get("name", "Test Vendor GmbH"),
        "country": "DE",
        "role": "PROCESSOR",
        "serviceCategory": "HOSTING",
        "status": kwargs.get("status", "ACTIVE"),
        "inherentRiskScore": kwargs.get("inherentRiskScore", 50),
    }
    payload.update(kwargs)
    resp = client.post("/api/compliance/vendor-compliance/vendors", json=payload)
    assert resp.status_code == 201
    return resp.json()["data"]


def _create_contract(vendor_id, **kwargs):
    payload = {
        "vendorId": vendor_id,
        "documentType": "AVV",
        "fileName": "avv-test.pdf",
        "status": "DRAFT",
    }
    payload.update(kwargs)
    resp = client.post("/api/compliance/vendor-compliance/contracts", json=payload)
    assert resp.status_code == 201
    return resp.json()["data"]


def _create_finding(vendor_id, **kwargs):
    payload = {
        "vendorId": vendor_id,
        "findingType": "GAP",
        "severity": "HIGH",
        "title": "Missing TOM Annex",
        "status": "OPEN",
    }
    payload.update(kwargs)
    resp = client.post("/api/compliance/vendor-compliance/findings", json=payload)
    assert resp.status_code == 201
    return resp.json()["data"]


def _create_control_instance(vendor_id, **kwargs):
    payload = {
        "vendorId": vendor_id,
        "controlId": "C-001",
        "controlDomain": "priv",
        "status": "PASS",
    }
    payload.update(kwargs)
    resp = client.post("/api/compliance/vendor-compliance/control-instances", json=payload)
    assert resp.status_code == 201
    return resp.json()["data"]


# =============================================================================
# Response Format Tests
# =============================================================================

class TestResponseFormat:
    def test_list_vendors_has_success_data_timestamp(self):
        resp = client.get("/api/compliance/vendor-compliance/vendors")
        assert resp.status_code == 200
        body = resp.json()
        assert body["success"] is True
        assert "data" in body
        assert "timestamp" in body

    def test_create_vendor_has_success_data_timestamp(self):
        resp = client.post("/api/compliance/vendor-compliance/vendors", json={"name": "Test"})
        assert resp.status_code == 201
        body = resp.json()
        assert body["success"] is True
        assert "data" in body
        assert body["data"]["name"] == "Test"
        assert "timestamp" in body


# =============================================================================
# camelCase / snake_case Round-Trip Tests
# =============================================================================

class TestCamelSnakeConversion:
    def test_create_with_camel_returns_camel(self):
        vendor = _create_vendor(
            name="CamelTest",
            legalForm="GmbH",
            serviceDescription="Cloud hosting",
            dataAccessLevel="CONTENT",
            inherentRiskScore=80,
        )
        assert vendor["legalForm"] == "GmbH"
        assert vendor["serviceDescription"] == "Cloud hosting"
        assert vendor["dataAccessLevel"] == "CONTENT"
        assert vendor["inherentRiskScore"] == 80

    def test_round_trip_preserves_values(self):
        vendor = _create_vendor(
            name="RoundTrip",
            processingLocations=["DE", "US"],
            primaryContact={"name": "Max", "email": "max@test.de"},
        )
        vid = vendor["id"]
        resp = client.get(f"/api/compliance/vendor-compliance/vendors/{vid}")
        assert resp.status_code == 200
        fetched = resp.json()["data"]
        assert fetched["processingLocations"] == ["DE", "US"]
        assert fetched["primaryContact"]["name"] == "Max"


# =============================================================================
# Vendor Tests
# =============================================================================

class TestVendorsCRUD:
    def test_list_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/vendors")
        assert resp.status_code == 200
        data = resp.json()["data"]
        assert data["items"] == []
        assert data["total"] == 0

    def test_create_vendor(self):
        vendor = _create_vendor(name="Hetzner GmbH")
        assert vendor["name"] == "Hetzner GmbH"
        assert "id" in vendor

    def test_get_vendor(self):
        vendor = _create_vendor()
        resp = client.get(f"/api/compliance/vendor-compliance/vendors/{vendor['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["id"] == vendor["id"]

    def test_update_vendor(self):
        vendor = _create_vendor()
        resp = client.put(
            f"/api/compliance/vendor-compliance/vendors/{vendor['id']}",
            json={"name": "Updated Name", "country": "AT"}
        )
        assert resp.status_code == 200
        updated = resp.json()["data"]
        assert updated["name"] == "Updated Name"
        assert updated["country"] == "AT"

    def test_delete_vendor(self):
        vendor = _create_vendor()
        resp = client.delete(f"/api/compliance/vendor-compliance/vendors/{vendor['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["deleted"] is True
        resp2 = client.get(f"/api/compliance/vendor-compliance/vendors/{vendor['id']}")
        assert resp2.status_code == 404

    def test_get_nonexistent_vendor_404(self):
        resp = client.get(f"/api/compliance/vendor-compliance/vendors/{uuid.uuid4()}")
        assert resp.status_code == 404

    def test_delete_nonexistent_vendor_404(self):
        resp = client.delete(f"/api/compliance/vendor-compliance/vendors/{uuid.uuid4()}")
        assert resp.status_code == 404


class TestVendorStats:
    def test_stats_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/vendors/stats")
        assert resp.status_code == 200
        stats = resp.json()["data"]
        assert stats["total"] == 0

    def test_stats_with_vendors(self):
        _create_vendor(name="V1", status="ACTIVE", inherentRiskScore=80)
        _create_vendor(name="V2", status="INACTIVE", inherentRiskScore=30)
        _create_vendor(name="V3", status="PENDING_REVIEW", inherentRiskScore=90)
        resp = client.get("/api/compliance/vendor-compliance/vendors/stats")
        stats = resp.json()["data"]
        assert stats["total"] == 3
        assert stats["active"] == 1
        assert stats["inactive"] == 1
        assert stats["pendingReview"] == 1
        assert stats["highRiskCount"] == 2  # 80 and 90


class TestVendorStatusPatch:
    def test_patch_status(self):
        vendor = _create_vendor(status="ACTIVE")
        resp = client.patch(
            f"/api/compliance/vendor-compliance/vendors/{vendor['id']}/status",
            json={"status": "TERMINATED"}
        )
        assert resp.status_code == 200
        assert resp.json()["data"]["status"] == "TERMINATED"

    def test_patch_invalid_status_400(self):
        vendor = _create_vendor()
        resp = client.patch(
            f"/api/compliance/vendor-compliance/vendors/{vendor['id']}/status",
            json={"status": "INVALID"}
        )
        assert resp.status_code == 400


class TestVendorFilter:
    def test_filter_by_status(self):
        _create_vendor(name="Active1", status="ACTIVE")
        _create_vendor(name="Inactive1", status="INACTIVE")
        resp = client.get("/api/compliance/vendor-compliance/vendors?status=ACTIVE")
        items = resp.json()["data"]["items"]
        assert len(items) == 1
        assert items[0]["name"] == "Active1"

    def test_filter_by_search(self):
        _create_vendor(name="Hetzner Online GmbH")
        _create_vendor(name="AWS Deutschland")
        resp = client.get("/api/compliance/vendor-compliance/vendors?search=Hetzner")
        items = resp.json()["data"]["items"]
        assert len(items) == 1
        assert "Hetzner" in items[0]["name"]


# =============================================================================
# Contract Tests
# =============================================================================

class TestContractsCRUD:
    def test_list_contracts_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/contracts")
        assert resp.status_code == 200
        assert resp.json()["data"] == []

    def test_create_contract(self):
        vendor = _create_vendor()
        contract = _create_contract(vendor["id"])
        assert contract["vendorId"] == vendor["id"]
        assert contract["documentType"] == "AVV"

    def test_get_contract(self):
        vendor = _create_vendor()
        contract = _create_contract(vendor["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/contracts/{contract['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["id"] == contract["id"]

    def test_update_contract(self):
        vendor = _create_vendor()
        contract = _create_contract(vendor["id"])
        resp = client.put(
            f"/api/compliance/vendor-compliance/contracts/{contract['id']}",
            json={"status": "ACTIVE", "complianceScore": 85}
        )
        assert resp.status_code == 200
        updated = resp.json()["data"]
        assert updated["status"] == "ACTIVE"
        assert updated["complianceScore"] == 85

    def test_delete_contract(self):
        vendor = _create_vendor()
        contract = _create_contract(vendor["id"])
        resp = client.delete(f"/api/compliance/vendor-compliance/contracts/{contract['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["deleted"] is True


class TestContractFilter:
    def test_filter_by_vendor_id(self):
        v1 = _create_vendor(name="V1")
        v2 = _create_vendor(name="V2")
        _create_contract(v1["id"])
        _create_contract(v1["id"])
        _create_contract(v2["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/contracts?vendor_id={v1['id']}")
        assert len(resp.json()["data"]) == 2


# =============================================================================
# Finding Tests
# =============================================================================

class TestFindingsCRUD:
    def test_list_findings_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/findings")
        assert resp.status_code == 200
        assert resp.json()["data"] == []

    def test_create_finding(self):
        vendor = _create_vendor()
        finding = _create_finding(vendor["id"])
        assert finding["vendorId"] == vendor["id"]
        assert finding["severity"] == "HIGH"

    def test_get_finding(self):
        vendor = _create_vendor()
        finding = _create_finding(vendor["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/findings/{finding['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["title"] == "Missing TOM Annex"

    def test_update_finding(self):
        vendor = _create_vendor()
        finding = _create_finding(vendor["id"])
        resp = client.put(
            f"/api/compliance/vendor-compliance/findings/{finding['id']}",
            json={"status": "RESOLVED", "resolution": "TOM annex added"}
        )
        assert resp.status_code == 200
        updated = resp.json()["data"]
        assert updated["status"] == "RESOLVED"
        assert updated["resolution"] == "TOM annex added"

    def test_delete_finding(self):
        vendor = _create_vendor()
        finding = _create_finding(vendor["id"])
        resp = client.delete(f"/api/compliance/vendor-compliance/findings/{finding['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["deleted"] is True


class TestFindingFilter:
    def test_filter_by_severity(self):
        vendor = _create_vendor()
        _create_finding(vendor["id"], severity="HIGH")
        _create_finding(vendor["id"], severity="LOW")
        resp = client.get("/api/compliance/vendor-compliance/findings?severity=HIGH")
        assert len(resp.json()["data"]) == 1

    def test_filter_by_vendor_id(self):
        v1 = _create_vendor(name="V1")
        v2 = _create_vendor(name="V2")
        _create_finding(v1["id"])
        _create_finding(v2["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/findings?vendor_id={v1['id']}")
        assert len(resp.json()["data"]) == 1


# =============================================================================
# Control Instance Tests
# =============================================================================

class TestControlInstancesCRUD:
    def test_list_control_instances_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/control-instances")
        assert resp.status_code == 200
        assert resp.json()["data"] == []

    def test_create_control_instance(self):
        vendor = _create_vendor()
        ci = _create_control_instance(vendor["id"])
        assert ci["vendorId"] == vendor["id"]
        assert ci["controlId"] == "C-001"
        assert ci["status"] == "PASS"

    def test_get_control_instance(self):
        vendor = _create_vendor()
        ci = _create_control_instance(vendor["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/control-instances/{ci['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["controlDomain"] == "priv"

    def test_update_control_instance(self):
        vendor = _create_vendor()
        ci = _create_control_instance(vendor["id"])
        resp = client.put(
            f"/api/compliance/vendor-compliance/control-instances/{ci['id']}",
            json={"status": "FAIL", "notes": "Needs remediation"}
        )
        assert resp.status_code == 200
        updated = resp.json()["data"]
        assert updated["status"] == "FAIL"
        assert updated["notes"] == "Needs remediation"

    def test_delete_control_instance(self):
        vendor = _create_vendor()
        ci = _create_control_instance(vendor["id"])
        resp = client.delete(f"/api/compliance/vendor-compliance/control-instances/{ci['id']}")
        assert resp.status_code == 200
        assert resp.json()["data"]["deleted"] is True


class TestControlInstanceFilter:
    def test_filter_by_vendor_id(self):
        v1 = _create_vendor(name="V1")
        v2 = _create_vendor(name="V2")
        _create_control_instance(v1["id"])
        _create_control_instance(v2["id"])
        resp = client.get(f"/api/compliance/vendor-compliance/control-instances?vendor_id={v1['id']}")
        assert len(resp.json()["data"]) == 1


# =============================================================================
# Controls Library Tests
# =============================================================================

class TestControlsLibrary:
    def test_list_controls_empty(self):
        resp = client.get("/api/compliance/vendor-compliance/controls")
        assert resp.status_code == 200
        assert resp.json()["data"] == []

    def test_create_control(self):
        resp = client.post("/api/compliance/vendor-compliance/controls", json={
            "domain": "priv",
            "controlCode": "PRIV-001",
            "title": "Datenschutz-Folgenabschaetzung",
            "description": "Art. 35 DSGVO Compliance"
        })
        assert resp.status_code == 201
        ctrl = resp.json()["data"]
        assert ctrl["domain"] == "priv"
        assert ctrl["controlCode"] == "PRIV-001"

    def test_delete_control(self):
        resp = client.post("/api/compliance/vendor-compliance/controls", json={
            "domain": "iam", "controlCode": "IAM-001", "title": "Access Control"
        })
        ctrl_id = resp.json()["data"]["id"]
        resp2 = client.delete(f"/api/compliance/vendor-compliance/controls/{ctrl_id}")
        assert resp2.status_code == 200
        assert resp2.json()["data"]["deleted"] is True


# =============================================================================
# Export Stub Tests
# =============================================================================

class TestExportStubs:
    def test_post_export_501(self):
        resp = client.post("/api/compliance/vendor-compliance/export", json={})
        assert resp.status_code == 501
        assert resp.json()["success"] is False

    def test_get_export_501(self):
        resp = client.get(f"/api/compliance/vendor-compliance/export/{uuid.uuid4()}")
        assert resp.status_code == 501

    def test_download_export_501(self):
        resp = client.get(f"/api/compliance/vendor-compliance/export/{uuid.uuid4()}/download")
        assert resp.status_code == 501
