Mercurial > kallithea
view kallithea/tests/conftest.py @ 8966:59185ce619c3 i18n
i18n: pl: reintroduce malformed translation removed by 19506ee31c1c
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Mon, 12 Dec 2022 18:28:10 +0100 |
parents | f3fab7b124f2 |
children |
line wrap: on
line source
import logging import os import sys import time import formencode import pkg_resources import pytest from paste.deploy import loadwsgi from pytest_localserver.http import WSGIServer from routes.util import URLGenerator from tg.util.webtest import test_context import kallithea.tests.base # FIXME: needed for setting testapp instance!!! from kallithea.controllers.root import RootController from kallithea.lib import inifile from kallithea.lib.utils import repo2db_mapper from kallithea.model import db, meta from kallithea.model.scm import ScmModel from kallithea.model.user import UserModel from kallithea.tests.base import TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH, invalidate_all_caches from kallithea.tests.fixture import create_test_env, create_test_index def pytest_configure(): os.environ['TZ'] = 'UTC' if not kallithea.is_windows: time.tzset() # only available on Unix path = os.getcwd() sys.path.insert(0, path) pkg_resources.working_set.add_entry(path) # Disable INFO logging of test database creation, restore with NOTSET logging.disable(logging.INFO) ini_settings = { '[server:main]': { 'port': '4999', }, '[app:main]': { 'ssh_enabled': 'true', # Mainly to safeguard against accidentally overwriting the real one: 'ssh_authorized_keys': os.path.join(TESTS_TMP_PATH, 'authorized_keys'), #'ssh_locale': 'C', 'app_instance_uuid': 'test', 'show_revision_number': 'true', 'session.secret': '{74e0cd75-b339-478b-b129-07dd221def1f}', #'i18n.lang': '', }, '[handler_console]': { 'formatter': 'color_formatter', }, # The 'handler_console_sql' block is very similar to the one in # development.ini, but without the explicit 'level=DEBUG' setting: # it causes duplicate sqlalchemy debug logs, one through # handler_console_sql and another through another path. '[handler_console_sql]': { 'formatter': 'color_formatter_sql', }, } create_database = os.environ.get('TEST_DB') # TODO: rename to 'CREATE_TEST_DB' if create_database: ini_settings['[app:main]']['sqlalchemy.url'] = create_database reuse_database = os.environ.get('REUSE_TEST_DB') if reuse_database: ini_settings['[app:main]']['sqlalchemy.url'] = reuse_database test_ini_file = os.path.join(TESTS_TMP_PATH, 'test.ini') inifile.create(test_ini_file, None, ini_settings) context = loadwsgi.loadcontext(loadwsgi.APP, 'config:%s' % test_ini_file) # set KALLITHEA_NO_TMP_PATH=1 to disable re-creating the database and test repos if not int(os.environ.get('KALLITHEA_NO_TMP_PATH', 0)): create_test_env(TESTS_TMP_PATH, context.config(), reuse_database=bool(reuse_database)) # set KALLITHEA_WHOOSH_TEST_DISABLE=1 to disable whoosh index during tests if not int(os.environ.get('KALLITHEA_WHOOSH_TEST_DISABLE', 0)): create_test_index(TESTS_TMP_PATH, context.config(), True) kallithea.tests.base.testapp = context.create() # do initial repo scan repo2db_mapper(ScmModel().repo_scan(TESTS_TMP_PATH)) logging.disable(logging.NOTSET) kallithea.tests.base.url = URLGenerator(RootController().mapper, {'HTTP_HOST': 'example.com'}) # set fixed language for form messages, regardless of environment settings formencode.api.set_stdtranslation(languages=[]) @pytest.fixture def create_test_user(): """Provide users that automatically disappear after test is over.""" test_user_ids = [] def _create_test_user(user_form): user = UserModel().create(user_form) test_user_ids.append(user.user_id) return user yield _create_test_user for user_id in test_user_ids: UserModel().delete(user_id) meta.Session().commit() def _set_settings(*kvtseq): session = meta.Session() for kvt in kvtseq: assert len(kvt) in (2, 3) k = kvt[0] v = kvt[1] t = kvt[2] if len(kvt) == 3 else 'unicode' db.Setting.create_or_update(k, v, t) session.commit() @pytest.fixture def set_test_settings(): """Restore settings after test is over.""" # Save settings. settings_snapshot = [ (s.app_settings_name, s.app_settings_value, s.app_settings_type) for s in db.Setting.query().all()] yield _set_settings # Restore settings. session = meta.Session() keys = frozenset(k for (k, v, t) in settings_snapshot) for s in db.Setting.query().all(): if s.app_settings_name not in keys: session.delete(s) for k, v, t in settings_snapshot: if t == 'list' and hasattr(v, '__iter__'): v = ','.join(v) # Quirk: must format list value manually. db.Setting.create_or_update(k, v, t) session.commit() @pytest.fixture def auto_clear_ip_permissions(): """Fixture that provides nothing but clearing IP permissions upon test exit. This clearing is needed to avoid other test failing to make fake http accesses.""" yield # cleanup user_model = UserModel() user_ids = [] user_ids.append(kallithea.DEFAULT_USER_ID) user_ids.append(db.User.get_by_username(TEST_USER_REGULAR_LOGIN).user_id) for user_id in user_ids: for ip in db.UserIpMap.query().filter(db.UserIpMap.user_id == user_id): user_model.delete_extra_ip(user_id, ip.ip_id) # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches() session = meta.Session() session.commit() @pytest.fixture def test_context_fixture(app_fixture): """ Encompass the entire test using this fixture in a test_context, making sure that certain functionality still works even if no call to self.app.get/post has been made. The typical error message indicating you need a test_context is: TypeError: No object (name: context) has been registered for this thread The standard way to fix this is simply using the test_context context manager directly inside your test: with test_context(self.app): <actions> but if test setup code (xUnit-style or pytest fixtures) also needs to be executed inside the test context, that method is not possible. Even if there is no such setup code, the fixture may reduce code complexity if the entire test needs to run inside a test context. To apply this fixture (like any other fixture) to all test methods of a class, use the following class decorator: @pytest.mark.usefixtures("test_context_fixture") class TestFoo(TestController): ... """ with test_context(app_fixture): yield class MyWSGIServer(WSGIServer): def repo_url(self, repo_name, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): """Return URL to repo on this web server.""" host, port = self.server_address proto = 'http' if self._server.ssl_context is None else 'https' auth = '' if username is not None: auth = username if password is not None: auth += ':' + password if auth: auth += '@' return '%s://%s%s:%s/%s' % (proto, auth, host, port, repo_name) @pytest.yield_fixture(scope="session") def webserver(): """Start web server while tests are running. Useful for debugging and necessary for vcs operation tests.""" server = MyWSGIServer(application=kallithea.tests.base.testapp) server.start() yield server server.stop()