CI / Build and push docker image (push) Successful in 2m56s
Assemble the Postgres DSN from DATABASE_ENGINE/HOST/PORT/NAME/USER/ PASSWORD/OPTIONS so only the password needs to live in a secret; the rest can go in a ConfigMap. DATABASE_URL remains a full-DSN override (used by the sqlite test suite). Credentials are percent-encoded, the port and options are omitted when empty, and the k8s migrate initContainer now also reads the config ConfigMap.
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
"""Unit tests for the database DSN assembly in :mod:`tavolo.config`.
|
|
|
|
``Settings.from_env`` is called directly with a fully replaced
|
|
``os.environ`` so no test leaks its ``DATABASE_*`` overrides into the
|
|
suite (``tests/__init__.py`` sets ``DATABASE_URL=sqlite://:memory:``
|
|
globally for the application tests).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from tavolo.config import Settings
|
|
|
|
|
|
def _settings(env: dict) -> Settings:
|
|
with patch.dict(os.environ, env, clear=True):
|
|
return Settings.from_env()
|
|
|
|
|
|
class DatabaseUrlTests(unittest.TestCase):
|
|
def test_defaults_assemble_from_parts(self):
|
|
settings = _settings({})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://tavolo:password@localhost/tavolo",
|
|
)
|
|
|
|
def test_components_override_defaults(self):
|
|
settings = _settings({
|
|
"DATABASE_ENGINE": "postgres",
|
|
"DATABASE_HOST": "db.internal",
|
|
"DATABASE_PORT": "5433",
|
|
"DATABASE_NAME": "cards",
|
|
"DATABASE_USER": "scopa",
|
|
"DATABASE_PASSWORD": "s3cret",
|
|
})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://scopa:s3cret@db.internal:5433/cards",
|
|
)
|
|
|
|
def test_options_are_appended_as_query_string(self):
|
|
settings = _settings({"DATABASE_OPTIONS": "ssl=require"})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://tavolo:password@localhost/tavolo?ssl=require",
|
|
)
|
|
|
|
def test_options_leading_question_mark_is_stripped(self):
|
|
settings = _settings({"DATABASE_OPTIONS": "?ssl=require"})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://tavolo:password@localhost/tavolo?ssl=require",
|
|
)
|
|
|
|
def test_credentials_are_percent_encoded(self):
|
|
settings = _settings({
|
|
"DATABASE_USER": "u@x",
|
|
"DATABASE_PASSWORD": "p@ss/word:1",
|
|
})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://u%40x:p%40ss%2Fword%3A1@localhost/tavolo",
|
|
)
|
|
|
|
def test_database_url_takes_precedence_over_parts(self):
|
|
settings = _settings({
|
|
"DATABASE_URL": "sqlite://:memory:",
|
|
"DATABASE_HOST": "db.internal",
|
|
"DATABASE_PASSWORD": "ignored",
|
|
})
|
|
self.assertEqual(settings.database_url, "sqlite://:memory:")
|
|
|
|
def test_empty_database_url_falls_back_to_parts(self):
|
|
settings = _settings({"DATABASE_URL": ""})
|
|
self.assertEqual(
|
|
settings.database_url,
|
|
"postgres://tavolo:password@localhost/tavolo",
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|