import csv
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from django.utils.http import urlencode
from intranet.utils.date import get_senior_graduation_year
from ...models import EighthActivity, EighthBlock, EighthRoom, EighthScheduledActivity, EighthSignup
from ..eighth_test import EighthAbstractTest
[docs]class EighthAdminAttendanceTest(EighthAbstractTest):
[docs] def test_take_attendance_zero(self):
"""Make sure all activities with zero students are marked as having attendance taken when button is pressed."""
self.make_admin()
block1 = self.add_block(date="3000-11-11", block_letter="A")
room1 = self.add_room(name="room1", capacity=1)
act1 = self.add_activity(name="Test Activity 1")
act1.rooms.add(room1)
schact1 = self.schedule_activity(act1.id, block1.id)
schact1.attendance_taken = False
schact1.save()
response = self.client.post(
reverse("eighth_admin_view_activities_without_attendance") + "?" + urlencode({"block": block1.id}), {"take_attendance_zero": "1"}
)
self.assertEqual(response.status_code, 302)
# Make sure activity is marked as attendance taken.
self.assertTrue(EighthScheduledActivity.objects.get(id=schact1.id).attendance_taken)
[docs] def test_take_attendance_cancelled(self):
"""Make sure students in a cancelled activity are marked as absent when the button is pressed."""
self.make_admin()
user1 = get_user_model().objects.create(username="user1", graduation_year=get_senior_graduation_year() + 1)
block1 = self.add_block(date="3000-11-11", block_letter="A")
room1 = self.add_room(name="room1", capacity=1)
act1 = self.add_activity(name="Test Activity 1")
act1.rooms.add(room1)
schact1 = self.schedule_activity(act1.id, block1.id)
schact1.attendance_taken = False
schact1.add_user(user1)
schact1.cancelled = True
schact1.save()
response = self.client.post(
reverse("eighth_admin_view_activities_without_attendance") + "?" + urlencode({"block": block1.id}), {"take_attendance_cancelled": "1"}
)
self.assertEqual(response.status_code, 302)
# Make sure attendance has been marked as taken.
self.assertTrue(EighthScheduledActivity.objects.get(id=schact1.id).attendance_taken)
# Make sure EighthSignup object has been marked as absent.
self.assertTrue(EighthSignup.objects.get(user=user1, scheduled_activity=schact1).was_absent)
# Make sure student has correct number of absences.
self.assertEqual(get_user_model().objects.get(id=user1.id).absence_count(), 1)
[docs] def test_activities_without_attendance_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.activities_without_attendance_view`."""
self.make_admin()
# Most of the functionality was tested above...
response = self.client.get(reverse("eighth_admin_view_activities_without_attendance"))
self.assertEqual(200, response.status_code)
[docs] def test_delinquent_students_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.delinquent_students_view`."""
self.make_admin()
# First, load the page
response = self.client.get(reverse("eighth_admin_view_delinquent_students"))
self.assertEqual(200, response.status_code)
# Test with empty set of students (absences)
EighthSignup.objects.all().delete()
response = self.client.get(
reverse("eighth_admin_view_delinquent_students"),
data={"lower": 1, "upper": 100, "freshmen": "on", "sophomores": "on", "juniors": "on", "seniors": "on"},
)
self.assertEqual(200, response.status_code)
self.assertEqual([], response.context["delinquents"])
# Add an absence
user = get_user_model().objects.get_or_create(username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student")[0]
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
EighthSignup.objects.create(user=user, scheduled_activity=scheduled, was_absent=True)
response = self.client.get(
reverse("eighth_admin_view_delinquent_students"),
data={"lower": 1, "upper": 100, "freshmen": "on", "sophomores": "on", "juniors": "on", "seniors": "on"},
)
self.assertEqual(200, response.status_code)
self.assertEqual([{"user": user, "absences": 1}], response.context["delinquents"])
# Exclude seniors
response = self.client.get(
reverse("eighth_admin_view_delinquent_students"), data={"lower": 1, "upper": 100, "freshmen": "on", "sophomores": "on", "juniors": "on"}
)
self.assertEqual(200, response.status_code)
self.assertEqual([], response.context["delinquents"])
# Test CSV output
response = self.client.get(
reverse("eighth_admin_download_delinquent_students_csv"),
data={"lower": 1, "upper": 100, "freshmen": "on", "sophomores": "on", "juniors": "on", "seniors": "on"},
)
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(1, len(reader_contents))
self.assertEqual(reader_contents[0]["TJ Email"], "2021awilliam@tjhsst.edu")
self.assertEqual(reader_contents[0]["Absences"], "1")
[docs] def test_no_signups_roster(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.no_signups_roster`."""
admin_user = self.make_admin()
admin_user.user_type = "teacher"
admin_user.save()
# Add a block
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)
# Load the page
response = self.client.get(reverse("eighth_admin_no_signups_roster", kwargs={"block_id": block.id}))
self.assertEqual(200, response.status_code)
self.assertEqual([], response.context["users"])
# Test CSV output
response = self.client.get(reverse("eighth_admin_no_signups_csv", kwargs={"block_id": block.id}))
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(0, len(reader_contents))
# Add a user
user = get_user_model().objects.get_or_create(username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student")[0]
# Load the page
response = self.client.get(reverse("eighth_admin_no_signups_roster", kwargs={"block_id": block.id}))
self.assertEqual(200, response.status_code)
self.assertEqual([user], response.context["users"])
# Test CSV output
response = self.client.get(reverse("eighth_admin_no_signups_csv", kwargs={"block_id": block.id}))
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(1, len(reader_contents))
self.assertEqual(reader_contents[0]["TJ Email"], "2021awilliam@tjhsst.edu")
[docs] def test_after_deadline_signup_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.after_deadline_signup_view`."""
admin_user = self.make_admin()
admin_user.user_type = "teacher"
admin_user.save()
# Add a block
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
# Load the page
response = self.client.get(reverse("eighth_admin_view_after_deadline_signups"))
self.assertEqual(200, response.status_code)
self.assertEqual([], list(response.context["signups"]))
# Make a user and a late signup
user = get_user_model().objects.get_or_create(
username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student", last_name="William"
)[0]
signup = EighthSignup.objects.create(user=user, scheduled_activity=scheduled, after_deadline=True)
# Load the page
response = self.client.get(reverse("eighth_admin_view_after_deadline_signups"))
self.assertEqual(200, response.status_code)
self.assertEqual([signup], list(response.context["signups"]))
# Test CSV output
response = self.client.get(reverse("eighth_admin_download_after_deadline_signups_csv"))
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(1, len(reader_contents))
self.assertEqual("William", reader_contents[0]["Last Name"])
self.assertEqual(str(block), reader_contents[0]["Block"])
[docs] def test_migrate_outstanding_passes_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.migrate_outstanding_passes_view`."""
self.make_admin()
EighthSignup.objects.all().delete()
EighthBlock.objects.all().delete()
EighthActivity.objects.all().delete()
# First, load the page
response = self.client.get(reverse("eighth_admin_migrate_outstanding_passes"))
self.assertEqual(200, response.status_code)
self.assertEqual([], list(response.context["blocks"]))
# Add a block, activity, and a late signup
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
user = get_user_model().objects.get_or_create(
username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student", last_name="William"
)[0]
signup = EighthSignup.objects.create(user=user, scheduled_activity=scheduled, after_deadline=True, pass_accepted=False)
# Load the page
response = self.client.get(reverse("eighth_admin_migrate_outstanding_passes"))
self.assertEqual(200, response.status_code)
self.assertEqual([block], list(response.context["blocks"]))
# POST something invalid, it should 404
response = self.client.post(reverse("eighth_admin_migrate_outstanding_passes")) # missing block number
self.assertEqual(404, response.status_code)
# Now POST the block ID with it and the signup should migrate
response = self.client.post(reverse("eighth_admin_migrate_outstanding_passes"), data={"block": block.id})
self.assertEqual(302, response.status_code)
self.assertEqual(1, EighthActivity.objects.filter(name="Z - 8th Period Pass Not Received").count())
self.assertEqual(
EighthScheduledActivity.objects.get(activity__name="Z - 8th Period Pass Not Received", block=block),
EighthSignup.objects.get(id=signup.id).scheduled_activity,
)
[docs] def test_out_of_building_schedules_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.out_of_building_schedules_view`."""
self.make_admin()
# First just load the page
response = self.client.get(reverse("eighth_admin_export_out_of_building_schedules"))
self.assertEqual(200, response.status_code)
# Add a block and the "out of building" room, and an activity set to that room
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
room = EighthRoom.objects.get_or_create(name="Out of Building", capacity=5000)[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
activity.rooms.add(room)
activity.save()
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
# Load the page with that block
response = self.client.get(reverse("eighth_admin_export_out_of_building_schedules"), data={"block": block.id})
self.assertEqual(200, response.status_code)
self.assertEqual([], list(response.context["signups"]))
# Add a user with a signup
user = get_user_model().objects.get_or_create(
username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student", last_name="William"
)[0]
signup = EighthSignup.objects.create(user=user, scheduled_activity=scheduled)
# Load the page with that block
response = self.client.get(reverse("eighth_admin_export_out_of_building_schedules"), data={"block": block.id})
self.assertEqual(200, response.status_code)
self.assertEqual([signup], list(response.context["signups"]))
# Test CSV
response = self.client.get(reverse("eighth_admin_export_out_of_building_schedules_csv", kwargs={"block_id": block.id}))
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(1, len(reader_contents))
self.assertEqual("William", reader_contents[0]["Last Name"])
self.assertEqual(str(activity.id), reader_contents[0]["Activity ID"])
[docs] def test_clear_absence_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.clear_absence_view`."""
self.make_admin()
# Add a user with an absence
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
user = get_user_model().objects.get_or_create(
username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student", last_name="William"
)[0]
signup = EighthSignup.objects.create(user=user, scheduled_activity=scheduled, was_absent=True)
response = self.client.post(reverse("eighth_admin_clear_absence", kwargs={"signup_id": signup.id}))
self.assertEqual(302, response.status_code) # to dashboard
self.assertFalse(EighthSignup.objects.get(id=signup.id).was_absent)
[docs] def test_open_passes_view(self):
"""Tests :func:`~intranet.apps.eighth.views.admin.attendance.open_passes_view`."""
self.make_admin()
# Load the page
response = self.client.get(reverse("eighth_admin_view_open_passes"))
self.assertEqual(200, response.status_code)
# Make a student with a pass
today = timezone.localtime().date()
block = EighthBlock.objects.get_or_create(date=today, block_letter="A")[0]
activity = EighthActivity.objects.get_or_create(name="Test Activity")[0]
scheduled = EighthScheduledActivity.objects.get_or_create(block=block, activity=activity, attendance_taken=True)[0]
user = get_user_model().objects.get_or_create(
username="2021awilliam", graduation_year=get_senior_graduation_year(), user_type="student", last_name="William"
)[0]
signup = EighthSignup.objects.create(user=user, scheduled_activity=scheduled, after_deadline=True)
# Accept the pass
response = self.client.post(reverse("eighth_admin_view_open_passes"), data={signup.id: "accept"})
self.assertEqual(200, response.status_code)
self.assertTrue(EighthSignup.objects.get(id=signup.id).pass_accepted)
self.assertFalse(EighthSignup.objects.get(id=signup.id).was_absent)
# Now, reject the pass
response = self.client.post(reverse("eighth_admin_view_open_passes"), data={signup.id: "reject"})
self.assertEqual(200, response.status_code)
self.assertTrue(EighthSignup.objects.get(id=signup.id).pass_accepted)
self.assertTrue(EighthSignup.objects.get(id=signup.id).was_absent)
# Test the CSV view
# but first, reset the pass
signup = EighthSignup.objects.get(id=signup.id)
signup.pass_accepted = False
signup.was_absent = False
signup.save()
response = self.client.get(reverse("eighth_admin_view_open_passes_csv"))
self.assertEqual(200, response.status_code)
reader = csv.DictReader(response.content.decode("UTF-8").split("\n"))
reader_contents = list(reader)
self.assertEqual(1, len(reader_contents))
self.assertEqual("0", reader_contents[0]["Absences"])