diff --git a/docs/changelog.rst b/docs/changelog.rst index 36eb5a75d..87290b66d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,17 @@ Changelog ========= +3.1.2 +----- + +Bug fixes +^^^^^^^^^ + +* Auto clearing of ``mail.outbox`` has been re-introduced to not break + functionality in 3.x.x release. This means that Compatibility issues + mentioned in the 3.1.0 release are no longer present. Related issue: + _`pytest-django issue ` + 3.1.1 ----- diff --git a/docs/helpers.rst b/docs/helpers.rst index 289ff3f06..5d7c2afeb 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -254,3 +254,11 @@ Clearing of site cache If ``django.contrib.sites`` is in your INSTALLED_APPS, Site cache will be cleared for each test to avoid hitting the cache and cause wrong Site object to be returned by ``Site.objects.get_current()``. + + +Clearing of mail.outbox +~~~~~~~~~~~~~~~~~~~~~~~ + +``mail.outbox`` will be cleared for each pytest, to give tests a empty +mailbox. It is however more pytestic to use the ``mailoutbox`` fixture +to access ``mail.outbox``. diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 1fb9120e5..067e33c52 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -415,44 +415,22 @@ def teardown(): request.addfinalizer(teardown) -class _DirectMailboxAccessProtector(list): - - def _raise_assertion(*args, **kwargs): - __tracebackhide__ = True - raise AssertionError('''To access mail.outbox, use the mailoutbox fixture. -See http://pytest-django.readthedocs.io/en/latest/helpers.html#mailoutbox for more information.''') - - __len__ = _raise_assertion - __getitem__ = _raise_assertion - __nonzero__ = _raise_assertion - __bool__ = _raise_assertion - __eq__ = _raise_assertion - __ne__ = _raise_assertion - __iter__ = _raise_assertion - - -@pytest.fixture(autouse=True) -def _error_on_direct_mail_outbox_access(monkeypatch): +@pytest.fixture(scope='function', autouse=True) +def _dj_autoclear_mailbox(): if not django_settings_is_configured(): return from django.core import mail - - outbox = _DirectMailboxAccessProtector() - monkeypatch.setattr(mail, 'outbox', outbox) - return outbox + del mail.outbox[:] @pytest.fixture(scope='function') -def mailoutbox(monkeypatch, _error_on_direct_mail_outbox_access): +def mailoutbox(monkeypatch, _dj_autoclear_mailbox): if not django_settings_is_configured(): return from django.core import mail - - outbox = list() - monkeypatch.setattr(mail, 'outbox', outbox) - return outbox + return mail.outbox @pytest.fixture(autouse=True, scope='function') diff --git a/tests/test_environment.py b/tests/test_environment.py index 6caa07d5e..fe56f669e 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -18,42 +18,17 @@ # This is possible with some of the testdir magic, but this is the lazy way # to do it. - -class Test_direct_mailbox_access_not_allowed(): - - def test_len(self): - with pytest.raises(AssertionError): - len(mail.outbox) - - def test_indexing(self): - with pytest.raises(AssertionError): - mail.outbox[0] - - def test_bool(self): - with pytest.raises(AssertionError): - if mail.outbox: - pass - - def test_equality(self): - with pytest.raises(AssertionError): - mail.outbox == 'whatever' - - def test_not_equality(self): - with pytest.raises(AssertionError): - mail.outbox != 'whatever' - - def test_unpacking(self): - with pytest.raises(AssertionError): - (foo,) = mail.outbox - - def test_iteration(self): - with pytest.raises(AssertionError): - for x in mail.outbox: - pass - - -def test_direct_mailbox_proection_should_not_break_sending_mail(): - mail.send_mail('subject', 'body', 'from@example.com', ['to@example.com']) +@pytest.mark.parametrize('subject', ['subject1', 'subject2']) +def test_autoclear_mailbox(subject): + assert len(mail.outbox) == 0 + mail.send_mail(subject, 'body', 'from@example.com', ['to@example.com']) + assert len(mail.outbox) == 1 + + m = mail.outbox[0] + assert m.subject == subject + assert m.body == 'body' + assert m.from_email == 'from@example.com' + assert m.to == ['to@example.com'] class TestDirectAccessWorksForDjangoTestCase(TestCase):