126 lines
4.1 KiB
Python
126 lines
4.1 KiB
Python
"""Feature flag configuration tests.
|
|
|
|
Verifies FeatureFlags class defaults and environment variable parsing.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from noteflow.config.settings import FeatureFlags, get_feature_flags
|
|
|
|
|
|
@pytest.fixture
|
|
def clear_feature_flags_cache() -> None:
|
|
"""Clear cached feature flags before each test."""
|
|
get_feature_flags.cache_clear()
|
|
|
|
|
|
@pytest.mark.usefixtures("clear_feature_flags_cache")
|
|
class TestFeatureFlagDefaults:
|
|
"""Verify default values for feature flags.
|
|
|
|
Note: These tests use monkeypatch to clear environment variables
|
|
that would otherwise override the code defaults.
|
|
"""
|
|
|
|
@pytest.mark.parametrize(
|
|
("attr", "expected"),
|
|
[
|
|
pytest.param("templates_enabled", True, id="templates-enabled"),
|
|
pytest.param("pdf_export_enabled", True, id="pdf-export-enabled"),
|
|
pytest.param("ner_enabled", False, id="ner-disabled"),
|
|
pytest.param("calendar_enabled", False, id="calendar-disabled"),
|
|
pytest.param("webhooks_enabled", True, id="webhooks-enabled"),
|
|
],
|
|
)
|
|
def test_default_values(self, attr: str, expected: bool) -> None:
|
|
"""Feature flags have correct default values in code (ignores .env)."""
|
|
# Use model_construct to bypass env file reading and test pure code defaults
|
|
flags = FeatureFlags.model_construct()
|
|
actual = getattr(flags, attr)
|
|
assert actual is expected, f"{attr} should default to {expected}"
|
|
|
|
|
|
@pytest.mark.usefixtures("clear_feature_flags_cache")
|
|
class TestFeatureFlagEnvironment:
|
|
"""Verify environment variable parsing."""
|
|
|
|
@pytest.mark.parametrize(
|
|
("env_var", "attr", "value", "expected"),
|
|
[
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_NER_ENABLED",
|
|
"ner_enabled",
|
|
"true",
|
|
True,
|
|
id="ner-enabled-true",
|
|
),
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_NER_ENABLED",
|
|
"ner_enabled",
|
|
"false",
|
|
False,
|
|
id="ner-enabled-false",
|
|
),
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_CALENDAR_ENABLED",
|
|
"calendar_enabled",
|
|
"true",
|
|
True,
|
|
id="calendar-enabled-true",
|
|
),
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_WEBHOOKS_ENABLED",
|
|
"webhooks_enabled",
|
|
"false",
|
|
False,
|
|
id="webhooks-disabled",
|
|
),
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_TEMPLATES_ENABLED",
|
|
"templates_enabled",
|
|
"false",
|
|
False,
|
|
id="templates-disabled",
|
|
),
|
|
pytest.param(
|
|
"NOTEFLOW_FEATURE_PDF_EXPORT_ENABLED",
|
|
"pdf_export_enabled",
|
|
"false",
|
|
False,
|
|
id="pdf-export-disabled",
|
|
),
|
|
],
|
|
)
|
|
def test_env_var_parsing(
|
|
self,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
env_var: str,
|
|
attr: str,
|
|
value: str,
|
|
expected: bool,
|
|
) -> None:
|
|
"""Feature flags parse from environment variables."""
|
|
monkeypatch.setenv(env_var, value)
|
|
flags = get_feature_flags()
|
|
actual = getattr(flags, attr)
|
|
assert actual == expected, f"{attr} should be {expected} when {env_var}={value}"
|
|
|
|
|
|
@pytest.mark.usefixtures("clear_feature_flags_cache")
|
|
class TestFeatureFlagCaching:
|
|
"""Verify feature flags are cached."""
|
|
|
|
def test_get_feature_flags_cached(self) -> None:
|
|
"""get_feature_flags returns same instance."""
|
|
flags1 = get_feature_flags()
|
|
flags2 = get_feature_flags()
|
|
assert flags1 is flags2, "Should return cached instance"
|
|
|
|
def test_cache_clear_returns_new_instance(self) -> None:
|
|
"""After cache_clear, a new instance is returned."""
|
|
flags1 = get_feature_flags()
|
|
get_feature_flags.cache_clear()
|
|
flags2 = get_feature_flags()
|
|
assert flags1 is not flags2, "Should return new instance after cache clear"
|
|
assert flags1.ner_enabled == flags2.ner_enabled, "Values should match"
|