Files
TimeTracker/tests/test_config_priority.py
Dries Peeters 90dde470da style: standardize code formatting and normalize line endings
- Normalize line endings from CRLF to LF across all files to match .editorconfig
- Standardize quote style from single quotes to double quotes
- Normalize whitespace and formatting throughout codebase
- Apply consistent code style across 372 files including:
  * Application code (models, routes, services, utils)
  * Test files
  * Configuration files
  * CI/CD workflows

This ensures consistency with the project's .editorconfig settings and
improves code maintainability.
2025-11-28 20:05:37 +01:00

163 lines
6.4 KiB
Python

"""
Tests for configuration priority system.
Tests that WebUI settings take priority over .env values, and that .env values
are used as initial startup values.
"""
import pytest
import os
from app.models import Settings
from app.utils.config_manager import ConfigManager
from app import db
class TestConfigPriority:
"""Tests for configuration priority: WebUI > .env > defaults"""
def test_settings_priority_over_env(self, app):
"""Test that Settings model values take priority over environment variables"""
with app.app_context():
# Set an environment variable
os.environ["CURRENCY"] = "USD"
# Get Settings and verify it's initialized from env
settings = Settings.get_settings()
assert settings.currency == "USD" or settings.currency == "EUR" # May be EUR if already exists
# Change the setting via WebUI (Settings model)
settings.currency = "GBP"
db.session.commit()
# ConfigManager should return the Settings value, not the env var
currency = ConfigManager.get_setting("currency")
assert currency == "GBP", "Settings model should take priority over env vars"
# Clean up
if "CURRENCY" in os.environ:
del os.environ["CURRENCY"]
def test_env_used_as_initial_value(self, app):
"""Test that .env values are used when creating new Settings instance"""
with app.app_context():
# Delete existing Settings to test initialization
Settings.query.delete()
db.session.commit()
# Set environment variables
os.environ["TZ"] = "America/New_York"
os.environ["CURRENCY"] = "CAD"
os.environ["ROUNDING_MINUTES"] = "5"
os.environ["SINGLE_ACTIVE_TIMER"] = "false"
os.environ["IDLE_TIMEOUT_MINUTES"] = "60"
# Create new Settings - should be initialized from env
settings = Settings.get_settings()
# Verify it was initialized from env (if it's a new instance)
# Note: If Settings already existed, it won't be re-initialized
assert settings.timezone in ["America/New_York", "Europe/Rome"] # May be existing value
assert settings.currency in ["CAD", "EUR", "GBP"] # May be existing value
# Clean up
for key in ["TZ", "CURRENCY", "ROUNDING_MINUTES", "SINGLE_ACTIVE_TIMER", "IDLE_TIMEOUT_MINUTES"]:
if key in os.environ:
del os.environ[key]
def test_config_manager_priority_order(self, app):
"""Test that ConfigManager checks in correct order: Settings > env > defaults"""
with app.app_context():
# Set environment variable
os.environ["ROUNDING_MINUTES"] = "10"
# Get Settings
settings = Settings.get_settings()
original_value = settings.rounding_minutes
# Change via Settings (simulating WebUI change)
settings.rounding_minutes = 15
db.session.commit()
# ConfigManager should return Settings value (15), not env var (10)
value = ConfigManager.get_setting("rounding_minutes")
assert value == 15, "ConfigManager should prioritize Settings over env vars"
# Restore original value
settings.rounding_minutes = original_value
db.session.commit()
# Clean up
if "ROUNDING_MINUTES" in os.environ:
del os.environ["ROUNDING_MINUTES"]
def test_env_fallback_when_settings_not_set(self, app):
"""Test that env vars are used when Settings field is None"""
with app.app_context():
# Set environment variable
os.environ["BACKUP_TIME"] = "03:00"
# Get Settings
settings = Settings.get_settings()
original_value = settings.backup_time
# ConfigManager should return env value if Settings is at default
# (This test verifies the fallback mechanism)
value = ConfigManager.get_setting("backup_time", "02:00")
# Value should be either from Settings or env, not the default
assert value in [settings.backup_time, "03:00", "02:00"]
# Clean up
if "BACKUP_TIME" in os.environ:
del os.environ["BACKUP_TIME"]
def test_settings_initialization_from_env_types(self, app):
"""Test that Settings initialization handles different value types correctly"""
with app.app_context():
# Delete existing Settings
Settings.query.delete()
db.session.commit()
# Set environment variables with different types
os.environ["TZ"] = "Asia/Tokyo" # String
os.environ["ROUNDING_MINUTES"] = "7" # Integer
os.environ["SINGLE_ACTIVE_TIMER"] = "false" # Boolean
os.environ["ALLOW_SELF_REGISTER"] = "true" # Boolean
# Create new Settings
settings = Settings.get_settings()
# Verify types are correct
assert isinstance(settings.timezone, str)
assert isinstance(settings.rounding_minutes, int)
assert isinstance(settings.single_active_timer, bool)
assert isinstance(settings.allow_self_register, bool)
# Clean up
for key in ["TZ", "ROUNDING_MINUTES", "SINGLE_ACTIVE_TIMER", "ALLOW_SELF_REGISTER"]:
if key in os.environ:
del os.environ[key]
def test_webui_changes_persist(self, app):
"""Test that changes made via WebUI (Settings model) persist and take priority"""
with app.app_context():
# Set environment variable
os.environ["CURRENCY"] = "JPY"
# Get Settings
settings = Settings.get_settings()
# Change via Settings (simulating WebUI)
settings.currency = "CHF"
db.session.commit()
# Verify the change persisted
db.session.refresh(settings)
assert settings.currency == "CHF"
# ConfigManager should return the persisted value
currency = ConfigManager.get_setting("currency")
assert currency == "CHF", "WebUI changes should persist and take priority"
# Clean up
if "CURRENCY" in os.environ:
del os.environ["CURRENCY"]