stages/invitation: add unittests
This commit is contained in:
parent
f289025d8e
commit
43a583e2d2
39
passbook/policies/dummy/tests.py
Normal file
39
passbook/policies/dummy/tests.py
Normal 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())
|
|
@ -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
28
passbook/root/tests.py
Normal 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)
|
|
@ -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"))
|
||||
|
|
Reference in a new issue