From 2883ee0c042017ebc4e84ab11107933d713ee0a2 Mon Sep 17 00:00:00 2001
From: Ethan Nguyen <etnguyen03@hotmail.com>
Date: Tue, 20 Apr 2021 19:34:53 -0400
Subject: [PATCH] test(destinations): add destinations app tests

---
 tjdests/apps/destinations/tests.py | 299 +++++++++++++++++++++++++++++
 1 file changed, 299 insertions(+)
 create mode 100644 tjdests/apps/destinations/tests.py

diff --git a/tjdests/apps/destinations/tests.py b/tjdests/apps/destinations/tests.py
new file mode 100644
index 0000000..127a5ef
--- /dev/null
+++ b/tjdests/apps/destinations/tests.py
@@ -0,0 +1,299 @@
+from unittest.mock import mock_open, patch
+
+from django.core.management import CommandError, call_command
+from django.urls import reverse
+
+from ...test import TJDestsTestCase
+from .models import College, Decision
+
+
+class DestinationsTest(TJDestsTestCase):
+    """Tests the destinations app."""
+
+    def test_destinations_list(self):
+        """Tests the destinations list page."""
+        # Test as an unauthenticated user.
+        response = self.client.get(reverse("destinations:students"))
+        self.assertEqual(302, response.status_code)
+        self.assertEqual(
+            reverse("authentication:login")
+            + f"?next={reverse('destinations:students')}",
+            response.url,
+        )
+
+        self.login(make_student=True, accept_tos=True)
+
+        # Load the page
+        response = self.client.get(reverse("destinations:students"))
+        self.assertEqual(200, response.status_code)
+
+        # Make us a senior
+        user = self.login(make_student=True, make_senior=True, accept_tos=True)
+        user.publish_data = True
+        user.save()
+
+        # Add a destination
+        college = College.objects.get_or_create(name="test college")[0]
+        Decision.objects.get_or_create(
+            college=college, user=user, decision_type="ED", admission_status="ADMIT"
+        )
+
+        response = self.client.get(reverse("destinations:students"))
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertIn(college.name, response.content.decode("UTF-8"))
+        self.assertIn("ED", response.content.decode("UTF-8"))
+        self.assertIn("fa-check", response.content.decode("UTF-8"))
+
+        # Add another user, but add us a name first
+        user.first_name = "Angela"
+        user.last_name = "William"
+        user.save()
+
+        user2 = self.login(
+            make_student=True,
+            username="2021awilliam",
+            make_senior=True,
+            accept_tos=True,
+        )
+        user2.first_name = "Adam"
+        user2.last_name = "William"
+        user2.save()
+
+        college2 = College.objects.get_or_create(name="university of test")[0]
+        Decision.objects.get_or_create(
+            college=college2, user=user2, decision_type="ED", admission_status="DENY"
+        )
+
+        response = self.client.get(reverse("destinations:students"))
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertNotIn(
+            user2, response.context["object_list"]
+        )  # haven't published data
+
+        user2.publish_data = True
+        user2.save()
+
+        response = self.client.get(reverse("destinations:students"))
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertIn(user2, response.context["object_list"])
+
+        # Now, test searching
+        response = self.client.get(
+            reverse("destinations:students"), data={"q": "Angela"}
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertNotIn(user2, response.context["object_list"])
+
+        response = self.client.get(reverse("destinations:students"), data={"q": "Adam"})
+        self.assertEqual(200, response.status_code)
+        self.assertNotIn(user, response.context["object_list"])
+        self.assertIn(user2, response.context["object_list"])
+
+        response = self.client.get(
+            reverse("destinations:students"), data={"q": "William"}
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertIn(user2, response.context["object_list"])
+
+        # Test filtering by college
+        response = self.client.get(
+            reverse("destinations:students"), data={"college": college.id}
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertNotIn(user2, response.context["object_list"])
+
+        response = self.client.get(
+            reverse("destinations:students"), data={"college": college2.id}
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertNotIn(user, response.context["object_list"])
+        self.assertIn(user2, response.context["object_list"])
+
+        # nonexist should 404
+        response = self.client.get(
+            reverse("destinations:students"), data={"college": "9999"}
+        )
+        self.assertEqual(404, response.status_code)
+
+        # Test filtering with both at the same time
+        response = self.client.get(
+            reverse("destinations:students"),
+            data={"college": college.id, "q": "Angela"},
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertIn(user, response.context["object_list"])
+        self.assertNotIn(user2, response.context["object_list"])
+
+        response = self.client.get(
+            reverse("destinations:students"), data={"college": college.id, "q": "Adam"}
+        )
+        self.assertEqual(200, response.status_code)
+        self.assertNotIn(user, response.context["object_list"])
+        self.assertNotIn(user2, response.context["object_list"])
+
+    def test_colleges_list(self):
+        """Tests the view to list colleges."""
+
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(302, response.status_code)
+        self.assertEqual(
+            reverse("authentication:login")
+            + f"?next={reverse('destinations:colleges')}",
+            response.url,
+        )
+
+        user = self.login(make_student=True, accept_tos=True, make_senior=True)
+
+        # Delete all the decisions
+        Decision.objects.all().delete()
+        College.objects.all().delete()
+
+        # Load the page
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(0, response.context["object_list"].count())
+
+        # Add a decision, try again
+        college = College.objects.get_or_create(
+            name="test college", ceeb_code="1235", location="Arlington, VA"
+        )[0]
+        Decision.objects.get_or_create(
+            college=college, user=user, decision_type="ED", admission_status="ADMIT"
+        )
+
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(
+            0, response.context["object_list"].count()
+        )  # because data not public
+
+        user.publish_data = True
+        user.save()
+
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(1, response.context["object_list"].count())
+        self.assertIn(college, response.context["object_list"])
+        self.assertEqual(1, response.context["object_list"][0].count_decisions)
+        self.assertEqual(1, response.context["object_list"][0].count_admit)
+        self.assertEqual(0, response.context["object_list"][0].count_waitlist)
+        self.assertEqual(0, response.context["object_list"][0].count_waitlist_admit)
+        self.assertEqual(0, response.context["object_list"][0].count_waitlist_deny)
+        self.assertEqual(0, response.context["object_list"][0].count_defer)
+        self.assertEqual(0, response.context["object_list"][0].count_defer_admit)
+        self.assertEqual(0, response.context["object_list"][0].count_defer_deny)
+        self.assertEqual(0, response.context["object_list"][0].count_deny)
+
+        # Add another decision under a different user but the same college
+        user2 = self.login(
+            username="2021awilliam",
+            make_student=True,
+            accept_tos=True,
+            make_senior=True,
+            publish_data=True,
+        )
+        Decision.objects.get_or_create(
+            college=college,
+            user=user2,
+            decision_type="ED",
+            admission_status="WAITLIST_DENY",
+        )
+
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(1, response.context["object_list"].count())
+        self.assertIn(college, response.context["object_list"])
+        self.assertEqual(2, response.context["object_list"][0].count_decisions)
+        self.assertEqual(1, response.context["object_list"][0].count_admit)
+        self.assertEqual(0, response.context["object_list"][0].count_waitlist)
+        self.assertEqual(0, response.context["object_list"][0].count_waitlist_admit)
+        self.assertEqual(1, response.context["object_list"][0].count_waitlist_deny)
+        self.assertEqual(0, response.context["object_list"][0].count_defer)
+        self.assertEqual(0, response.context["object_list"][0].count_defer_admit)
+        self.assertEqual(0, response.context["object_list"][0].count_defer_deny)
+        self.assertEqual(0, response.context["object_list"][0].count_deny)
+
+        # Add another decision for user2 under a different college
+        college2 = College.objects.get_or_create(
+            name="university of test", ceeb_code="1234", location="Alexandria, VA"
+        )[0]
+        Decision.objects.get_or_create(
+            college=college2, user=user2, decision_type="RD", admission_status="DENY"
+        )
+
+        response = self.client.get(reverse("destinations:colleges"))
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(2, response.context["object_list"].count())
+
+        # Test filtering
+        response = self.client.get(reverse("destinations:colleges"), data={"q": "VA"})
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(2, response.context["object_list"].count())
+        self.assertIn(college, response.context["object_list"])
+        self.assertIn(college2, response.context["object_list"])
+
+        response = self.client.get(reverse("destinations:colleges"), data={"q": "1234"})
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(1, response.context["object_list"].count())
+        self.assertIn(college2, response.context["object_list"])
+
+    def test_import_ceeb_command(self):
+        # First, just call the command
+        with self.assertRaises(CommandError):
+            call_command("import_ceeb")
+
+        College.objects.all().delete()
+
+        file_contents = (
+            "CEEB,College Name,City,State\n"
+            "1234,Test University,Alexandria,VA\n"
+            "1235,University of Test,Arlington,VA"
+        )
+        with patch(
+            "tjdests.apps.destinations.management.commands.import_ceeb.open",
+            mock_open(read_data=file_contents),
+        ) as mock_obj:
+            call_command("import_ceeb", "foo.csv")
+
+        mock_obj.assert_called_with("foo.csv", "r")
+
+        self.assertEqual(
+            1,
+            College.objects.filter(
+                ceeb_code="1234", name="Test University", location="Alexandria, VA"
+            ).count(),
+        )
+        self.assertEqual(
+            1,
+            College.objects.filter(
+                ceeb_code="1235", name="University of Test", location="Arlington, VA"
+            ).count(),
+        )
+
+        # Doing it again should have no duplicates
+        with patch(
+            "tjdests.apps.destinations.management.commands.import_ceeb.open",
+            mock_open(read_data=file_contents),
+        ) as mock_obj:
+            call_command("import_ceeb", "foo.csv")
+
+        mock_obj.assert_called_with("foo.csv", "r")
+
+        self.assertEqual(
+            1,
+            College.objects.filter(
+                ceeb_code="1234", name="Test University", location="Alexandria, VA"
+            ).count(),
+        )
+        self.assertEqual(
+            1,
+            College.objects.filter(
+                ceeb_code="1235", name="University of Test", location="Arlington, VA"
+            ).count(),
+        )