diff --git a/backend/core/serializers.py b/backend/core/serializers.py index c6c93836dd2a4425c3d4efe54d3849084ef209f7..5aaef0f372ffcbee49aef9f1576565f9f6a802c1 100644 --- a/backend/core/serializers.py +++ b/backend/core/serializers.py @@ -1,5 +1,10 @@ from rest_framework import serializers from core.models import ExamType, Feedback, Student, Submission, Tutor +from util.factories import GradyUserFactory +import logging + +log = logging.getLogger(__name__) +user_factory = GradyUserFactory() class ExamSerializer(serializers.ModelSerializer): @@ -40,8 +45,14 @@ class StudentSerializer(serializers.ModelSerializer): class TutorSerializer(serializers.ModelSerializer): - username = serializers.ReadOnlyField(source='user.username') - feedback_count = serializers.IntegerField(source='get_feedback_count') + username = serializers.CharField(source='user.username') + feedback_count = serializers.IntegerField(source='get_feedback_count', + read_only=True) + + def create(self, validated_data): + log.info("Crating tutor from data %s", validated_data) + return user_factory.make_tutor( + username=validated_data['user']['username']) class Meta: model = Tutor diff --git a/backend/core/tests/data_factories.py b/backend/core/tests/data_factories.py index a7cb725a35c8315738a3e83c460775816e8b5647..25e5ca71f2c33bc70e2204987b3b4c9ceb506204 100644 --- a/backend/core/tests/data_factories.py +++ b/backend/core/tests/data_factories.py @@ -1,9 +1,8 @@ """ A set of factory methods that make testing easier. Each method creates all reuired subfields if not provided by via kwargs. """ -from core.models import (UserAccount, Student, Tutor, Reviewer, - ExamType, SubmissionType, Submission, Feedback) - +from core.models import (ExamType, Feedback, Reviewer, Student, Submission, + SubmissionType, Tutor, UserAccount) # These methods are meant to be used to provide data to insert into the test # database diff --git a/backend/core/tests/test_access_rights.py b/backend/core/tests/test_access_rights.py index 2e97b2edf551ce6e8ee1a449e836a4c7df18cda1..ff9857d688f1ebde249371bbabf497c8a0743ad2 100644 --- a/backend/core/tests/test_access_rights.py +++ b/backend/core/tests/test_access_rights.py @@ -1,9 +1,10 @@ -from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate +from django.urls import reverse from rest_framework import status +from rest_framework.test import (APIRequestFactory, APITestCase, + force_authenticate) + from core.models import Reviewer -from django.urls import reverse from core.views import StudentApiView - from util.factories import GradyUserFactory diff --git a/backend/core/tests/test_auth.py b/backend/core/tests/test_auth.py index 99bf60d37602d43c8a8d3725ec40c6e3e53315c0..85505585b10b0362b4f851f1ea16c3a88a5e3987 100644 --- a/backend/core/tests/test_auth.py +++ b/backend/core/tests/test_auth.py @@ -1,4 +1,5 @@ from rest_framework.test import APIClient, APITestCase + from core.models import UserAccount diff --git a/backend/core/tests/test_student_page.py b/backend/core/tests/test_student_page.py index ceabdb69caa40e5025ef3b428c89292ba51e58bd..2b15fb974d92ec1319df33e3abfa017cd0d261ea 100644 --- a/backend/core/tests/test_student_page.py +++ b/backend/core/tests/test_student_page.py @@ -1,8 +1,10 @@ -from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate +from django.urls import reverse from rest_framework import status +from rest_framework.test import (APIRequestFactory, APITestCase, + force_authenticate) + from core.models import Reviewer, SubmissionType from core.tests import data_factories -from django.urls import reverse from core.views import StudentApiView diff --git a/backend/core/tests/test_tutor_api_endpoints.py b/backend/core/tests/test_tutor_api_endpoints.py index 87dbe2b2c31ccbfa57b3656cfd420dcf3eee51df..0df99792d12ff53ad8de34b2b61a6644412cbb08 100644 --- a/backend/core/tests/test_tutor_api_endpoints.py +++ b/backend/core/tests/test_tutor_api_endpoints.py @@ -5,18 +5,19 @@ * GET /tutorlist list of all tutors with their scores """ -from rest_framework.test import APITestCase, APIRequestFactory, force_authenticate -from rest_framework import status from django.urls import reverse -from core.views import TutorListApiView -from core.models import Tutor +from rest_framework import status +from rest_framework.test import (APIRequestFactory, APITestCase, + force_authenticate) +from core.models import Feedback, Tutor +from core.views import TutorCreateView, TutorListApiView from util.factories import GradyUserFactory NUMBER_OF_TUTORS = 7 -class TutorAPIEndpoints(APITestCase): +class TutorListTests(APITestCase): @classmethod def setUpTestData(cls): @@ -27,7 +28,7 @@ class TutorAPIEndpoints(APITestCase): self.tutor_list = [self.user_factory.make_tutor() for _ in range(NUMBER_OF_TUTORS)] self.reviewer = self.user_factory.make_reviewer() - self.request = self.factory.get(reverse('tutorlist')) + self.request = self.factory.get(reverse('tutor-list')) self.view = TutorListApiView.as_view() force_authenticate(self.request, user=self.reviewer.user) @@ -39,9 +40,39 @@ class TutorAPIEndpoints(APITestCase): def test_get_a_list_of_all_tutors(self): self.assertEqual(len(self.response.data), NUMBER_OF_TUTORS) - def test_sum_of_feedback_count_matches_database(self): + def test_feedback_count_matches_database(self): def verify_fields(tutor_obj): t = Tutor.objects.get(user__username=tutor_obj['username']) return t.get_feedback_count() == tutor_obj['feedback_count'] self.assertTrue(all(map(verify_fields, self.response.data))) + + def test_sum_of_feedback_count(self): + self.assertEqual(sum(obj['feedback_count'] + for obj in self.response.data), + Feedback.objects.count()) + + +class TutorCreateTests(APITestCase): + + USERNAME = 'some weird name!' + + @classmethod + def setUpTestData(cls): + cls.factory = APIRequestFactory() + cls.user_factory = GradyUserFactory() + + def setUp(self): + self.reviewer = self.user_factory.make_reviewer() + self.request = self.factory.post(reverse('tutor-create'), + {'username': self.USERNAME}) + self.view = TutorCreateView.as_view() + + force_authenticate(self.request, user=self.reviewer.user) + self.response = self.view(self.request) + + def test_can_access(self): + self.assertEqual(self.response.status_code, status.HTTP_201_CREATED) + + def test_can_create(self): + self.assertEqual(Tutor.objects.first().user.username, self.USERNAME) diff --git a/backend/core/urls.py b/backend/core/urls.py index 41582a5c2ec055c1e42221d59c596d8912196aa8..d7eb60ece02c1c1e784ac6b0d1f9c00b49e74594 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -7,7 +7,8 @@ from core import views urlpatterns = [ url(r'^api/student/$', views.StudentApiView.as_view(), name='student-page'), - url(r'^api/tutorlist/$', views.TutorListApiView.as_view(), name='tutorlist'), + url(r'^api/tutor/$', views.TutorCreateView.as_view(), name='tutor-create'), + url(r'^api/tutorlist/$', views.TutorListApiView.as_view(), name='tutor-list'), url(r'^api-token-auth/', obtain_jwt_token), url(r'^api-token-refresh', refresh_jwt_token), diff --git a/backend/core/views.py b/backend/core/views.py index 2b02516e300514fa2047e714a02dc9fecc994072..f47ac2500bb4d922a9b3e2d6769b60675d1da540 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -1,6 +1,6 @@ import logging -from rest_framework.generics import RetrieveAPIView, ListAPIView +from rest_framework import generics from core.permissions import IsStudent, IsReviewer from core.serializers import StudentSerializer, TutorSerializer @@ -9,7 +9,7 @@ from core.models import Tutor log = logging.getLogger(__name__) -class StudentApiView(RetrieveAPIView): +class StudentApiView(generics.RetrieveAPIView): permission_classes = (IsStudent,) def get_object(self): @@ -19,8 +19,14 @@ class StudentApiView(RetrieveAPIView): serializer_class = StudentSerializer -class TutorListApiView(ListAPIView): +class TutorListApiView(generics.ListAPIView): """ A list of all tutors with informationi about what they corrected """ permission_classes = (IsReviewer,) queryset = Tutor.objects.all() serializer_class = TutorSerializer + + +class TutorCreateView(generics.CreateAPIView): + permission_classes = (IsReviewer,) + serializer_class = TutorSerializer +