"""Pytest fixtures for testing.""" import sys import toml import yaml import json import os import shutil import pytest def patch_translate(moulinette): """Configure translator to raise errors when there are missing keys.""" old_translate = moulinette.core.Translator.translate def new_translate(self, key, *args, **kwargs): if key not in self._translations[self.default_locale].keys(): message = "Unable to retrieve key '%s' for default locale!" % key raise KeyError(message) return old_translate(self, key, *args, **kwargs) moulinette.core.Translator.translate = new_translate def new_m18nn(self, key, *args, **kwargs): return self._global.translate(key, *args, **kwargs) moulinette.core.Moulinette18n.g = new_m18nn def logging_configuration(moulinette): """Configure logging to use the custom logger.""" handlers = {"tty", "api"} root_handlers = set(handlers) level = "INFO" tty_level = "INFO" return { "version": 1, "disable_existing_loggers": True, "formatters": { "tty-debug": {"format": "%(relativeCreated)-4d %(fmessage)s"}, "precise": { "format": "%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s" # noqa }, }, "filters": {"action": {"()": "moulinette.utils.log.ActionFilter"}}, "handlers": { "api": { "level": level, "class": "moulinette.interfaces.api.APIQueueHandler", }, "tty": { "level": tty_level, "class": "moulinette.interfaces.cli.TTYHandler", "formatter": "", }, }, "loggers": { "moulinette": {"level": level, "handlers": [], "propagate": True}, "moulinette.interface": { "level": level, "handlers": handlers, "propagate": False, }, }, "root": {"level": level, "handlers": root_handlers}, } def patch_lock(moulinette): moulinette.core.MoulinetteLock.base_lockfile = "moulinette_%s.lock" @pytest.fixture(scope="session", autouse=True) def moulinette(tmp_path_factory): import moulinette import moulinette.core from moulinette.utils.log import configure_logging # Can't call the namespace just 'test' because # that would lead to some "import test" not importing the right stuff namespace = "moulitest" tmp_dir = str(tmp_path_factory.mktemp(namespace)) shutil.copy("./test/actionsmap/moulitest.yml", f"{tmp_dir}/moulitest.yml") shutil.copytree("./test/src", f"{tmp_dir}/lib/{namespace}/") shutil.copytree("./test/locales", f"{tmp_dir}/locales") sys.path.insert(0, f"{tmp_dir}/lib") patch_translate(moulinette) patch_lock(moulinette) configure_logging(logging_configuration(moulinette)) moulinette.m18n.set_locales_dir(f"{tmp_dir}/locales") # Dirty hack to pass this path to Api() and Cli() init later moulinette._actionsmap_path = f"{tmp_dir}/moulitest.yml" return moulinette @pytest.fixture def moulinette_webapi(moulinette): from webtest import TestApp from webtest.app import CookiePolicy # Dirty hack needed, otherwise cookies ain't reused between request .. not # sure why :| def return_true(self, cookie, request): return True CookiePolicy.return_ok_secure = return_true from moulinette.interfaces.api import Interface as Api return TestApp(Api(routes={}, actionsmap=moulinette._actionsmap_path)._app) @pytest.fixture def moulinette_cli(moulinette, mocker): import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument( "--debug", action="store_true", default=False, help="Log and print debug messages", ) mocker.patch("os.isatty", return_value=True) from moulinette.interfaces.cli import Interface as Cli cli = Cli(top_parser=parser, actionsmap=moulinette._actionsmap_path) mocker.stopall() return cli @pytest.fixture def test_file(tmp_path): test_text = "foo\nbar\n" test_file = tmp_path / "test.txt" test_file.write_bytes(test_text.encode()) return test_file @pytest.fixture def test_json(tmp_path): test_json = json.dumps({"foo": "bar"}) test_file = tmp_path / "test.json" test_file.write_bytes(test_json.encode()) return test_file @pytest.fixture def test_yaml(tmp_path): test_yaml = yaml.dump({"foo": "bar"}) test_file = tmp_path / "test.txt" test_file.write_bytes(test_yaml.encode()) return test_file @pytest.fixture def test_toml(tmp_path): test_toml = toml.dumps({"foo": "bar"}) test_file = tmp_path / "test.txt" test_file.write_bytes(test_toml.encode()) return test_file @pytest.fixture def user(): return os.getlogin() @pytest.fixture def test_url(): return "https://some.test.url/yolo.txt"