From 6efab98a5f3757839c5f81169c17dfb8a433c6ae Mon Sep 17 00:00:00 2001
From: janmax <mail-github@jmx.io>
Date: Thu, 23 Nov 2017 22:39:06 +0100
Subject: [PATCH] Tutor create now possible via post

* ran isort on all test files
---
 backend/core/serializers.py                   | 15 ++++++-
 backend/core/tests/data_factories.py          |  5 +--
 backend/core/tests/test_access_rights.py      |  7 +--
 backend/core/tests/test_auth.py               |  1 +
 backend/core/tests/test_student_page.py       |  6 ++-
 .../core/tests/test_tutor_api_endpoints.py    | 45 ++++++++++++++++---
 backend/core/urls.py                          |  3 +-
 backend/core/views.py                         | 12 +++--
 8 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/backend/core/serializers.py b/backend/core/serializers.py
index c6c93836..5aaef0f3 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 a7cb725a..25e5ca71 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 2e97b2ed..ff9857d6 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 99bf60d3..85505585 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 ceabdb69..2b15fb97 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 87dbe2b2..0df99792 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 41582a5c..d7eb60ec 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 2b02516e..f47ac250 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
+
-- 
GitLab