import json
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from ...test.ion_test import IonTestCase
from ...utils.date import get_senior_graduation_year
from ..eighth.models import EighthActivity
from ..users.models import Group
from .models import Announcement, AnnouncementRequest
[docs]class AnnouncementTest(IonTestCase):
"""Tests for the announcements module."""
[docs] def setUp(self):
self.user = get_user_model().objects.get_or_create(
username="awilliam", graduation_year=get_senior_graduation_year() + 1, user_type="student"
)[0]
[docs] def test_get_announcements(self):
self.login()
response = self.client.get(reverse("view_announcements"))
self.assertEqual(response.status_code, 200)
# Add an announcement
announce = Announcement.objects.get_or_create(title="test8", content="test8")[0]
response = self.client.get(reverse("view_announcements"))
self.assertEqual(response.status_code, 200)
self.assertIn(announce.content, response.content.decode("UTF-8"))
response = self.client.get(reverse("view_announcement", args=[9001]))
self.assertEqual(response.status_code, 404)
[docs] def test_change_announcements(self):
self.login()
group = Group.objects.get_or_create(name="admin_all")[0]
get_user_model().objects.get_or_create(username="awilliam")[0].groups.add(group)
response = self.client.get(reverse("add_announcement"))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin_approve_announcement", args=[9001]))
self.assertEqual(response.status_code, 404)
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("approve_announcement", args=[9001]))
self.assertEqual(response.status_code, 404)
response = self.client.get(reverse("announcements_archive"))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("delete_announcement", args=[9001]))
self.assertEqual(response.status_code, 404)
response = self.client.post(reverse("hide_announcement"))
self.assertEqual(response.status_code, 404)
response = self.client.get(reverse("modify_announcement", args=[9001]))
self.assertEqual(response.status_code, 404)
response = self.client.get(reverse("request_announcement"))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("show_announcement"))
self.assertEqual(response.status_code, 404)
[docs] def test_announcement_approval_allowed_users(self):
"""Tests to ensure that only allowed users can approve announcements."""
teacher = get_user_model().objects.get_or_create(username="teacher", user_type="teacher", first_name="timmy", last_name="teacher")[0]
counselor = get_user_model().objects.get_or_create(username="counselor", user_type="counselor", first_name="c", last_name="c")[0]
user = get_user_model().objects.get_or_create(username="user", user_type="user", first_name="ursula", last_name="user")[0]
student = get_user_model().objects.get_or_create(username="3000student", user_type="student", first_name="s", last_name="tudent")[0]
self.assertEqual(list(get_user_model().objects.get_approve_announcements_users_sorted()), [counselor, teacher, user])
self.assertNotIn(student, get_user_model().objects.get_approve_announcements_users_sorted())
[docs] def test_announcement_request(self):
"""Tests the announcement request view."""
self.login()
response = self.client.get(reverse("request_announcement"))
self.assertEqual(response.status_code, 200)
teacher = get_user_model().objects.get_or_create(username="awilliam1", user_type="teacher", first_name="a", last_name="william")[0]
# Now, try to POST an announcement
response = self.client.post(
reverse("request_announcement"),
data={
"title": "This is a test!",
"author": "Sysadmins",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"expiration_date": "3000-01-01 00:00:00",
"teachers_requested": str(teacher.id),
"notes": "Enter something here!",
},
)
self.assertEqual(response.status_code, 302) # to "success" page
self.assertEqual(1, AnnouncementRequest.objects.count())
# See if that AnnouncementRequest appears
self.assertEqual(
AnnouncementRequest.objects.filter(
title="This is a test!",
author="Sysadmins",
content="Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
teachers_requested=teacher,
notes="Enter something here!",
).count(),
1,
)
[docs] def test_request_announcement_success_view(self):
self.login()
response = self.client.get(reverse("request_announcement_success"))
self.assertEqual(200, response.status_code)
[docs] def test_request_announcement_success_self_view(self):
self.login()
response = self.client.get(reverse("request_announcement_success_self"))
self.assertEqual(200, response.status_code)
self.assertTrue(response.context["self"])
[docs] def test_approve_announcement_view(self):
teacher = get_user_model().objects.get_or_create(username="awilliam1", user_type="teacher", first_name="a", last_name="william")[0]
user = self.login()
request = AnnouncementRequest.objects.create(title="test", content="hello", author="Sysadmins", user=user)
self.login("awilliam1")
# The user is not in the "requested_teachers" list, so this should 302 to the index page
response = self.client.get(reverse("approve_announcement", kwargs={"req_id": request.id}))
self.assertEqual(302, response.status_code)
response = self.client.get(reverse("approve_announcement", kwargs={"req_id": request.id}), follow=True)
self.assertEqual(200, response.status_code)
self.assertIn("You do not have permission to approve this announcement.", list(map(str, list(response.context["messages"]))))
request.teachers_requested.add(teacher)
request.save()
# This should now just 200
response = self.client.get(reverse("approve_announcement", kwargs={"req_id": request.id}))
self.assertEqual(200, response.status_code)
self.assertNotIn("You do not have permission to approve this announcement.", list(map(str, list(response.context["messages"]))))
# Don't approve this announcement
response = self.client.post(
reverse("approve_announcement", kwargs={"req_id": request.id}),
data={
"title": "test",
"content": "hello",
"author": "test sysadmins",
"expiration_date": "3000-01-01",
"user": request.user.id,
"teachers_requested": teacher.id,
"reject": "Reject Announcement",
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual("reject", response.context.get("status"))
# Now, approve this announcement
response = self.client.post(
reverse("approve_announcement", kwargs={"req_id": request.id}),
data={
"title": "test",
"content": "hello",
"author": "test sysadmins",
"user": request.user.id,
"teachers_requested": teacher.id,
"approve": "approve",
"notify_post": "1",
"expiration_date": "3000-01-01",
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual("accept", response.context.get("status"))
self.assertEqual(1, AnnouncementRequest.objects.filter(title="test", content="hello", teachers_approved=teacher).count())
[docs] def test_admin_approve_announcement_view(self):
teacher = get_user_model().objects.get_or_create(username="awilliam1", user_type="teacher", first_name="a", last_name="william")[0]
user = self.make_admin()
# Create an AnnouncementRequest.
announce_request = AnnouncementRequest.objects.get_or_create(title="test", content="hello", user=user)[0]
announce_request.teachers_requested.add(teacher)
announce_request.save()
# Load the page.
response = self.client.get(reverse("admin_approve_announcement", kwargs={"req_id": announce_request.id}))
self.assertEqual(200, response.status_code)
# Reject the announcement.
response = self.client.post(
reverse("admin_approve_announcement", kwargs={"req_id": announce_request.id}),
data={
"title": "test",
"content": "hello",
"author": "test sysadmins",
"user": announce_request.user.id,
"teachers_requested": teacher.id,
"expiration_date": "3000-01-01",
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertTrue(AnnouncementRequest.objects.get(title="test", content="hello").rejected)
# Accept the announcement now
response = self.client.post(
reverse("admin_approve_announcement", kwargs={"req_id": announce_request.id}),
data={
"title": "test",
"content": "hello",
"author": "test sysadmins",
"user": announce_request.user.id,
"teachers_requested": teacher.id,
"expiration_date": "3000-01-01",
"approve": "approve",
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual(1, Announcement.objects.filter(title="test", content="hello").count())
# Do another announcement, but restrict posting to a group this time
group = Group.objects.create(name="test_group")
user.groups.add(group)
user.save()
announce_request2 = AnnouncementRequest.objects.get_or_create(title="test", content="hello", user=user)[0]
announce_request2.teachers_requested.add(teacher)
announce_request2.save()
response = self.client.post(
reverse("admin_approve_announcement", kwargs={"req_id": announce_request2.id}),
data={
"title": "test2",
"content": "hello",
"author": "test sysadmins",
"user": announce_request2.user.id,
"teachers_requested": teacher.id,
"expiration_date": "3000-01-01",
"approve": "approve",
"groups": group.id,
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual(1, Announcement.objects.filter(title="test2", content="hello", groups=group).count())
[docs] def test_admin_request_status_view(self):
# Delete all the AnnouncementRequests to ensure that nothing interferes with this
AnnouncementRequest.objects.all().delete()
user = self.make_admin()
# Load the page.
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(200, response.status_code)
self.assertEqual(0, len(response.context["awaiting_teacher"]))
self.assertEqual(0, len(response.context["awaiting_approval"]))
self.assertEqual(0, len(response.context["approved"]))
self.assertEqual(0, len(response.context["rejected"]))
# Add an AnnouncementRequest
announce_request = AnnouncementRequest.objects.get_or_create(title="test", content="hello")[0]
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(200, response.status_code)
self.assertEqual(1, len(response.context["awaiting_teacher"]))
self.assertEqual(0, len(response.context["awaiting_approval"]))
self.assertEqual(0, len(response.context["approved"]))
self.assertEqual(0, len(response.context["rejected"]))
# "Approve" the announcement
announce_request.teachers_approved.add(user)
announce_request.save()
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(200, response.status_code)
self.assertEqual(0, len(response.context["awaiting_teacher"]))
self.assertEqual(1, len(response.context["awaiting_approval"]))
self.assertEqual(0, len(response.context["approved"]))
self.assertEqual(0, len(response.context["rejected"]))
# Reject the announcement
announce_request.rejected = True
announce_request.save()
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(200, response.status_code)
self.assertEqual(0, len(response.context["awaiting_teacher"]))
self.assertEqual(0, len(response.context["awaiting_approval"]))
self.assertEqual(0, len(response.context["approved"]))
self.assertEqual(1, len(response.context["rejected"]))
# Post the announcement
announce = Announcement.objects.get_or_create(title="test", content="hello")[0]
announce_request.posted = announce
announce_request.rejected = False
announce_request.save()
response = self.client.get(reverse("admin_request_status"))
self.assertEqual(200, response.status_code)
self.assertEqual(0, len(response.context["awaiting_teacher"]))
self.assertEqual(0, len(response.context["awaiting_approval"]))
self.assertEqual(1, len(response.context["approved"]))
self.assertEqual(0, len(response.context["rejected"]))
[docs] def test_add_announcement_view(self):
self.make_admin()
# Load the add page
response = self.client.get(reverse("add_announcement"))
self.assertEqual(200, response.status_code)
# Post an announcement
response = self.client.post(
reverse("add_announcement"),
data={
"title": "test3",
"content": "hello3",
"author": "test sysadmins",
"expiration_date": "3000-01-01",
"notify_post": True,
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual(1, Announcement.objects.filter(title="test3", content="hello3").count())
# Do it again, but check the "notify all" box
response = self.client.post(
reverse("add_announcement"),
data={
"title": "test4",
"content": "hello3",
"author": "test sysadmins",
"expiration_date": "3000-01-01",
"notify_post": True,
"notify_email_all": True,
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual(1, Announcement.objects.filter(title="test4", content="hello3").count())
[docs] def test_view_announcement_view(self):
self.login()
# Add an announcement
announce = Announcement.objects.get_or_create(title="test4", content="test4")[0]
# Load the page
response = self.client.get(reverse("view_announcement", kwargs={"announcement_id": announce.id}))
self.assertEqual(200, response.status_code)
self.assertIn("test4", response.content.decode("UTF-8"))
[docs] def test_modify_announcement_view(self):
self.make_admin()
# Add an announcement
announce = Announcement.objects.get_or_create(title="test5", content="test5")[0]
# Load the page
response = self.client.get(reverse("modify_announcement", kwargs={"announcement_id": announce.id}))
self.assertEqual(200, response.status_code)
self.assertIn("test5", response.content.decode("UTF-8"))
# Modify the announcement
response = self.client.post(
reverse("modify_announcement", kwargs={"announcement_id": announce.id}),
data={
"title": "test5-1",
"content": "hello3there",
"author": "test sysadmins2",
"expiration_date": "3000-01-01",
},
follow=True,
)
self.assertEqual(200, response.status_code)
self.assertEqual(1, Announcement.objects.filter(title="test5-1", content="hello3there", author="test sysadmins2", id=announce.id).count())
[docs] def test_delete_announcement_view(self):
self.make_admin()
# Add an announcement
announce = Announcement.objects.get_or_create(title="test6", content="test6")[0]
# Load the page
response = self.client.get(reverse("delete_announcement", kwargs={"announcement_id": announce.id}))
self.assertEqual(200, response.status_code)
self.assertEqual(announce, response.context["announcement"])
# Test expiring the announcement
response = self.client.post(reverse("delete_announcement", kwargs={"announcement_id": announce.id}), data={"id": announce.id}, follow=True)
self.assertEqual(200, response.status_code)
self.assertLess(Announcement.objects.get(id=announce.id).expiration_date, timezone.localtime())
# Test a full delete
response = self.client.post(
reverse("delete_announcement", kwargs={"announcement_id": announce.id}), data={"id": announce.id, "full_delete": True}, follow=True
)
self.assertEqual(200, response.status_code)
self.assertEqual(0, Announcement.objects.filter(id=announce.id).count())
[docs] def test_show_announcement_view(self):
# Add an announcement
announce = Announcement.objects.get_or_create(title="test7", content="test7")[0]
# Hide that announcement
user = self.login()
announce.user_map.users_hidden.add(user)
announce.user_map.save()
# Sanity check
assert announce in Announcement.objects.hidden_announcements(user)
# Show that announcement again
response = self.client.post(reverse("show_announcement"), data={"announcement_id": announce.id})
self.assertEqual(200, response.status_code)
self.assertNotIn(announce, Announcement.objects.hidden_announcements(user))
# Check that GET returns 405
response = self.client.get(reverse("show_announcement"))
self.assertEqual(405, response.status_code)
[docs] def test_hide_announcement_view(self):
# Add an announcement
announce = Announcement.objects.get_or_create(title="test8", content="test8")[0]
# Hide that announcement
user = self.login()
response = self.client.post(reverse("hide_announcement"), data={"announcement_id": announce.id})
self.assertEqual(200, response.status_code)
self.assertIn(announce, Announcement.objects.hidden_announcements(user))
# Check that GET returns 405
response = self.client.get(reverse("hide_announcement"))
self.assertEqual(405, response.status_code)
[docs] def test_modify_club_announcement(self):
self.make_admin()
act = EighthActivity.objects.get_or_create(name="test")[0]
announce = Announcement.objects.get_or_create(title="test9", content="test9", activity=act)[0]
self.client.post(
reverse("modify_club_announcement", args=[announce.id]),
{"title": "hi", "content": "bye", "expiration_date": "3000-01-01"},
)
announce.refresh_from_db()
self.assertEqual(act, announce.activity)
[docs]class ApiTest(IonTestCase):
[docs] def test_api_announcements_list(self):
# First, just test loading an empty list
self.login()
response = self.client.get(reverse("api_announcements_list_create"), data={"format": "json"})
self.assertEqual(200, response.status_code)
response_json = json.loads(response.content.decode("UTF-8"))
self.assertEqual(0, len(response_json["results"]))
# Add an announcement
announce = Announcement.objects.get_or_create(title="test9", content="test9")[0]
response = self.client.get(reverse("api_announcements_list_create"), data={"format": "json"})
self.assertEqual(200, response.status_code)
response_json = json.loads(response.content.decode("UTF-8"))
self.assertEqual(1, len(response_json["results"]))
self.assertEqual(announce.title, response_json["results"][0]["title"])
[docs] def test_api_announcements_detail(self):
self.login()
# Add an announcement
announce = Announcement.objects.get_or_create(title="test9", content="test9")[0]
response = self.client.get(reverse("api_announcements_detail", kwargs={"pk": announce.id}), data={"format": "json"})
self.assertEqual(200, response.status_code)
response_json = json.loads(response.content.decode("UTF-8"))
self.assertEqual(announce.title, response_json["title"])