from contextlib import contextmanager
from importlib import reload
from os import environ

from django.test import TestCase

from config.settings import base as settings


class TestDatabaseUrl(TestCase):
    def test_sslmode_defaults_to_required(self):
        with setenv("DATABASE_URL", "pgsql://u:p@h/d"):
            self._assert_sslmode_is("require")

    def test_sslmode_not_set_for_sqlite(self):
        with setenv("DATABASE_URL", "sqlite:///some/path"):
            self._assert_sslmode_is(None)

    def test_sslmode_can_be_disabled_via_database_url(self):
        with setenv("DATABASE_URL", "pgsql://u:p@h/d?sslmode=disable"):
            self._assert_sslmode_is("disable")

    def test_sslmode_can_be_required_via_database_url(self):
        with setenv("DATABASE_URL", "pgsql://u:p@h/d?sslmode=require"):
            self._assert_sslmode_is("require")

    def test_database_url_with_complex_user(self):
        with setenv("DATABASE_URL", "pgsql://user%40host:p@h/d"):
            self._assert_user_is("user@host")

    def _assert_sslmode_is(self, expected):
        actual = settings.DATABASES["default"].get("OPTIONS", {}).get("sslmode")
        self.assertEqual(actual, expected)

    def _assert_user_is(self, expected):
        actual = settings.DATABASES["default"].get("USER", "")
        self.assertEqual(actual, expected)


@contextmanager
def setenv(key, value):
    environ[key] = value
    reload(settings)
    yield
    del environ[key]
