-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathconftest.py
More file actions
188 lines (152 loc) · 6.33 KB
/
conftest.py
File metadata and controls
188 lines (152 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""
This module contains shared fixtures for pytest
"""
from __future__ import annotations
from typing import Any, TYPE_CHECKING
from unittest.mock import patch
import pytest
from django.contrib.auth import get_user_model
from django.core.management import call_command
from django.test.client import AsyncClient, Client
from integreat_cms.cms.constants.roles import (
APP_TEAM,
AUTHOR,
CMS_TEAM,
EDITOR,
EVENT_MANAGER,
MANAGEMENT,
MARKETING_TEAM,
OBSERVER,
SERVICE_TEAM,
)
from integreat_cms.cms.models import Language, Page, Region
from integreat_cms.firebase_api.firebase_security_service import FirebaseSecurityService
from tests.mock import MockServer
if TYPE_CHECKING:
from collections.abc import Callable, Generator
from typing import Final
from _pytest.fixtures import SubRequest
from pytest_django.fixtures import SettingsWrapper
from pytest_django.plugin import _DatabaseBlocker # type: ignore[attr-defined]
from pytest_httpserver.httpserver import HTTPServer
#: A role identifier for superusers
ROOT: Final = "ROOT"
#: A role identifier for anonymous users
ANONYMOUS: Final = "ANONYMOUS"
#: All roles with editing permissions
WRITE_ROLES: Final = [MANAGEMENT, EDITOR, AUTHOR, EVENT_MANAGER]
#: All roles of region users
REGION_ROLES: Final = [*WRITE_ROLES, OBSERVER]
#: All roles of staff users
STAFF_ROLES: Final = [ROOT, SERVICE_TEAM, CMS_TEAM, APP_TEAM, MARKETING_TEAM]
#: All roles of staff users that don't just have read-only permissions
PRIV_STAFF_ROLES: Final = [ROOT, APP_TEAM, SERVICE_TEAM, CMS_TEAM]
#: All roles of staff users that don't just have read-only permissions
HIGH_PRIV_STAFF_ROLES: Final = [ROOT, SERVICE_TEAM, CMS_TEAM]
#: All region and staff roles
ROLES: Final = REGION_ROLES + STAFF_ROLES
#: All region and staff roles and anonymous users
ALL_ROLES: Final = [*ROLES, ANONYMOUS]
#: Enable the aiohttp pytest plugin to make use of the test server
pytest_plugins: Final = "aiohttp.pytest_plugin"
@pytest.fixture(scope="session")
def load_test_data(django_db_setup: None, django_db_blocker: _DatabaseBlocker) -> None:
"""
Load the test data initially for all test cases
:param django_db_setup: The fixture providing the database availability
:param django_db_blocker: The fixture providing the database blocker
"""
with django_db_blocker.unblock():
call_command("loaddata", "integreat_cms/cms/fixtures/test_data.json")
@pytest.fixture(scope="function")
def load_test_data_transactional(
transactional_db: None,
django_db_blocker: _DatabaseBlocker,
) -> None:
"""
Load the test data initially for all transactional test cases
:param transactional_db: The fixture providing transaction support for the database
:param django_db_blocker: The fixture providing the database blocker
"""
with django_db_blocker.unblock():
call_command("loaddata", "integreat_cms/cms/fixtures/test_roles.json")
call_command("loaddata", "integreat_cms/cms/fixtures/test_data.json")
@pytest.fixture(scope="session", params=ALL_ROLES)
def login_role_user(
request: SubRequest,
load_test_data: None,
django_db_blocker: _DatabaseBlocker,
) -> tuple[Client, str]:
"""
Get the test user of the current role and force a login. Gets executed only once per user.
:param request: The request object providing the parametrized role variable through ``request.param``
:param load_test_data: The fixture providing the test data (see :meth:`~tests.conftest.load_test_data`)
:param django_db_blocker: The fixture providing the database blocker
:return: The http client and the current role
"""
client = Client()
# Only log in user if the role is not anonymous
if request.param != ANONYMOUS:
with django_db_blocker.unblock():
user = get_user_model().objects.get(username=request.param.lower())
client.force_login(user)
return client, request.param
@pytest.fixture(scope="session", params=ALL_ROLES)
def login_role_user_async(
request: SubRequest,
load_test_data: None,
django_db_blocker: _DatabaseBlocker,
) -> tuple[AsyncClient, str]:
"""
Get the test user of the current role and force a login. Gets executed only once per user.
Identical to :meth:`~tests.conftest.login_role_user` with the difference that it returns
an :class:`django.test.client.AsyncClient` instead of :class:`django.test.client.Client`.
:param request: The request object providing the parametrized role variable through ``request.param``
:param load_test_data: The fixture providing the test data (see :meth:`~tests.conftest.load_test_data`)
:param django_db_blocker: The fixture providing the database blocker
:return: The http client and the current role
"""
async_client = AsyncClient()
# Only log in user if the role is not anonymous
if request.param != ANONYMOUS:
with django_db_blocker.unblock():
user = get_user_model().objects.get(username=request.param.lower())
async_client.force_login(user)
return async_client, request.param
@pytest.fixture(scope="function")
def mock_server(httpserver: HTTPServer) -> MockServer:
return MockServer(httpserver)
@pytest.fixture(scope="function")
def mock_firebase_credentials() -> Generator[None, None, None]:
patch_obj = patch.object(
FirebaseSecurityService,
"_get_access_token",
return_value="secret access token",
)
patch_obj.start()
yield
patch_obj.stop()
@pytest.fixture(autouse=True)
def configure_celery_for_tests(settings: SettingsWrapper) -> None:
# by default, no worker is running to consume tasks during tests,
# so we set celery to run synchronously and propagate errors to the test runner
settings.CELERY_TASK_ALWAYS_EAGER = True
settings.CELERY_TASK_EAGER_PROPAGATES = True
@pytest.fixture()
def create_page() -> Callable[..., Page]:
def _create_page(
region: Region | None,
name_add: str = "",
parent: Page | None = None,
) -> Page:
return (
parent.add_child(region=parent.region)
if parent
else Page.add_root(region=region)
)
return _create_page
@pytest.fixture()
def create_language() -> Callable[..., Language]:
def _create_language(**kwargs: Any) -> Language:
return Language.objects.create(**kwargs)
return _create_language