Add Team/TeamRole/TeamMembership/TeamPicture models and fix two test bugs
- Fix Member.create(): post_save signal creates Member immediately on User creation,
so new users always hit the hasattr branch; check `created` flag to set initial
password and notes for genuinely new users
- Fix Season.for_date(): replace get() with filter().order_by("-start_date").first()
to handle overlapping seasons gracefully and raise DoesNotExist when none match
- Add TeamRole, Team, TeamMembership, TeamPicture models with rules permissions
- Add migration 0002 for new models
- Add test suites for members and teams covering all new model behaviour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,7 +83,13 @@ class Member(RulesModel):
|
||||
|
||||
if hasattr(user, "member"):
|
||||
member = user.member
|
||||
if password is not None and password != "":
|
||||
if created:
|
||||
if password is None or password == "":
|
||||
initial_password = "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(20))
|
||||
password = initial_password
|
||||
member.notes = f"Initial password: {initial_password}"
|
||||
user.set_password(password)
|
||||
elif password is not None and password != "":
|
||||
user.set_password(password)
|
||||
else:
|
||||
member = cls()
|
||||
|
||||
@@ -2,6 +2,8 @@ from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.test import TestCase
|
||||
|
||||
from members.models import Member
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@@ -28,3 +30,63 @@ class MembersTestCase(TestCase):
|
||||
self.assertTrue(self.user_a.has_perm("members.member_manager"))
|
||||
self.assertTrue(self.user_a.has_perm("members.add_member"))
|
||||
self.assertFalse(self.user_a.is_superuser)
|
||||
|
||||
|
||||
class MemberCreateTest(TestCase):
|
||||
def test_create_new_member(self):
|
||||
member = Member.create(first_name="Alice", last_name="Smith", email="alice@test.com")
|
||||
self.assertIsNotNone(member.pk)
|
||||
self.assertEqual(member.user.first_name, "Alice")
|
||||
self.assertEqual(member.user.last_name, "Smith")
|
||||
self.assertEqual(member.user.email, "alice@test.com")
|
||||
|
||||
def test_create_sets_initial_password_note(self):
|
||||
member = Member.create(first_name="Alice", last_name="Smith", email="alice@test.com")
|
||||
self.assertIn("Initial password:", member.notes)
|
||||
|
||||
def test_create_with_explicit_password(self):
|
||||
member = Member.create(first_name="Alice", last_name="Smith", email="alice@test.com", password="secret123")
|
||||
self.assertTrue(member.user.check_password("secret123"))
|
||||
self.assertIsNone(member.notes)
|
||||
|
||||
def test_create_existing_user_reuses_member(self):
|
||||
existing_user = User.objects.create(username="bob@test.com", email="bob@test.com", first_name="Bob", last_name="Old")
|
||||
original_member_pk = existing_user.member.pk
|
||||
|
||||
member = Member.create(first_name="Bob", last_name="New", email="bob@test.com")
|
||||
self.assertEqual(member.pk, original_member_pk)
|
||||
self.assertEqual(member.user.last_name, "New")
|
||||
|
||||
def test_create_update_existing_member(self):
|
||||
existing_member = Member.create(first_name="Carol", last_name="Old", email="carol@test.com")
|
||||
updated_member = Member.create(first_name="Carol", last_name="Updated", email="carol@test.com", member=existing_member)
|
||||
|
||||
self.assertEqual(updated_member.pk, existing_member.pk)
|
||||
self.assertEqual(updated_member.user.last_name, "Updated")
|
||||
|
||||
def test_create_update_existing_member_with_password(self):
|
||||
existing_member = Member.create(first_name="Dave", last_name="D", email="dave@test.com")
|
||||
Member.create(first_name="Dave", last_name="D", email="dave@test.com", password="newpass", member=existing_member)
|
||||
existing_member.user.refresh_from_db()
|
||||
self.assertTrue(existing_member.user.check_password("newpass"))
|
||||
|
||||
def test_create_reactivates_inactive_user(self):
|
||||
member = Member.create(first_name="Eve", last_name="E", email="eve@test.com")
|
||||
member.user.is_active = False
|
||||
member.user.save()
|
||||
|
||||
reactivated = Member.create(first_name="Eve", last_name="E", email="eve@test.com", member=member)
|
||||
self.assertTrue(reactivated.user.is_active)
|
||||
|
||||
def test_create_member_is_active_by_default(self):
|
||||
member = Member.create(first_name="Frank", last_name="F", email="frank@test.com")
|
||||
self.assertTrue(member.user.is_active)
|
||||
|
||||
|
||||
class MemberManagerTest(TestCase):
|
||||
def test_queryset_select_related(self):
|
||||
User.objects.create(username="user_mgr", first_name="Mgr", last_name="Test", email="mgr@test.com")
|
||||
# select_related means no extra query is needed to access member.user
|
||||
with self.assertNumQueries(1):
|
||||
members = list(Member.objects.all())
|
||||
_ = [m.user.get_full_name() for m in members]
|
||||
|
||||
Reference in New Issue
Block a user