119 lines
5.3 KiB
Python
119 lines
5.3 KiB
Python
"""Integration tests for trigger and retention settings loading."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from noteflow.config.settings import Settings, get_settings, get_trigger_settings
|
|
from tests.conftest import approx_float
|
|
|
|
pytestmark = [pytest.mark.integration, pytest.mark.usefixtures("clear_settings_cache")]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"attr,expected",
|
|
[
|
|
("trigger_meeting_apps", ["zoom", "teams"]),
|
|
("trigger_suppressed_apps", ["spotify"]),
|
|
("trigger_audio_min_samples", 5),
|
|
],
|
|
)
|
|
def test_trigger_settings_env_parsing(
|
|
monkeypatch: pytest.MonkeyPatch, attr: str, expected: list[str] | int
|
|
) -> None:
|
|
"""TriggerSettings should parse CSV lists from environment variables."""
|
|
monkeypatch.setenv("NOTEFLOW_TRIGGER_MEETING_APPS", "zoom, teams")
|
|
monkeypatch.setenv("NOTEFLOW_TRIGGER_SUPPRESSED_APPS", "spotify")
|
|
monkeypatch.setenv("NOTEFLOW_TRIGGER_AUDIO_MIN_SAMPLES", "5")
|
|
monkeypatch.setenv("NOTEFLOW_TRIGGER_POLL_INTERVAL_SECONDS", "1.5")
|
|
settings = get_trigger_settings()
|
|
actual = getattr(settings, attr)
|
|
assert actual == expected, f"TriggerSettings.{attr}: expected {expected!r}, got {actual!r}"
|
|
|
|
|
|
def test_trigger_settings_poll_interval_parsing(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""TriggerSettings parses poll interval as float."""
|
|
monkeypatch.setenv("NOTEFLOW_TRIGGER_POLL_INTERVAL_SECONDS", "1.5")
|
|
settings = get_trigger_settings()
|
|
actual = settings.trigger_poll_interval_seconds
|
|
assert actual == approx_float(1.5), f"poll_interval_seconds: expected 1.5, got {actual}"
|
|
|
|
|
|
class TestRetentionSettings:
|
|
"""Tests for retention settings."""
|
|
|
|
def test_retention_defaults(self) -> None:
|
|
"""Retention settings should have correct defaults."""
|
|
# Access via class to check field defaults without loading from env
|
|
expected_retention_days_default = 90
|
|
expected_check_interval_default = 24
|
|
retention_enabled_default = Settings.model_fields["retention_enabled"].default
|
|
retention_days_default = Settings.model_fields["retention_days"].default
|
|
check_interval_default = Settings.model_fields["retention_check_interval_hours"].default
|
|
assert retention_enabled_default is False, (
|
|
f"retention_enabled default: expected False, got {retention_enabled_default!r}"
|
|
)
|
|
assert retention_days_default == expected_retention_days_default, (
|
|
f"retention_days default: expected {expected_retention_days_default}, got {retention_days_default}"
|
|
)
|
|
assert check_interval_default == expected_check_interval_default, (
|
|
f"retention_check_interval_hours default: expected {expected_check_interval_default}, "
|
|
f"got {check_interval_default}"
|
|
)
|
|
|
|
def test_retention_env_parsing(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""Retention settings should parse from environment variables."""
|
|
monkeypatch.setenv("NOTEFLOW_DATABASE_URL", "postgresql+asyncpg://user:pass@localhost/db")
|
|
monkeypatch.setenv("NOTEFLOW_RETENTION_ENABLED", "true")
|
|
expected_retention_days = 30
|
|
expected_check_interval = 12
|
|
monkeypatch.setenv("NOTEFLOW_RETENTION_DAYS", str(expected_retention_days))
|
|
monkeypatch.setenv("NOTEFLOW_RETENTION_CHECK_INTERVAL_HOURS", str(expected_check_interval))
|
|
|
|
settings = get_settings()
|
|
|
|
assert settings.retention_enabled is True, (
|
|
f"retention_enabled: expected True, got {settings.retention_enabled!r}"
|
|
)
|
|
assert settings.retention_days == expected_retention_days, (
|
|
f"retention_days: expected {expected_retention_days}, got {settings.retention_days}"
|
|
)
|
|
assert settings.retention_check_interval_hours == expected_check_interval, (
|
|
f"retention_check_interval_hours: expected {expected_check_interval}, "
|
|
f"got {settings.retention_check_interval_hours}"
|
|
)
|
|
|
|
def test_retention_days_validation(self) -> None:
|
|
"""Retention days should be validated within range."""
|
|
from pydantic import ValidationError
|
|
|
|
# ge=1, le=3650
|
|
with pytest.raises(ValidationError, match="retention_days"):
|
|
Settings.model_validate(
|
|
{"database_url": "postgresql+asyncpg://x:x@x/x", "retention_days": 0}
|
|
)
|
|
with pytest.raises(ValidationError, match="retention_days"):
|
|
Settings.model_validate(
|
|
{"database_url": "postgresql+asyncpg://x:x@x/x", "retention_days": 4000}
|
|
)
|
|
|
|
def test_retention_check_interval_validation(self) -> None:
|
|
"""Retention check interval should be validated within range."""
|
|
from pydantic import ValidationError
|
|
|
|
# ge=1, le=168
|
|
with pytest.raises(ValidationError, match="retention_check_interval_hours"):
|
|
Settings.model_validate(
|
|
{
|
|
"database_url": "postgresql+asyncpg://x:x@x/x",
|
|
"retention_check_interval_hours": 0,
|
|
}
|
|
)
|
|
with pytest.raises(ValidationError, match="retention_check_interval_hours"):
|
|
Settings.model_validate(
|
|
{
|
|
"database_url": "postgresql+asyncpg://x:x@x/x",
|
|
"retention_check_interval_hours": 200,
|
|
}
|
|
)
|