简体   繁体   中英

Extend social pipeline and prevent a specific function to run during tests

I'm using Python Django Social Auth and extended the pipeline with the following three steps

  1. One before the user is created ( partial pipeline ) requesting some data.
  2. One for the user creation (overrides the social.pipeline.user.create_user method).
  3. One after the user is created.

Here's how the pipeline currently looks like

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'myapp.file.before_user_is_created',
    'myapp.file.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'myapp.file.after_user_creation',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
)

In order to test it, I'm following similar logic to the one used here . This is what I have

@mock.patch("social_core.backends.base.BaseAuth.request")
def test_complete(self, mock_request):
        url = reverse("social:complete", kwargs={"backend": "facebook"})
        url += "?code=2&state=1"
        mock_request.return_value.json.return_value = {"access_token": "123"}
        with mock.patch(
            "django.contrib.sessions.backends.base.SessionBase" ".set_expiry",
            side_effect=[OverflowError, None],
        ):
            response_1 = self.client.get(url)
            self.assertEqual(response_1.status_code, 302)
            self.assertEqual(response_1.url, "/before-user-is-created/")

            response_2 = self.client.post("/before-user-is-created/", {"some_keys": "some_values"})
            self.assertEqual(response_2.status_code, 302)
            self.assertEqual(response_2.url, "/social-auth/complete/facebook/")

            response_3 = self.client.post("/social-auth/complete/facebook/")
            return response_3

For step 1, I have a url ( /before-user-is-created/ ) and a specific view. So, I get that view and I'm able to act on it when running

response_1 = self.client.get(url)

as you can see from the self.assertEqual(response_1.url, "/before-user-is-created/") and from response_2 = self.client.post("/before-user-is-created/", {"some_keys": "some_values"}) .

The problem is with step 3. That is essentially a function ( after_user_creation() ) that calls another one ( function_called() )

def after_user_creation(user, *args, **kwargs):
    ...
    function_called(something_from_user)

That function is called in this part during the test (together with load_extra_data and user_details (the ones coming after it in the pipeline))

response_2 = self.client.post("/before-user-is-created/", {"some_keys": "some_values"})
...
response_3 = self.client.post("/social-auth/complete/facebook/")
...

How to prevent function_called(something_from_user) to run during tests?

You can patch myapp.file.function_called as usual:

with mock.patch(
    "django.contrib.sessions.backends.base.SessionBase" ".set_expiry",
    side_effect=[OverflowError, None],
), mock.patch("myapp.file.function_called"):

Alternatively:

@mock.patch("myapp.file.function_called")
@mock.patch("social_core.backends.base.BaseAuth.request")
def test_complete(self, mock_request, mock_function_called):

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM