(backend) correctly reload urls in tests

After removing most of the usage of S3 in the tests, these ones are
faster and make some flakyness more relevant. For example, in tests
related to the external api we have to reload the urls based on the
settings. We now have some race conditions where tests collapsed and
urls are not correctly reloaded.
This commit is contained in:
Manuel Raynaud
2026-08-13 14:32:12 +02:00
parent da22054507
commit a832ac2b82
3 changed files with 63 additions and 7 deletions
+20 -1
View File
@@ -10,7 +10,7 @@ import responses
from core import factories
from core.services.yhub_services import YHubService
from core.tests.utils.urls import reload_urls
from core.tests.utils.urls import reload_urls, restore_urls
USER = "user"
TEAM = "team"
@@ -23,6 +23,25 @@ def clear_cache():
cache.clear()
@pytest.fixture(autouse=True)
def restore_urlconf():
"""
Put the URLs back after a test that reloaded them.
Reloading is how a test makes the resource server routes appear or checks
that they are absent, but the URLconf belongs to the process: without this,
a test asserting a 404 on `/external_api/` and one asserting a 401 pass or
fail depending on which ran first in their worker.
Autouse and asking for nothing, so it is set up before the `settings`
fixture and torn down after it: the reload then sees the settings of the
project, not the ones of the test.
"""
yield
restore_urls()
@pytest.fixture
def mock_user_teams():
"""Mock for the "teams" property on the User model."""
@@ -581,11 +581,17 @@ def test_external_api_documents_trashbin_not_allowed(
assert response.status_code == 403
def test_external_api_documents_create_for_owner_not_allowed():
def test_external_api_documents_create_for_owner_not_allowed(
resource_server_backend_conf,
):
"""
Authenticated users SHOULD NOT be allowed to call create documents
on behalf of other users.
This API endpoint is reserved for server-to-server calls.
The route only exists when the resource server is enabled, hence the
fixture: the endpoint answering 401 is what this asserts, not the
`/external_api/` prefix being routed at all.
"""
user = factories.UserFactory()
+36 -5
View File
@@ -5,16 +5,47 @@ import importlib
from django.urls import clear_url_caches
class _URLConf:
"""
Whether a test reloaded the URLs of this process.
The URLconf is module-level state: a reload outlives the test that did it
and every test running after it in the same worker sees its routes — which
ones share a worker changes from one run to the next. `restore_urls` puts
the default back, and this flag keeps it to the tests that need it.
"""
reloaded = False
def _reload():
"""Reload the URL modules and drop the resolver caches."""
import core.urls # pylint:disable=import-outside-toplevel # noqa: PLC0415
import impress.urls # pylint:disable=import-outside-toplevel # noqa: PLC0415
importlib.reload(core.urls)
importlib.reload(impress.urls)
clear_url_caches()
def reload_urls():
"""
Reload the URLs. Since the URLs are loaded based on a
settings value, we need to reload them to make the
URL settings based condition effective.
"""
import core.urls # pylint:disable=import-outside-toplevel # noqa: PLC0415
_URLConf.reloaded = True
_reload()
import impress.urls # pylint:disable=import-outside-toplevel # noqa: PLC0415
importlib.reload(core.urls)
importlib.reload(impress.urls)
clear_url_caches()
def restore_urls():
"""
Reload the URLs of a test that changed them, so the next one starts clean.
Called once the settings of the test are restored, so the routes are the
ones the settings of the project declare.
"""
if _URLConf.reloaded:
_URLConf.reloaded = False
_reload()