120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
"""
|
|
Utilities for writing third_party_auth tests.
|
|
|
|
Used by Django and non-Django tests; must not have Django deps.
|
|
"""
|
|
|
|
from contextlib import contextmanager
|
|
import unittest
|
|
import mock
|
|
|
|
from third_party_auth import provider
|
|
|
|
|
|
AUTH_FEATURES_KEY = 'ENABLE_THIRD_PARTY_AUTH'
|
|
|
|
|
|
class FakeDjangoSettings(object):
|
|
"""A fake for Django settings."""
|
|
|
|
def __init__(self, mappings):
|
|
"""Initializes the fake from mappings dict."""
|
|
for key, value in mappings.iteritems():
|
|
setattr(self, key, value)
|
|
|
|
|
|
class TestCase(unittest.TestCase):
|
|
"""Base class for auth test cases."""
|
|
|
|
# Allow access to protected methods (or module-protected methods) under
|
|
# test.
|
|
# pylint: disable-msg=protected-access
|
|
|
|
def setUp(self):
|
|
super(TestCase, self).setUp()
|
|
self._original_providers = provider.Registry._get_all()
|
|
provider.Registry._reset()
|
|
|
|
def tearDown(self):
|
|
provider.Registry._reset()
|
|
provider.Registry.configure_once(self._original_providers)
|
|
super(TestCase, self).tearDown()
|
|
|
|
|
|
@contextmanager
|
|
def simulate_running_pipeline(pipeline_target, backend, email=None, fullname=None, username=None):
|
|
"""Simulate that a pipeline is currently running.
|
|
|
|
You can use this context manager to test packages that rely on third party auth.
|
|
|
|
This uses `mock.patch` to override some calls in `third_party_auth.pipeline`,
|
|
so you will need to provide the "target" module *as it is imported*
|
|
in the software under test. For example, if `foo/bar.py` does this:
|
|
|
|
>>> from third_party_auth import pipeline
|
|
|
|
then you will need to do something like this:
|
|
|
|
>>> with simulate_running_pipeline("foo.bar.pipeline", "google-oauth2"):
|
|
>>> bar.do_something_with_the_pipeline()
|
|
|
|
If, on the other hand, `foo/bar.py` had done this:
|
|
|
|
>>> import third_party_auth
|
|
|
|
then you would use the target "foo.bar.third_party_auth.pipeline" instead.
|
|
|
|
Arguments:
|
|
|
|
pipeline_target (string): The path to `third_party_auth.pipeline` as it is imported
|
|
in the software under test.
|
|
|
|
backend (string): The name of the backend currently running, for example "google-oauth2".
|
|
Note that this is NOT the same as the name of the *provider*. See the Python
|
|
social auth documentation for the names of the backends.
|
|
|
|
Keyword Arguments:
|
|
email (string): If provided, simulate that the current provider has
|
|
included the user's email address (useful for filling in the registration form).
|
|
|
|
fullname (string): If provided, simulate that the current provider has
|
|
included the user's full name (useful for filling in the registration form).
|
|
|
|
username (string): If provided, simulate that the pipeline has provided
|
|
this suggested username. This is something that the `third_party_auth`
|
|
app generates itself and should be available by the time the user
|
|
is authenticating with a third-party provider.
|
|
|
|
Returns:
|
|
None
|
|
|
|
"""
|
|
pipeline_data = {
|
|
"backend": backend,
|
|
"kwargs": {
|
|
"details": {}
|
|
}
|
|
}
|
|
if email is not None:
|
|
pipeline_data["kwargs"]["details"]["email"] = email
|
|
if fullname is not None:
|
|
pipeline_data["kwargs"]["details"]["fullname"] = fullname
|
|
if username is not None:
|
|
pipeline_data["kwargs"]["username"] = username
|
|
|
|
pipeline_get = mock.patch("{pipeline}.get".format(pipeline=pipeline_target), spec=True)
|
|
pipeline_running = mock.patch("{pipeline}.running".format(pipeline=pipeline_target), spec=True)
|
|
|
|
mock_get = pipeline_get.start()
|
|
mock_running = pipeline_running.start()
|
|
|
|
mock_get.return_value = pipeline_data
|
|
mock_running.return_value = True
|
|
|
|
try:
|
|
yield
|
|
|
|
finally:
|
|
pipeline_get.stop()
|
|
pipeline_running.stop()
|