moulinette/test/conftest.py

182 lines
4.9 KiB
Python

"""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 = set(["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"