From f91e7d5313f453714e6e9b644b164ecacf1e48f0 Mon Sep 17 00:00:00 2001 From: Ethan Nguyen Date: Tue, 20 Apr 2021 14:28:19 -0400 Subject: [PATCH] test: add test skeleton and profile app tests --- tjdests/apps/profile/tests.py | 543 ++++++++++++++++++++++++++++++++++ tjdests/test.py | 38 +++ 2 files changed, 581 insertions(+) create mode 100644 tjdests/apps/profile/tests.py create mode 100644 tjdests/test.py diff --git a/tjdests/apps/profile/tests.py b/tjdests/apps/profile/tests.py new file mode 100644 index 0000000..b3dcc43 --- /dev/null +++ b/tjdests/apps/profile/tests.py @@ -0,0 +1,543 @@ +from django.urls import reverse + +from tjdests.apps.authentication.models import User +from tjdests.apps.destinations.models import College, Decision, TestScore +from tjdests.test import TJDestsTestCase + + +class ProfileTest(TJDestsTestCase): + """Tests for the Profile app.""" + + def test_profile_view(self): + """Tests views.profile_view.""" + + # Test as an unauthenticated user. + response = self.client.get(reverse("profile:index")) + self.assertEqual(302, response.status_code) + self.assertEqual( + reverse("authentication:login") + f"?next={reverse('profile:index')}", + response.url, + ) + + # Test as a user that hasn't accepted TOS. + self.login(accept_tos=False, make_student=True) + response = self.client.get(reverse("profile:index")) + self.assertEqual(302, response.status_code) + self.assertEqual(reverse("authentication:tos"), response.url) + + # Test as a user that has accepted TOS + user = self.login(accept_tos=True, make_student=True) + response = self.client.get(reverse("profile:index")) + self.assertEqual(200, response.status_code) + + # POST submit the profile form + response = self.client.post( + reverse("profile:index"), + data={ + "biography": "hello", + "attending_decision": "", + "publish_data": False, + }, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 1, + User.objects.filter( + id=user.id, + biography="hello", + attending_decision=None, + publish_data=False, + ).count(), + ) + + # Test creating an admitted decision, then setting that as our destination. + college = College.objects.get_or_create(name="test college")[0] + decision = Decision.objects.get_or_create( + college=college, user=user, decision_type="ED", admission_status="ADMIT" + )[0] + + response = self.client.post( + reverse("profile:index"), + data={ + "biography": "hello2", + "attending_decision": decision.id, + "publish_data": True, + }, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 1, + User.objects.filter( + id=user.id, + biography="hello2", + attending_decision=decision, + publish_data=True, + ).count(), + ) + + def test_testscore_create(self): + """Tests creating test scores.""" + + # Load the page to create a test score + # First, test seniors only + self.login(accept_tos=True, make_student=True) + response = self.client.get(reverse("profile:testscores_add")) + self.assertEqual(403, response.status_code) + + user = self.login(accept_tos=True, make_student=True, make_senior=True) + response = self.client.get(reverse("profile:testscores_add")) + self.assertEqual(200, response.status_code) + + # POST and create a test score + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT_TOTAL", "exam_score": 1600}, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + user=user, exam_type="SAT_TOTAL", exam_score=1600 + ).count(), + ) + + # Test invalid (and valid) test scores + # Invalid SAT > 1600 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT_TOTAL", "exam_score": 1700}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="SAT_TOTAL", exam_score=1700 + ).count(), + ) + + # Invalid SAT, doesn't mod 10 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT_TOTAL", "exam_score": 1543}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="SAT_TOTAL", exam_score=1543 + ).count(), + ) + + # Valid ACT + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "ACT_COMP", "exam_score": 5}, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + user=user, exam_type="ACT_COMP", exam_score=5 + ).count(), + ) + + # Invalid ACT, > 36 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "ACT_COMP", "exam_score": 37}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="ACT_COMP", exam_score=37 + ).count(), + ) + + # Invalid ACT, not an integer + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "ACT_COMP", "exam_score": 3.6}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="ACT_COMP", exam_score=3.6 + ).count(), + ) + + # Valid SAT2 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT2_MATH2", "exam_score": 300}, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + user=user, exam_type="SAT2_MATH2", exam_score=300 + ).count(), + ) + + # Invalid SAT2, <200 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT2_MATH2", "exam_score": 100}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="SAT2_MATH2", exam_score=100 + ).count(), + ) + + # Invalid SAT2, doesn't mod 10 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "SAT2_MATH2", "exam_score": 243}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="SAT2_MATH2", exam_score=243 + ).count(), + ) + + # Valid AP + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "AP_CSA", "exam_score": 5}, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + user=user, exam_type="AP_CSA", exam_score=5 + ).count(), + ) + + # Invalid AP, <1 + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "AP_CSA", "exam_score": 0}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="AP_CSA", exam_score=0 + ).count(), + ) + + # Invalid AP, not an integer + response = self.client.post( + reverse("profile:testscores_add"), + data={"exam_type": "AP_CSA", "exam_score": 3.6}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 0, + TestScore.objects.filter( + user=user, exam_type="AP_CSA", exam_score=3.6 + ).count(), + ) + + def test_testscore_update(self): + """Tests the view to update testscores.""" + + user = self.login(make_senior=True, make_student=True, accept_tos=True) + + # Create a test score + testscore = TestScore.objects.get_or_create( + user=user, exam_type="AP_CSA", exam_score=5 + )[0] + + # Load the page to edit it + response = self.client.get( + reverse("profile:testscores_edit", kwargs={"pk": testscore.id}) + ) + self.assertEqual(200, response.status_code) + + # Logging in as someone else should 404 + self.login( + username="2021awilliam", + make_student=True, + make_senior=True, + accept_tos=True, + ) + response = self.client.get( + reverse("profile:testscores_edit", kwargs={"pk": testscore.id}) + ) + self.assertEqual(404, response.status_code) + + self.login(make_senior=True, make_student=True, accept_tos=True) + + # Change the score to a 4 + response = self.client.post( + reverse("profile:testscores_edit", kwargs={"pk": testscore.id}), + data={"exam_type": "AP_CSA", "exam_score": 4}, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + id=testscore.id, exam_type="AP_CSA", exam_score=4 + ).count(), + ) + self.assertEqual( + 0, + TestScore.objects.filter( + id=testscore.id, exam_type="AP_CSA", exam_score=5 + ).count(), + ) + + # Test invalid score + response = self.client.post( + reverse("profile:testscores_edit", kwargs={"pk": testscore.id}), + data={"exam_type": "AP_CSA", "exam_score": 6}, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 1, + TestScore.objects.filter( + id=testscore.id, exam_type="AP_CSA", exam_score=4 + ).count(), + ) + self.assertEqual( + 0, + TestScore.objects.filter( + id=testscore.id, exam_type="AP_CSA", exam_score=6 + ).count(), + ) + + def test_testscore_delete(self): + """Tests the view to delete testscores.""" + + user = self.login(make_senior=True, make_student=True, accept_tos=True) + + # Create a test score + testscore = TestScore.objects.get_or_create( + user=user, exam_type="AP_CSA", exam_score=5 + )[0] + + # Load the page to delete it + response = self.client.get( + reverse("profile:testscores_delete", kwargs={"pk": testscore.id}) + ) + self.assertEqual(200, response.status_code) + + # Logging in as someone else should 404 + self.login( + username="2021awilliam", + make_student=True, + make_senior=True, + accept_tos=True, + ) + response = self.client.get( + reverse("profile:testscores_delete", kwargs={"pk": testscore.id}) + ) + self.assertEqual(404, response.status_code) + + self.login(make_senior=True, make_student=True, accept_tos=True) + + # Delete it + response = self.client.post( + reverse("profile:testscores_delete", kwargs={"pk": testscore.id}) + ) + self.assertEqual(302, response.status_code) + self.assertEqual(0, TestScore.objects.filter(id=testscore.id).count()) + + def test_decision_create(self): + """Tests the view to create decisions.""" + + user = self.login(make_senior=True, make_student=True, accept_tos=True) + + # Create a college. + college = College.objects.get_or_create(name="test college")[0] + + # Load the page + response = self.client.get(reverse("profile:decision_add")) + self.assertEqual(200, response.status_code) + + # Clear any decisions present + Decision.objects.all().delete() + + # Add the decision + response = self.client.post( + reverse("profile:decision_add"), + data={ + "college": college.id, + "decision_type": "RL", # rolling + "admission_status": "ADMIT", + }, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + Decision.objects.filter( + college=college, + user=user, + decision_type=Decision.ROLLING, + admission_status=Decision.ADMIT, + ).count(), + ) + + # Adding another decision of this college should not work + response = self.client.post( + reverse("profile:decision_add"), + data={ + "college": college.id, + "decision_type": "RD", + "admission_status": "WAITLIST", + }, + ) + self.assertEqual(200, response.status_code) + self.assertEqual(1, Decision.objects.filter(college=college, user=user).count()) + + def test_decision_update(self): + user = self.login(make_senior=True, make_student=True, accept_tos=True) + + # Create a college. + college = College.objects.get_or_create(name="test college")[0] + + # Clear any decisions present + Decision.objects.all().delete() + + # Create a decision + decision = Decision.objects.get_or_create( + college=college, user=user, decision_type="ED", admission_status="ADMIT" + )[0] + + # Load the update page + response = self.client.get( + reverse("profile:decision_edit", kwargs={"pk": decision.id}) + ) + self.assertEqual(200, response.status_code) + + # Logging in as someone else should 404 + self.login( + username="2021awilliam", + make_student=True, + make_senior=True, + accept_tos=True, + ) + response = self.client.get( + reverse("profile:decision_edit", kwargs={"pk": decision.id}) + ) + self.assertEqual(404, response.status_code) + + self.login(make_senior=True, make_student=True, accept_tos=True) + + # Make an update but don't change the college + response = self.client.post( + reverse("profile:decision_edit", kwargs={"pk": decision.id}), + data={ + "college": college.id, + "decision_type": "ED", + "admission_status": "DENY", + }, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + Decision.objects.filter( + college=college, + user=user, + decision_type="ED", + admission_status="DENY", + id=decision.id, + ).count(), + ) + self.assertEqual( + 0, + Decision.objects.filter( + college=college, user=user, decision_type="ED", admission_status="ADMIT" + ).count(), + ) + + # Change the college + college2 = College.objects.get_or_create(name="University of Test")[0] + response = self.client.post( + reverse("profile:decision_edit", kwargs={"pk": decision.id}), + data={ + "college": college2.id, + "decision_type": "ED", + "admission_status": "DENY", + }, + ) + self.assertEqual(302, response.status_code) + self.assertEqual( + 1, + Decision.objects.filter( + college=college2, + user=user, + decision_type="ED", + admission_status="DENY", + id=decision.id, + ).count(), + ) + self.assertEqual(0, Decision.objects.filter(college=college).count()) + + # Add a decision for college (not college2) + Decision.objects.get_or_create( + college=college, user=user, decision_type="ED", admission_status="ADMIT" + ) + + # Now, there are two decisions, one for college and one for college2 + # Try to edit the decision for college2 -> college + decision2 = Decision.objects.get(college=college2, user=user) + + response = self.client.post( + reverse("profile:decision_edit", kwargs={"pk": decision2.id}), + data={ + "college": college.id, + "decision_type": "ED", + "admission_status": "DENY", + }, + ) + self.assertEqual(200, response.status_code) + self.assertEqual( + 1, Decision.objects.filter(college=college2, user=user).count() + ) + self.assertEqual(1, Decision.objects.filter(college=college, user=user).count()) + + def test_decision_delete(self): + """Tests the view to delete a decision.""" + + user = self.login(make_senior=True, make_student=True, accept_tos=True) + + # Create a decision + college = College.objects.get_or_create(name="test college")[0] + decision = Decision.objects.get_or_create( + college=college, user=user, decision_type="ED", admission_status="ADMIT" + )[0] + + # Load the update page + response = self.client.get( + reverse("profile:decision_delete", kwargs={"pk": decision.id}) + ) + self.assertEqual(200, response.status_code) + + # Logging in as someone else should 404 + self.login( + username="2021awilliam", + make_student=True, + make_senior=True, + accept_tos=True, + ) + response = self.client.get( + reverse("profile:decision_delete", kwargs={"pk": decision.id}) + ) + self.assertEqual(404, response.status_code) + + self.login(make_senior=True, make_student=True, accept_tos=True) + + # Delete the decision + response = self.client.post( + reverse("profile:decision_delete", kwargs={"pk": decision.id}) + ) + self.assertEqual(302, response.status_code) + self.assertEqual(0, Decision.objects.filter(id=decision.id).count()) diff --git a/tjdests/test.py b/tjdests/test.py new file mode 100644 index 0000000..d4a669c --- /dev/null +++ b/tjdests/test.py @@ -0,0 +1,38 @@ +from django.test import TestCase + +from tjdests.apps.authentication.models import User + + +class TJDestsTestCase(TestCase): + def login( # pylint: disable=too-many-arguments + self, + username: str = "awilliam", + accept_tos: bool = False, + make_student: bool = False, + make_senior: bool = False, + make_superuser: bool = False, + ) -> User: + """ + Log in as the specified user. + + Args: + username: The username to log in as. + accept_tos: Whether to accept the terms or not. + make_student: Whether to make this user a student. + make_senior: Whether to make this user a senior. + make_superuser: Whether to make this user a superuser. + Return: + The user. + """ + user = User.objects.update_or_create( + username=username, + defaults={ + "is_student": make_student, + "is_staff": make_superuser, + "is_superuser": make_superuser, + "is_senior": make_senior, + "accepted_terms": accept_tos, + }, + )[0] + self.client.force_login(user) + return user