"""Tests for transcription.config — settings loading, provider defaults, and paths.""" from pathlib import Path import pytest from pydantic import ValidationError from transcription.config import Provider from transcription.config import Settings def _make_settings(**overrides) -> Settings: """Build a Settings instance with a dummy API key unless overridden.""" defaults = {"openrouter_api_key": "test-key-abc123"} defaults.update(overrides) return Settings(**defaults) class TestSettingsLoading: """Verify Settings construction and required-field validation.""" def test_loads_from_env(self, monkeypatch): """Settings constructs when OPENROUTER_API_KEY is provided.""" monkeypatch.setenv("OPENROUTER_API_KEY", "test-key-xyz") settings = Settings() assert settings.openrouter_api_key == "test-key-xyz" def test_requires_api_key(self, monkeypatch): """Settings raises ValidationError when OPENROUTER_API_KEY is missing.""" monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) with pytest.raises(ValidationError): Settings(_env_file=None) class TestProviderSettings: """Verify provider enum defaults and validation.""" def test_defaults_to_openrouter(self): """Default provider is openrouter when not explicitly set.""" settings = _make_settings() assert settings.provider == Provider.OPENROUTER assert settings.provider == "openrouter" def test_rejects_invalid_value(self): """Setting PROVIDER to an invalid value raises ValidationError.""" with pytest.raises(ValidationError): _make_settings(provider="not-a-provider") def test_optional_fields_default_to_none(self): """provider_model, openrouter_http_referer, and openrouter_app_title are None when unset.""" settings = _make_settings() assert settings.provider_model is None assert settings.openrouter_http_referer is None assert settings.openrouter_app_title is None class TestPathSettings: """Verify filesystem path field types.""" def test_path_fields_are_path_objects(self): """upload_dir and prompt_dir are Path instances.""" settings = _make_settings() assert isinstance(settings.upload_dir, Path) assert isinstance(settings.prompt_dir, Path) class TestMigrationSafetySettings: """Verify migration safety settings defaults.""" def test_migration_safety_defaults(self): """Migration auto-apply is off and startup schema validation is on by default.""" settings = _make_settings() assert settings.migration_auto_apply_on_startup is False assert settings.validate_schema_on_startup is True class TestSecuritySettings: """Verify Step 5 security-related settings behavior.""" def test_security_defaults(self): """Security controls default to disabled auth and bounded upload size.""" settings = _make_settings() assert settings.max_upload_bytes == 15 * 1024 * 1024 assert settings.operator_access_enabled is False assert settings.operator_username == "operator" assert settings.operator_password is None def test_operator_password_required_when_access_enabled(self): """Enabling operator access requires OPERATOR_PASSWORD.""" with pytest.raises(ValidationError): _make_settings(operator_access_enabled=True, operator_password=None) class TestWorkerReliabilitySettings: """Verify worker retry settings defaults.""" def test_worker_retry_defaults(self): """worker retry settings default to no retries and no backoff.""" settings = _make_settings() assert settings.worker_max_retries == 0 assert settings.worker_retry_backoff_seconds == 0.0