Skip to content

Commit bc23f20

Browse files
peterlauripelme
authored andcommitted
autouse function scoped fixture that cleares django.contrib.sites.models.SITE_CACHE #323 (#323)
1 parent 274efdf commit bc23f20

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Features
99
* Added new function scoped fixture ``mailoutbox`` that gives access to
1010
djangos ``mail.outbox``. The will clean/empty the ``mail.outbox`` to
1111
assure that no old mails are still in the outbox.
12+
* If ``django.contrib.sites`` is in your INSTALLED_APPS, Site cache will
13+
be cleared for each test to avoid hitting the cache and cause wrong Site
14+
object to be returned by ``Site.objects.get_current()``.
1215

1316
Compatibility
1417
^^^^^^^^^^^^^

docs/helpers.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,18 @@ Example
239239
assert m.from_email == '[email protected]'
240240
assert list(m.to) == ['[email protected]']
241241

242+
243+
Environment autouse fixtures
244+
----------------------------
245+
246+
pytest-django provides some pytest fixtures that are of autouse
247+
nature. They provide functionality to assure a clean environment
248+
during tests.
249+
250+
251+
Clearing of site cache
252+
~~~~~~~~~~~~~~~~~~~~~~
253+
254+
If ``django.contrib.sites`` is in your INSTALLED_APPS, Site cache will
255+
be cleared for each test to avoid hitting the cache and cause wrong Site
256+
object to be returned by ``Site.objects.get_current()``.

pytest_django/plugin.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,20 @@ def _template_string_if_invalid_marker(request):
539539
else:
540540
dj_settings.TEMPLATE_STRING_IF_INVALID.fail = False
541541

542+
543+
@pytest.fixture(autouse=True, scope='function')
544+
def _django_clear_site_cache():
545+
"""Clears ``django.contrib.sites.models.SITE_CACHE`` to avoid
546+
unexpected behavior with cached site objects.
547+
"""
548+
549+
if django_settings_is_configured():
550+
from django.conf import settings as dj_settings
551+
552+
if 'django.contrib.sites' in dj_settings.INSTALLED_APPS:
553+
from django.contrib.sites.models import Site
554+
Site.objects.clear_cache()
555+
542556
# ############### Helper Functions ################
543557

544558

tests/test_environment.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import os
44

55
import pytest
6+
from django.contrib.sites.models import Site
7+
from django.contrib.sites import models as site_models
68
from django.core import mail
79
from django.db import connection
810
from django.test import TestCase
11+
from pytest_django.lazy_django import get_django_version
912

1013
from pytest_django_test.app.models import Item
1114

@@ -215,3 +218,26 @@ def test_more_verbose_with_vv_and_reusedb(self, testdir):
215218
"*PASSED*"])
216219
assert ("*Destroying test database for alias 'default' ('*')...*"
217220
not in result.stdout.str())
221+
222+
223+
@pytest.mark.skipif(
224+
get_django_version() < (1, 8),
225+
reason='Django 1.7 requires settings.SITE_ID to be set, so this test is invalid'
226+
)
227+
@pytest.mark.django_db
228+
@pytest.mark.parametrize('site_name', ['site1', 'site2'])
229+
def test_clear_site_cache(site_name, rf, monkeypatch):
230+
request = rf.get('/')
231+
monkeypatch.setattr(request, 'get_host', lambda: 'foo.com')
232+
Site.objects.create(domain='foo.com', name=site_name)
233+
assert Site.objects.get_current(request=request).name == site_name
234+
235+
236+
@pytest.mark.django_db
237+
@pytest.mark.parametrize('site_name', ['site1', 'site2'])
238+
def test_clear_site_cache_check_site_cache_size(site_name, settings):
239+
assert len(site_models.SITE_CACHE) == 0
240+
site = Site.objects.create(domain='foo.com', name=site_name)
241+
settings.SITE_ID = site.id
242+
assert Site.objects.get_current() == site
243+
assert len(site_models.SITE_CACHE) == 1

0 commit comments

Comments
 (0)