Files
schichtplanung/backend/apps/events/tests.py
T

145 lines
7.6 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 Skill, Event, TaskArea, Shift, ShiftSignup
User = get_user_model()
class EventAndShiftTests(TestCase):
def setUp(self):
self.client = APIClient()
self.skill = Skill.objects.create(name="Ersthelfer", color="#ef4444")
self.user = User.objects.create_user(
username="doctor_who", email="doctor@tardis.org", password="password123", display_name="Dr. Who"
)
self.event = Event.objects.create(title="Sommerfest", start_date="2026-08-10", end_date="2026-08-12")
self.ta = TaskArea.objects.create(event=self.event, name="Sanitätsdienst")
self.shift = Shift.objects.create(
task_area=self.ta, title="Hauptschicht", start_time="10:00", end_time="18:00", max_participants=2
)
self.shift.required_skills.add(self.skill)
def test_guest_cannot_signup_for_skill_required_shift(self):
res = self.client.post(f'/api/shifts/{self.shift.id}/signup/', {
'guest_name': 'Guest User',
'captcha_token': 'test-captcha-token'
})
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn('Gäste können keine Fähigkeiten haben', res.data['error'])
def test_user_without_skill_blocked_and_with_skill_allowed(self):
self.client.force_authenticate(user=self.user)
# Attempt signup without skill
res_fail = self.client.post(f'/api/shifts/{self.shift.id}/signup/')
self.assertEqual(res_fail.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn('Dir fehlen folgende erforderliche Fähigkeiten', res_fail.data['error'])
# Add skill to user
self.user.skills.add(self.skill)
# Attempt signup with skill
res_ok = self.client.post(f'/api/shifts/{self.shift.id}/signup/')
self.assertEqual(res_ok.status_code, status.HTTP_201_CREATED)
def test_guest_privacy_redaction_in_matrix(self):
# Add signup
self.user.skills.add(self.skill)
ShiftSignup.objects.create(shift=self.shift, user=self.user)
# Unauthenticated request (Guest)
anon_client = APIClient()
res_anon = anon_client.get(f'/api/events/{self.event.id}/matrix/')
self.assertEqual(res_anon.status_code, status.HTTP_200_OK)
signup_data_anon = res_anon.data['task_areas'][0]['shifts'][0]['signups'][0]
self.assertEqual(signup_data_anon['display_name'], 'Belegt (Anonym)')
# Authenticated request
self.client.force_authenticate(user=self.user)
res_auth = self.client.get(f'/api/events/{self.event.id}/matrix/')
self.assertEqual(res_auth.status_code, status.HTTP_200_OK)
signup_data_auth = res_auth.data['task_areas'][0]['shifts'][0]['signups'][0]
self.assertEqual(signup_data_auth['display_name'], 'Dr. Who')
def test_event_edit_and_deactivation_permissions(self):
admin = User.objects.create_user(
username="admin_user", email="admin@verein.de", password="password123", is_admin_user=True
)
other_user = User.objects.create_user(
username="other_user", email="other@verein.de", password="password123"
)
user_event = Event.objects.create(
title="User Event", start_date="2026-09-01", end_date="2026-09-02", created_by=self.user
)
# Other user cannot deactivate user_event
self.client.force_authenticate(user=other_user)
res_fail = self.client.patch(f'/api/events/{user_event.id}/', {'is_active': False})
self.assertEqual(res_fail.status_code, status.HTTP_403_FORBIDDEN)
# Creator (self.user) CAN deactivate their own event
self.client.force_authenticate(user=self.user)
res_creator_ok = self.client.patch(f'/api/events/{user_event.id}/', {'is_active': False})
self.assertEqual(res_creator_ok.status_code, status.HTTP_200_OK)
self.assertFalse(res_creator_ok.data['is_active'])
# Admin CAN manage and reactivate any event
self.client.force_authenticate(user=admin)
res_admin_ok = self.client.patch(f'/api/events/{user_event.id}/', {'is_active': True})
self.assertEqual(res_admin_ok.status_code, status.HTTP_200_OK)
self.assertTrue(res_admin_ok.data['is_active'])
def test_shift_and_participant_management_permissions(self):
creator = User.objects.create_user(username="creator", email="creator@verein.de", password="password123")
other_user = User.objects.create_user(username="other", email="other@verein.de", password="password123")
event = Event.objects.create(title="Creator Event", start_date="2026-09-01", end_date="2026-09-02", created_by=creator)
ta = TaskArea.objects.create(event=event, name="Bar")
shift = Shift.objects.create(task_area=ta, title="Abendschicht", start_time="19:00", end_time="23:00", max_participants=2)
signup = ShiftSignup.objects.create(shift=shift, user=other_user)
# Other user CANNOT remove creator's participant from creator's shift
third_user = User.objects.create_user(username="third", email="third@verein.de", password="password123")
self.client.force_authenticate(user=third_user)
res_fail = self.client.delete(f'/api/shifts/{shift.id}/signup/', {'signup_id': signup.id}, format='json')
self.assertEqual(res_fail.status_code, status.HTTP_404_NOT_FOUND)
# Creator CAN remove participant from shift on their own event
self.client.force_authenticate(user=creator)
res_ok = self.client.delete(f'/api/shifts/{shift.id}/signup/', {'signup_id': signup.id}, format='json')
self.assertEqual(res_ok.status_code, status.HTTP_200_OK)
self.assertFalse(ShiftSignup.objects.filter(pk=signup.id).exists())
def test_co_manager_permissions_and_guest_skill_bypass(self):
owner = User.objects.create_user(username="owner_user", email="owner@test.de", password="password123")
co_manager = User.objects.create_user(username="comanager", email="comanager@test.de", password="password123")
event = Event.objects.create(title="CoManaged Event", start_date="2026-10-01", end_date="2026-10-02", created_by=owner)
event.co_managers.add(co_manager)
ta = TaskArea.objects.create(event=event, name="Einlass")
shift = Shift.objects.create(task_area=ta, title="Spätschicht", start_time="20:00", end_time="24:00", max_participants=5)
shift.required_skills.add(self.skill)
# Co-manager can edit event
self.client.force_authenticate(user=co_manager)
res_edit = self.client.patch(f'/api/events/{event.id}/', {'location': 'Haupteingang'})
self.assertEqual(res_edit.status_code, status.HTTP_200_OK)
self.assertEqual(res_edit.data['location'], 'Haupteingang')
# Co-manager CAN register a guest on skill-required shift (skill check bypassed for manager!)
res_guest = self.client.post(f'/api/shifts/{shift.id}/signup/', {'guest_name': 'VIP Gast'}, format='json')
self.assertEqual(res_guest.status_code, status.HTTP_201_CREATED)
self.assertIn('ohne Qualifikationsprüfung', res_guest.data['message'])
# Check signup exists
signup_id = res_guest.data['signup_id']
signup = ShiftSignup.objects.get(pk=signup_id)
self.assertEqual(signup.guest_name, 'VIP Gast')
# Co-manager can delete any signup
res_del = self.client.delete(f'/api/shifts/{shift.id}/signup/', {'signup_id': signup_id}, format='json')
self.assertEqual(res_del.status_code, status.HTTP_200_OK)