Skip to content

Commit 20eb5a2

Browse files
authored
Optimize error handling staffmember instance doesn't exist (#48)
* Optimize error handling staffmember instance doesn't exist * Fixed tests for users * Added test for error handling
1 parent 18d86b4 commit 20eb5a2

File tree

4 files changed

+63
-23
lines changed

4 files changed

+63
-23
lines changed

appointment/services.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,22 @@
99
import datetime
1010

1111
from django.contrib.auth import get_user_model
12+
from django.core.exceptions import ObjectDoesNotExist
1213
from django.shortcuts import render
1314
from django.urls import reverse
1415
from django.utils import timezone
15-
from django.utils.translation import gettext as _
16-
from django.utils.translation import gettext_lazy as _
16+
from django.utils.translation import gettext as _, gettext_lazy as _
1717

18-
from appointment.forms import StaffDaysOffForm, StaffWorkingHoursForm, PersonalInformationForm, ServiceForm
18+
from appointment.forms import PersonalInformationForm, ServiceForm, StaffDaysOffForm, StaffWorkingHoursForm
1919
from appointment.settings import APPOINTMENT_PAYMENT_URL
20-
from appointment.utils.date_time import get_ar_end_time, convert_12_hour_time_to_24_hour_time, \
21-
convert_str_to_time
22-
from appointment.utils.db_helpers import get_all_appointments, get_staff_member_appointment_list, \
23-
get_appointment_by_id, get_all_staff_members, get_staff_member_from_user_id_or_logged_in, \
24-
day_off_exists_for_date_range, working_hours_exist, Appointment, WorkingHours, Service, StaffMember, \
25-
get_user_by_email, EmailVerificationCode, create_new_user
26-
from appointment.utils.db_helpers import get_working_hours_for_staff_and_day, get_appointments_for_date_and_time, \
27-
get_times_from_config, exclude_booked_slots, calculate_slots, \
28-
calculate_staff_slots, check_day_off_for_staff
20+
from appointment.utils.date_time import convert_12_hour_time_to_24_hour_time, convert_str_to_time, get_ar_end_time
21+
from appointment.utils.db_helpers import Appointment, EmailVerificationCode, Service, StaffMember, WorkingHours, \
22+
calculate_slots, calculate_staff_slots, check_day_off_for_staff, create_new_user, day_off_exists_for_date_range, \
23+
exclude_booked_slots, get_all_appointments, get_all_staff_members, get_appointment_by_id, \
24+
get_appointments_for_date_and_time, get_staff_member_appointment_list, get_staff_member_from_user_id_or_logged_in, \
25+
get_times_from_config, get_user_by_email, get_working_hours_for_staff_and_day, working_hours_exist
2926
from appointment.utils.error_codes import ErrorCode
30-
from appointment.utils.json_context import json_response, get_generic_context
27+
from appointment.utils.json_context import get_generic_context, json_response
3128
from appointment.utils.permissions import check_entity_ownership
3229
from appointment.utils.session import handle_email_change
3330

@@ -38,11 +35,16 @@ def fetch_user_appointments(user):
3835
:param user: The user instance.
3936
:return: A list of appointments.
4037
"""
41-
4238
if user.is_superuser:
4339
return get_all_appointments()
44-
staff_member_instance = user.staffmember
45-
return get_staff_member_appointment_list(staff_member_instance)
40+
try:
41+
staff_member_instance = user.staffmember
42+
return get_staff_member_appointment_list(staff_member_instance)
43+
except ObjectDoesNotExist:
44+
if user.is_staff:
45+
return []
46+
47+
raise ValueError("User is not a staff member or a superuser")
4648

4749

4850
def prepare_appointment_display_data(user, appointment_id):
@@ -534,4 +536,3 @@ def handle_service_management_request(post_data, files_data=None, service_id=Non
534536
return None, False, get_error_message_in_form(form=form)
535537
except Exception as e:
536538
return None, False, str(e)
537-

appointment/tests/test_services.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
handle_service_management_request, handle_working_hours_form, handle_day_off_form
1515
from appointment.tests.base.base_test import BaseTest
1616
from appointment.utils.date_time import convert_str_to_time, get_ar_end_time
17-
from appointment.utils.db_helpers import get_user_model, DayOff, WorkingHours, Config, EmailVerificationCode, \
17+
from appointment.utils.db_helpers import Appointment, AppointmentRequest, DayOff, WorkingHours, Config, \
18+
EmailVerificationCode, \
1819
StaffMember
1920

2021

@@ -27,6 +28,9 @@ def setUp(self):
2728
# Create some appointments for testing purposes
2829
self.appointment_for_user1 = self.create_appointment_for_user1()
2930
self.appointment_for_user2 = self.create_appointment_for_user2()
31+
self.staff_user = self.create_user_(username='staff_user', password='test')
32+
self.staff_user.is_staff = True
33+
self.staff_user.save()
3034

3135
def test_fetch_appointments_for_superuser(self):
3236
"""Test that a superuser can fetch all appointments."""
@@ -55,12 +59,18 @@ def test_fetch_appointments_for_staff_member(self):
5559
"Staff members should not see appointments not linked to them. User2's appointment was found.")
5660

5761
def test_fetch_appointments_for_regular_user(self):
58-
"""Test that a regular user (not a staff member) cannot fetch appointments."""
59-
# Fetching appointments for a regular user (client1 in this case) should raise an exception
60-
with self.assertRaises(get_user_model().staffmember.RelatedObjectDoesNotExist,
61-
msg="Regular users without a staff member profile can't fetch appointments."):
62+
"""Test that a regular user (not a user with staff member instance or staff) cannot fetch appointments."""
63+
# Fetching appointments for a regular user (client1 in this case) should raise ValueError
64+
with self.assertRaises(ValueError,
65+
msg="Regular users without staff or superuser status should raise a ValueError."):
6266
fetch_user_appointments(self.client1)
6367

68+
def test_fetch_appointments_for_staff_user_without_staff_member_instance(self):
69+
"""Test that a staff user without a staff member instance gets an empty list of appointments."""
70+
appointments = fetch_user_appointments(self.staff_user)
71+
# Check that the returned value is an empty list
72+
self.assertEqual(appointments, [], "Expected an empty list for a staff user without a staff member instance.")
73+
6474

6575
class PrepareAppointmentDisplayDataTests(BaseTest):
6676
"""Test suite for the `prepare_appointment_display_data` service function."""

appointment/tests/test_views.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
from datetime import date, timedelta, time
44

55
from django.contrib import messages
6+
from django.contrib.messages import get_messages
67
from django.contrib.messages.middleware import MessageMiddleware
78
from django.contrib.sessions.middleware import SessionMiddleware
89
from django.test import Client
910
from django.test.client import RequestFactory
1011
from django.urls import reverse
1112
from django.utils.translation import gettext as _
1213

13-
from appointment.models import AppointmentRequest, Appointment, EmailVerificationCode
14+
from appointment.models import AppointmentRequest, Appointment, EmailVerificationCode, StaffMember
1415
from appointment.tests.base.base_test import BaseTest
1516
from appointment.utils.db_helpers import WorkingHours
1617
from appointment.views import verify_user_and_login
@@ -28,6 +29,7 @@ def setUp(self):
2829
start_time=datetime.time(8, 0), end_time=datetime.time(12, 0))
2930
self.ar = self.create_appt_request_for_sm1()
3031
self.request = self.factory.get('/')
32+
self.user1.is_staff = True
3133
self.request.user = self.user1
3234
middleware = SessionMiddleware(lambda req: None)
3335
middleware.process_request(self.request)
@@ -137,3 +139,27 @@ def test_default_thank_you(self):
137139
response = self.client.get(url)
138140
self.assertEqual(response.status_code, 200)
139141
self.assertIn(appointment.get_service_name(), str(response.content))
142+
143+
def test_staff_user_without_staff_member_instance(self):
144+
"""Test that a staff user without a staff member instance receives an appropriate error message."""
145+
self.user1.is_staff = True
146+
147+
# Delete any AppointmentRequests and Appointments linked to the StaffMember instance of self.user1
148+
AppointmentRequest.objects.filter(staff_member__user=self.user1).delete()
149+
Appointment.objects.filter(appointment_request__staff_member__user=self.user1).delete()
150+
151+
# Now safely delete the StaffMember instance
152+
StaffMember.objects.filter(user=self.user1).delete()
153+
154+
self.user1.save() # Save the user to the database after updating
155+
self.client.force_login(self.user1) # Log in as self.user1
156+
157+
url = reverse('appointment:get_user_appointments')
158+
response = self.client.get(url)
159+
160+
message_list = list(get_messages(response.wsgi_request))
161+
self.assertTrue(any(
162+
message.message == "User doesn't have a staff member instance. Please contact the administrator." for
163+
message in message_list),
164+
"Expected error message not found in messages.")
165+

appointment/views_admin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def get_user_appointments(request, response_type='html'):
4848
'appointments': json.dumps(appointments_json),
4949
}
5050
context = get_generic_context_with_extra(request=request, extra=extra_context)
51+
# if appointment is empty and user doesn't have a staff-member instance, put a message
52+
if not appointments and not StaffMember.objects.filter(user=request.user).exists() and request.user.is_staff:
53+
messages.error(request, _("User doesn't have a staff member instance. Please contact the administrator."))
5154
return render(request, 'administration/staff_index.html', context)
5255

5356

0 commit comments

Comments
 (0)