Files
VacatureRadar/tests/integration/test_auth_login.py
T
2026-07-26 05:03:53 +02:00

166 lines
5.9 KiB
Python

"""Tests voor het herwerkte loginscherm en de bijbehorende authenticatie-flows."""
from __future__ import annotations
import pytest
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core import mail
from django.test import override_settings
from django.urls import reverse
pytestmark = [pytest.mark.integration, pytest.mark.django_db]
def test_login_page_renders_stitch_design(client):
response = client.get(reverse("login"))
assert response.status_code == 200
body = response.content.decode("utf-8")
assert "<h1>Inloggen</h1>" in body
assert 'name="username"' in body and 'type="email"' in body
assert "Wachtwoord vergeten?" in body
# Local-first: geen externe CDN-assets op het loginscherm.
assert "cdn.tailwindcss.com" not in body
assert "https://fonts.googleapis.com" not in body
assert reverse("password_reset") in body
assert 'src="/static/js/login.js?' in body
assert "<script>" not in body
assert "Persoonlijke intelligence cockpit" in body
assert 'alt="VacatureRadar"' in body
assert "Ontwikkeld door" in body
assert 'aria-label="Ontwikkeld door ITWorx.tech"' in body
assert 'src="/static/img/itworx-wordmark.png" alt=""' in body
assert 'src="/static/img/itworx-wordmark.png"' in body
assert 'href="/static/favicon.svg?' in body
assert 'sizes="any"' in body
@override_settings(VACATURERADAR_OWNER_NAME="Eigen merk")
def test_login_page_keeps_official_brand_separate_from_owner_setting(client):
body = client.get(reverse("login")).content.decode("utf-8")
assert "Eigen merk" not in body
assert 'content="VacatureRadar"' in body
def test_login_with_email(client, user):
response = client.post(
reverse("login"),
{"username": user.email, "password": "correct-horse-battery-staple"},
)
assert response.status_code == 302
assert response.url == reverse("dashboard:today")
assert client.session.get("_auth_user_id") == str(user.pk)
def test_login_with_username_still_works(client, user):
response = client.post(
reverse("login"),
{"username": user.username, "password": "correct-horse-battery-staple"},
)
assert response.status_code == 302
assert client.session.get("_auth_user_id") == str(user.pk)
def test_login_email_case_insensitive(client, user):
response = client.post(
reverse("login"),
{"username": user.email.upper(), "password": "correct-horse-battery-staple"},
)
assert response.status_code == 302
assert client.session.get("_auth_user_id") == str(user.pk)
def test_login_wrong_password_shows_error(client, user):
response = client.post(
reverse("login"),
{"username": user.email, "password": "verkeerd-wachtwoord"},
)
assert response.status_code == 200
assert "klopt niet" in response.content.decode("utf-8")
def test_password_reset_sends_email(client, user):
response = client.post(reverse("password_reset"), {"email": user.email})
assert response.status_code == 302
assert response.url == reverse("password_reset_done")
assert len(mail.outbox) == 1
message = mail.outbox[0]
assert user.email in message.to
assert "wachtwoord" in message.subject.lower()
assert "/wachtwoord/herstellen/" in message.body
def test_password_reset_unknown_email_is_silent(client):
response = client.post(reverse("password_reset"), {"email": "onbekend@example.invalid"})
assert response.status_code == 302
assert len(mail.outbox) == 0
def test_demo_button_visible_by_default(client):
assert reverse("demo-login") in client.get(reverse("login")).content.decode("utf-8")
@override_settings(DEMO_MODE_ENABLED=False)
def test_demo_login_disabled_redirects(client):
response = client.post(reverse("demo-login"))
assert response.status_code == 302
assert response.url == reverse("login")
assert client.session.get("_auth_user_id") is None
@override_settings(DEMO_MODE_ENABLED=False)
def test_demo_button_hidden_when_disabled(client):
assert "demo-login" not in client.get(reverse("login")).content.decode("utf-8")
def test_demo_login_logs_in_and_seeds_environment(client):
from apps.jobs.models import Application, JobPosting, ScoreRun
from apps.profiles.models import SearchProfile
response = client.post(reverse("demo-login"))
assert response.status_code == 302
assert response.url == reverse("dashboard:today")
user = get_user_model().objects.get(username=settings.DEMO_USERNAME)
assert not user.has_usable_password()
assert client.session.get("_auth_user_id") == str(user.pk)
# Fictieve, gevulde demo-omgeving.
profile = SearchProfile.objects.get(user=user, is_active=True)
assert JobPosting.objects.count() >= 5
assert ScoreRun.objects.filter(profile=profile).count() >= 5
assert Application.objects.filter(user=user).exists()
# Het gevulde dashboard rendert zonder fouten.
dashboard = client.get(reverse("dashboard:today"))
assert dashboard.status_code == 200
def test_demo_login_is_idempotent(client):
from apps.jobs.models import JobPosting
client.post(reverse("demo-login"))
first = JobPosting.objects.count()
client.post(reverse("demo-login"))
assert JobPosting.objects.count() == first
def test_entra_login_disabled_redirects(client):
response = client.post(reverse("entra-login"))
assert response.status_code == 302
assert response.url == reverse("login")
@override_settings(ENTRA_ID_ENABLED=True, ENTRA_CLIENT_ID="", ENTRA_TENANT_ID="")
def test_entra_login_enabled_but_unconfigured_is_handled(client):
# Ingeschakeld maar zonder credentials: nette redirect, geen 500.
response = client.post(reverse("entra-login"), follow=False)
assert response.status_code == 302
assert response.url == reverse("login")
@override_settings(ENTRA_ID_ENABLED=True)
def test_entra_button_visible_when_enabled(client):
assert reverse("entra-login") in client.get(reverse("login")).content.decode("utf-8")