You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
9.8 KiB
233 lines
9.8 KiB
import datetime
|
|
from django.urls import reverse
|
|
from rest_framework import status
|
|
from rest_framework.test import APITestCase
|
|
from apps.account.models import User
|
|
from apps.profiles.models import Institution, InstitutionMember
|
|
from apps.events.models import Event, EventRegistration, EventCategory, LocationType, RegistrationStatus
|
|
|
|
|
|
class Phase7EventsAPITests(APITestCase):
|
|
def setUp(self):
|
|
# Create Users
|
|
self.superadmin = User.objects.create_superuser(
|
|
email="[email protected]",
|
|
password="Password123!",
|
|
fullname="Super Admin"
|
|
)
|
|
self.inst_admin = User.objects.create_user(
|
|
email="[email protected]",
|
|
password="Password123!",
|
|
fullname="Ali Najafi",
|
|
user_type="institution_admin"
|
|
)
|
|
self.member_user = User.objects.create_user(
|
|
email="[email protected]",
|
|
password="Password123!",
|
|
fullname="Reza Moradi",
|
|
user_type="client"
|
|
)
|
|
self.unrelated_user = User.objects.create_user(
|
|
email="[email protected]",
|
|
password="Password123!",
|
|
fullname="Stranger Person",
|
|
user_type="client"
|
|
)
|
|
|
|
# Create Institution
|
|
self.institution = Institution.objects.create(
|
|
name="Imam Ali Islamic Center",
|
|
slug="imam-ali-center",
|
|
type="cultural_center",
|
|
country="Germany",
|
|
city="Berlin",
|
|
address="Center St 123",
|
|
latitude=52.5200,
|
|
longitude=13.4050,
|
|
verification_status="approved",
|
|
is_active=True
|
|
)
|
|
|
|
# Add admin member
|
|
InstitutionMember.objects.create(
|
|
institution=self.institution,
|
|
user=self.inst_admin,
|
|
role="admin"
|
|
)
|
|
|
|
# Create Initial Event
|
|
self.event = Event.objects.create(
|
|
title="International Peace & Coexistence Conference",
|
|
slug="international-peace-conference",
|
|
description="A global dialogue on peaceful coexistence and cultural diplomacy.",
|
|
organizer=self.institution,
|
|
created_by=self.inst_admin,
|
|
category=EventCategory.CONFERENCE,
|
|
event_date=datetime.date.today() + datetime.timedelta(days=7),
|
|
start_time=datetime.time(10, 0),
|
|
end_time=datetime.time(12, 30),
|
|
speaker_name="Dr. Hassan Tabatabaei",
|
|
speaker_title="Head of Philosophy Dept",
|
|
location_type=LocationType.HYBRID,
|
|
venue_address="Hall A, Berlin",
|
|
online_meeting_url="https://meet.jit.si/peace-conf-2026",
|
|
capacity=50,
|
|
is_active=True,
|
|
is_featured=True,
|
|
language="en"
|
|
)
|
|
|
|
def test_list_events(self):
|
|
url = reverse('event-list-create')
|
|
response = self.client.get(url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
# Should include the event in results
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0]['title'], self.event.title)
|
|
self.assertEqual(results[0]['organizer']['name'], self.institution.name)
|
|
|
|
def test_filter_events_by_category_and_search(self):
|
|
url = reverse('event-list-create')
|
|
|
|
# Search match
|
|
response = self.client.get(url, {'search': 'Coexistence'})
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 1)
|
|
|
|
# Search no match
|
|
response = self.client.get(url, {'search': 'NonexistentTopic'})
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 0)
|
|
|
|
# Category match
|
|
response = self.client.get(url, {'category': 'conference'})
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 1)
|
|
|
|
# Category no match
|
|
response = self.client.get(url, {'category': 'counseling'})
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 0)
|
|
|
|
def test_create_event_authorized(self):
|
|
self.client.force_authenticate(user=self.inst_admin)
|
|
url = reverse('event-list-create')
|
|
payload = {
|
|
"title": "Ramadan Quran Recitation Workshop",
|
|
"description": "Daily recitation and reflection sessions.",
|
|
"organizer_id": self.institution.id,
|
|
"category": "workshop",
|
|
"event_date": str(datetime.date.today() + datetime.timedelta(days=14)),
|
|
"start_time": "18:00:00",
|
|
"end_time": "19:30:00",
|
|
"speaker_name": "Qari Ahmad",
|
|
"location_type": "online",
|
|
"capacity": 200,
|
|
"language": "ar"
|
|
}
|
|
response = self.client.post(url, payload, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
|
self.assertEqual(response.data['title'], "Ramadan Quran Recitation Workshop")
|
|
self.assertEqual(response.data['organizer']['id'], self.institution.id)
|
|
|
|
def test_create_event_unauthorized_user(self):
|
|
self.client.force_authenticate(user=self.unrelated_user)
|
|
url = reverse('event-list-create')
|
|
payload = {
|
|
"title": "Unauthorized Event",
|
|
"description": "Description",
|
|
"organizer_id": self.institution.id,
|
|
"category": "cultural",
|
|
"event_date": str(datetime.date.today() + datetime.timedelta(days=10)),
|
|
"start_time": "10:00:00"
|
|
}
|
|
response = self.client.post(url, payload, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
error_fields = [e.get('field') for e in response.data.get('errors', [])] if 'errors' in response.data else response.data
|
|
self.assertTrue('organizer_id' in error_fields)
|
|
|
|
def test_retrieve_event_by_id_and_slug(self):
|
|
# By ID
|
|
url_id = reverse('event-detail', kwargs={'id_or_slug': str(self.event.id)})
|
|
response = self.client.get(url_id)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data['slug'], self.event.slug)
|
|
|
|
# By Slug
|
|
url_slug = reverse('event-detail', kwargs={'id_or_slug': self.event.slug})
|
|
response = self.client.get(url_slug)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data['id'], self.event.id)
|
|
|
|
def test_update_event_permissions(self):
|
|
url = reverse('event-detail', kwargs={'id_or_slug': str(self.event.id)})
|
|
|
|
# Unauthenticated attempt
|
|
response = self.client.patch(url, {"title": "New Title"}, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
|
|
|
# Unrelated user attempt
|
|
self.client.force_authenticate(user=self.unrelated_user)
|
|
response = self.client.patch(url, {"title": "New Title"}, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
|
|
# Authorized inst_admin attempt
|
|
self.client.force_authenticate(user=self.inst_admin)
|
|
response = self.client.patch(url, {"title": "Updated Peace Conference Title"}, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data['title'], "Updated Peace Conference Title")
|
|
|
|
def test_event_registration_flow_and_cancellation(self):
|
|
self.client.force_authenticate(user=self.member_user)
|
|
reg_url = reverse('event-register', kwargs={'id_or_slug': str(self.event.id)})
|
|
|
|
# Register
|
|
response = self.client.post(reg_url, {"notes": "Looking forward to attending!"}, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertTrue(response.data['is_registered'])
|
|
self.assertEqual(response.data['registration_count'], 1)
|
|
|
|
# Duplicate registration attempt
|
|
response = self.client.post(reg_url, {}, format='json')
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
|
|
# Cancel registration
|
|
cancel_url = reverse('event-cancel-registration', kwargs={'id_or_slug': str(self.event.id)})
|
|
response = self.client.post(cancel_url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertFalse(response.data['is_registered'])
|
|
self.assertEqual(response.data['registration_count'], 0)
|
|
|
|
def test_event_registrations_list_for_organizer(self):
|
|
# Register a participant
|
|
EventRegistration.objects.create(
|
|
event=self.event,
|
|
user=self.member_user,
|
|
status=RegistrationStatus.REGISTERED,
|
|
notes="Participant notes"
|
|
)
|
|
self.event.update_registration_count()
|
|
|
|
url = reverse('event-registrations-list', kwargs={'id_or_slug': str(self.event.id)})
|
|
|
|
# Unrelated user cannot view attendees
|
|
self.client.force_authenticate(user=self.unrelated_user)
|
|
response = self.client.get(url)
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
|
|
# Inst admin can view attendees
|
|
self.client.force_authenticate(user=self.inst_admin)
|
|
response = self.client.get(url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
results = response.data.get('results', response.data)
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0]['user']['email'], self.member_user.email)
|
|
|
|
def test_calendar_view(self):
|
|
url = reverse('event-calendar')
|
|
today = datetime.date.today()
|
|
response = self.client.get(url, {'year': today.year, 'month': today.month})
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
results = response.data.get('results', response.data)
|
|
self.assertTrue(len(results) >= 1)
|