# #region Test.Models.AuthLlm [C:1] [TYPE Module] [SEMANTICS test,models,auth,llm,generate_uuid] # @BRIEF Tests for generate_uuid functions in auth.py and llm.py, and model column attributes. # @RELATION BINDS_TO -> [AuthModels] # @RELATION BINDS_TO -> [LlmModels] import pytest class TestAuthGenerateUuid: """generate_uuid in auth.py — UUID generation for primary keys.""" def test_returns_string(self): from src.models.auth import generate_uuid uid = generate_uuid() assert isinstance(uid, str) assert len(uid) > 20 def test_unique_values(self): from src.models.auth import generate_uuid uids = {generate_uuid() for _ in range(100)} assert len(uids) == 100 class TestAuthModelColumnAttrs: """Verify auth model column attributes. Note: SQLAlchemy Column(default=...) is INSERT-time only, not Python __init__ time. So we must pass all values explicitly. """ def test_user_columns(self): from src.models.auth import User user = User( id="u-1", username="test_user", auth_source="LOCAL", is_active=True, is_ad_user=False, ) assert user.id == "u-1" assert user.username == "test_user" assert user.auth_source == "LOCAL" assert user.is_active is True assert user.is_ad_user is False assert user.email is None assert user.password_hash is None assert user.full_name is None def test_user_with_all_fields(self): from src.models.auth import User user = User( id="u-2", username="admin", email="admin@example.com", password_hash="hash", full_name="Admin User", auth_source="ADFS", is_active=True, is_ad_user=True, ) assert user.email == "admin@example.com" assert user.password_hash == "hash" assert user.full_name == "Admin User" assert user.auth_source == "ADFS" assert user.is_ad_user is True def test_role_columns(self): from src.models.auth import Role role = Role(id="r-1", name="test_role", is_admin=False) assert role.id == "r-1" assert role.name == "test_role" assert role.is_admin is False def test_role_admin(self): from src.models.auth import Role role = Role(id="r-2", name="admin", is_admin=True) assert role.is_admin is True def test_permission_columns(self): from src.models.auth import Permission perm = Permission(id="p-1", resource="dashboard", action="READ") assert perm.id == "p-1" assert perm.resource == "dashboard" assert perm.action == "READ" def test_ad_group_mapping_columns(self): from src.models.auth import ADGroupMapping mapping = ADGroupMapping(id="m-1", ad_group="DOMAIN\\Users", role_id="role-1") assert mapping.id == "m-1" assert mapping.ad_group == "DOMAIN\\Users" assert mapping.role_id == "role-1" def test_token_blacklist_columns(self): from datetime import datetime from src.models.auth import TokenBlacklist ts = datetime.now() tb = TokenBlacklist( jti="jti-1", token_hash="a" * 64, expires_at=ts, revoked_at=ts, ) assert tb.jti == "jti-1" assert tb.token_hash == "a" * 64 assert tb.expires_at == ts assert tb.revoked_at is not None class TestLlmGenerateUuid: """generate_uuid in llm.py.""" def test_returns_string(self): from src.models.llm import generate_uuid uid = generate_uuid() assert isinstance(uid, str) assert len(uid) > 20 def test_unique_values(self): from src.models.llm import generate_uuid uids = {generate_uuid() for _ in range(50)} assert len(uids) == 50 class TestLlmModelColumnAttrs: """Verify LLM model column attributes with explicit values.""" def test_llm_provider_columns(self): from src.models.llm import LLMProvider provider = LLMProvider( id="lp-1", provider_type="openai", name="GPT-4", base_url="https://api.openai.com", api_key="sk-xxx", default_model="gpt-4", is_active=True, is_multimodal=False, ) assert provider.id == "lp-1" assert provider.is_active is True assert provider.is_multimodal is False def test_llm_provider_multimodal(self): from src.models.llm import LLMProvider provider = LLMProvider( id="lp-2", provider_type="openai", name="GPT-4V", base_url="https://api.openai.com", api_key="sk-xxx", default_model="gpt-4-vision", is_active=True, is_multimodal=True, max_images=10, context_window=128000, max_output_tokens=4096, ) assert provider.is_multimodal is True assert provider.max_images == 10 assert provider.context_window == 128000 assert provider.max_output_tokens == 4096 def test_validation_policy_columns(self): from datetime import time from src.models.llm import ValidationPolicy policy = ValidationPolicy( id="vp-1", name="Test Policy", environment_id="env-1", dashboard_ids=["1", "2"], schedule_days=[1, 3, 5], window_start=time(9, 0), window_end=time(18, 0), is_active=True, screenshot_enabled=True, logs_enabled=True, execute_chart_data=False, llm_batch_size=1, policy_dashboard_concurrency_limit=3, notify_owners=True, alert_condition="FAIL_ONLY", ) assert policy.id == "vp-1" assert policy.is_active is True assert policy.screenshot_enabled is True assert policy.logs_enabled is True assert policy.execute_chart_data is False assert policy.llm_batch_size == 1 def test_validation_policy_v2_fields(self): from datetime import time from src.models.llm import ValidationPolicy policy = ValidationPolicy( id="vp-2", name="V2 Policy", environment_id="env-2", dashboard_ids=[], schedule_days=[1, 3, 5], window_start=time(9, 0), window_end=time(18, 0), prompt_template="Custom template", screenshot_enabled=False, logs_enabled=False, execute_chart_data=True, llm_batch_size=5, policy_dashboard_concurrency_limit=10, ) assert policy.prompt_template == "Custom template" assert policy.llm_batch_size == 5 assert policy.policy_dashboard_concurrency_limit == 10 def test_validation_source_columns(self): from src.models.llm import ValidationSource source = ValidationSource( id="vs-1", policy_id="pol-1", type="dashboard_id", value="42", status="valid", ) assert source.id == "vs-1" assert source.status == "valid" def test_validation_source_invalid_status(self): from src.models.llm import ValidationSource source = ValidationSource( id="vs-2", policy_id="pol-1", type="dashboard_url", value="http://superset/dash/42", status="parse_failed", last_error="Could not parse URL", title="Sales Dashboard", resolved_dashboard_id="42", ) assert source.status == "parse_failed" assert source.last_error == "Could not parse URL" assert source.title == "Sales Dashboard" def test_validation_record_columns(self): from src.models.llm import ValidationRecord record = ValidationRecord( id="vr-1", dashboard_id="42", environment_id="env-1", status="PASS", summary="All good", issues=[], ) assert record.id == "vr-1" assert record.issues == [] assert record.task_id is None def test_validation_record_with_issues(self): from src.models.llm import ValidationRecord record = ValidationRecord( id="vr-2", dashboard_id="99", environment_id="env-1", status="FAIL", summary="Errors found", issues=[{"severity": "FAIL", "message": "Chart broken"}], screenshot_path="/screens/1.png", raw_response='{"ok": false}', ) assert len(record.issues) == 1 assert record.screenshot_path == "/screens/1.png" def test_validation_run_columns(self): from src.models.llm import ValidationRun run = ValidationRun( id="vrun-1", policy_id="pol-1", trigger="manual", status="running", dashboard_count=0, ) assert run.id == "vrun-1" assert run.trigger == "manual" assert run.status == "running" assert run.dashboard_count == 0 def test_validation_run_scheduled(self): from src.models.llm import ValidationRun run = ValidationRun( id="vrun-2", policy_id="pol-1", trigger="scheduled", status="completed", dashboard_count=5, pass_count=4, fail_count=1, warn_count=0, unknown_count=0, ) assert run.trigger == "scheduled" assert run.dashboard_count == 5 assert run.pass_count == 4 # #endregion Test.Models.AuthLlm