Source code for minos.common.testing.testcases

from __future__ import (
    annotations,
)

import unittest
from abc import (
    ABC,
)
from contextlib import (
    suppress,
)
from pathlib import (
    Path,
)
from typing import (
    Any,
    Union,
)
from uuid import (
    uuid4,
)

from ..config import (
    Config,
)
from ..database import (
    DatabaseClient,
    DatabaseClientPool,
    ManagementDatabaseOperationFactory,
)
from ..injections import (
    DependencyInjector,
    InjectableMixin,
)
from ..pools import (
    PoolFactory,
)


[docs]class MinosTestCase(unittest.IsolatedAsyncioTestCase, ABC): CONFIG_FILE_PATH: Path
[docs] def setUp(self) -> None: super().setUp() self.config = self.get_config() self.injector = DependencyInjector(self.config, self.get_injections()) self.injector.wire_injections()
[docs] def get_config(self) -> Config: return Config(self.get_config_file_path())
[docs] def get_config_file_path(self) -> Path: return self.CONFIG_FILE_PATH
[docs] def get_injections(self) -> list[Union[InjectableMixin, type[InjectableMixin], str]]: return []
[docs] async def asyncSetUp(self) -> None: await super().asyncSetUp() await self.injector.setup_injections()
[docs] async def asyncTearDown(self) -> None: await self.injector.destroy_injections() await super().asyncTearDown()
[docs] def tearDown(self) -> None: self.injector.unwire_injections() super().tearDown()
def __getattr__(self, item: str) -> Any: if item != "injector": with suppress(Exception): return getattr(self.injector, item) raise AttributeError(f"{type(self).__name__!r} does not contain the {item!r} attribute.")
[docs]class DatabaseMinosTestCase(MinosTestCase, ABC):
[docs] def setUp(self): self.base_config = Config(self.get_config_file_path()) self._uuid = uuid4() self._test_db = {"database": f"test_db_{self._uuid.hex}"} super().setUp()
[docs] def get_client(self) -> DatabaseClient: default_config = self.base_config.get_default_database() client = default_config.get("client") return client.from_config(self.base_config)
[docs] def get_config(self) -> Config: config = Config(self.get_config_file_path()) base_fn = config.get_databases def _fn(): return {k: (v | self._test_db) for k, v in base_fn().items()} config.get_databases = _fn return config
[docs] def get_injections(self) -> list[Union[InjectableMixin, type[InjectableMixin], str]]: return [PoolFactory.from_config(self.config, default_classes={"database": DatabaseClientPool})]
[docs] async def asyncSetUp(self): await self._create_database(self._test_db) await super().asyncSetUp()
[docs] async def asyncTearDown(self): await super().asyncTearDown() await self._drop_database(self._test_db)
async def _create_database(self, test: dict[str, Any]) -> None: await self._drop_database(test) async with self.get_client() as client: operation = client.get_factory(ManagementDatabaseOperationFactory).build_create(test["database"]) await client.execute(operation) async def _drop_database(self, test: dict[str, Any]) -> None: async with self.get_client() as client: operation = client.get_factory(ManagementDatabaseOperationFactory).build_delete(test["database"]) await client.execute(operation)