from pathlib import Path import pytest from audita.config import AuditaConfig, ConfigOverrides from audita.config import ( DEFAULT_GLOSSARY_CONFIDENCE_THRESHOLD, DEFAULT_GLOSSARY_MAX_LLM_PASSES, DEFAULT_GRAMMAR_CONFIDENCE_THRESHOLD, DEFAULT_GRAMMAR_MAX_LLM_PASSES, DEFAULT_GRAMMAR_VALIDATION_CONFIDENCE_THRESHOLD, DEFAULT_GRAMMAR_VALIDATION_ENABLED, DEFAULT_MAX_RETRIES, DEFAULT_MAX_SECTION_TOKENS, DEFAULT_NORMALIZE_ELLIPSIS_GAP, DEFAULT_NORMALIZE_MAX_SEGMENT_DURATION, DEFAULT_NORMALIZE_MAX_SEGMENT_GAP, DEFAULT_NORMALIZE_MAX_SEGMENT_TOKENS, DEFAULT_WORK_DIR, ) from audita.errors import AuditaConfigError def test_config_uses_defaults_with_api_key(): config = AuditaConfig.from_sources(env={"OPENROUTER_API_KEY": "key"}) assert config.glossary_confidence_threshold == DEFAULT_GLOSSARY_CONFIDENCE_THRESHOLD assert config.glossary_confidence_threshold == 0.8 assert config.grammar_confidence_threshold == DEFAULT_GRAMMAR_CONFIDENCE_THRESHOLD assert config.grammar_confidence_threshold == 0.8 assert config.max_section_tokens == DEFAULT_MAX_SECTION_TOKENS assert config.max_retries == DEFAULT_MAX_RETRIES assert config.glossary_max_llm_passes == DEFAULT_GLOSSARY_MAX_LLM_PASSES assert config.grammar_max_llm_passes == DEFAULT_GRAMMAR_MAX_LLM_PASSES assert config.grammar_validation_enabled == DEFAULT_GRAMMAR_VALIDATION_ENABLED assert config.grammar_validation_enabled is True assert config.grammar_validation_confidence_threshold == DEFAULT_GRAMMAR_VALIDATION_CONFIDENCE_THRESHOLD assert config.grammar_validation_confidence_threshold == 0.8 assert config.normalize_max_segment_gap == DEFAULT_NORMALIZE_MAX_SEGMENT_GAP assert config.normalize_max_segment_gap == 5.0 assert config.normalize_ellipsis_gap == DEFAULT_NORMALIZE_ELLIPSIS_GAP assert config.normalize_max_segment_duration == DEFAULT_NORMALIZE_MAX_SEGMENT_DURATION assert config.normalize_max_segment_duration == 60.0 assert config.normalize_max_segment_tokens == DEFAULT_NORMALIZE_MAX_SEGMENT_TOKENS assert config.normalize_max_segment_tokens == 2048 assert config.work_dir == Path(DEFAULT_WORK_DIR) def test_config_env_overrides_defaults(): config = AuditaConfig.from_sources( env={ "OPENROUTER_API_KEY": "key", "AUDITA_MAX_SECTION_TOKENS": "42", "AUDITA_GLOSSARY_CONFIDENCE_THRESHOLD": "0.9", "AUDITA_GRAMMAR_CONFIDENCE_THRESHOLD": "0.7", "AUDITA_MAX_RETRIES": "5", "AUDITA_GLOSSARY_MAX_LLM_PASSES": "7", "AUDITA_GRAMMAR_MAX_LLM_PASSES": "4", "AUDITA_GRAMMAR_VALIDATION_ENABLED": "false", "AUDITA_GRAMMAR_VALIDATION_CONFIDENCE_THRESHOLD": "0.91", "AUDITA_NORMALIZE_MAX_SEGMENT_GAP": "4.5", "AUDITA_NORMALIZE_ELLIPSIS_GAP": "1.5", "AUDITA_NORMALIZE_MAX_SEGMENT_DURATION": "45.0", "AUDITA_NORMALIZE_MAX_SEGMENT_TOKENS": "512", "AUDITA_WORK_DIR": "/tmp/custom-audita", } ) assert config.max_section_tokens == 42 assert config.glossary_confidence_threshold == 0.9 assert config.grammar_confidence_threshold == 0.7 assert config.max_retries == 5 assert config.glossary_max_llm_passes == 7 assert config.grammar_max_llm_passes == 4 assert config.grammar_validation_enabled is False assert config.grammar_validation_confidence_threshold == 0.91 assert config.normalize_max_segment_gap == 4.5 assert config.normalize_ellipsis_gap == 1.5 assert config.normalize_max_segment_duration == 45.0 assert config.normalize_max_segment_tokens == 512 assert config.work_dir == Path("/tmp/custom-audita") def test_config_cli_overrides_env(): config = AuditaConfig.from_sources( env={ "OPENROUTER_API_KEY": "key", "AUDITA_MAX_SECTION_TOKENS": "42", "AUDITA_MAX_RETRIES": "5", "AUDITA_GLOSSARY_MAX_LLM_PASSES": "7", "AUDITA_GRAMMAR_MAX_LLM_PASSES": "6", "AUDITA_GRAMMAR_VALIDATION_ENABLED": "false", "AUDITA_GRAMMAR_VALIDATION_CONFIDENCE_THRESHOLD": "0.91", "AUDITA_NORMALIZE_MAX_SEGMENT_GAP": "4.5", "AUDITA_NORMALIZE_ELLIPSIS_GAP": "1.5", "AUDITA_NORMALIZE_MAX_SEGMENT_DURATION": "45.0", "AUDITA_NORMALIZE_MAX_SEGMENT_TOKENS": "512", "AUDITA_WORK_DIR": "/tmp/env-audita", }, overrides=ConfigOverrides( max_section_tokens=100, glossary_confidence_threshold=0.7, grammar_confidence_threshold=0.65, max_retries=3, glossary_max_llm_passes=2, grammar_max_llm_passes=3, grammar_validation_enabled=True, grammar_validation_confidence_threshold=0.75, normalize_max_segment_gap=3.0, normalize_ellipsis_gap=1.0, normalize_max_segment_duration=30.0, normalize_max_segment_tokens=256, work_dir=Path("/tmp/cli-audita"), ), ) assert config.max_section_tokens == 100 assert config.glossary_confidence_threshold == 0.7 assert config.grammar_confidence_threshold == 0.65 assert config.max_retries == 3 assert config.glossary_max_llm_passes == 2 assert config.grammar_max_llm_passes == 3 assert config.grammar_validation_enabled is True assert config.grammar_validation_confidence_threshold == 0.75 assert config.normalize_max_segment_gap == 3.0 assert config.normalize_ellipsis_gap == 1.0 assert config.normalize_max_segment_duration == 30.0 assert config.normalize_max_segment_tokens == 256 assert config.work_dir == Path("/tmp/cli-audita") def test_config_requires_api_key(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources(env={}) def test_config_rejects_bad_env_int(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_MAX_SECTION_TOKENS": "many"} ) def test_config_rejects_invalid_glossary_pass_count(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GLOSSARY_MAX_LLM_PASSES": "0"} ) def test_config_rejects_invalid_grammar_pass_count(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GRAMMAR_MAX_LLM_PASSES": "0"} ) def test_config_rejects_invalid_stage_thresholds(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GLOSSARY_CONFIDENCE_THRESHOLD": "1.1"} ) with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GRAMMAR_CONFIDENCE_THRESHOLD": "-0.1"} ) with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GRAMMAR_VALIDATION_CONFIDENCE_THRESHOLD": "1.1"} ) def test_config_rejects_invalid_grammar_validation_enabled(): with pytest.raises(AuditaConfigError): AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_GRAMMAR_VALIDATION_ENABLED": "maybe"} ) def test_legacy_confidence_threshold_env_is_ignored(): config = AuditaConfig.from_sources( env={"OPENROUTER_API_KEY": "key", "AUDITA_CONFIDENCE_THRESHOLD": "0.9"} ) assert config.glossary_confidence_threshold == DEFAULT_GLOSSARY_CONFIDENCE_THRESHOLD assert config.grammar_confidence_threshold == DEFAULT_GRAMMAR_CONFIDENCE_THRESHOLD def test_config_rejects_invalid_normalization_values(): invalid_envs = [ {"AUDITA_NORMALIZE_MAX_SEGMENT_GAP": "-1"}, {"AUDITA_NORMALIZE_ELLIPSIS_GAP": "-1"}, { "AUDITA_NORMALIZE_MAX_SEGMENT_GAP": "1", "AUDITA_NORMALIZE_ELLIPSIS_GAP": "2", }, {"AUDITA_NORMALIZE_MAX_SEGMENT_DURATION": "0"}, {"AUDITA_NORMALIZE_MAX_SEGMENT_TOKENS": "0"}, {"AUDITA_NORMALIZE_MAX_SEGMENT_GAP": "nan"}, ] for env in invalid_envs: with pytest.raises(AuditaConfigError): AuditaConfig.from_sources(env={"OPENROUTER_API_KEY": "key", **env})