172 lines
7.2 KiB
Python
172 lines
7.2 KiB
Python
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)
|