coulomb-social/tests/test_shell.py
tegwick 29a9ff735e Complete identity smoke path: id_token claims, registration entry, cutover docs
Prefer verified KeyCape id_token claims when /userinfo returns 401; soft-fail
userinfo. Add CSOC-WP-0003 registration entry (disabled until NetKingdom URL),
AAL step-up hooks, smoke/cutover evidence for tegwick OIDC without MFA.
2026-08-09 22:42:51 +02:00

96 lines
2.9 KiB
Python

import pytest
from django.urls import reverse
from coulomb_social.apps.identity.services import establish_session
from coulomb_social.apps.identity.user_engine import IdentityClaims
from coulomb_social.apps.members.models import Member, User
@pytest.mark.django_db
def test_healthz(client):
r = client.get("/healthz")
assert r.status_code == 200
assert r.json()["status"] == "ok"
@pytest.mark.django_db
def test_landing_public(client):
r = client.get(reverse("core:landing"))
assert r.status_code == 200
assert b"Sign in" in r.content
@pytest.mark.django_db
def test_registration_link_uses_only_configured_destination(client, settings):
settings.NETKINGDOM_REGISTRATION_URL = (
"https://users.coulomb.social/register?client_id=coulomb-social"
)
r = client.get(reverse("identity:register") + "?next=https://evil.example")
assert r.status_code == 302
assert r["Location"] == settings.NETKINGDOM_REGISTRATION_URL
@pytest.mark.django_db
def test_app_home_requires_login(client):
r = client.get(reverse("core:app_home"))
assert r.status_code == 302
assert reverse("identity:login") in r["Location"]
@pytest.mark.django_db
def test_dev_login_establishes_member_and_shell(client, settings):
settings.DEBUG = True
settings.OIDC_ENABLED = False
r = client.post(
reverse("identity:dev_login"),
{
"subject": "sub-abc",
"issuer": "https://local.dev/issuer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"preferred_username": "ada",
},
)
assert r.status_code == 302
assert reverse("core:app_home") in r["Location"]
member = Member.objects.get(subject="sub-abc")
assert member.tenant_id == settings.DEFAULT_TENANT_ID
assert member.display_name == "Ada Lovelace"
assert member.user_engine_user_id
assert member.user.has_usable_password() is False
home = client.get(reverse("core:app_home"))
assert home.status_code == 200
assert b"Ada Lovelace" in home.content
assert b"sub-abc" in home.content
@pytest.mark.django_db
def test_establish_session_idempotent(client, settings):
claims = IdentityClaims(
issuer="https://id.example",
subject="same-sub",
email="x@example.com",
name="Once",
)
# Use request factory via client session by posting twice
settings.DEBUG = True
settings.OIDC_ENABLED = False
client.post(
reverse("identity:dev_login"),
{"subject": "same-sub", "issuer": "https://id.example", "name": "Once"},
)
client.post(
reverse("identity:dev_login"),
{"subject": "same-sub", "issuer": "https://id.example", "name": "Once"},
)
assert Member.objects.filter(subject="same-sub").count() == 1
assert User.objects.count() == 1
@pytest.mark.django_db
def test_no_password_columns_on_member():
field_names = {f.name for f in Member._meta.fields}
assert "password" not in field_names