-
Notifications
You must be signed in to change notification settings - Fork 538
/
conftest.py
236 lines (175 loc) Β· 6.96 KB
/
conftest.py
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
"""
pytest hooks and fixtures used for our unittests.
Please note that there should not be any Django/Olympia related imports
on module-level, they should instead be added to hooks or fixtures directly.
"""
import os
import uuid
import pytest
import responses
@pytest.fixture(autouse=True)
def unpin_db(request):
"""Unpin the database from master in the current DB.
The `multidb` middleware pins the current thread to master for 15 seconds
after any POST request, which can lead to unexpected results for tests
of DB slave functionality."""
from multidb import pinning
request.addfinalizer(pinning.unpin_this_thread)
@pytest.fixture(autouse=True, scope='class')
def mock_elasticsearch():
"""Mock ElasticSearch in tests by default.
Tests that do need ES should inherit from ESTestCase, which will stop the
mock at setup time."""
from olympia.amo.tests import start_es_mocks, stop_es_mocks
start_es_mocks()
yield
stop_es_mocks()
@pytest.fixture(autouse=True)
def start_responses_mocking(request):
"""Enable ``responses`` this enforcing us to explicitly mark tests
that require internet usage.
"""
marker = request.node.get_closest_marker('allow_external_http_requests')
if not marker:
responses.start()
yield
try:
if not marker:
responses.stop()
responses.reset()
except RuntimeError:
# responses patcher was already uninstalled
pass
@pytest.fixture(autouse=True)
def mock_basket(settings):
"""Mock Basket in tests by default.
Tests that do need basket to work should disable `responses`
and add a passthrough.
"""
USER_TOKEN = '13f64f64-1de7-42f6-8c7f-a19e2fae5021'
responses.add(
responses.GET,
settings.BASKET_URL + '/news/lookup-user/',
json={'status': 'ok', 'newsletters': [], 'token': USER_TOKEN},
)
responses.add(
responses.POST,
settings.BASKET_URL + '/news/subscribe/',
json={'status': 'ok', 'token': USER_TOKEN},
)
responses.add(
responses.POST,
settings.BASKET_URL + '/news/unsubscribe/{}/'.format(USER_TOKEN),
json={'status': 'ok', 'token': USER_TOKEN},
)
def pytest_configure(config):
import django
# Forcefully call `django.setup`, pytest-django tries to be very lazy
# and doesn't call it if it has already been setup.
# That is problematic for us since we overwrite our logging config
# in settings_test and it can happen that django get's initialized
# with the wrong configuration. So let's forcefully re-initialize
# to setup the correct logging config since at this point
# DJANGO_SETTINGS_MODULE should be `settings_test` every time.
django.setup()
from olympia.amo.tests import prefix_indexes
prefix_indexes(config)
@pytest.fixture(autouse=True, scope='session')
def instrument_jinja():
"""Make sure the "templates" list in a response is properly updated, even
though we're using Jinja2 and not the default django template engine."""
from django import test
import jinja2
old_render = jinja2.Template.render
def instrumented_render(self, *args, **kwargs):
context = dict(*args, **kwargs)
test.signals.template_rendered.send(sender=self, template=self, context=context)
return old_render(self, *args, **kwargs)
jinja2.Template.render = instrumented_render
def default_prefixer(settings):
"""Make sure each test starts with a default URL prefixer."""
from django import http
from olympia import amo
request = http.HttpRequest()
request.META['SCRIPT_NAME'] = ''
prefixer = amo.urlresolvers.Prefixer(request)
prefixer.app = settings.DEFAULT_APP
prefixer.locale = settings.LANGUAGE_CODE
amo.reverse.set_url_prefix(prefixer)
@pytest.fixture(autouse=True)
def test_pre_setup(request, tmpdir, settings):
from django.core.cache import caches
from django.utils import translation
from waffle import models as waffle_models
from waffle.utils import get_cache as waffle_get_cache
from olympia import amo, core
from olympia.translations.hold import clean_translations
# Clear all cache-instances. They'll be re-initialized by Django
# This will make sure that our random `KEY_PREFIX` is applied
# appropriately.
# This is done by Django too whenever `settings` is changed
# directly but because we're using the `settings` fixture
# here this is not detected correctly.
if hasattr(caches, '_caches'):
# django 2.2
caches._caches.caches = {}
else:
# django 3.2
for cache in caches:
try:
del caches[cache]
except AttributeError:
pass
# Randomize the cache key prefix to keep
# tests isolated from each other.
prefix = uuid.uuid4().hex
settings.CACHES['default']['KEY_PREFIX'] = 'amo:{0}:'.format(prefix)
# Reset global django-waffle cache instance to make sure it's properly
# using our new key prefix
waffle_models.cache = waffle_get_cache()
translation.trans_real.deactivate()
# Django fails to clear this cache.
translation.trans_real._translations = {}
translation.trans_real.activate(settings.LANGUAGE_CODE)
def _path(*args):
path = str(os.path.join(*args))
if not os.path.exists(path):
os.makedirs(path)
return path
settings.STORAGE_ROOT = storage_root = _path(str(tmpdir.mkdir('storage')))
settings.SHARED_STORAGE = shared_storage = _path(storage_root, 'shared_storage')
settings.ADDONS_PATH = _path(storage_root, 'files')
settings.GIT_FILE_STORAGE_PATH = _path(storage_root, 'git-storage')
settings.MLBF_STORAGE_PATH = _path(storage_root, 'mlbf')
settings.MEDIA_ROOT = _path(shared_storage, 'uploads')
settings.SITEMAP_STORAGE_PATH = _path(storage_root, 'sitemaps')
settings.TMP_PATH = _path(shared_storage, 'tmp')
# Reset the prefixer and urlconf after updating media root
default_prefixer(settings)
from django.urls import clear_url_caches, set_urlconf
def _clear_urlconf():
clear_url_caches()
set_urlconf(None)
_clear_urlconf()
request.addfinalizer(_clear_urlconf)
yield
core.set_user(None)
clean_translations(None) # Make sure queued translations are removed.
# Make sure we revert everything we might have changed to prefixers.
amo.reverse.clean_url_prefixes()
@pytest.fixture
def admin_group(db):
"""Create the Admins group."""
from olympia.access.models import Group
return Group.objects.create(name='Admins', rules='*:*')
@pytest.fixture
def mozilla_user(admin_group, settings):
"""Create a "Mozilla User"."""
from olympia.access.models import GroupUser
from olympia.users.models import UserProfile
user = UserProfile.objects.create(
pk=settings.TASK_USER_ID, email='[email protected]', username='admin'
)
user.save()
GroupUser.objects.create(user=user, group=admin_group)
return user