Skip to content

Commit

Permalink
course api tests, permission fixes, test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
PJDeSmijter committed Mar 10, 2024
1 parent 42b7ab4 commit cefeb98
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 21 deletions.
29 changes: 9 additions & 20 deletions backend/pigeonhole/apps/courses/permissions.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
from rest_framework import permissions
from backend.pigeonhole.apps.users.models import Student, Teacher
from backend.pigeonhole.apps.users.models import Teacher, Student


class CourseUserPermissions(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_superuser:
return True
if isinstance(request.user, Teacher):
return True

if isinstance(request.user, Student):
return view.action in ['list', 'retrieve']

return False

def has_object_permission(self, request, view, obj):
if request.user.is_superuser:
return True
if isinstance(request.user, Teacher):
if request.user.is_admin:
if Teacher.objects.filter(id=request.user.id).exists():
teacher = Teacher.objects.get(id=request.user.id)
if teacher.is_admin:
return True
elif Teacher.objects.filter(id=request.user.id, course=obj).exists():
# Check if the teacher is assigned to the course
course = view.kwargs.get('pk')
if teacher.course.filter(course_id=course).exists():
return True
return view.action in ['list', 'retrieve', 'create']
elif Student.objects.filter(id=request.user.id).exists():
return view.action in ['list', 'retrieve']

if isinstance(request.user, Student):
return view.action in ['list', 'retrieve']

return False
2 changes: 1 addition & 1 deletion backend/pigeonhole/tests/test_models/test_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ def setUp(self):
project = Project.objects.create(
name="Project",
course_id=course,
deadline="2021-12-12 12:12:12",
description="Project Description"
)

# Create conditions
self.conditions = Conditions.objects.create(
submission_id=project,
condition="Condition 1",
deadline="2021-12-12 12:12:12",
test_file_location="path/to/test",
test_file_type="txt"
)
Expand Down
1 change: 1 addition & 0 deletions backend/pigeonhole/tests/test_models/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def setUp(self):
project = Project.objects.create(
name="Project",
course_id=course,
deadline="2021-12-12 12:12:12",
description="Project Description",
)

Expand Down
1 change: 1 addition & 0 deletions backend/pigeonhole/tests/test_models/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def setUp(self):
self.project = Project.objects.create(
name="Project",
course_id=course,
deadline="2021-12-12 12:12:12",
description="Project Description",
)

Expand Down
1 change: 1 addition & 0 deletions backend/pigeonhole/tests/test_models/test_submissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def setUp(self):
project = Project.objects.create(
name="Project",
course_id=course,
deadline="2021-12-12 12:12:12",
description="Project Description",
)

Expand Down
Empty file.
173 changes: 173 additions & 0 deletions backend/pigeonhole/tests/test_views/test_course.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
from django.test import TestCase
from rest_framework.test import APIClient
from rest_framework import status
from backend.pigeonhole.apps.users.models import User, Teacher, Student
from backend.pigeonhole.apps.courses.models import Course

API_ENDPOINT = '/courses/' # Updated the API_ENDPOINT


class CourseTestTeacher(TestCase):
def setUp(self):
self.client = APIClient()

self.course_data = {
'name': 'Test Course',
'description': 'This is a test course.'
}

self.course = Course.objects.create(**self.course_data)

self.course_not_of_teacher = Course.objects.create(name="Not of Teacher", description="This is not of the teacher")

# Create a regular user (teacher)
self.user = User.objects.create_user(
username="teacher_username",
email="teacher@gmail.com",
first_name="Kermit",
last_name="The Frog",
)

# Create a Teacher instance and use .set() to assign the course
self.teacher = Teacher.objects.create(id=self.user)
self.teacher.course.set([self.course])

# Authenticate the test client with the teacher user
self.client.force_authenticate(user=self.user)

def test_create_course(self):
response = self.client.post(API_ENDPOINT, self.course_data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Course.objects.count(), 3)

def test_update_course(self):
updated_data = {
'name': 'Updated Course',
'description': 'This course has been updated.'
}
response = self.client.put(f'{API_ENDPOINT}{self.course.course_id}/', updated_data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.course.refresh_from_db()
self.assertEqual(self.course.name, updated_data['name'])
self.assertEqual(self.course.description, updated_data['description'])

# TODO
def test_update_course_not_of_teacher(self):
updated_data = {
'name': 'Updated Course',
'description': 'This course has been updated.'
}
response = self.client.put(f'{API_ENDPOINT}{self.course_not_of_teacher.course_id}/', updated_data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_delete_course(self):
response = self.client.delete(f'{API_ENDPOINT}{self.course.course_id}/')
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(Course.objects.count(), 1)

# TODO
def test_delete_course_not_of_teacher(self):
response = self.client.delete(f'{API_ENDPOINT}{self.course_not_of_teacher.course_id}/')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_list_courses(self):
response = self.client.get(API_ENDPOINT)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)

def test_retrieve_course(self):
response = self.client.get(f'{API_ENDPOINT}{self.course.course_id}/')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['name'], self.course.name)
self.assertEqual(response.data['description'], self.course.description)


class CourseTestStudent(TestCase):
def setUp(self):
self.client = APIClient()

# Create a regular user (teacher)
self.user = User.objects.create_user(
username="teacher_username",
email="kermit@gmail.com",
first_name="Kermit",
last_name="The Frog"
)

self.course_data = {
'name': 'Test Course',
'description': 'This is a test course.'
}

self.course = Course.objects.create(**self.course_data)

# Provide a value for the "number" field when creating the Student instance
self.student = Student.objects.create(id=self.user, number=123456)
self.student.course.set([self.course])

# Authenticate the test client with the regular user
self.client.force_authenticate(user=self.user)

def test_create_course(self):
response = self.client.post(API_ENDPOINT, self.course_data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(Course.objects.count(), 1)

def test_update_course(self):
updated_data = {
'name': 'Updated Course',
'description': 'This course has been updated.'
}
response = self.client.put(f'{API_ENDPOINT}{self.course.course_id}/', updated_data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.course.refresh_from_db()
self.assertNotEqual(self.course.name, updated_data['name'])
self.assertNotEqual(self.course.description, updated_data['description'])

def test_delete_course(self):
response = self.client.delete(f'{API_ENDPOINT}{self.course.course_id}/')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(Course.objects.count(), 1)

def test_list_courses(self):
response = self.client.get(API_ENDPOINT)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)


class CourseTestUnauthorized(TestCase):
def setUp(self):
self.client = APIClient()

self.course_data = {
'name': 'Test Course',
'description': 'This is a test course.'
}

self.course = Course.objects.create(**self.course_data)

def test_create_course(self):
response = self.client.post(API_ENDPOINT, self.course_data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(Course.objects.count(), 1)

def test_update_course(self):
updated_data = {
'name': 'Updated Course',
'description': 'This course has been updated.'
}
response = self.client.put(f'{API_ENDPOINT}{self.course.course_id}/', updated_data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.course.refresh_from_db()
self.assertNotEqual(self.course.name, updated_data['name'])
self.assertNotEqual(self.course.description, updated_data['description'])

def test_delete_course(self):
response = self.client.delete(f'{API_ENDPOINT}{self.course.course_id}/')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(Course.objects.count(), 1)

def test_list_courses(self):
response = self.client.get(API_ENDPOINT)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(len(response.data), 1)

0 comments on commit cefeb98

Please sign in to comment.