"""Tests for Company Profile routes (company_profile_routes.py).""" import json import pytest from unittest.mock import MagicMock, patch from compliance.api.company_profile_routes import ( CompanyProfileRequest, row_to_response, log_audit, ) class TestCompanyProfileRequest: """Tests for request model defaults.""" def test_default_values(self): req = CompanyProfileRequest() assert req.company_name == "" assert req.legal_form == "GmbH" assert req.business_model == "B2B" assert req.company_size == "small" assert req.headquarters_country == "DE" assert req.is_data_controller is True assert req.is_data_processor is False assert req.uses_ai is False assert req.is_complete is False def test_custom_values(self): req = CompanyProfileRequest( company_name="Test GmbH", industry="Software", uses_ai=True, ai_use_cases=["Chatbot", "Analytics"], offerings=["app_web", "software_saas"], ) assert req.company_name == "Test GmbH" assert req.uses_ai is True assert len(req.ai_use_cases) == 2 assert len(req.offerings) == 2 def test_serialization(self): req = CompanyProfileRequest(company_name="Test") data = req.model_dump() assert data["company_name"] == "Test" assert isinstance(data["target_markets"], list) class TestRowToResponse: """Tests for DB row to response conversion.""" def _make_row(self, **overrides): """Create a mock DB row with 40 fields (matching row_to_response indices).""" defaults = [ "uuid-123", # 0: id "default", # 1: tenant_id "Test GmbH", # 2: company_name "GmbH", # 3: legal_form "IT", # 4: industry 2020, # 5: founded_year "B2B", # 6: business_model ["app_web"], # 7: offerings "small", # 8: company_size "10-49", # 9: employee_count "2-10 Mio", # 10: annual_revenue "DE", # 11: headquarters_country "Berlin", # 12: headquarters_city False, # 13: has_international_locations [], # 14: international_countries ["DE", "AT"], # 15: target_markets "DE", # 16: primary_jurisdiction True, # 17: is_data_controller False, # 18: is_data_processor False, # 19: uses_ai [], # 20: ai_use_cases "Max Muster", # 21: dpo_name "dpo@test.de", # 22: dpo_email None, # 23: legal_contact_name None, # 24: legal_contact_email None, # 25: machine_builder True, # 26: is_complete "2026-01-01", # 27: completed_at "2026-01-01", # 28: created_at "2026-01-01", # 29: updated_at # Phase 2 fields (indices 30-39) [], # 30: repos [], # 31: document_sources [], # 32: processing_systems [], # 33: ai_systems [], # 34: technical_contacts False, # 35: subject_to_nis2 False, # 36: subject_to_ai_act False, # 37: subject_to_iso27001 None, # 38: supervisory_authority 12, # 39: review_cycle_months ] return tuple(defaults) def test_basic_conversion(self): row = self._make_row() response = row_to_response(row) assert response.id == "uuid-123" assert response.tenant_id == "default" assert response.company_name == "Test GmbH" assert response.is_complete is True def test_none_values_handled(self): row = list(self._make_row()) row[5] = None # founded_year row[21] = None # dpo_name row[25] = None # machine_builder row[27] = None # completed_at response = row_to_response(tuple(row)) assert response.founded_year is None assert response.dpo_name is None assert response.machine_builder is None assert response.completed_at is None def test_non_list_jsonb_handled(self): row = list(self._make_row()) row[7] = None # offerings (JSONB could be None) row[14] = None # international_countries response = row_to_response(tuple(row)) assert response.offerings == [] assert response.international_countries == [] class TestLogAudit: """Tests for audit logging helper.""" def test_log_audit_success(self): db = MagicMock() log_audit(db, "tenant-1", "create", {"company_name": "Test"}, "admin") db.execute.assert_called_once() def test_log_audit_with_none_fields(self): db = MagicMock() log_audit(db, "tenant-1", "update", None, None) db.execute.assert_called_once() def test_log_audit_db_error_handled(self): db = MagicMock() db.execute.side_effect = Exception("DB error") # Should not raise log_audit(db, "tenant-1", "create", {}, "admin")