Files
breakpilot-compliance/backend-compliance/tests/test_license_gate.py
Benjamin Admin 050f353192
All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 40s
CI/CD / test-python-backend-compliance (push) Successful in 41s
CI/CD / test-python-document-crawler (push) Successful in 26s
CI/CD / test-python-dsms-gateway (push) Successful in 23s
CI/CD / validate-canonical-controls (push) Successful in 18s
CI/CD / deploy-hetzner (push) Successful in 2m26s
feat(canonical-controls): Canonical Control Library — rechtssichere Security Controls
Eigenstaendig formulierte Security Controls mit unabhaengiger Taxonomie
und Open-Source-Verankerung (OWASP, NIST, ENISA). Keine BSI-Nomenklatur.

- Migration 044: 5 DB-Tabellen (frameworks, controls, sources, licenses, mappings)
- 10 Seed Controls mit 39 Open-Source-Referenzen
- License Gate: Quellen-Berechtigungspruefung (analysis/excerpt/embeddings/product)
- Too-Close-Detektor: 5 Metriken (exact-phrase, token-overlap, ngram, embedding, LCS)
- REST API: 8 Endpoints unter /v1/canonical/
- Go Loader mit Multi-Index (ID, domain, severity, framework)
- Frontend: Control Library Browser + Provenance Wiki
- CI/CD: validate-controls.py Job (schema, no-leak, open-anchors)
- 67 Tests (8 Go + 59 Python), alle PASS
- MkDocs Dokumentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:55:06 +01:00

162 lines
5.8 KiB
Python

"""Tests for License Gate service (license_gate.py)."""
import pytest
from unittest.mock import MagicMock, patch
from collections import namedtuple
from compliance.services.license_gate import (
check_source_allowed,
get_license_matrix,
get_source_permissions,
USAGE_COLUMN_MAP,
)
class TestUsageColumnMap:
"""Test the usage type to column mapping."""
def test_all_usage_types_mapped(self):
expected = {"analysis", "store_excerpt", "ship_embeddings", "ship_in_product"}
assert set(USAGE_COLUMN_MAP.keys()) == expected
def test_column_names(self):
assert USAGE_COLUMN_MAP["analysis"] == "allowed_analysis"
assert USAGE_COLUMN_MAP["store_excerpt"] == "allowed_store_excerpt"
assert USAGE_COLUMN_MAP["ship_embeddings"] == "allowed_ship_embeddings"
assert USAGE_COLUMN_MAP["ship_in_product"] == "allowed_ship_in_product"
class TestCheckSourceAllowed:
"""Tests for check_source_allowed()."""
def _mock_db(self, return_value):
db = MagicMock()
mock_result = MagicMock()
if return_value is None:
mock_result.fetchone.return_value = None
else:
mock_result.fetchone.return_value = (return_value,)
db.execute.return_value = mock_result
return db
def test_allowed_analysis(self):
db = self._mock_db(True)
assert check_source_allowed(db, "OWASP_ASVS", "analysis") is True
def test_denied_ship_in_product(self):
db = self._mock_db(False)
assert check_source_allowed(db, "BSI_TR03161_1", "ship_in_product") is False
def test_unknown_source(self):
db = self._mock_db(None)
assert check_source_allowed(db, "NONEXISTENT", "analysis") is False
def test_unknown_usage_type(self):
db = MagicMock()
assert check_source_allowed(db, "OWASP_ASVS", "invalid_type") is False
# DB should not be called for invalid usage type
db.execute.assert_not_called()
def test_allowed_store_excerpt(self):
db = self._mock_db(True)
assert check_source_allowed(db, "OWASP_ASVS", "store_excerpt") is True
def test_denied_store_excerpt(self):
db = self._mock_db(False)
assert check_source_allowed(db, "BSI_TR03161_1", "store_excerpt") is False
class TestGetLicenseMatrix:
"""Tests for get_license_matrix()."""
def test_returns_list(self):
LicRow = namedtuple("LicRow", [
"license_id", "name", "terms_url", "commercial_use",
"ai_training_restriction", "tdm_allowed_under_44b",
"deletion_required", "notes",
])
rows = [
LicRow("OWASP_CC_BY_SA", "CC BY-SA 4.0", "https://example.com",
"allowed", None, "yes", False, "Open source"),
LicRow("BSI_TOS_2025", "BSI ToS", "https://bsi.bund.de",
"restricted", "unclear", "yes", True, "Commercial restricted"),
]
db = MagicMock()
db.execute.return_value.fetchall.return_value = rows
result = get_license_matrix(db)
assert len(result) == 2
assert result[0]["license_id"] == "OWASP_CC_BY_SA"
assert result[0]["commercial_use"] == "allowed"
assert result[0]["deletion_required"] is False
assert result[1]["license_id"] == "BSI_TOS_2025"
assert result[1]["commercial_use"] == "restricted"
assert result[1]["deletion_required"] is True
def test_empty_result(self):
db = MagicMock()
db.execute.return_value.fetchall.return_value = []
result = get_license_matrix(db)
assert result == []
class TestGetSourcePermissions:
"""Tests for get_source_permissions()."""
def test_returns_list_with_join(self):
SrcRow = namedtuple("SrcRow", [
"source_id", "title", "publisher", "url", "version_label",
"language", "license_id", "allowed_analysis", "allowed_store_excerpt",
"allowed_ship_embeddings", "allowed_ship_in_product",
"vault_retention_days", "vault_access_tier",
"license_name", "commercial_use",
])
rows = [
SrcRow(
"OWASP_ASVS", "OWASP ASVS", "OWASP Foundation",
"https://owasp.org", "4.0.3", "en", "OWASP_CC_BY_SA",
True, True, True, True, 30, "public",
"CC BY-SA 4.0", "allowed",
),
]
db = MagicMock()
db.execute.return_value.fetchall.return_value = rows
result = get_source_permissions(db)
assert len(result) == 1
src = result[0]
assert src["source_id"] == "OWASP_ASVS"
assert src["allowed_analysis"] is True
assert src["allowed_ship_in_product"] is True
assert src["license_name"] == "CC BY-SA 4.0"
assert src["commercial_use"] == "allowed"
def test_restricted_source(self):
SrcRow = namedtuple("SrcRow", [
"source_id", "title", "publisher", "url", "version_label",
"language", "license_id", "allowed_analysis", "allowed_store_excerpt",
"allowed_ship_embeddings", "allowed_ship_in_product",
"vault_retention_days", "vault_access_tier",
"license_name", "commercial_use",
])
rows = [
SrcRow(
"BSI_TR03161_1", "BSI TR-03161 Teil 1", "BSI",
"https://bsi.bund.de", "1.0", "de", "BSI_TOS_2025",
True, False, False, False, 30, "restricted",
"BSI Nutzungsbedingungen", "restricted",
),
]
db = MagicMock()
db.execute.return_value.fetchall.return_value = rows
result = get_source_permissions(db)
src = result[0]
assert src["allowed_analysis"] is True
assert src["allowed_store_excerpt"] is False
assert src["allowed_ship_embeddings"] is False
assert src["allowed_ship_in_product"] is False