Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to test stripe webhook using pytest-django #1039

Open
BoPeng opened this issue Dec 15, 2022 · 1 comment
Open

How to test stripe webhook using pytest-django #1039

BoPeng opened this issue Dec 15, 2022 · 1 comment

Comments

@BoPeng
Copy link

BoPeng commented Dec 15, 2022

I have a docker-compose based development environment with

services:
    django:
    postgres:
    stripe:
        command: listen --forward-to http://django:8000/stripe/webhook

When the user uses stripe to make a payment, an event is forwarded by stripe to a webhook http://django:800/stripe/webhook, handled by the django instance.

When I use pytest to test the service, the following happens (as far as I understand):

  1. django is still running with access to the regular database
  2. A live_server with --ds=config.settings.test is created with access to the test database
  3. When a payment is made during testing, stripe still forwards the request to django, which accesses the regular database, NOT the test database that is hooked to live_server, and the test payment would fail.

To fix this problem, we may

  1. Fix stripe: Somehow configure stripe to --forward-to live_server.url/stripe/webhoo. This is what is supposed to happen but requires a different stripe cli instance to be created after live_server.url is determined.
  2. Keep --forward-to to the regular django instance, but django (NOT live_server) will access the test database to complete the test. This may be easier but I am not sure how to configure django to access the test database.

Does anyone have any suggestions on how to do this properly?

Edit: A third option maybe running the tests on django directly without firing up a live_server, and using the normal database. The trouble is then how to direct pytest-django to NOT use the test database.

@BoPeng
Copy link
Author

BoPeng commented Dec 16, 2022

It is quite a bit of exploratory work but here is how option two can be implemented:

  1. In settings.test, add non_test_db as a placeholder for the original "normal" database. This should probably be a separate setting file to avoid demanding other tests to list non_test_db in django_db.
DATABASES['non_test_db'] = copy.deepcopy(DATABASES['default'])
  1. Define a DATABASE_ROUTER to use non_test_db,
class NO_TEST_DB_ROUTER(object):

    def db_for_read(self, model, **hints):
        return 'non_test_db'

    def db_for_write(self, model, **hints):
        return 'non_test_db'

    def allow_relation(self, obj1, obj2, **hints):
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return True
  1. define a fixture to switch the database operation on the non-test-database
@pytest.fixture
def non_test_db(settings):
    oldname = settings.DATABASES['non_test_db']['NAME']
    settings.DATABASES['non_test_db']['NAME'] = oldname.split('_')[1]
    settings.DATABASE_ROUTERS = ['bioworkflows.tests.utils.NO_TEST_DB_ROUTER']
    yield
    settings.DATABASES['non_test_db']['NAME'] = oldname
    settings.DATABASE_ROUTERS = []
  1. Finally, for the test that need to access the non-test database,
@override_settings(ALLOWED_HOSTS=['*'])
@pytest.mark.django_db(databases=['default', 'non_test_db'])
def test_post_bounty(non_test_db):
    pass

What is happening here is that when the test is started, the non_test_db fixture will modify settings.DATABASES and point non_test_db to the original database, and add a DATABASE_ROUTERS to force all database options to happen on the non-test database. This fixture needs to be placed before any other database-operating fixtures.

This will allow the tests to operate on the non-test database with data accessible by the webhook

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant