Skip to content

Commit

Permalink
chore: readded tests (#419)
Browse files Browse the repository at this point in the history
  • Loading branch information
Topvennie authored May 13, 2024
1 parent def84ab commit c08540f
Show file tree
Hide file tree
Showing 16 changed files with 756 additions and 791 deletions.
12 changes: 11 additions & 1 deletion backend/api/logic/parse_zip_files.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import zipfile

from api.models.checks import FileExtension, StructureCheck
Expand All @@ -13,7 +14,16 @@ def parse_zip(project: Project, zip_file: InMemoryUploadedFile) -> bool:

with zipfile.ZipFile(zip_file, 'r') as zip:
files = zip.namelist()
directories = [file.filename for file in zip.infolist() if file.is_dir()]
directories = [file for file in files if file.endswith('/')]

# Check if all directories start the same
common_prefix = os.path.commonprefix(directories)
if '/' in common_prefix:
prefixes = common_prefix.split('/')
if common_prefix[-1] != '/':
prefixes = prefixes[:-1]

directories += [prefix + '/' for prefix in prefixes]

# Add for each directory a structure check
for directory in directories:
Expand Down
2 changes: 2 additions & 0 deletions backend/api/models/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

if TYPE_CHECKING:
from api.models.assistant import Assistant
from api.models.project import Project
from api.models.student import Student
from api.models.teacher import Teacher
from django.db.models.manager import RelatedManager
Expand Down Expand Up @@ -95,5 +96,6 @@ def academic_year(self) -> str:

if TYPE_CHECKING:
assistants: RelatedManager['Assistant']
projects: RelatedManager['Project']
students: RelatedManager['Student']
teachers: RelatedManager['Teacher']
49 changes: 38 additions & 11 deletions backend/api/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from datetime import timedelta

from api.models.assistant import Assistant
from api.models.checks import FileExtension, StructureCheck
from api.models.checks import ExtraCheck, FileExtension, StructureCheck
from api.models.course import Course
from api.models.docker import DockerImage
from api.models.group import Group
from api.models.project import Project
from api.models.student import Student
Expand All @@ -15,7 +18,7 @@ def create_faculty(name: str | int) -> Faculty:
return Faculty.objects.create(id=name, name=name)


def create_user(id: str | int, first_name: str, last_name: str, email: str, faculty: list[Faculty] = None) -> User:
def create_user(id: str | int, first_name: str, last_name: str, email: str, faculties: list[Faculty] | None = None) -> User:
username = f"{first_name.lower()}{last_name.lower()}"

user = User.objects.create(
Expand All @@ -26,14 +29,14 @@ def create_user(id: str | int, first_name: str, last_name: str, email: str, facu
email=email
)

if faculty is not None:
for faculty in faculty:
if faculties is not None:
for faculty in faculties:
user.faculties.add(faculty)

return user


def create_admin(id: str | int, first_name: str, last_name: str, email: str, faculty: list[Faculty] = None):
def create_admin(id: str | int, first_name: str, last_name: str, email: str, faculty: list[Faculty] | None = None):
"""Create an Admin with the given arguments."""
admin = create_user(id, first_name, last_name, email, faculty)
admin.make_admin()
Expand All @@ -47,8 +50,8 @@ def create_student(
email: str,
student_id: str = "",
is_active: bool = True,
faculty: list[Faculty] = None,
courses: list[Course] = None
faculty: list[Faculty] | None = None,
courses: list[Course] | None = None
) -> Student:
"""Create a student with the given arguments."""
username = f"{first_name.lower()}{last_name.lower()}"
Expand Down Expand Up @@ -143,6 +146,11 @@ def create_structure_check(path, project, obligated_extensions, blocked_extensio
return check


def create_extra_check(project, docker_image, file):
"""Create an ExtraCheck with the given arguments."""
return ExtraCheck.objects.create(name="test extra check", project=project, docker_image=docker_image, file=file)


def create_project(name, description, days, course, max_score=5, group_size=5, visible=True, archived=False):
"""Create a Project with the given arguments."""
deadline = timezone.now() + timezone.timedelta(days=days)
Expand All @@ -159,7 +167,12 @@ def create_project(name, description, days, course, max_score=5, group_size=5, v
)


def create_course(name: str | int, academic_startyear: int, description: str = None, parent_course: Course = None) -> Course:
def create_course(
name: str | int,
academic_startyear: int,
description: str | None = None,
parent_course: Course | None = None
) -> Course:
"""Create a Course with the given arguments."""
return Course.objects.create(
name=name,
Expand All @@ -174,11 +187,25 @@ def create_group(project: Project, score: int = 0) -> Group:
return Group.objects.create(project=project, score=score)


def create_submission(submission_number: int, group: Group, structure_checks_passed: bool) -> Submission:
def create_submission(group: Group, zip: str) -> Submission:
"""Create a Submission with the given arguments."""

return Submission.objects.create(
submission_number=submission_number,
group=group,
structure_checks_passed=structure_checks_passed,
zip=zip,
)


def create_docker_image(file: str, owner: User):
"""Create a DockerImage with the given arguments."""
return DockerImage.objects.create(name="test docker image", owner=owner, file=file)


def create_past_project(name, description, days, course, days_start_date):
"""Create a Project with the given arguments."""
deadline = timezone.now() + timedelta(days=days)
start_date = timezone.now() + timedelta(days=days_start_date)

return Project.objects.create(
name=name, description=description, deadline=deadline, course=course, score_visible=True, start_date=start_date
)
19 changes: 10 additions & 9 deletions backend/api/tests/test_admin.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import json
from django.urls import reverse
from rest_framework.test import APITestCase

from api.tests.helpers import create_admin, create_faculty
from authentication.models import User
from django.urls import reverse
from rest_framework.test import APITestCase


class AdminModelTests(APITestCase):
def setUp(self):
self.client.force_authenticate(
self.client.force_authenticate( # type: ignore
User.get_dummy_admin()
)

Expand All @@ -19,7 +20,7 @@ def test_no_admins(self):
response_root = self.client.get(reverse("admin-list"), follow=True)
self.assertEqual(response_root.status_code, 200)
# Assert that the response is JSON
self.assertEqual(response_root.accepted_media_type, "application/json")
self.assertEqual(response_root.accepted_media_type, "application/json") # type: ignore
# Parse the JSON content from the response
content_json = json.loads(response_root.content.decode("utf-8"))
# Assert that the parsed JSON is an empty list
Expand All @@ -40,7 +41,7 @@ def test_admin_exists(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -75,7 +76,7 @@ def test_multiple_admins(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -113,7 +114,7 @@ def test_admin_detail_view(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -147,7 +148,7 @@ def test_admin_faculty(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand All @@ -164,7 +165,7 @@ def test_admin_faculty(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down
30 changes: 16 additions & 14 deletions backend/api/tests/test_assistant.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import json
from django.urls import reverse
from rest_framework.test import APITestCase

from api.models.assistant import Assistant
from api.models.teacher import Teacher
from api.tests.helpers import create_faculty, create_course, create_assistant, create_user
from api.tests.helpers import (create_assistant, create_course, create_faculty,
create_user)
from authentication.models import User
from django.urls import reverse
from rest_framework.test import APITestCase


class AssistantModelTests(APITestCase):
def setUp(self) -> None:
self.client.force_authenticate(
self.client.force_authenticate( # type: ignore
User.get_dummy_admin()
)

Expand Down Expand Up @@ -75,7 +77,7 @@ def test_no_assistant(self):
response_root = self.client.get(reverse("assistant-list"), follow=True)
self.assertEqual(response_root.status_code, 200)
# Assert that the response is JSON
self.assertEqual(response_root.accepted_media_type, "application/json")
self.assertEqual(response_root.accepted_media_type, "application/json") # type: ignore
# Parse the JSON content from the response
content_json = json.loads(response_root.content.decode("utf-8"))
# Assert that the parsed JSON is an empty list
Expand All @@ -96,7 +98,7 @@ def test_assistant_exists(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -131,7 +133,7 @@ def test_multiple_assistant(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -170,7 +172,7 @@ def test_assistant_detail_view(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -205,7 +207,7 @@ def test_assistant_faculty(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand All @@ -223,7 +225,7 @@ def test_assistant_faculty(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -262,7 +264,7 @@ def test_assistant_courses(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand All @@ -280,7 +282,7 @@ def test_assistant_courses(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down Expand Up @@ -311,7 +313,7 @@ def setUp(self) -> None:
email="[email protected]"
)

self.client.force_authenticate(self.user)
self.client.force_authenticate(self.user) # type: ignore

def test_retrieve_assistant_list(self):
"""
Expand All @@ -333,7 +335,7 @@ def test_retrieve_assistant_list(self):
self.assertEqual(response.status_code, 200)

# Assert that the response is JSON
self.assertEqual(response.accepted_media_type, "application/json")
self.assertEqual(response.accepted_media_type, "application/json") # type: ignore

# Parse the JSON content from the response
content_json = json.loads(response.content.decode("utf-8"))
Expand Down
Loading

0 comments on commit c08540f

Please sign in to comment.