Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mureytasroc committed Oct 27, 2023
1 parent c388600 commit 6892e3b
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 27 deletions.
37 changes: 17 additions & 20 deletions backend/plan/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from ics.grammar.parse import ContentLine
from rest_framework import status, viewsets
from rest_framework.decorators import api_view, permission_classes, schema
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
Expand Down Expand Up @@ -398,6 +399,20 @@ def check_semester(data, sections):
status=status.HTTP_400_BAD_REQUEST,
)

def validate_name(self, request, existing_schedule=None):
if PATH_REGISTRATION_SCHEDULE_NAME in [
request.data.get("name"),
existing_schedule and existing_schedule.name,
] and not isinstance(request.successful_authenticator, PlatformAuthentication):
raise PermissionDenied(
"You cannot create/update/delete a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME
)

def destroy(self, request, *args, **kwargs):
self.validate_name(request, existing_schedule=self.get_object())
return super().destroy(request, *args, **kwargs)

def update(self, request, pk=None):
if not pk or not Schedule.objects.filter(id=pk).exists():
return Response({"detail": "Not found."}, status=status.HTTP_404_NOT_FOUND)
Expand All @@ -409,16 +424,7 @@ def update(self, request, pk=None):
status=status.HTTP_403_FORBIDDEN,
)

if request.name == PATH_REGISTRATION_SCHEDULE_NAME and not isinstance(
request.successful_authenticator, PlatformAuthentication
):
return Response(
{
"detail": f"You cannot update a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME
},
status=status.HTTP_403_FORBIDDEN,
)
self.validate_name(request, existing_schedule=schedule)

try:
sections = self.get_sections(request.data)
Expand Down Expand Up @@ -452,16 +458,7 @@ def create(self, request, *args, **kwargs):
if Schedule.objects.filter(id=request.data.get("id")).exists():
return self.update(request, request.data.get("id"))

if request.name == PATH_REGISTRATION_SCHEDULE_NAME and not isinstance(
request.successful_authenticator, PlatformAuthentication
):
return Response(
{
"detail": f"You cannot create a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME
},
status=status.HTTP_403_FORBIDDEN,
)
self.validate_name(request)

try:
sections = self.get_sections(request.data)
Expand Down
64 changes: 64 additions & 0 deletions backend/tests/plan/test_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from alert.models import AddDropPeriod
from courses.util import get_average_reviews, invalidate_current_semester_cache
from PennCourses.settings.base import PATH_REGISTRATION_SCHEDULE_NAME
from plan.models import Schedule
from tests.courses.util import create_mock_data_with_reviews

Expand Down Expand Up @@ -684,3 +685,66 @@ def test_update_schedule_no_semester_no_courses(self):
self.assertEqual(response.data["name"], "New Test Schedule")
self.assertEqual(response.data["semester"], TEST_SEMESTER)
self.assertEqual(len(response.data["sections"]), 0)

def test_create_path_registration_schedule_403(self):
response = self.client.post(
"/api/plan/schedules/",
json.dumps(
{
"semester": TEST_SEMESTER,
"name": PATH_REGISTRATION_SCHEDULE_NAME,
"sections": [
{"id": "CIS-121-001", "semester": TEST_SEMESTER},
{"id": "CIS-160-001", "semester": TEST_SEMESTER},
],
}
),
content_type="application/json",
)
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.data["detail"],
"You cannot create/update/delete a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME,
)

def test_update_to_path_registration_schedule_403(self):
response = self.client.put(
f"/api/plan/schedules/{self.s.id}/",
json.dumps({"name": PATH_REGISTRATION_SCHEDULE_NAME, "sections": []}),
content_type="application/json",
)
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.data["detail"],
"You cannot create/update/delete a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME,
)

def test_update_from_path_registration_schedule_403(self):
path_schedule = Schedule.objects.create(
name=PATH_REGISTRATION_SCHEDULE_NAME, person=self.s.person, semester=TEST_SEMESTER
)
response = self.client.put(
f"/api/plan/schedules/{path_schedule.id}/",
json.dumps({"name": "Not Path Registration", "sections": []}),
content_type="application/json",
)
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.data["detail"],
"You cannot create/update/delete a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME,
)

def test_delete_path_registration_schedule_403(self):
path_schedule = Schedule.objects.create(
name=PATH_REGISTRATION_SCHEDULE_NAME, person=self.s.person, semester=TEST_SEMESTER
)
response = self.client.delete(f"/api/plan/schedules/{path_schedule.id}/")
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.data["detail"],
"You cannot create/update/delete a schedule with the name "
+ PATH_REGISTRATION_SCHEDULE_NAME,
)
16 changes: 9 additions & 7 deletions frontend/plan/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,14 @@ function buildCourseSearchUrl(filterData) {
if (
filterData[filterFields[i]] &&
JSON.stringify(filterData[filterFields[i]]) !==
JSON.stringify(defaultFilters[i])
JSON.stringify(defaultFilters[i])
) {
const filterRange = filterData[filterFields[i]];
if (filterFields[i] === "time") {
const start = decimalToTime(24 - filterRange[1]);
const end = decimalToTime(24 - filterRange[0]);
queryString += `&${filterFields[i]}=${
start === 7 ? "" : start
}-${end === 10.3 ? "" : end}`;
queryString += `&${filterFields[i]}=${start === 7 ? "" : start
}-${end === 10.3 ? "" : end}`;
} else {
queryString += `&${filterFields[i]}=${filterRange[0]}-${filterRange[1]}`;
}
Expand Down Expand Up @@ -305,7 +304,7 @@ function buildCourseSearchUrl(filterData) {
if (
filterData[checkboxFields[i]] &&
JSON.stringify(filterData[checkboxFields[i]]) !==
JSON.stringify(checkboxDefaultFields[i])
JSON.stringify(checkboxDefaultFields[i])
) {
const applied = [];
Object.keys(filterData[checkboxFields[i]]).forEach((item) => {
Expand Down Expand Up @@ -336,7 +335,7 @@ function buildCourseSearchUrl(filterData) {
if (
filterData[buttonFields[i]] &&
JSON.stringify(filterData[buttonFields[i]]) !==
JSON.stringify(buttonDefaultFields[i])
JSON.stringify(buttonDefaultFields[i])
) {
// get each filter's value
const applied = filterData[buttonFields[i]];
Expand Down Expand Up @@ -582,7 +581,7 @@ export const updateScheduleOnBackend = (name, schedule) => (dispatch) => {
dispatch(markScheduleSynced(name));
}
})
.catch(() => {});
.catch(() => { });
};

export function fetchSectionInfo(searchData) {
Expand Down Expand Up @@ -642,6 +641,9 @@ export const deleteScheduleOnBackend = (user, scheduleName, scheduleId) => (
if (scheduleName === "cart") {
return;
}
if (scheduleName === "Path Registration") {
return;
}
dispatch(deletionAttempted(scheduleName));
rateLimitedFetch(`/plan/schedules/${scheduleId}/`, {
method: "DELETE",
Expand Down

0 comments on commit 6892e3b

Please sign in to comment.