Source code for intranet.apps.api.tests

import datetime
import json
import urllib.parse

from django.conf import settings
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from oauth2_provider.models import AccessToken, get_application_model
from oauth2_provider.settings import oauth2_settings

from ...test.ion_test import IonTestCase
from ...utils.date import get_senior_graduation_year
from ..bus.models import Route
from ..eighth.models import EighthActivity, EighthBlock, EighthRoom, EighthScheduledActivity, EighthSignup
from ..schedule.models import Block, Day, DayType, Time

Application = get_application_model()


[docs]class ApiTest(IonTestCase): """Tests for the api module."""
[docs] def setUp(self): self.user = get_user_model().objects.get_or_create(username="awilliam", graduation_year=get_senior_graduation_year() + 1)[0] self.application = Application( name="Test Application", redirect_uris="http://localhost http://example.com http://example.it", user=self.user, client_type=Application.CLIENT_CONFIDENTIAL, authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE, ) self.application.save() self.client_credentials_application = Application( name="Test Client Credentials Application", redirect_uris="http://localhost http://example.com http://example.it", user=self.user, client_type=Application.CLIENT_CONFIDENTIAL, authorization_grant_type=Application.GRANT_CLIENT_CREDENTIALS, ) self.client_credentials_application.save() oauth2_settings._SCOPES = ["read", "write"] # pylint: disable=protected-access self.auth = None
[docs] def make_token(self): tok = AccessToken.objects.create( user=self.user, token="1234567890", application=self.application, scope="read write", expires=timezone.now() + datetime.timedelta(days=1) ) self.auth = f"Bearer {tok.token}"
[docs] def get_api_eighth_block_list(self, query=""): return self.client.get(reverse("api_eighth_block_list") + query, HTTP_AUTHORIZATION=self.auth)
[docs] def get_api_eighth_signup_list(self, query=""): return self.client.get(reverse("api_eighth_user_signup_list_myid") + query, HTTP_AUTHORIZATION=self.auth)
[docs] def test_get_emerg(self): response = self.client.get(reverse("api_emerg_status")) self.assertEqual(response.status_code, 200)
[docs] def test_get_profile(self): self.make_token() response = self.client.get(reverse("api_user_myprofile_detail"), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) response = self.client.get(reverse("api_user_profile_detail", args=[9001]), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 404)
[docs] def test_get_announcements(self): self.make_token() response = self.client.get(reverse("api_announcements_list_create"), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) response = self.client.get(reverse("api_announcements_detail", args=[9001]), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 404)
[docs] def test_oauth_read(self): self.make_token() response = self.client.get(reverse("api_announcements_list_create"), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) response = self.client.get(reverse("api_user_myprofile_detail"), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode()) self.assertEqual(parsed_response["id"], int(self.user.id)) self.assertEqual(parsed_response["ion_username"], self.user.username)
[docs] def test_oauth_write(self): self.make_admin() self.make_token() block = EighthBlock.objects.create(date=datetime.datetime(2015, 1, 1), block_letter="A") room = EighthRoom.objects.create(name="room1", capacity=1) act = EighthActivity.objects.create(name="Test Activity 1") act.rooms.add(room) schact1 = EighthScheduledActivity.objects.create(activity=act, block=block) response = self.client.post( reverse("api_eighth_user_signup_list_myid"), {"scheduled_activity": schact1.id, "use_scheduled_activity": True}, HTTP_AUTHORIZATION=self.auth, ) self.assertEqual(response.status_code, 201) self.assertEqual(schact1.members.count(), 1)
[docs] def test_oauth_client_credentials_read(self): tok = AccessToken.objects.create( user=self.user, token="1234567890", application=self.client_credentials_application, scope="read write", expires=timezone.now() + datetime.timedelta(days=1), ) auth = f"Bearer {tok.token}" # List announcements response = self.client.get(reverse("api_announcements_list_create"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List emergency status response = self.client.get(reverse("api_emerg_status"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List schedule response = self.client.get(reverse("api_schedule_day_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List activities response = self.client.get(reverse("api_eighth_activity_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List blocks response = self.client.get(reverse("api_eighth_block_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List specific block block = EighthBlock.objects.create(date=datetime.datetime(2015, 1, 1), block_letter="A") response = self.client.get(reverse("api_eighth_block_detail", kwargs={"pk": block.pk}), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) resp = json.loads(response.content.decode()) self.assertTrue("id" in resp) # Should be able to list profile response = self.client.get(reverse("api_user_myprofile_detail"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200)
[docs] def test_oauth_client_credentials_read_anonymous(self): tok = AccessToken.objects.create( user=None, token="1234567890", application=self.client_credentials_application, scope="read write", expires=timezone.now() + datetime.timedelta(days=1), ) auth = f"Bearer {tok.token}" # List announcements response = self.client.get(reverse("api_announcements_list_create"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List emergency status response = self.client.get(reverse("api_emerg_status"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List schedule response = self.client.get(reverse("api_schedule_day_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List activities response = self.client.get(reverse("api_eighth_activity_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List blocks response = self.client.get(reverse("api_eighth_block_list"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) # List specific block block = EighthBlock.objects.create(date=datetime.datetime(2015, 1, 1), block_letter="A") response = self.client.get(reverse("api_eighth_block_detail", kwargs={"pk": block.pk}), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 200) resp = json.loads(response.content.decode()) self.assertTrue("id" in resp) # Should not be able to list profile response = self.client.get(reverse("api_user_myprofile_detail"), HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 403)
[docs] def test_no_credentials_read(self): if "intranet.apps.api.authentication.ApiBasicAuthentication" in settings.REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]: status_code = 401 else: status_code = 403 # Announcements should only be available to logged in users response = self.client.get(reverse("api_announcements_list_create")) self.assertEqual(response.status_code, status_code) # Activity list should only be available to logged in users response = self.client.get(reverse("api_eighth_activity_list")) self.assertEqual(response.status_code, status_code) # Block list should only be available to logged in users response = self.client.get(reverse("api_eighth_block_list")) self.assertEqual(response.status_code, status_code)
[docs] def test_api_root(self): # Should be able to read API root without authentication response = self.client.get(reverse("api_root")) self.assertEqual(response.status_code, 200)
[docs] def test_api_schedule_detail(self): self.make_token() today = timezone.localdate() one_day = datetime.timedelta(days=1) Day.objects.filter(date__gte=today - one_day, date__lte=today + one_day).delete() no_school_type = DayType.objects.get_or_create(name="NO SCHOOL<br>", special=True)[0] Day.objects.create(date=today, day_type=no_school_type) test_day_type = DayType.objects.get_or_create(name="Test day")[0] test_day_type.blocks.add( Block.objects.create( name="Test period", start=Time.objects.create(hour=10, minute=0), end=Time.objects.create(hour=11, minute=0), order=1 ) ) Day.objects.create(date=today - one_day, day_type=test_day_type) date_str = (today - one_day).strftime("%Y-%m-%d") url = reverse("api_schedule_day_detail", kwargs={"date": date_str}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(urllib.parse.urlparse(response.json()["url"]).path, url) self.assertEqual(response.json()["date"], date_str) self.assertEqual(response.json()["day_type"]["name"], test_day_type.name) self.assertEqual(response.json()["day_type"]["special"], False) self.assertEqual(response.json()["day_type"]["blocks"], [{"order": 1, "name": "Test period", "start": "10:00", "end": "11:00"}]) for day in [today, today + one_day]: date_str = day.strftime("%Y-%m-%d") url = reverse("api_schedule_day_detail", kwargs={"date": date_str}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(urllib.parse.urlparse(response.json()["url"]).path, url) self.assertEqual(response.json()["date"], date_str) self.assertEqual(response.json()["day_type"]["name"], no_school_type.name) self.assertEqual(response.json()["day_type"]["special"], no_school_type.special) self.assertEqual(response.json()["day_type"]["blocks"], [])
[docs] def test_api_eighth_block_list(self): self.make_token() # Don't let blocks created in other tests contaminate these results EighthBlock.objects.all().delete() # List everything response = self.get_api_eighth_block_list() self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["results"], []) # Test a good date response = self.get_api_eighth_block_list("?date=2019-04-18") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["results"], []) # Test a bad date response = self.get_api_eighth_block_list("?date=2019-04-18bad") self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), ["Invalid format for date."]) # Test a good start date response = self.get_api_eighth_block_list("?start_date=2019-04-18") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["results"], []) # Test a bad start date response = self.get_api_eighth_block_list("?start_date=2019-04-18bad") self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), ["Invalid format for start_date."]) # Now let's add some data now = timezone.localtime(timezone.now()) block_old = EighthBlock.objects.create(date=(now - datetime.timedelta(days=370)).date(), block_letter="A") block_new = EighthBlock.objects.create(date=now.date(), block_letter="A") block_old_date_str = block_old.date.strftime("%Y-%m-%d") block_new_date_str = block_new.date.strftime("%Y-%m-%d") future_date_str = (block_new.date + datetime.timedelta(days=1)).strftime("%Y-%m-%d") # List everything response = self.get_api_eighth_block_list() self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 1) self.assertEqual(response.json()["results"][0]["id"], block_new.id) self.assertEqual(response.json()["results"][0]["date"], block_new_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block_new.block_letter) # Test a date with a block scheduled response = self.get_api_eighth_block_list("?date=" + block_new_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 1) self.assertEqual(response.json()["results"][0]["id"], block_new.id) self.assertEqual(response.json()["results"][0]["date"], block_new_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block_new.block_letter) # Test another date with a block scheduled response = self.get_api_eighth_block_list("?date=" + block_old_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 1) self.assertEqual(response.json()["results"][0]["id"], block_old.id) self.assertEqual(response.json()["results"][0]["date"], block_old_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block_old.block_letter) # Test a date with no blocks scheduled response = self.get_api_eighth_block_list("?date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["results"], []) # Test a start date with blocks scheduled response = self.get_api_eighth_block_list("?start_date=" + block_new_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 1) self.assertEqual(response.json()["results"][0]["id"], block_new.id) self.assertEqual(response.json()["results"][0]["date"], block_new_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block_new.block_letter) # Test an earlier start date response = self.get_api_eighth_block_list("?start_date=" + block_old_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 2) self.assertEqual(response.json()["results"][0]["id"], block_old.id) self.assertEqual(response.json()["results"][0]["date"], block_old_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block_old.block_letter) self.assertEqual(response.json()["results"][1]["id"], block_new.id) self.assertEqual(response.json()["results"][1]["date"], block_new_date_str) self.assertEqual(response.json()["results"][1]["block_letter"], block_new.block_letter) # Test a late start date response = self.get_api_eighth_block_list("?start_date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["results"], []) # Test that past blocks are shown if there are no upcoming blocks EighthBlock.objects.all().delete() block = EighthBlock.objects.create(date=(now - datetime.timedelta(days=1)).date(), block_letter="A") block_date_str = block.date.strftime("%Y-%m-%d") response = self.get_api_eighth_block_list("?date=" + block_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["results"]), 1) self.assertEqual(response.json()["results"][0]["id"], block.id) self.assertEqual(response.json()["results"][0]["date"], block_date_str) self.assertEqual(response.json()["results"][0]["block_letter"], block.block_letter)
[docs] def test_api_eighth_signup_list(self): self.make_token() # Don't let blocks created in other tests contaminate these results EighthBlock.objects.all().delete() act1 = EighthActivity.objects.create(name="Test Activity 1") act2 = EighthActivity.objects.create(name="Test Activity 2") # Check the list response = self.get_api_eighth_signup_list() self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a good date response = self.get_api_eighth_signup_list("?date=2019-04-18") self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a bad date response = self.get_api_eighth_signup_list("?date=2019-04-18bad") self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), ["Invalid format for date."]) # Test a good start date response = self.get_api_eighth_signup_list("?start_date=2019-04-18") self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a bad start date response = self.get_api_eighth_signup_list("?start_date=2019-04-18bad") self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), ["Invalid format for start_date."]) # Create some blocks now = timezone.localtime(timezone.now()) block1 = EighthBlock.objects.create(date=(now - datetime.timedelta(days=370)).date(), block_letter="A") schact1 = EighthScheduledActivity.objects.create(block=block1, activity=act1) block2 = EighthBlock.objects.create(date=now.date(), block_letter="A") schact2 = EighthScheduledActivity.objects.create(block=block2, activity=act2) block1_date_str = block1.date.strftime("%Y-%m-%d") block2_date_str = block2.date.strftime("%Y-%m-%d") future_date_str = (block2.date + datetime.timedelta(days=1)).strftime("%Y-%m-%d") # Check the list response = self.get_api_eighth_signup_list() self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Sign up sgn1 = EighthSignup.objects.create(user=self.user, scheduled_activity=schact1) # Check the list response = self.get_api_eighth_signup_list() self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a start date with an upcoming signup response = self.get_api_eighth_signup_list("?start_date=" + block1_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["id"], sgn1.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact1.id) self.assertEqual(response.json()[0]["block"]["id"], block1.id) self.assertEqual(response.json()[0]["activity"]["id"], act1.id) # Test a date with an upcoming signup response = self.get_api_eighth_signup_list("?date=" + block1_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["id"], sgn1.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact1.id) self.assertEqual(response.json()[0]["block"]["id"], block1.id) self.assertEqual(response.json()[0]["activity"]["id"], act1.id) # Test a start date with no upcoming signups response = self.get_api_eighth_signup_list("?start_date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a date with no signups response = self.get_api_eighth_signup_list("?date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Sign up for another block sgn2 = EighthSignup.objects.create(user=self.user, scheduled_activity=schact2) # Check the list response = self.get_api_eighth_signup_list() self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["id"], sgn2.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact2.id) self.assertEqual(response.json()[0]["block"]["id"], block2.id) self.assertEqual(response.json()[0]["activity"]["id"], act2.id) # Test a date with a signup response = self.get_api_eighth_signup_list("?date=" + block1_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["id"], sgn1.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact1.id) self.assertEqual(response.json()[0]["block"]["id"], block1.id) self.assertEqual(response.json()[0]["activity"]["id"], act1.id) # Test another date with a signup response = self.get_api_eighth_signup_list("?date=" + block2_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["id"], sgn2.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact2.id) self.assertEqual(response.json()[0]["block"]["id"], block2.id) self.assertEqual(response.json()[0]["activity"]["id"], act2.id) # Test a start date with two upcoming signups response = self.get_api_eighth_signup_list("?start_date=" + block1_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 2) self.assertEqual(response.json()[0]["id"], sgn1.id) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact1.id) self.assertEqual(response.json()[0]["block"]["id"], block1.id) self.assertEqual(response.json()[0]["activity"]["id"], act1.id) self.assertEqual(response.json()[1]["id"], sgn2.id) self.assertEqual(response.json()[1]["user"], self.user.id) self.assertEqual(response.json()[1]["scheduled_activity"], schact2.id) self.assertEqual(response.json()[1]["block"]["id"], block2.id) self.assertEqual(response.json()[1]["activity"]["id"], act2.id) # Test a start date with an upcoming signup response = self.get_api_eighth_signup_list("?start_date=" + block2_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) self.assertEqual(response.json()[0]["user"], self.user.id) self.assertEqual(response.json()[0]["scheduled_activity"], schact2.id) self.assertEqual(response.json()[0]["block"]["id"], block2.id) self.assertEqual(response.json()[0]["activity"]["id"], act2.id) # Test a start date with no upcoming signups response = self.get_api_eighth_signup_list("?start_date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) # Test a date with no signups response = self.get_api_eighth_signup_list("?date=" + future_date_str) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), [])
[docs] def test_api_bus_list(self): self.make_token() route = Route.objects.create(route_name="JT-01", bus_number="JT-01") response = self.client.get(reverse("api_bus_list"), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) results = response.json()["results"] self.assertEqual(len(results), 1) self.assertEqual(results, [{"id": route.id, "status": "o", "route_name": route.route_name, "bus_number": route.bus_number, "space": ""}])
[docs] def test_api_bus_detail(self): self.make_token() route_1 = Route.objects.create(route_name="JT-01", bus_number="JT-01") response = self.client.get(reverse("api_bus_detail", args=[route_1.pk]), HTTP_AUTHORIZATION=self.auth) self.assertEqual(response.status_code, 200) self.assertEqual( response.json(), {"id": route_1.id, "route_name": route_1.route_name, "space": "", "bus_number": route_1.bus_number, "status": "o"} )