From 85428244fba673f66d6467fd6081987a198d1210 Mon Sep 17 00:00:00 2001
From: "robinwilliam.hundt" <robinwilliam.hundt@stud.uni-goettingen.de>
Date: Tue, 21 Nov 2017 22:07:24 +0100
Subject: [PATCH] Refactored GradyUserFactory to factories.py

---
 backend/core/tests/test_student_page.py |  14 +++
 backend/core/tests/tests.py             |   2 +-
 backend/util/factories.py               | 110 ++++++++++++++++++++++++
 backend/util/importer.py                | 109 +----------------------
 4 files changed, 129 insertions(+), 106 deletions(-)
 create mode 100644 backend/core/tests/test_student_page.py
 create mode 100644 backend/util/factories.py

diff --git a/backend/core/tests/test_student_page.py b/backend/core/tests/test_student_page.py
new file mode 100644
index 00000000..72a8aedc
--- /dev/null
+++ b/backend/core/tests/test_student_page.py
@@ -0,0 +1,14 @@
+from rest_framework.test import APIClient, APITestCase
+from util.factories import GradyUserFactory
+
+
+class StudentPageTests(APITestCase):
+    @classmethod
+    def setUpTestData(cls):
+        cls.factory = GradyUserFactory()
+        cls.student = cls.factory.make_student(username='student01', matrikel_no='12345',
+                                               exam='Exam01')
+        cls.tutor = cls.factory.make_tutor(username='tutor01')
+        cls.reviewer = cls.factory.make_reviewer(username='reviewer01')
+
+
diff --git a/backend/core/tests/tests.py b/backend/core/tests/tests.py
index f3290fbe..408ebb75 100644
--- a/backend/core/tests/tests.py
+++ b/backend/core/tests/tests.py
@@ -2,7 +2,7 @@ from django.test import TestCase
 
 from core.models import (Feedback, Reviewer, Student, Submission,
                          SubmissionType, Tutor)
-from util.importer import GradyUserFactory
+from util.factories import GradyUserFactory
 
 
 class FeedbackTestCase(TestCase):
diff --git a/backend/util/factories.py b/backend/util/factories.py
new file mode 100644
index 00000000..953d323d
--- /dev/null
+++ b/backend/util/factories.py
@@ -0,0 +1,110 @@
+import configparser
+import secrets
+
+from core.models import UserAccount as User, Student, Tutor, Reviewer
+from util.importer import PASSWORDS
+
+
+class GradyUserFactory:
+
+    def __init__(self, password_generator_func=get_xkcd_password, *args, **kwargs):
+        self.password_generator_func = password_generator_func
+
+    @staticmethod
+    def _get_random_name(prefix='', suffix='', k=1):
+        return ''.join((prefix, get_xkcd_password(k), suffix))
+
+    def _make_base_user(self, username, groupname, store_pw=False, **kwargs):
+        """ This is a specific wrapper for the django update_or_create method of
+        objects.
+            * A new user is created and password and group are set accordingly
+            * If the user was there before password is NOT change but group is. A
+              user must only have one group.
+
+        Returns:
+            (User object, str): The user object that was added to the group and
+            the password of that user if it was created.
+        """
+        username = username.strip()
+
+        user, created = User.objects.update_or_create(
+            username=username,
+            defaults=kwargs)
+
+        if created:
+            password = self.password_generator_func()
+            user.set_password(password)
+            user.save()
+
+        if created and store_pw:
+            store_password(username, groupname, password)
+
+        return user
+
+    def _get_user_model_for_group(self, groupname):
+        """ Returns the model class for a usergroup """
+        return {
+            STUDENTS: Student,
+            TUTORS: Tutor,
+            REVIEWERS: Reviewer,
+        }[groupname]
+
+    def _make_user_generic(self, username, groupname, **kwargs):
+        """ Provides a model with a associated user but without any defaults
+        """
+
+        if not username:
+            username = self._get_random_name(prefix=groupname.lower() + '_')
+
+        model = self._get_user_model_for_group(groupname)
+        user = self._make_base_user(username, groupname, **kwargs)
+
+        generic_user, _ = model.objects.get_or_create(user=user)
+
+        return generic_user
+
+    def make_student(self, username=None, matrikel_no=None, exam=None, **kwargs):
+        """ Creates a student. Defaults can be passed via kwargs like in
+        relation managers objects.update method. """
+        user = self._make_user_generic(username, STUDENTS, **kwargs)
+        if matrikel_no:
+            user.objects.update(matrikel_no=matrikel_no)
+        if exam:
+            user.objects.update(exam=exam)
+        return user
+
+    def make_tutor(self, username=None, **kwargs):
+        """ Creates or updates a tutor if needed with defaults """
+        return self._make_user_generic(username, TUTORS, **kwargs)
+
+    def make_reviewer(self, username=None, **kwargs):
+        """ Creates or updates a reviewer if needed with defaults """
+        return self._make_user_generic(username, REVIEWERS, **kwargs)
+
+
+STUDENTS = 'students'
+TUTORS = 'tutors'
+REVIEWERS = 'reviewers'
+
+
+def get_xkcd_password(k=2):
+    with open('/usr/share/dict/words') as words:
+        choose_from = list({word.strip().lower()
+                            for word in words if 5 < len(word) < 8})
+
+    return ''.join(secrets.choice(choose_from) for _ in range(k))
+
+
+def store_password(username, groupname, password):
+    storage = configparser.ConfigParser()
+    storage.read(PASSWORDS)
+
+    if not groupname in storage:
+        storage[groupname] = {}
+
+    storage[groupname][username] = password
+
+    with open(PASSWORDS, 'w') as passwd_file:
+        storage.write(passwd_file)
+
+
diff --git a/backend/util/importer.py b/backend/util/importer.py
index 299f4ae5..0c77ba2f 100644
--- a/backend/util/importer.py
+++ b/backend/util/importer.py
@@ -1,23 +1,18 @@
-import configparser
 import csv
 import json
 import os
 import readline
-import secrets
 from typing import Callable
 
 import util.convert
 import util.processing
+from core.models import (ExamType, Feedback, Student, Submission,
+                         SubmissionType, Test)
 from core.models import UserAccount as User
-from core.models import (ExamType, Feedback, Reviewer, Student, Submission,
-                         SubmissionType, Test, Tutor)
+from util.factories import GradyUserFactory, STUDENTS, TUTORS, REVIEWERS
 from util.messages import info, warn
 from util.processing import EmptyTest
 
-STUDENTS = 'students'
-TUTORS = 'tutors'
-REVIEWERS = 'reviewers'
-
 HISTFILE = '.importer_history'
 RECORDS = '.importer'
 PASSWORDS = '.importer_passwords'
@@ -62,14 +57,6 @@ class chdir_context(object):
         os.chdir(self.old_dir)
 
 
-def get_xkcd_password(k=2):
-    with open('/usr/share/dict/words') as words:
-        choose_from = list({word.strip().lower()
-                            for word in words if 5 < len(word) < 8})
-
-    return ''.join(secrets.choice(choose_from) for _ in range(k))
-
-
 def i(prompt: str, default: str='', is_path: bool=False, is_file: bool=False):
     if default is YES or default is NO:
         answer = valid[input(f'[Q] {prompt} ({default}): ').lower() or ('y' if YES == default else 'n')]
@@ -85,97 +72,9 @@ def i(prompt: str, default: str='', is_path: bool=False, is_file: bool=False):
     return answer
 
 
-def store_password(username, groupname, password):
-    storage = configparser.ConfigParser()
-    storage.read(PASSWORDS)
-
-    if not groupname in storage:
-        storage[groupname] = {}
-
-    storage[groupname][username] = password
-
-    with open(PASSWORDS, 'w') as passwd_file:
-        storage.write(passwd_file)
-
-
-class GradyUserFactory:
-
-    def __init__(self, password_generator_func=get_xkcd_password, *args, **kwargs):
-        self.password_generator_func = password_generator_func
-
-    @staticmethod
-    def _get_random_name(prefix='', suffix='', k=1):
-        return ''.join((prefix, get_xkcd_password(k), suffix))
-
-    def _make_base_user(self, username, groupname, store_pw=False, **kwargs):
-        """ This is a specific wrapper for the django update_or_create method of
-        objects.
-            * A new user is created and password and group are set accordingly
-            * If the user was there before password is NOT change but group is. A
-              user must only have one group.
-
-        Returns:
-            (User object, str): The user object that was added to the group and
-            the password of that user if it was created.
-        """
-        username = username.strip()
-
-        user, created = User.objects.update_or_create(
-            username=username,
-            defaults=kwargs)
-
-        if created:
-            password = self.password_generator_func()
-            user.set_password(password)
-            user.save()
-
-        if created and store_pw:
-            store_password(username, groupname, password)
-
-        return user
-
-    def _get_user_model_for_group(self, groupname):
-        """ Returns the model class for a usergroup """
-        return {
-            STUDENTS: Student,
-            TUTORS: Tutor,
-            REVIEWERS: Reviewer,
-        }[groupname]
-
-    def _make_user_generic(self, username, groupname, **kwargs):
-        """ Provides a model with a associated user but without any defaults
-        """
-
-        if not username:
-            username = self._get_random_name(prefix=groupname.lower() + '_')
-
-        model = self._get_user_model_for_group(groupname)
-        user = self._make_base_user(username, groupname, **kwargs)
-
-        generic_user, _ = model.objects.get_or_create(user=user)
-
-        return generic_user
-
-    def make_student(self, username=None, matrikel_no=None, exam=None, **kwargs):
-        """ Creates a student. Defaults can be passed via kwargs like in
-        relation managers objects.update method. """
-        user = self._make_user_generic(username, STUDENTS, **kwargs)
-        if matrikel_no:
-            user.objects.update(matrikel_no=matrikel_no)
-        if exam:
-            user.objects.update(exam=exam)
-        return user
-
-    def make_tutor(self, username=None, **kwargs):
-        """ Creates or updates a tutor if needed with defaults """
-        return self._make_user_generic(username, TUTORS, **kwargs)
-
-    def make_reviewer(self, username=None, **kwargs):
-        """ Creates or updates a reviewer if needed with defaults """
-        return self._make_user_generic(username, REVIEWERS, **kwargs)
-
 # TODO more factories
 
+
 def add_user(username, group, **kwargs):
     user = GradyUserFactory()._make_base_user(
         username, group, store_pw=True, **kwargs
-- 
GitLab