Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

358 lines
12 KiB
Python

"""
Behavioral tests for settings/env_registry module.
Tests convenience functions for CI detection, test mode,
and rate limiting.
"""
import os
from unittest.mock import patch
import pytest
class TestRegistry:
"""Tests for the global registry instance."""
def test_registry_is_settings_registry(self):
"""Registry is a SettingsRegistry instance."""
from local_deep_research.settings.env_registry import registry
from local_deep_research.settings.env_settings import SettingsRegistry
assert isinstance(registry, SettingsRegistry)
def test_registry_has_categories(self):
"""Registry has registered categories."""
from local_deep_research.settings.env_registry import registry
# Should have at least some categories from ALL_SETTINGS
all_vars = registry.get_all_env_vars()
assert len(all_vars) > 0
class TestGetEnvSetting:
"""Tests for get_env_setting function."""
def test_returns_default_for_unknown_key(self):
"""Returns default for unknown setting key."""
from local_deep_research.settings.env_registry import get_env_setting
result = get_env_setting(
"completely.unknown.key.xyz", default="fallback"
)
assert result == "fallback"
def test_returns_none_default(self):
"""Returns None when no default specified and key not found."""
from local_deep_research.settings.env_registry import get_env_setting
result = get_env_setting("completely.unknown.key.xyz")
assert result is None
class TestIsTestMode:
"""Tests for is_test_mode function."""
def test_returns_bool(self):
"""Returns a boolean."""
from local_deep_research.settings.env_registry import is_test_mode
result = is_test_mode()
assert isinstance(result, bool)
def test_callable_without_args(self):
"""Callable without arguments."""
from local_deep_research.settings.env_registry import is_test_mode
# Should not raise
is_test_mode()
class TestIsCiEnvironment:
"""Tests for is_ci_environment function."""
def test_returns_bool(self):
"""Returns a boolean."""
from local_deep_research.settings.env_registry import is_ci_environment
result = is_ci_environment()
assert isinstance(result, bool)
def test_true_when_ci_set(self):
"""Returns True when CI env var is 'true'."""
from local_deep_research.settings.env_registry import is_ci_environment
with patch.dict(os.environ, {"CI": "true"}):
assert is_ci_environment() is True
def test_true_when_ci_is_1(self):
"""Returns True when CI env var is '1'."""
from local_deep_research.settings.env_registry import is_ci_environment
with patch.dict(os.environ, {"CI": "1"}):
assert is_ci_environment() is True
def test_true_when_ci_is_yes(self):
"""Returns True when CI env var is 'yes'."""
from local_deep_research.settings.env_registry import is_ci_environment
with patch.dict(os.environ, {"CI": "yes"}):
assert is_ci_environment() is True
def test_false_when_ci_is_false(self):
"""Returns False when CI env var is 'false'."""
from local_deep_research.settings.env_registry import is_ci_environment
with patch.dict(os.environ, {"CI": "false"}):
assert is_ci_environment() is False
def test_false_when_ci_not_set(self):
"""Returns False when CI env var is not set."""
from local_deep_research.settings.env_registry import is_ci_environment
env = os.environ.copy()
env.pop("CI", None)
with patch.dict(os.environ, env, clear=True):
assert is_ci_environment() is False
def test_case_insensitive(self):
"""CI check is case-insensitive."""
from local_deep_research.settings.env_registry import is_ci_environment
with patch.dict(os.environ, {"CI": "TRUE"}):
assert is_ci_environment() is True
with patch.dict(os.environ, {"CI": "True"}):
assert is_ci_environment() is True
class TestIsGithubActions:
"""Tests for is_github_actions function."""
def test_returns_bool(self):
"""Returns a boolean."""
from local_deep_research.settings.env_registry import is_github_actions
result = is_github_actions()
assert isinstance(result, bool)
def test_true_when_set(self):
"""Returns True when GITHUB_ACTIONS is 'true'."""
from local_deep_research.settings.env_registry import is_github_actions
with patch.dict(os.environ, {"GITHUB_ACTIONS": "true"}):
assert is_github_actions() is True
def test_false_when_not_set(self):
"""Returns False when GITHUB_ACTIONS is not set."""
from local_deep_research.settings.env_registry import is_github_actions
env = os.environ.copy()
env.pop("GITHUB_ACTIONS", None)
with patch.dict(os.environ, env, clear=True):
assert is_github_actions() is False
def test_false_when_false(self):
"""Returns False when GITHUB_ACTIONS is 'false'."""
from local_deep_research.settings.env_registry import is_github_actions
with patch.dict(os.environ, {"GITHUB_ACTIONS": "false"}):
assert is_github_actions() is False
class TestIsRateLimitingEnabled:
"""Tests for is_rate_limiting_enabled function."""
@pytest.fixture(autouse=True)
def clean_env(self):
"""Strip both env-var forms before each test.
CI exports `LDR_DISABLE_RATE_LIMITING=true`, and `patch.dict` does
not clear pre-existing keys — it only adds/overrides the keys it
is given. Without this fixture, the canonical var bleeds in from
the outer process, short-circuits before the legacy code path,
and silently breaks any test that exercises the legacy form.
"""
from local_deep_research.settings.env_registry import (
_reset_legacy_warning_flag_for_tests,
)
env_vars = ("DISABLE_RATE_LIMITING", "LDR_DISABLE_RATE_LIMITING")
original_env = {k: os.environ[k] for k in env_vars if k in os.environ}
for k in env_vars:
os.environ.pop(k, None)
_reset_legacy_warning_flag_for_tests()
yield
for k in env_vars:
os.environ.pop(k, None)
for key, value in original_env.items():
os.environ[key] = value
_reset_legacy_warning_flag_for_tests()
def test_returns_bool(self):
"""Returns a boolean."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
result = is_rate_limiting_enabled()
assert isinstance(result, bool)
def test_enabled_by_default(self):
"""Rate limiting is enabled by default."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
env = os.environ.copy()
env.pop("DISABLE_RATE_LIMITING", None)
env.pop("LDR_DISABLE_RATE_LIMITING", None)
with patch.dict(os.environ, env, clear=True):
assert is_rate_limiting_enabled() is True
def test_disabled_when_flag_true(self):
"""Rate limiting disabled when DISABLE_RATE_LIMITING=true."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "true"}):
assert is_rate_limiting_enabled() is False
def test_disabled_when_flag_1(self):
"""Rate limiting disabled when DISABLE_RATE_LIMITING=1."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "1"}):
assert is_rate_limiting_enabled() is False
def test_disabled_when_flag_yes(self):
"""Rate limiting disabled when DISABLE_RATE_LIMITING=yes."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "yes"}):
assert is_rate_limiting_enabled() is False
def test_enabled_when_flag_false(self):
"""Rate limiting stays enabled when DISABLE_RATE_LIMITING=false."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "false"}):
assert is_rate_limiting_enabled() is True
def test_case_insensitive(self):
"""DISABLE_RATE_LIMITING check is case-insensitive."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
)
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "TRUE"}):
assert is_rate_limiting_enabled() is False
def test_legacy_form_emits_deprecation_warning_once(self, loguru_caplog):
"""Legacy DISABLE_RATE_LIMITING=true emits warning exactly once per process."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
_reset_legacy_warning_flag_for_tests,
)
_reset_legacy_warning_flag_for_tests()
try:
with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "true"}):
with loguru_caplog.at_level("WARNING"):
is_rate_limiting_enabled()
first_warnings = [
r
for r in loguru_caplog.records
if "DISABLE_RATE_LIMITING is deprecated" in r.getMessage()
]
assert len(first_warnings) == 1, (
"Legacy form should emit deprecation warning on first call"
)
loguru_caplog.clear()
with loguru_caplog.at_level("WARNING"):
is_rate_limiting_enabled()
is_rate_limiting_enabled()
repeat_warnings = [
r
for r in loguru_caplog.records
if "DISABLE_RATE_LIMITING is deprecated" in r.getMessage()
]
assert repeat_warnings == [], (
"Deprecation warning should not re-fire after first call"
)
finally:
_reset_legacy_warning_flag_for_tests()
def test_canonical_form_does_not_emit_deprecation_warning(
self, loguru_caplog
):
"""LDR_DISABLE_RATE_LIMITING does not emit deprecation warning."""
from local_deep_research.settings.env_registry import (
is_rate_limiting_enabled,
_reset_legacy_warning_flag_for_tests,
)
_reset_legacy_warning_flag_for_tests()
try:
env_clean = {
k: v
for k, v in os.environ.items()
if k != "DISABLE_RATE_LIMITING"
}
env_clean["LDR_DISABLE_RATE_LIMITING"] = "true"
with patch.dict(os.environ, env_clean, clear=True):
with loguru_caplog.at_level("WARNING"):
assert is_rate_limiting_enabled() is False
warnings = [
r
for r in loguru_caplog.records
if "deprecated" in r.getMessage()
]
assert warnings == [], (
"Canonical form should not emit deprecation warning"
)
finally:
_reset_legacy_warning_flag_for_tests()
class TestModuleExports:
"""Tests for module __all__ exports."""
def test_exports_registry(self):
"""Exports registry."""
from local_deep_research.settings.env_registry import __all__
assert "registry" in __all__
def test_exports_get_env_setting(self):
"""Exports get_env_setting."""
from local_deep_research.settings.env_registry import __all__
assert "get_env_setting" in __all__
def test_exports_is_test_mode(self):
"""Exports is_test_mode."""
from local_deep_research.settings.env_registry import __all__
assert "is_test_mode" in __all__
def test_exports_is_ci_environment(self):
"""Exports is_ci_environment."""
from local_deep_research.settings.env_registry import __all__
assert "is_ci_environment" in __all__
def test_exports_is_rate_limiting_enabled(self):
"""Exports is_rate_limiting_enabled."""
from local_deep_research.settings.env_registry import __all__
assert "is_rate_limiting_enabled" in __all__