Source code for django_functest.utils

import warnings
from importlib import import_module

from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY as AUTH_BACKEND_SESSION_KEY
from django.contrib.auth import HASH_SESSION_KEY as AUTH_HASH_SESSION_KEY
from django.contrib.auth import SESSION_KEY as AUTH_ID_SESSION_KEY
from django.contrib.auth import authenticate
from furl import furl


[docs]class ShortcutLoginMixin: """ A mixin that provides a fast way of logging in and out. """
[docs] def shortcut_login(self, **credentials): user = authenticate(**credentials) if not user: raise ValueError(f"User {user} was not authenticated") session_auth_hash = "" if hasattr(user, "get_session_auth_hash"): session_auth_hash = user.get_session_auth_hash() # Mimicking django.contrib.auth functionality self.set_session_data( { AUTH_ID_SESSION_KEY: user.pk, AUTH_HASH_SESSION_KEY: session_auth_hash, AUTH_BACKEND_SESSION_KEY: user.backend, } )
[docs] def shortcut_logout(self): self.flush_session()
def get_session_store(session_key=None): engine = import_module(settings.SESSION_ENGINE) # Implement a database session store object that will contain the session key. store = engine.SessionStore(session_key=session_key) if session_key is None: store.save() else: store.load() return store class CommonMixin: def assertUrlsEqual(self, url, other_url=None): """ Asserts that the URLs match. Empty protocol or domain are ignored. """ if other_url is None: other_url = self.current_url url1 = furl(url) url2 = furl(other_url) self.assertEqual(url1.path, url2.path) self.assertEqual(url1.query, url2.query) if url1.netloc and url2.netloc: self.assertEqual(url1.netloc, url2.netloc) if url1.scheme and url2.scheme: self.assertEqual(url1.scheme, url2.scheme) def fill_by_id(self, data): """ Same as ``fill`` except the keys are input IDs """ warnings.warn( "instead of `fill_by_id({'foo': 'bar'})` do `fill({'#foo': 'bar'})`", DeprecationWarning, ) self.fill({"#" + k: v for k, v in data.items()}) def fill_by_name(self, fields, prefix=""): """ Same as ``fill`` except the keys are input names """ self.fill({f'[name="{prefix}{k}"]': v for k, v in fields.items()})
[docs]class AdminLoginMixin(ShortcutLoginMixin): """ A mixin that logs in via the normal admin login page """
[docs] def do_login(self, username=None, password=None, shortcut=True): if shortcut: self.shortcut_login(username=username, password=password) return self.get_url("admin:index") self.fill( { "#id_username": username, "#id_password": password, } ) self.submit("input[type=submit]")
[docs] def do_logout(self, shortcut=True): if shortcut: self.shortcut_logout() return self.get_url("admin:logout")
class BrowserSessionToken: # Simple container class to hide the fact that the value is really a # webdriver instance or webtest instance (but that may change in future) def __init__(self, value): self.value = value def __eq__(self, other): return self.value == other.value def __repr__(self): return f"<BrowserSessionToken {id(self.value)}>"