from django.test import TestCase from django.contrib.auth import get_user_model from rest_framework.test import APIClient from rest_framework import status from .models import RegistrationDomainRule, RegistrationRestrictionSetting, EmailVerificationToken from apps.events.models import Event, TaskArea, Shift, ShiftSignup User = get_user_model() class UserRegistrationTests(TestCase): def setUp(self): self.client = APIClient() def test_domain_restriction_enforcement(self): # Enable domain restriction setting = RegistrationRestrictionSetting.get_solo() setting.is_restriction_enabled = True setting.save() # Add rule for verein.de RegistrationDomainRule.objects.create(domain='verein.de', is_active=True) # Attempt registration with non-allowed domain res = self.client.post('/api/users/register/', { 'username': 'testuser', 'email': 'user@otherdomain.com', 'password': 'password123', 'display_name': 'Test User' }) self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn('Registrierungen sind derzeit nur für folgende E-Mail-Domains erlaubt', str(res.data)) # Attempt registration with allowed domain res_ok = self.client.post('/api/users/register/', { 'username': 'alloweduser', 'email': 'user@verein.de', 'password': 'password123', 'display_name': 'Allowed User' }) self.assertEqual(res_ok.status_code, status.HTTP_201_CREATED) self.assertTrue(res_ok.data.get('requires_verification')) def test_email_verification_flow(self): # Register new user res_reg = self.client.post('/api/users/register/', { 'username': 'verify_user', 'email': 'verify@example.com', 'password': 'password123', 'display_name': 'Verify User' }) self.assertEqual(res_reg.status_code, status.HTTP_201_CREATED) self.assertTrue(res_reg.data.get('requires_verification')) v_token_str = res_reg.data.get('verification_token') # Login should be blocked prior to verification or admin approval res_login_blocked = self.client.post('/api/users/login/', { 'username': 'verify_user', 'password': 'password123' }) self.assertEqual(res_login_blocked.status_code, status.HTTP_403_FORBIDDEN) # Verify email using verification token res_verify = self.client.post('/api/users/verify-email/', { 'token': v_token_str }) self.assertEqual(res_verify.status_code, status.HTTP_200_OK) self.assertIn('token', res_verify.data) # Login should now succeed res_login_ok = self.client.post('/api/users/login/', { 'username': 'verify_user', 'password': 'password123' }) self.assertEqual(res_login_ok.status_code, status.HTTP_200_OK) self.assertIn('token', res_login_ok.data) def test_guest_shift_claiming_on_registration(self): # Create event, task area, shift event = Event.objects.create(title="Test Event", start_date="2026-08-01", end_date="2026-08-02") ta = TaskArea.objects.create(event=event, name="Tresendienst") shift = Shift.objects.create(task_area=ta, title="Frühschicht", start_time="09:00", end_time="13:00") # Guest signs up with guest_name="Max Mustermann" session = self.client.session session.save() session_key = session.session_key signup = ShiftSignup.objects.create( shift=shift, guest_name="Max Mustermann", guest_session_key=session_key ) # Now register user with display_name="Max Mustermann" res = self.client.post('/api/users/register/', { 'username': 'max_mustermann', 'email': 'max@example.com', 'password': 'password123', 'display_name': 'Max Mustermann' }) self.assertEqual(res.status_code, status.HTTP_201_CREATED) self.assertEqual(res.data['claimed_shifts_count'], 1) signup.refresh_from_db() self.assertIsNotNone(signup.user) self.assertEqual(signup.user.username, 'max_mustermann') self.assertIsNone(signup.guest_name) def test_admin_approval_workflow(self): # Register user res_reg = self.client.post('/api/users/register/', { 'username': 'pending_user', 'email': 'pending@example.com', 'password': 'password123', 'display_name': 'Pending User' }) self.assertEqual(res_reg.status_code, status.HTTP_201_CREATED) # Attempt login before approval (should be blocked) res_login_fail = self.client.post('/api/users/login/', { 'username': 'pending_user', 'password': 'password123' }) self.assertEqual(res_login_fail.status_code, status.HTTP_403_FORBIDDEN) # Admin approves user admin = User.objects.create_superuser(username='admin', email='admin@test.com', password='adminpassword') self.client.force_authenticate(user=admin) pending_user = User.objects.get(username='pending_user') res_approve = self.client.post(f'/api/users/{pending_user.id}/approve/') self.assertEqual(res_approve.status_code, status.HTTP_200_OK) # Attempt login after approval (should succeed) self.client.logout() res_login_ok = self.client.post('/api/users/login/', { 'username': 'pending_user', 'password': 'password123' }) self.assertEqual(res_login_ok.status_code, status.HTTP_200_OK) self.assertIn('token', res_login_ok.data) def test_guest_claim_token_and_registration_link(self): admin = User.objects.create_user(username="admin_gen", email="admin_gen@test.com", password="password123", is_admin_user=True) event = Event.objects.create(title="Claim Event", start_date="2026-09-01", end_date="2026-09-02") ta = TaskArea.objects.create(event=event, name="Kasse") shift = Shift.objects.create(task_area=ta, title="Spätschicht", start_time="18:00", end_time="22:00") signup = ShiftSignup.objects.create(shift=shift, guest_name="Erika Muster") # Admin generates claim link self.client.force_authenticate(user=admin) res_token = self.client.post(f'/api/users/signups/{signup.id}/generate-claim-link/') self.assertEqual(res_token.status_code, status.HTTP_200_OK) claim_token = res_token.data['token'] self.assertEqual(res_token.data['guest_name'], 'Erika Muster') # Recipient registers using claim_token self.client.logout() res_reg = self.client.post('/api/users/register/', { 'username': 'erika_muster', 'email': 'erika@muster.de', 'password': 'password123', 'display_name': 'Erika Muster', 'claim_token': claim_token }) self.assertEqual(res_reg.status_code, status.HTTP_201_CREATED) signup.refresh_from_db() self.assertIsNotNone(signup.user) self.assertEqual(signup.user.username, 'erika_muster') self.assertIsNone(signup.guest_name)