Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment viewset #24

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
3 changes: 0 additions & 3 deletions autograder_django_backend/assignments/admin.py

This file was deleted.

6 changes: 0 additions & 6 deletions autograder_django_backend/assignments/apps.py

This file was deleted.

This file was deleted.

Empty file.
6 changes: 0 additions & 6 deletions autograder_django_backend/assignments/models.py

This file was deleted.

7 changes: 0 additions & 7 deletions autograder_django_backend/assignments/serializers.py

This file was deleted.

3 changes: 0 additions & 3 deletions autograder_django_backend/assignments/tests.py

This file was deleted.

11 changes: 0 additions & 11 deletions autograder_django_backend/assignments/urls.py

This file was deleted.

45 changes: 0 additions & 45 deletions autograder_django_backend/assignments/views.py

This file was deleted.

9 changes: 9 additions & 0 deletions autograder_django_backend/autograder/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import serializers

from .models import Assignment


class AssignmentSerializer(serializers.ModelSerializer):
class Meta:
model = Assignment
fields = "__all__"
20 changes: 19 additions & 1 deletion autograder_django_backend/autograder/tests/factory.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from faker import Faker
from autograder.models import Student
from autograder.models import Assignment, Student


fake = Faker()
Expand All @@ -19,3 +19,21 @@ def student_factory(**kwargs):
student = Student.objects.create(**kwargs)

return student


def assignment_factory(**kwargs):
if "name" not in kwargs:
kwargs["name"] = fake.name()
if "description" not in kwargs:
kwargs["description"] = fake.text()
if "due_date" not in kwargs:
kwargs["due_date"] = fake.date_time_between(start_date="-1y", end_date="now")
if "assignment_spec" not in kwargs:
kwargs["assignment_spec"] = fake.text()

# Check that there are only 4 arguments in kwargs
assert len(kwargs) == 4

student = Assignment.objects.create(**kwargs)

return student
38 changes: 38 additions & 0 deletions autograder_django_backend/autograder/tests/test_assignment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.test import TestCase
import pytest
from autograder.models import Course, Assignment, Professor, Student
from autograder_django_backend.utils.tests import get_client

# Test creating a course through the API
@pytest.mark.django_db(transaction=True)
def test_create_assignment_api():
client, user = get_client()

professor = Professor.objects.create(name="test_professor", email="test@test.com")

course = Course.objects.create(
course_id="test_course",
name="test_course",
description="test_course",
section="test_course",
professor=professor,
)

response = client.post(
"/api/assignments/",
{
"name": "test_assignment",
"description": "test_description",
"due_date": "2020-01-01T00:00:00Z",
"assignment_spec": "test_assignment_spec",
"course": course.id,
},
format="json",
)

assert response.status_code == 201

assignment = Assignment.objects.get(name="test_assignment")

assert assignment.name == "test_assignment"
assert assignment.description == "test_description"
10 changes: 8 additions & 2 deletions autograder_django_backend/autograder/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
from django.shortcuts import render
from rest_framework import viewsets

# Create your views here.
from .models import Assignment
from .serializers import AssignmentSerializer


class AssignmentViewSet(viewsets.ModelViewSet):
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _update_or_create_site_with_sequence(site_model, connection, domain, name):
# site is created.
# To avoid this, we need to manually update DB sequence and make sure it's
# greater than the maximum value.
max_id = site_model.objects.order_by('-id').first().id
max_id = site_model.objects.order_by("-id").first().id
with connection.cursor() as cursor:
cursor.execute("SELECT last_value from django_site_id_seq")
(current_id,) = cursor.fetchone()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _

from autograder_django_backend.users.forms import UserAdminChangeForm, UserAdminCreationForm
from autograder_django_backend.users.forms import (
UserAdminChangeForm,
UserAdminCreationForm,
)

User = get_user_model()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from rest_framework.test import APIClient
from autograder_django_backend.users.models import User


def get_client():
"""
Returns a Django test client.
"""

client = APIClient()

test_user = User.objects.create_user(username="test_user", password="test_password")

client.login(username="test_user", password="test_password")

return (client, test_user)
2 changes: 2 additions & 0 deletions autograder_django_backend/config/api_router.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from rest_framework.routers import DefaultRouter, SimpleRouter
from autograder.views import AssignmentViewSet

from autograder_django_backend.users.api.views import UserViewSet

Expand All @@ -9,6 +10,7 @@
router = SimpleRouter()

router.register("users", UserViewSet)
router.register("assignments", AssignmentViewSet)


app_name = "api"
Expand Down
11 changes: 7 additions & 4 deletions autograder_django_backend/config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@

LOCAL_APPS = [
"autograder_django_backend.users",
"assignments",
"autograder",
# Your stuff: custom apps go here
]
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down Expand Up @@ -297,7 +295,9 @@
# https://django-allauth.readthedocs.io/en/latest/configuration.html
SOCIALACCOUNT_ADAPTER = "autograder_django_backend.users.adapters.SocialAccountAdapter"
# https://django-allauth.readthedocs.io/en/latest/forms.html
SOCIALACCOUNT_FORMS = {"signup": "autograder_django_backend.users.forms.UserSocialSignupForm"}
SOCIALACCOUNT_FORMS = {
"signup": "autograder_django_backend.users.forms.UserSocialSignupForm"
}

# django-rest-framework
# -------------------------------------------------------------------------------
Expand Down Expand Up @@ -328,7 +328,10 @@
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
"SERVERS": [
{"url": "http://127.0.0.1:8000", "description": "Local Development server"},
{"url": "https://autograder.ccss.carleton.ca", "description": "Production server"},
{
"url": "https://autograder.ccss.carleton.ca",
"description": "Production server",
},
],
}
# Your stuff...
Expand Down
25 changes: 25 additions & 0 deletions autograder_django_backend/config/settings/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,28 @@
CELERY_TASK_EAGER_PROPAGATES = True
# Your stuff...
# ------------------------------------------------------------------------------


# django-rest-framework
# -------------------------------------------------------------------------------
# django-rest-framework - https://www.django-rest-framework.org/api-guide/settings/
REST_FRAMEWORK = {
# "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

# By Default swagger ui is available only to admin user(s). You can change permission classes to change that
# See more configuration options at https://drf-spectacular.readthedocs.io/en/latest/settings.html#settings
SPECTACULAR_SETTINGS = {
"TITLE": "Autograder Django Backend API",
"DESCRIPTION": "Documentation of API endpoints of Autograder Django Backend",
"VERSION": "1.0.0",
"SERVE_PERMISSIONS": [],
"SERVERS": [
{"url": "http://127.0.0.1:8000", "description": "Local Development server"},
{
"url": "https://autograder.ccss.carleton.ca",
"description": "Production server",
},
],
}
4 changes: 3 additions & 1 deletion autograder_django_backend/config/settings/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
SECRET_KEY = env("DJANGO_SECRET_KEY")
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["autograder.ccss.carleton.ca"])
ALLOWED_HOSTS = env.list(
"DJANGO_ALLOWED_HOSTS", default=["autograder.ccss.carleton.ca"]
)

# DATABASES
# ------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion autograder_django_backend/config/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:",
}
}
}
10 changes: 8 additions & 2 deletions autograder_django_backend/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@
from django.views.generic import TemplateView
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from rest_framework.authtoken.views import obtain_auth_token
from rest_framework import permissions, routers

from autograder.views import AssignmentViewSet

router = routers.DefaultRouter(trailing_slash=True)
router.register("assignments", AssignmentViewSet)


urlpatterns = [
# DRF router
path("api/", include(router.urls)),
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
path(
"about/", TemplateView.as_view(template_name="pages/about.html"), name="about"
Expand All @@ -19,8 +27,6 @@
# User management
path("users/", include("autograder_django_backend.users.urls", namespace="users")),
path("accounts/", include("allauth.urls")),
# Your stuff: custom urls includes go here
path("api/assignments/", include("assignments.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
# Static file serving when using Gunicorn + Uvicorn for local web socket development
Expand Down