mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
feat(api): update with latests changes and add tests
This commit is contained in:
@@ -498,23 +498,7 @@ class BaseComplianceReportGenerator(ABC):
|
||||
elements.append(Spacer(1, 0.5 * inch))
|
||||
|
||||
# Compliance info table
|
||||
info_rows = [
|
||||
("Framework:", data.framework),
|
||||
("ID:", data.compliance_id),
|
||||
("Name:", data.name),
|
||||
("Version:", data.version),
|
||||
]
|
||||
|
||||
# Add provider info if available
|
||||
if data.provider_obj:
|
||||
info_rows.append(("Provider:", data.provider_obj.provider.upper()))
|
||||
info_rows.append(("Account ID:", data.provider_obj.uid or "N/A"))
|
||||
info_rows.append(("Alias:", data.provider_obj.alias or "N/A"))
|
||||
|
||||
info_rows.append(("Scan ID:", data.scan_id))
|
||||
|
||||
if data.description:
|
||||
info_rows.append(("Description:", data.description))
|
||||
info_rows = self._build_info_rows(data, language=self.config.language)
|
||||
|
||||
info_table = create_info_table(
|
||||
rows=info_rows,
|
||||
@@ -526,6 +510,73 @@ class BaseComplianceReportGenerator(ABC):
|
||||
|
||||
return elements
|
||||
|
||||
def _build_info_rows(
|
||||
self, data: ComplianceData, language: str = "en"
|
||||
) -> list[tuple[str, str]]:
|
||||
"""Build the standard info rows for the cover page table.
|
||||
|
||||
This helper method creates the common metadata rows used in all
|
||||
report cover pages. Subclasses can use this to maintain consistency
|
||||
while customizing other aspects of the cover page.
|
||||
|
||||
Args:
|
||||
data: Aggregated compliance data.
|
||||
language: Language for labels ("en" or "es").
|
||||
|
||||
Returns:
|
||||
List of (label, value) tuples for the info table.
|
||||
"""
|
||||
# Labels based on language
|
||||
labels = {
|
||||
"en": {
|
||||
"framework": "Framework:",
|
||||
"id": "ID:",
|
||||
"name": "Name:",
|
||||
"version": "Version:",
|
||||
"provider": "Provider:",
|
||||
"account_id": "Account ID:",
|
||||
"alias": "Alias:",
|
||||
"scan_id": "Scan ID:",
|
||||
"description": "Description:",
|
||||
},
|
||||
"es": {
|
||||
"framework": "Framework:",
|
||||
"id": "ID:",
|
||||
"name": "Nombre:",
|
||||
"version": "Versión:",
|
||||
"provider": "Proveedor:",
|
||||
"account_id": "Account ID:",
|
||||
"alias": "Alias:",
|
||||
"scan_id": "Scan ID:",
|
||||
"description": "Descripción:",
|
||||
},
|
||||
}
|
||||
lang_labels = labels.get(language, labels["en"])
|
||||
|
||||
info_rows = [
|
||||
(lang_labels["framework"], data.framework),
|
||||
(lang_labels["id"], data.compliance_id),
|
||||
(lang_labels["name"], data.name),
|
||||
(lang_labels["version"], data.version),
|
||||
]
|
||||
|
||||
# Add provider info if available
|
||||
if data.provider_obj:
|
||||
info_rows.append(
|
||||
(lang_labels["provider"], data.provider_obj.provider.upper())
|
||||
)
|
||||
info_rows.append(
|
||||
(lang_labels["account_id"], data.provider_obj.uid or "N/A")
|
||||
)
|
||||
info_rows.append((lang_labels["alias"], data.provider_obj.alias or "N/A"))
|
||||
|
||||
info_rows.append((lang_labels["scan_id"], data.scan_id))
|
||||
|
||||
if data.description:
|
||||
info_rows.append((lang_labels["description"], data.description))
|
||||
|
||||
return info_rows
|
||||
|
||||
def create_detailed_findings(self, data: ComplianceData, **kwargs) -> list:
|
||||
"""Create the detailed findings section.
|
||||
|
||||
|
||||
@@ -98,15 +98,18 @@ class ENSReportGenerator(BaseComplianceReportGenerator):
|
||||
)
|
||||
elements.append(Spacer(1, 0.5 * inch))
|
||||
|
||||
# Compliance info table
|
||||
info_data = [
|
||||
["Framework:", data.framework],
|
||||
["ID:", data.compliance_id],
|
||||
["Nombre:", Paragraph(data.name, self.styles["normal_center"])],
|
||||
["Versión:", data.version],
|
||||
["Scan ID:", data.scan_id],
|
||||
["Descripción:", Paragraph(data.description, self.styles["normal_center"])],
|
||||
]
|
||||
# Compliance info table - use base class helper for consistency
|
||||
info_rows = self._build_info_rows(data, language="es")
|
||||
# Convert tuples to lists and wrap long text in Paragraphs
|
||||
info_data = []
|
||||
for label, value in info_rows:
|
||||
if label in ("Nombre:", "Descripción:") and value:
|
||||
info_data.append(
|
||||
[label, Paragraph(value, self.styles["normal_center"])]
|
||||
)
|
||||
else:
|
||||
info_data.append([label, value])
|
||||
|
||||
info_table = Table(info_data, colWidths=[2 * inch, 4 * inch])
|
||||
info_table.setStyle(
|
||||
TableStyle(
|
||||
|
||||
@@ -110,14 +110,17 @@ class NIS2ReportGenerator(BaseComplianceReportGenerator):
|
||||
elements.append(title)
|
||||
elements.append(Spacer(1, 0.3 * inch))
|
||||
|
||||
# Compliance metadata table
|
||||
metadata_data = [
|
||||
["Framework:", data.framework],
|
||||
["Name:", Paragraph(data.name, self.styles["normal_center"])],
|
||||
["Version:", data.version or "N/A"],
|
||||
["Scan ID:", data.scan_id],
|
||||
["Description:", Paragraph(data.description, self.styles["normal_center"])],
|
||||
]
|
||||
# Compliance metadata table - use base class helper for consistency
|
||||
info_rows = self._build_info_rows(data, language="en")
|
||||
# Convert tuples to lists and wrap long text in Paragraphs
|
||||
metadata_data = []
|
||||
for label, value in info_rows:
|
||||
if label in ("Name:", "Description:") and value:
|
||||
metadata_data.append(
|
||||
[label, Paragraph(value, self.styles["normal_center"])]
|
||||
)
|
||||
else:
|
||||
metadata_data.append([label, value])
|
||||
|
||||
metadata_table = Table(metadata_data, colWidths=[2 * inch, 4 * inch])
|
||||
metadata_table.setStyle(
|
||||
|
||||
@@ -819,6 +819,219 @@ class TestBaseComplianceReportGenerator:
|
||||
assert left == "Página 1"
|
||||
|
||||
|
||||
class TestBuildInfoRows:
|
||||
"""Tests for _build_info_rows helper method."""
|
||||
|
||||
def _create_generator(self, language="en"):
|
||||
"""Create a concrete generator for testing."""
|
||||
|
||||
class ConcreteGenerator(BaseComplianceReportGenerator):
|
||||
def create_executive_summary(self, data):
|
||||
return []
|
||||
|
||||
def create_charts_section(self, data):
|
||||
return []
|
||||
|
||||
def create_requirements_index(self, data):
|
||||
return []
|
||||
|
||||
config = FrameworkConfig(name="test", display_name="Test", language=language)
|
||||
return ConcreteGenerator(config)
|
||||
|
||||
def test_build_info_rows_english(self):
|
||||
"""Test info rows are built with English labels."""
|
||||
generator = self._create_generator(language="en")
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test Framework",
|
||||
name="Test Name",
|
||||
version="1.0",
|
||||
description="Test description",
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="en")
|
||||
|
||||
assert ("Framework:", "Test Framework") in rows
|
||||
assert ("Name:", "Test Name") in rows
|
||||
assert ("Version:", "1.0") in rows
|
||||
assert ("Scan ID:", "scan-123") in rows
|
||||
assert ("Description:", "Test description") in rows
|
||||
|
||||
def test_build_info_rows_spanish(self):
|
||||
"""Test info rows are built with Spanish labels."""
|
||||
generator = self._create_generator(language="es")
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test Framework",
|
||||
name="Test Name",
|
||||
version="1.0",
|
||||
description="Test description",
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="es")
|
||||
|
||||
assert ("Framework:", "Test Framework") in rows
|
||||
assert ("Nombre:", "Test Name") in rows
|
||||
assert ("Versión:", "1.0") in rows
|
||||
assert ("Scan ID:", "scan-123") in rows
|
||||
assert ("Descripción:", "Test description") in rows
|
||||
|
||||
def test_build_info_rows_with_provider(self):
|
||||
"""Test info rows include provider info when available."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
generator = self._create_generator(language="en")
|
||||
|
||||
mock_provider = Mock()
|
||||
mock_provider.provider = "aws"
|
||||
mock_provider.uid = "123456789012"
|
||||
mock_provider.alias = "my-account"
|
||||
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="",
|
||||
provider_obj=mock_provider,
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="en")
|
||||
|
||||
assert ("Provider:", "AWS") in rows
|
||||
assert ("Account ID:", "123456789012") in rows
|
||||
assert ("Alias:", "my-account") in rows
|
||||
|
||||
def test_build_info_rows_with_provider_spanish(self):
|
||||
"""Test provider info uses Spanish labels."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
generator = self._create_generator(language="es")
|
||||
|
||||
mock_provider = Mock()
|
||||
mock_provider.provider = "azure"
|
||||
mock_provider.uid = "subscription-id"
|
||||
mock_provider.alias = "mi-suscripcion"
|
||||
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="",
|
||||
provider_obj=mock_provider,
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="es")
|
||||
|
||||
assert ("Proveedor:", "AZURE") in rows
|
||||
assert ("Account ID:", "subscription-id") in rows
|
||||
assert ("Alias:", "mi-suscripcion") in rows
|
||||
|
||||
def test_build_info_rows_without_provider(self):
|
||||
"""Test info rows work without provider info."""
|
||||
generator = self._create_generator(language="en")
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="",
|
||||
provider_obj=None,
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="en")
|
||||
|
||||
# Provider info should not be present
|
||||
labels = [label for label, _ in rows]
|
||||
assert "Provider:" not in labels
|
||||
assert "Account ID:" not in labels
|
||||
assert "Alias:" not in labels
|
||||
|
||||
def test_build_info_rows_provider_with_missing_fields(self):
|
||||
"""Test provider info handles None values gracefully."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
generator = self._create_generator(language="en")
|
||||
|
||||
mock_provider = Mock()
|
||||
mock_provider.provider = "gcp"
|
||||
mock_provider.uid = None
|
||||
mock_provider.alias = None
|
||||
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="",
|
||||
provider_obj=mock_provider,
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="en")
|
||||
|
||||
assert ("Provider:", "GCP") in rows
|
||||
assert ("Account ID:", "N/A") in rows
|
||||
assert ("Alias:", "N/A") in rows
|
||||
|
||||
def test_build_info_rows_without_description(self):
|
||||
"""Test info rows exclude description when empty."""
|
||||
generator = self._create_generator(language="en")
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="",
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="en")
|
||||
|
||||
labels = [label for label, _ in rows]
|
||||
assert "Description:" not in labels
|
||||
|
||||
def test_build_info_rows_defaults_to_english(self):
|
||||
"""Test unknown language defaults to English labels."""
|
||||
generator = self._create_generator(language="en")
|
||||
data = ComplianceData(
|
||||
tenant_id="t1",
|
||||
scan_id="scan-123",
|
||||
provider_id="p1",
|
||||
compliance_id="test_compliance",
|
||||
framework="Test",
|
||||
name="Test",
|
||||
version="1.0",
|
||||
description="Desc",
|
||||
)
|
||||
|
||||
rows = generator._build_info_rows(data, language="fr") # Unknown language
|
||||
|
||||
# Should use English labels as fallback
|
||||
assert ("Name:", "Test") in rows
|
||||
assert ("Description:", "Desc") in rows
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Integration Tests
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user