stages/invitation: add unittests

This commit is contained in:
Jens Langhammer 2020-05-13 23:20:27 +02:00
parent f289025d8e
commit 43a583e2d2
4 changed files with 134 additions and 44 deletions

View file

@ -0,0 +1,39 @@
"""dummy policy tests"""
from django.test import TestCase
from guardian.shortcuts import get_anonymous_user
from passbook.policies.dummy.forms import DummyPolicyForm
from passbook.policies.dummy.models import DummyPolicy
from passbook.policies.engine import PolicyRequest
class TestDummyPolicy(TestCase):
"""Test dummy policy"""
def setUp(self):
super().setUp()
self.request = PolicyRequest(user=get_anonymous_user())
def test_policy(self):
"""test policy .passes"""
policy: DummyPolicy = DummyPolicy.objects.create(
name="dummy", wait_min=1, wait_max=2
)
result = policy.passes(self.request)
self.assertFalse(result.passing)
self.assertEqual(result.messages, ("dummy",))
def test_form(self):
"""test form"""
form = DummyPolicyForm(
data={
"name": "dummy",
"negate": False,
"order": 0,
"timeout": 1,
"result": True,
"wait_min": 1,
"wait_max": 2,
}
)
self.assertTrue(form.is_valid())

View file

@ -45,20 +45,15 @@ ALLOWED_HOSTS = ["*"]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
LOGIN_URL = "passbook_flows:default-authentication"
# CSRF_FAILURE_VIEW = 'passbook.core.views.errors.CSRFErrorView.as_view'
# Custom user model
AUTH_USER_MODEL = "passbook_core.User"
if DEBUG:
CSRF_COOKIE_NAME = "passbook_csrf_debug"
LANGUAGE_COOKIE_NAME = "passbook_language_debug"
SESSION_COOKIE_NAME = "passbook_session_debug"
SESSION_COOKIE_SAMESITE = None
else:
CSRF_COOKIE_NAME = "passbook_csrf"
LANGUAGE_COOKIE_NAME = "passbook_language"
SESSION_COOKIE_NAME = "passbook_session"
_cookie_suffix = "_debug" if DEBUG else ""
CSRF_COOKIE_NAME = f"passbook_csrf{_cookie_suffix}"
LANGUAGE_COOKIE_NAME = f"passbook_language{_cookie_suffix}"
SESSION_COOKIE_NAME = f"passbook_session{_cookie_suffix}"
SESSION_COOKIE_DOMAIN = CONFIG.y("domain", None)
AUTHENTICATION_BACKENDS = [
@ -396,6 +391,7 @@ for _app in INSTALLED_APPS:
pass
if DEBUG:
SESSION_COOKIE_SAMESITE = None
INSTALLED_APPS.append("debug_toolbar")
MIDDLEWARE.append("debug_toolbar.middleware.DebugToolbarMiddleware")

28
passbook/root/tests.py Normal file
View file

@ -0,0 +1,28 @@
"""root tests"""
from base64 import b64encode
from django.conf import settings
from django.shortcuts import reverse
from django.test import Client, TestCase
class TestRoot(TestCase):
"""Test root application"""
def setUp(self):
super().setUp()
self.client = Client()
def test_monitoring_error(self):
"""Test monitoring without any credentials"""
response = self.client.get(reverse("metrics"))
self.assertEqual(response.status_code, 401)
def test_monitoring_ok(self):
"""Test monitoring with credentials"""
creds = "Basic " + b64encode(f"monitor:{settings.SECRET_KEY}".encode()).decode(
"utf-8"
)
auth_headers = {"HTTP_AUTHORIZATION": creds}
response = self.client.get(reverse("metrics"), **auth_headers)
self.assertEqual(response.status_code, 200)

View file

@ -1,14 +1,18 @@
"""login tests"""
"""invitation tests"""
from unittest.mock import MagicMock, patch
from django.shortcuts import reverse
from django.test import Client, TestCase
from guardian.shortcuts import get_anonymous_user
from passbook.core.models import User
from passbook.flows.models import Flow, FlowDesignation, FlowStageBinding
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from passbook.flows.views import SESSION_KEY_PLAN
from passbook.stages.invitation.forms import InvitationStageForm
from passbook.stages.invitation.models import Invitation, InvitationStage
from passbook.stages.invitation.stage import INVITATION_TOKEN_KEY, PLAN_CONTEXT_PROMPT
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from passbook.stages.user_login.forms import UserLoginStageForm
from passbook.stages.user_login.models import UserLoginStage
class TestUserLoginStage(TestCase):
@ -20,15 +24,41 @@ class TestUserLoginStage(TestCase):
self.client = Client()
self.flow = Flow.objects.create(
name="test-login",
slug="test-login",
name="test-invitation",
slug="test-invitation",
designation=FlowDesignation.AUTHENTICATION,
)
self.stage = UserLoginStage.objects.create(name="login")
self.stage = InvitationStage.objects.create(name="invitation")
FlowStageBinding.objects.create(flow=self.flow, stage=self.stage, order=2)
def test_valid_password(self):
"""Test with a valid pending user and backend"""
def test_form(self):
"""Test Form"""
data = {"name": "test"}
self.assertEqual(InvitationStageForm(data).is_valid(), True)
def test_without_invitation_fail(self):
"""Test without any invitation, continue_flow_without_invitation not set."""
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
PLAN_CONTEXT_AUTHENTICATION_BACKEND
] = "django.contrib.auth.backends.ModelBackend"
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse(
"passbook_flows:flow-executor", kwargs={"flow_slug": self.flow.slug}
)
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("passbook_flows:denied"))
def test_without_invitation_continue(self):
"""Test without any invitation, continue_flow_without_invitation is set."""
self.stage.continue_flow_without_invitation = True
self.stage.save()
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
@ -45,39 +75,36 @@ class TestUserLoginStage(TestCase):
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("passbook_core:overview"))
self.stage.continue_flow_without_invitation = False
self.stage.save()
def test_without_user(self):
"""Test a plan without any pending user, resulting in a denied"""
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse(
"passbook_flows:flow-executor", kwargs={"flow_slug": self.flow.slug}
)
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("passbook_flows:denied"))
def test_without_backend(self):
"""Test a plan with pending user, without backend, resulting in a denied"""
def test_with_invitation(self):
"""Test with invitation, check data in session"""
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
PLAN_CONTEXT_AUTHENTICATION_BACKEND
] = "django.contrib.auth.backends.ModelBackend"
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.get(
reverse(
data = {"foo": "bar"}
invite = Invitation.objects.create(
created_by=get_anonymous_user(), fixed_data=data
)
with patch("passbook.flows.views.FlowExecutorView.cancel", MagicMock()):
base_url = reverse(
"passbook_flows:flow-executor", kwargs={"flow_slug": self.flow.slug}
)
)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("passbook_flows:denied"))
response = self.client.get(
base_url + f"?{INVITATION_TOKEN_KEY}={invite.pk.hex}"
)
def test_form(self):
"""Test Form"""
data = {"name": "test"}
self.assertEqual(UserLoginStageForm(data).is_valid(), True)
session = self.client.session
plan: FlowPlan = session[SESSION_KEY_PLAN]
self.assertEqual(plan.context[PLAN_CONTEXT_PROMPT], data)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse("passbook_core:overview"))