Files
RosterChief/accounts/tests.py
Bernard Siebens 2ead824c5d Add accounts app: custom User, Member, families & guardianship
Introduce the foundational accounts app:
- Custom email-as-username User (AbstractBaseUser + PermissionsMixin) set
  as AUTH_USER_MODEL, decoupled from membership so children can be members
  without a login.
- Member model holding personal/roster data (names, contact email, phone +
  emergency phone via django-phonenumber-field, license number, DOB) with an
  optional link to a User.
- Family household grouping and directional Guardianship (guardian -> child)
  with uniqueness and no-self-guardian constraints.
- Custom UserAdmin plus Member/Family admin with inlines and autocomplete.
- Settings: register apps, AUTH_USER_MODEL, phonenumber defaults (BE/E164).
- Add CLAUDE.md and a tracked static/ directory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:08:51 +02:00

88 lines
3.3 KiB
Python

from django.core.exceptions import ValidationError
from django.db import IntegrityError, transaction
from django.test import TestCase
from .models import Family, Guardianship, Member, User
class UserManagerTests(TestCase):
def test_create_user_with_email(self):
user = User.objects.create_user(email="Parent@Example.com", password="pw")
self.assertEqual(user.email, "Parent@example.com") # domain normalized
self.assertTrue(user.check_password("pw"))
self.assertFalse(user.is_staff)
self.assertFalse(user.is_superuser)
def test_create_superuser(self):
admin = User.objects.create_superuser(email="admin@example.com", password="pw")
self.assertTrue(admin.is_staff)
self.assertTrue(admin.is_superuser)
def test_create_user_requires_email(self):
with self.assertRaises(ValueError):
User.objects.create_user(email="", password="pw")
def test_create_superuser_rejects_non_superuser_flag(self):
with self.assertRaises(ValueError):
User.objects.create_superuser(email="a@b.com", password="pw", is_superuser=False)
class MemberTests(TestCase):
def test_member_without_login_or_optional_fields(self):
member = Member.objects.create(
first_name="Kid",
last_name="Smith",
date_of_birth="2015-05-01",
)
self.assertIsNone(member.user)
self.assertEqual(member.email, "")
self.assertEqual(member.phone, "")
self.assertEqual(member.license_number, "")
def test_valid_phone_accepted(self):
member = Member(
first_name="Ann",
last_name="Smith",
date_of_birth="1980-01-01",
phone="+32470123456",
)
member.full_clean() # should not raise
def test_invalid_phone_rejected(self):
member = Member(
first_name="Ann",
last_name="Smith",
date_of_birth="1980-01-01",
phone="not-a-number",
)
with self.assertRaises(ValidationError):
member.full_clean()
class FamilyAndGuardianshipTests(TestCase):
def setUp(self):
self.family = Family.objects.create(name="The Smiths")
self.parent = Member.objects.create(
first_name="Ann", last_name="Smith", date_of_birth="1980-01-01", family=self.family
)
self.child = Member.objects.create(
first_name="Kid", last_name="Smith", date_of_birth="2015-05-01", family=self.family
)
def test_family_groups_members(self):
self.assertEqual(self.family.members.count(), 2)
def test_guardianship_relations_resolve(self):
Guardianship.objects.create(guardian=self.parent, child=self.child)
self.assertIn(self.parent, self.child.guardians.all())
self.assertIn(self.child, self.parent.dependents.all())
def test_no_self_guardianship(self):
with transaction.atomic(), self.assertRaises(IntegrityError):
Guardianship.objects.create(guardian=self.parent, child=self.parent)
def test_guardianship_is_unique(self):
Guardianship.objects.create(guardian=self.parent, child=self.child)
with transaction.atomic(), self.assertRaises(IntegrityError):
Guardianship.objects.create(guardian=self.parent, child=self.child)