Metadata-Version: 2.1
Name: django-capture-on-commit-callbacks
Version: 1.1.0
Summary: Capture and make assertions on transaction.on_commit() callbacks.
Home-page: https://github.com/adamchainz/django-capture-on-commit-callbacks
Author: Adam Johnson
Author-email: me@adamj.eu
License: MIT
Project-URL: Changelog, https://github.com/adamchainz/django-capture-on-commit-callbacks/blob/master/HISTORY.rst
Description: ==================================
        django-capture-on-commit-callbacks
        ==================================
        
        .. image:: https://github.com/adamchainz/django-capture-on-commit-callbacks/workflows/CI/badge.svg?branch=master
           :target: https://github.com/adamchainz/django-capture-on-commit-callbacks/actions?workflow=CI
        
        .. image:: https://img.shields.io/pypi/v/django-capture-on-commit-callbacks.svg
           :target: https://pypi.python.org/pypi/django-capture-on-commit-callbacks
        
        .. image:: https://img.shields.io/badge/code%20style-black-000000.svg
           :target: https://github.com/python/black
        
        Capture and make assertions on ``transaction.on_commit()`` `callbacks <https://docs.djangoproject.com/en/3.0/topics/db/transactions/#performing-actions-after-commit>`__.
        This allows you to write your tests with the ``TestCase``, rather than needing the slower ``TransactionTestCase`` to actually commit the transactions.
        
        This package was made as a first pass for `Django PR #12944 <https://github.com/django/django/pull/12944>`__, which is a solution for `Ticket #30457 “on_commit should be triggered in a TestCase” <https://code.djangoproject.com/ticket/30457>`__.
        
        Read more in my blog post `The Fast Way to Test Django transaction.on_commit() Callbacks <https://adamj.eu/tech/2020/05/20/the-fast-way-to-test-django-transaction-on-commit-callbacks/>`__.
        
        Installation
        ============
        
        Use **pip**:
        
        .. code-block:: bash
        
            python -m pip install django-capture-on-commit-callbacks
        
        Requirements
        ============
        
        Python 3.5 to 3.8 supported.
        
        Django 2.0 to 3.0 suppported.
        
        API
        ===
        
        ``capture_on_commit_callbacks(*, using="default", execute=False)``
        ------------------------------------------------------------------
        
        Acts as a context manager that captures ``on_commit`` callbacks for the given database connection.
        It returns a list that contains, on exit of the context, the captured callback functions.
        From this list you can make assertions on the callbacks or call them to invoke their side effects, emulating a commit.
        
        All arguments must be passed as keyword arguments.
        
        ``using`` is the alias of the database connection to capture callbacks for.
        
        ``execute`` specifies whether to call all the callbacks automatically as the context manager exits, if no exception has been raised.
        
        For example, you can test a commit hook that sends an email like so:
        
        .. code-block:: python
        
            from django.core import mail
            from django.test import TestCase
            from django_capture_on_commit_callbacks import capture_on_commit_callbacks
        
        
            class ContactTests(TestCase):
                def test_post(self):
                    with capture_on_commit_callbacks() as callbacks:
                        response = self.client.post(
                            "/contact/",
                            {"message": "I like your site"},
                        )
        
                    self.assertEqual(response.status_code, 200)
        
                    self.assertEqual(len(callbacks), 1)
                    # Execute the callback
                    callbacks[0]()
        
                    self.assertEqual(len(mail.outbox), 1)
                    self.assertEqual(mail.outbox[0].subject, "Contact Form")
                    self.assertEqual(mail.outbox[0].body, "I like your site")
        
        The same test can be written a bit more succinctly with ``execute=True``:
        
        .. code-block:: python
        
            from django.core import mail
            from django.test import TestCase
            from django_capture_on_commit_callbacks import capture_on_commit_callbacks
        
        
            class ContactTests(TestCase):
                def test_post(self):
                    with capture_on_commit_callbacks(execute=True) as callbacks:
                        response = self.client.post(
                            "/contact/",
                            {"message": "I like your site"},
                        )
        
                    self.assertEqual(response.status_code, 200)
        
                    self.assertEqual(len(callbacks), 1)
        
                    self.assertEqual(len(mail.outbox), 1)
                    self.assertEqual(mail.outbox[0].subject, "Contact Form")
                    self.assertEqual(mail.outbox[0].body, "I like your site")
        
        ``TestCaseMixin``
        -----------------
        
        A mixin class to be added to your custom ``TestCase`` subclass.
        It adds one method, ``captureOnCommitCallbacks()`` that aliases ``capture_on_commit_callbacks()``, to match the ``camelCase`` style of unittest assertions.
        
        You can add to your custom ``TestCase`` classes like so:
        
        .. code-block:: python
        
            from django import test
            from django_capture_on_commit_callbacks import TestCaseMixin
        
        
            class TestCase(TestCaseMixin, test.TestCase):
                pass
        
        You could then rewrite the above tests with your custom ``TestCase`` class like so:
        
        .. code-block:: python
        
            from django.core import mail
            from example.test import TestCase
        
        
            class ContactTests(TestCase):
                def test_post(self):
                    with self.captureOnCommitCallbacks(execute=True) as callbacks:
                        response = self.client.post(
                            "/contact/",
                            {"message": "I like your site"},
                        )
        
                    self.assertEqual(response.status_code, 200)
        
                    self.assertEqual(len(callbacks), 1)
        
                    self.assertEqual(len(mail.outbox), 1)
                    self.assertEqual(mail.outbox[0].subject, "Contact Form")
                    self.assertEqual(mail.outbox[0].body, "I like your site")
        
        History
        =======
        
        1.1.0 (2020-05-24)
        ------------------
        
        * Made ``captureOnCommitCallbacks()`` a ``classmethod`` so it can be used from within class methods such as ``setUpClass()``, ``setUpTestData()``.
        * Avoiding capturing callbacks enqueued within rolled back ``atomic()`` blocks.
          As a side effect of this change, the returned list of callbacks is only populated when the context manager exits.
        * Add Django 3.1 support.
        
        1.0.0 (2020-05-20)
        ------------------
        
        * Initial release.
        
Keywords: Django
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django :: 2.0
Classifier: Framework :: Django :: 2.1
Classifier: Framework :: Django :: 2.2
Classifier: Framework :: Django :: 3.0
Classifier: Framework :: Django :: 3.1
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Requires-Python: >=3.5
Description-Content-Type: text/x-rst
