old_console/console/tests/test_utils.py
2024-11-02 14:12:45 +03:00

181 lines
6.5 KiB
Python

import http
import os
import socket
import time
import pytest
from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse
from pytest_django.live_server_helper import LiveServer
from perms.models import Perm
from users.models import UserInfo
DEFAULT_USER = 'admin'
DEFAULT_PASSWORD = 'nimda'
TEST_LANGS = sorted(('ru', 'en'))
TEST_TIMEZONES = sorted(('UTC', 'Europe/Moscow', 'Europe/Paris', 'America/New_York'))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CUR_DIR = os.path.abspath(os.getcwd())
TIMEOUT = 10 # time before timeout exception appears
POLL_TIMEOUT = 0.3 # time execute next poll cycle, for example when waiting element
from django.conf import settings
LOGS_F = os.path.join(getattr(settings, 'LOG_PATH', ''), getattr(settings, 'USER_LOG_FILENAME', ''))
@pytest.fixture(scope='session')
def test_server() -> LiveServer:
""" Custom fixture for creating live test server """
addr = socket.gethostbyname(socket.gethostname())
server = LiveServer(addr)
try:
yield server
finally:
server.stop()
def find_message_in_log_file(file, message):
""" Function for finding certain string in log file
:param file: Log file descriptor
:param message: message, that needs to be found
:return:
Assert True if message is found
Assert False if message not found
"""
with open(file, encoding='utf-8') as f:
if message in f.read():
return True, message
else:
return False, message
@pytest.fixture
def get_url(test_server):
""" Get url from liveserver
:param url: Url's name
:param kwargs: Dictionary with arguments for reverse function
:return: string with url
"""
def _get_url(url, kwargs=None):
return test_server.url + reverse(url, kwargs=kwargs)
return _get_url
@pytest.fixture
def add_user_with_permissions(django_user_model):
""" Add user with selected permissions
:param username: User name
:param password: User password
:param permissions: List with Perm's permissions, that will be add to created user
:param is_superuser: If True - user will be superuser
:return: created user with updated permissions cache
"""
def _login_user(username, password, permissions=[], is_superuser=False):
user = django_user_model.objects.create_user(username=username, password=password)
if is_superuser:
user.is_superuser = True
user.save()
UserInfo(user=user).save()
for cur in permissions:
user.user_permissions.add(Perm.get_rights(cur))
return django_user_model.objects.get(pk=user.pk)
return _login_user
def wait_db_element(query_method, message='', timeout=TIMEOUT, poll=POLL_TIMEOUT):
end_time = time.time() + timeout
screen, stacktrace = None, None
while True:
try:
e = query_method()
if e:
return e
except ObjectDoesNotExist as exc:
message = message or str(exc)
screen = getattr(exc, 'screen', None)
stacktrace = getattr(exc, 'stacktrace', None)
time.sleep(poll)
if time.time() > end_time:
break
# TODO: Maybe add here screen and stacktrace from above
raise RuntimeError(message)
class PermApiBaseTest:
""" Test class for checking API permissions
@param get_url: URL to check
@param test_server: testing server instance
@param api_list: Fixture with API for testing in following format:
[Permission_to_check, URL of api, arguments for API (optional)]
e.x. with arguments
[[Perm.can_export_events], 'api_change_event_export', dict(state='disable')]
e.x. without arguments
[[Perm.can_export_events], 'api_change_event_export']
"""
def test_api_without_perms(self, get_url, test_server, api_list, add_user_with_permissions, client):
username = 'user_with_no_perms'
password = 'nimda'
user = add_user_with_permissions(username=username, password=password)
client.force_login(user)
if len(api_list) == 2:
response = client.get(get_url(api_list[1]))
elif len(api_list) == 3:
response = client.get(get_url(api_list[1], api_list[2]))
else:
assert False, f'Incorrect format of api_list instance: {api_list}'
assert response.status_code == http.HTTPStatus.FORBIDDEN
def test_api_with_perms(self, get_url, test_server, add_user_with_permissions, api_list, client):
# username 'admin_1' used instead of DEFAULT_USER because in some cases login_user failing due to the
# existence of user with that username
# Fixed by @lvlukianenko in recent commits
username = 'user_with_perms'
password = 'nimda'
user = add_user_with_permissions(username=username, password=password, permissions=api_list[0])
client.force_login(user)
if len(api_list) == 2:
response = client.get(get_url(api_list[1]))
elif len(api_list) == 3:
response = client.get(get_url(api_list[1], api_list[2]))
else:
assert False, f'Incorrect format of api_list instance: {api_list}'
assert response.status_code == http.HTTPStatus.OK
# TODO: Move to integration tests
# class TestDeleteElasticsearchIndexes:
# index_name = 'test-index'
#
# @pytest.fixture(autouse=True)
# def setup_tests(self):
# self.es = Elasticsearch([{'host': ELK_HOST, 'port': ELK_PORT}], http_auth=(ELK_LOGIN, ELK_PASS))
# for i in range(3):
# self.es.indices.create(index=f'{self.index_name}-{i}', ignore=400)
# yield
# self.es.indices.delete(index=f'{self.index_name}-*', ignore=[400, 404])
#
# def test_delete_all_index_by_template(self):
# index_template = f'{self.index_name}-*'
# index_count = len(self.es.indices.get_alias(index=index_template).keys())
# assert index_count == 3
# delete_elasticsearch_indexes_by_template(index_template)
# assert len(self.es.indices.get_alias(index=index_template)) == 0
#
# @pytest.mark.parametrize('exclude_indexes,expected', TEST_EXCLUDE_INDEXES)
# def test_delete_index_by_template_witch_exclude_index(self, exclude_indexes: set, expected: int):
# index_template = f'{self.index_name}-*'
# delete_elasticsearch_indexes_by_template(index_template, es=self.es, exclude_indexes=exclude_indexes)
# assert len(self.es.indices.get_alias(index=index_template, ignore=[400, 404])) == expected