From 7885abce18c6cbcd90c5a4cdf6ca087970dabbac Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:34:16 +0100 Subject: [PATCH 01/44] Create python-package.yml --- .github/workflows/python-package.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/workflows/python-package.yml diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1 @@ + From 8c7fb1408cf8a2f7e8c4f9f66d77337a95890e10 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:35:56 +0100 Subject: [PATCH 02/44] Delete .github/workflows directory --- .github/workflows/python-package.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/workflows/python-package.yml diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml deleted file mode 100644 index 8b137891..00000000 --- a/.github/workflows/python-package.yml +++ /dev/null @@ -1 +0,0 @@ - From 23d4d2dd1f6ed29a5081c8108a10c153a479d729 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:36:47 +0100 Subject: [PATCH 03/44] Create django.yml --- .github/workflows/django.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/django.yml diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml new file mode 100644 index 00000000..b3c11a93 --- /dev/null +++ b/.github/workflows/django.yml @@ -0,0 +1,30 @@ +name: Django CI + +on: + push: + branches: [ "main", "develop" ] + pull_request: + branches: [ "main", "develop" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run Tests + run: | + python manage.py test From d7a2fdae45b0eeeb8661585dc54df501ff1b878e Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:38:28 +0100 Subject: [PATCH 04/44] Update django.yml --- .github/workflows/django.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index b3c11a93..c5ea24a6 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -2,9 +2,9 @@ name: Django CI on: push: - branches: [ "main", "develop" ] + branches: [ "develop" ] pull_request: - branches: [ "main", "develop" ] + branches: [ "develop" ] jobs: build: From 583d3544c0c08a01239e885ebdc1f38ea648db5a Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sun, 3 Mar 2024 21:10:26 +0100 Subject: [PATCH 05/44] test with updated secrets --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3ff18b8..094fc81c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# UGent-4 \ No newline at end of file +# UGent-4 From 3abac5a82c6b9b1ffd42564138951c266d628580 Mon Sep 17 00:00:00 2001 From: Mathis De Witte Date: Sun, 10 Mar 2024 15:46:24 +0100 Subject: [PATCH 06/44] code cleanup --- api/asgi.py | 2 +- api/middleware.py | 8 +- api/models/gebruiker.py | 4 +- api/models/groep.py | 6 +- api/models/indiening.py | 7 +- api/models/project.py | 3 +- api/models/score.py | 6 +- api/models/vak.py | 10 +- api/serializers/gebruiker.py | 12 +-- api/serializers/groep.py | 21 ++-- api/serializers/indiening.py | 2 +- api/serializers/project.py | 2 +- api/serializers/score.py | 3 +- api/serializers/vak.py | 37 ++++--- api/settings.py | 126 ++++++++++++------------ api/tests/factories/gebruiker.py | 6 +- api/tests/models/test_gebruiker.py | 27 ++--- api/tests/serializers/test_gebruiker.py | 15 +-- api/tests/test_views.py | 4 +- api/tests/views/test_gebruiker.py | 14 +-- api/urls.py | 35 +++---- api/utils.py | 25 ++--- api/views/gebruiker.py | 28 +++--- api/views/groep.py | 34 +++---- api/views/indiening.py | 25 ++--- api/views/project.py | 29 +++--- api/views/score.py | 25 ++--- api/views/vak.py | 28 +++--- api/views/views.py | 18 +++- api/wsgi.py | 2 +- 30 files changed, 301 insertions(+), 263 deletions(-) diff --git a/api/asgi.py b/api/asgi.py index 7f38f25f..4cb57e4b 100644 --- a/api/asgi.py +++ b/api/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings") application = get_asgi_application() diff --git a/api/middleware.py b/api/middleware.py index 150bc458..33880a7f 100644 --- a/api/middleware.py +++ b/api/middleware.py @@ -2,14 +2,18 @@ from django.shortcuts import redirect from django.urls import reverse + class RedirectAnonymousUserMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Check if the user is anonymous and the current path is not the login page - if request.user.is_anonymous and request.path not in ['/oauth2/login', '/oauth2/callback']: + if request.user.is_anonymous and request.path not in [ + "/oauth2/login", + "/oauth2/callback", + ]: # Redirect to the login page return redirect(settings.LOGIN_URL) - return self.get_response(request) \ No newline at end of file + return self.get_response(request) diff --git a/api/models/gebruiker.py b/api/models/gebruiker.py index c2345671..9c489814 100644 --- a/api/models/gebruiker.py +++ b/api/models/gebruiker.py @@ -4,7 +4,9 @@ class Gebruiker(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) - subjects = models.ManyToManyField('Vak', related_name='gebruiker_vakken', blank=True) + subjects = models.ManyToManyField( + "Vak", related_name="gebruiker_vakken", blank=True + ) is_lesgever = models.BooleanField(default=False) def __str__(self): diff --git a/api/models/groep.py b/api/models/groep.py index 3494ba86..094ffd89 100644 --- a/api/models/groep.py +++ b/api/models/groep.py @@ -3,8 +3,10 @@ class Groep(models.Model): group_id = models.AutoField(primary_key=True) - students = models.ManyToManyField('Gebruiker', related_name='groep_studenten', blank=True) - project = models.ForeignKey('Project', on_delete=models.CASCADE) + students = models.ManyToManyField( + "Gebruiker", related_name="groep_studenten", blank=True + ) + project = models.ForeignKey("Project", on_delete=models.CASCADE) def __str__(self): return f"Group {self.group_id}" diff --git a/api/models/indiening.py b/api/models/indiening.py index da4a7228..c43346d9 100644 --- a/api/models/indiening.py +++ b/api/models/indiening.py @@ -1,12 +1,11 @@ from django.db import models - + class Indiening(models.Model): indiening_id = models.AutoField(primary_key=True) - indiener = models.ForeignKey('Groep', on_delete=models.CASCADE) - indieningsbestanden = models.FileField(upload_to='uploads/') + indiener = models.ForeignKey("Groep", on_delete=models.CASCADE) + indieningsbestanden = models.FileField(upload_to="uploads/") tijdstip = models.DateTimeField(null=False) def __str__(self): return self.tijdstip - \ No newline at end of file diff --git a/api/models/project.py b/api/models/project.py index 45eb6ee8..9ebe00c3 100644 --- a/api/models/project.py +++ b/api/models/project.py @@ -6,11 +6,10 @@ class Project(models.Model): project_id = models.AutoField(primary_key=True) titel = models.CharField(max_length=100) description = models.TextField() - opgavebestanden = models.FileField(upload_to='data/opgaves/') + opgavebestanden = models.FileField(upload_to="data/opgaves/") vak = models.ForeignKey(Vak, on_delete=models.CASCADE) deadline = models.DateTimeField(null=True) # indiening restricties def __str__(self): return self.titel - \ No newline at end of file diff --git a/api/models/score.py b/api/models/score.py index 0b6cc20d..f8e959a9 100644 --- a/api/models/score.py +++ b/api/models/score.py @@ -1,10 +1,10 @@ from django.db import models - + class Score(models.Model): score = models.SmallIntegerField() - indiening = models.ForeignKey('Indiening', on_delete=models.CASCADE) - groep = models.ForeignKey('Groep', on_delete=models.CASCADE) + indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE) + groep = models.ForeignKey("Groep", on_delete=models.CASCADE) def __str__(self): return self.score diff --git a/api/models/vak.py b/api/models/vak.py index bdc66f71..db49583b 100644 --- a/api/models/vak.py +++ b/api/models/vak.py @@ -4,10 +4,12 @@ class Vak(models.Model): vak_id = models.AutoField(primary_key=True) name = models.CharField(max_length=100) - students = models.ManyToManyField('Gebruiker', related_name='vak_gebruikers', blank=True) - teachers = models.ManyToManyField('Gebruiker', related_name='vak_lesgevers', blank=True) + students = models.ManyToManyField( + "Gebruiker", related_name="vak_gebruikers", blank=True + ) + teachers = models.ManyToManyField( + "Gebruiker", related_name="vak_lesgevers", blank=True + ) def __str__(self): return self.name - - diff --git a/api/serializers/gebruiker.py b/api/serializers/gebruiker.py index c2891f36..d6a99525 100644 --- a/api/serializers/gebruiker.py +++ b/api/serializers/gebruiker.py @@ -5,10 +5,10 @@ class GebruikerSerializer(serializers.ModelSerializer): class Meta: model = Gebruiker - fields = '__all__' + fields = "__all__" def create(self, validated_data): - subjects_data = validated_data.pop('subjects') + subjects_data = validated_data.pop("subjects") instance = Gebruiker.objects.create(**validated_data) instance.subjects.set(subjects_data) @@ -17,10 +17,9 @@ def create(self, validated_data): return instance def update(self, instance, validated_data): - instance.is_lesgever = validated_data.pop('is_lesgever', False) + instance.is_lesgever = validated_data.pop("is_lesgever", False) - - subjects_data = validated_data.pop('subjects', []) + subjects_data = validated_data.pop("subjects", []) depopulate_subject_gebruikers(instance) @@ -40,7 +39,8 @@ def populate_subject_gebruikers(gebruiker): else: subject.students.add(gebruiker) + def depopulate_subject_gebruikers(gebruiker): for subject in gebruiker.subjects.all(): subject.students.remove(gebruiker) - subject.teachers.remove(gebruiker) \ No newline at end of file + subject.teachers.remove(gebruiker) diff --git a/api/serializers/groep.py b/api/serializers/groep.py index a53984e7..9cae2f90 100644 --- a/api/serializers/groep.py +++ b/api/serializers/groep.py @@ -5,22 +5,22 @@ class GroepSerializer(serializers.ModelSerializer): class Meta: model = Groep - fields = '__all__' + fields = "__all__" def create(self, validated_data): - students_data = validated_data.pop('students') - + students_data = validated_data.pop("students") + validate_students(students_data) - + instance = Groep.objects.create(**validated_data) instance.students.set(students_data) return instance - + def update(self, validated_data): - students_data = validated_data.pop('students') - + students_data = validated_data.pop("students") + validate_students(students_data) - + instance = Groep.objects.create(**validated_data) instance.students.set(students_data) @@ -28,8 +28,9 @@ def update(self, validated_data): return instance - def validate_students(students_data): for student in students_data: if student.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'students' moeten studenten zijn!") \ No newline at end of file + raise serializers.ValidationError( + "Alle gebruikers in 'students' moeten studenten zijn!" + ) diff --git a/api/serializers/indiening.py b/api/serializers/indiening.py index a52b760b..6ae935e8 100644 --- a/api/serializers/indiening.py +++ b/api/serializers/indiening.py @@ -5,7 +5,7 @@ class IndieningSerializer(serializers.ModelSerializer): class Meta: model = Indiening - fields = '__all__' + fields = "__all__" def create(self, validated_data): return Indiening.objects.create(**validated_data) diff --git a/api/serializers/project.py b/api/serializers/project.py index 35223c12..344787d4 100644 --- a/api/serializers/project.py +++ b/api/serializers/project.py @@ -5,4 +5,4 @@ class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project - fields = '__all__' \ No newline at end of file + fields = "__all__" diff --git a/api/serializers/score.py b/api/serializers/score.py index a7899445..3fcc75e2 100644 --- a/api/serializers/score.py +++ b/api/serializers/score.py @@ -5,8 +5,7 @@ class ScoreSerializer(serializers.ModelSerializer): class Meta: model = Score - fields = '__all__' + fields = "__all__" def create(self, validated_data): return Score.objects.create(**validated_data) - diff --git a/api/serializers/vak.py b/api/serializers/vak.py index 5f518e1f..baccc1ca 100644 --- a/api/serializers/vak.py +++ b/api/serializers/vak.py @@ -5,13 +5,13 @@ class VakSerializer(serializers.ModelSerializer): class Meta: model = Vak - fields = '__all__' - + fields = "__all__" + def create(self, validated_data): - students_data = validated_data.pop('students') - teachers_data = validated_data.pop('teachers') - projects_data = validated_data.pop('projects') - + students_data = validated_data.pop("students") + teachers_data = validated_data.pop("teachers") + projects_data = validated_data.pop("projects") + validate_students_teachers(students_data, teachers_data) vak = Vak.objects.create(**validated_data) @@ -24,11 +24,11 @@ def create(self, validated_data): return vak def update(self, instance, validated_data): - instance.name = validated_data.pop('name') + instance.name = validated_data.pop("name") - students_data = validated_data.pop('students', []) - teachers_data = validated_data.pop('teachers', []) - projects_data = validated_data.pop('projects', []) + students_data = validated_data.pop("students", []) + teachers_data = validated_data.pop("teachers", []) + projects_data = validated_data.pop("projects", []) validate_students_teachers(students_data, teachers_data) @@ -45,17 +45,23 @@ def update(self, instance, validated_data): instance.save() populate_student_teacher_vakken(instance) - + return instance - + + def validate_students_teachers(students_data, teachers_data): for student in students_data: if student.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'students' moeten studenten zijn") + raise serializers.ValidationError( + "Alle gebruikers in 'students' moeten studenten zijn" + ) for teacher in teachers_data: if not teacher.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'teachers' moeten lesgevers zijn") + raise serializers.ValidationError( + "Alle gebruikers in 'teachers' moeten lesgevers zijn" + ) + def populate_student_teacher_vakken(vak): for student in vak.students.all(): @@ -64,9 +70,10 @@ def populate_student_teacher_vakken(vak): for teacher in vak.teachers.all(): teacher.subjects.add(vak) + def depopulate_student_teacher_vakken(vak): for student in vak.students.all(): student.subjects.remove(vak) for teacher in vak.teachers.all(): - teacher.subjects.remove(vak) \ No newline at end of file + teacher.subjects.remove(vak) diff --git a/api/settings.py b/api/settings.py index bea4ecbe..25007a4a 100644 --- a/api/settings.py +++ b/api/settings.py @@ -24,71 +24,71 @@ # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ.get('SECRET_KEY') +SECRET_KEY = os.environ.get("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['sel2-4.ugent.be', 'localhost', '127.0.0.1'] +ALLOWED_HOSTS = ["sel2-4.ugent.be", "localhost", "127.0.0.1"] # Application definition INSTALLED_APPS = [ - 'rest_framework', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'django_auth_adfs', - 'api', + "rest_framework", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "django_auth_adfs", + "api", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", #'api.middleware.RedirectAnonymousUserMiddleware', ] -ROOT_URLCONF = 'api.urls' +ROOT_URLCONF = "api.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'api.wsgi.application' +WSGI_APPLICATION = "api.wsgi.application" # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': os.environ.get('DB_ENGINE'), - 'NAME': os.environ.get('DB_NAME'), - 'USER': os.environ.get('DB_USER'), - 'PASSWORD': os.environ.get('DB_PASSWORD'), - 'HOST': os.environ.get('DB_HOST'), - 'PORT': os.environ.get('DB_PORT'), + "default": { + "ENGINE": os.environ.get("DB_ENGINE"), + "NAME": os.environ.get("DB_NAME"), + "USER": os.environ.get("DB_USER"), + "PASSWORD": os.environ.get("DB_PASSWORD"), + "HOST": os.environ.get("DB_HOST"), + "PORT": os.environ.get("DB_PORT"), } } @@ -98,16 +98,16 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -115,9 +115,9 @@ # Internationalization # https://docs.djangoproject.com/en/5.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -127,40 +127,42 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = "static/" # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -STATIC_ROOT = os.path.join(BASE_DIR, 'static/') +STATIC_ROOT = os.path.join(BASE_DIR, "static/") -CLIENT_ID = os.environ.get('CLIENT_ID') -CLIENT_SECRET = os.environ.get('CLIENT_SECRET') -TENANT_ID = os.environ.get('TENANT_ID') +CLIENT_ID = os.environ.get("CLIENT_ID") +CLIENT_SECRET = os.environ.get("CLIENT_SECRET") +TENANT_ID = os.environ.get("TENANT_ID") -AD_URL = os.environ.get('AD_URL') +AD_URL = os.environ.get("AD_URL") AUTH_ADFS = { - 'AUDIENCE': CLIENT_ID, - 'CLIENT_ID': CLIENT_ID, - 'CLIENT_SECRET': CLIENT_SECRET, - 'CLAIM_MAPPING': {'first_name': 'given_name', - 'last_name': 'family_name', - 'email': 'upn'}, - 'GROUPS_CLAIM': 'roles', - 'MIRROR_GROUPS': True, - 'USERNAME_CLAIM': 'upn', - 'TENANT_ID': TENANT_ID, - 'RELYING_PARTY_ID': CLIENT_ID, + "AUDIENCE": CLIENT_ID, + "CLIENT_ID": CLIENT_ID, + "CLIENT_SECRET": CLIENT_SECRET, + "CLAIM_MAPPING": { + "first_name": "given_name", + "last_name": "family_name", + "email": "upn", + }, + "GROUPS_CLAIM": "roles", + "MIRROR_GROUPS": True, + "USERNAME_CLAIM": "upn", + "TENANT_ID": TENANT_ID, + "RELYING_PARTY_ID": CLIENT_ID, } AUTHENTICATION_BACKENDS = [ - 'django_auth_adfs.backend.AdfsAuthCodeBackend', + "django_auth_adfs.backend.AdfsAuthCodeBackend", ] LOGIN_URL = "django_auth_adfs:login" -LOGIN_REDIRECT_URL = "/login_redirect" \ No newline at end of file +LOGIN_REDIRECT_URL = "/login_redirect" diff --git a/api/tests/factories/gebruiker.py b/api/tests/factories/gebruiker.py index 6267cf91..05fb4c40 100644 --- a/api/tests/factories/gebruiker.py +++ b/api/tests/factories/gebruiker.py @@ -2,12 +2,14 @@ from api.models.gebruiker import Gebruiker import factory + class UserFactory(factory.django.DjangoModelFactory): class Meta: model = User - username = factory.Sequence(lambda n: f'user{n}') - password = factory.PostGenerationMethodCall('set_password', 'password') + username = factory.Sequence(lambda n: f"user{n}") + password = factory.PostGenerationMethodCall("set_password", "password") + class GebruikerFactory(factory.django.DjangoModelFactory): class Meta: diff --git a/api/tests/models/test_gebruiker.py b/api/tests/models/test_gebruiker.py index ca3cff74..5971ada5 100644 --- a/api/tests/models/test_gebruiker.py +++ b/api/tests/models/test_gebruiker.py @@ -2,30 +2,31 @@ from api.models.gebruiker import Gebruiker from django.contrib.auth.models import User + class GebruikerTestCase(TestCase): def setUp(self): - user1 = User.objects.create_user(username='user1') - user2 = User.objects.create_user(username='user2') + user1 = User.objects.create_user(username="user1") + user2 = User.objects.create_user(username="user2") Gebruiker.objects.create(user=user1, is_lesgever=False) Gebruiker.objects.create(user=user2, is_lesgever=True) def test_gebruiker_is_lesgever(self): - user1 = Gebruiker.objects.get(user__username='user1') - user2 = Gebruiker.objects.get(user__username='user2') + user1 = Gebruiker.objects.get(user__username="user1") + user2 = Gebruiker.objects.get(user__username="user2") self.assertEqual(user1.is_lesgever, False) self.assertEqual(user2.is_lesgever, True) def test_user_label(self): - user = Gebruiker.objects.get(user__username='user1') - field_label = user._meta.get_field('user').verbose_name - self.assertEqual(field_label, 'user') + user = Gebruiker.objects.get(user__username="user1") + field_label = user._meta.get_field("user").verbose_name + self.assertEqual(field_label, "user") def test_subjects_label(self): - user = Gebruiker.objects.get(user__username='user1') - field_label = user._meta.get_field('subjects').verbose_name - self.assertEqual(field_label, 'subjects') - + user = Gebruiker.objects.get(user__username="user1") + field_label = user._meta.get_field("subjects").verbose_name + self.assertEqual(field_label, "subjects") + def test_str_method(self): - gebruiker = Gebruiker.objects.get(user__username='user1') + gebruiker = Gebruiker.objects.get(user__username="user1") expected_object_name = gebruiker.user.first_name - self.assertEqual(str(gebruiker), expected_object_name) \ No newline at end of file + self.assertEqual(str(gebruiker), expected_object_name) diff --git a/api/tests/serializers/test_gebruiker.py b/api/tests/serializers/test_gebruiker.py index 209a8a14..cc8186cd 100644 --- a/api/tests/serializers/test_gebruiker.py +++ b/api/tests/serializers/test_gebruiker.py @@ -6,14 +6,15 @@ from django.contrib.auth.models import User from api.models.vak import Vak + class GebruikerSerializerTest(APITestCase): def setUp(self): # Create a User instance - self.user = User.objects.create_user(username='testuser') + self.user = User.objects.create_user(username="testuser") self.gebruiker_attributes = { - 'user': self.user, + "user": self.user, } self.serializer_data = GebruikerSerializer().data @@ -28,17 +29,17 @@ def setUp(self): def test_contains_expected_fields(self): data = self.serializer.data - self.assertCountEqual(data.keys(), ['user', 'is_lesgever', 'subjects']) + self.assertCountEqual(data.keys(), ["user", "is_lesgever", "subjects"]) def test_user_field_content(self): data = self.serializer.data - self.assertEqual(data['user'], self.user.id) + self.assertEqual(data["user"], self.user.id) def test_subjects_field_content(self): data = self.serializer.data subjects = [subject.pk for subject in self.gebruiker.subjects.all()] - self.assertEqual(data['subjects'], subjects) + self.assertEqual(data["subjects"], subjects) def test_validation_for_blank_items(self): - serializer = GebruikerSerializer(data={'name': '', 'subjects': []}) - self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) \ No newline at end of file + serializer = GebruikerSerializer(data={"name": "", "subjects": []}) + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/test_views.py b/api/tests/test_views.py index 88a8195b..4f06e8a5 100644 --- a/api/tests/test_views.py +++ b/api/tests/test_views.py @@ -1,4 +1,4 @@ -''' from django.test import TestCase +""" from django.test import TestCase from django.urls import reverse class TestViews(TestCase): @@ -6,4 +6,4 @@ def test_should_show_register_page(self): #self.client.get(reverse('register')) #self.assertEqual(response.status_code, 200) #self.assertTemplateUsed(response, "authentication/register") - self.assertTrue(True) ''' \ No newline at end of file + self.assertTrue(True) """ diff --git a/api/tests/views/test_gebruiker.py b/api/tests/views/test_gebruiker.py index 0c2d8ff9..7795aeb1 100644 --- a/api/tests/views/test_gebruiker.py +++ b/api/tests/views/test_gebruiker.py @@ -9,12 +9,12 @@ def setUp(self): self.gebruiker = GebruikerFactory.create() def test_get_gebruiker_list(self): - response = self.client.get('/api/gebruikers/') + response = self.client.get("/api/gebruikers/") self.assertEqual(response.status_code, 200) def test_post_gebruiker_list(self): - data = {'user': UserFactory.create().id, 'is_lesgever': True} - response = self.client.post('/api/gebruikers/', data) + data = {"user": UserFactory.create().id, "is_lesgever": True} + response = self.client.post("/api/gebruikers/", data) self.assertEqual(response.status_code, 201) @@ -22,15 +22,15 @@ class GebruikerDetailViewTest(APITestCase): def setUp(self): self.client = APIClient() self.gebruiker = GebruikerFactory.create() - self.url = reverse('gebruiker_detail', kwargs={'id': self.gebruiker.user.id}) + self.url = reverse("gebruiker_detail", kwargs={"id": self.gebruiker.user.id}) def test_get_gebruiker_detail(self): response = self.client.get(self.url) self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['user'], self.gebruiker.user.id) + self.assertEqual(response.data["user"], self.gebruiker.user.id) def test_put_gebruiker_detail(self): - data = {'user': self.gebruiker.user.id, 'is_lesgever': True, 'subjects': []} + data = {"user": self.gebruiker.user.id, "is_lesgever": True, "subjects": []} response = self.client.put(self.url, data) self.assertEqual(response.status_code, 200) - #self.assertEqual(response.data['is_lesgever'], True) + # self.assertEqual(response.data['is_lesgever'], True) diff --git a/api/urls.py b/api/urls.py index 3de95fd8..8f03251a 100644 --- a/api/urls.py +++ b/api/urls.py @@ -14,6 +14,7 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + from django.contrib import admin from django.urls import path, include from rest_framework.urlpatterns import format_suffix_patterns @@ -27,23 +28,23 @@ from .views.groep import groep_list, groep_detail urlpatterns = [ - path('.well-known/microsoft-identity-association.json', microsoft_association), - path('admin/', admin.site.urls), - path('oauth2/', include('django_auth_adfs.urls')), - path('login_redirect/', login_redirect), - path('api/', home), - path('api/gebruikers/', gebruiker_list), - path('api/gebruikers//', gebruiker_detail, name='gebruiker_detail'), - path('api/vakken/', vak_list), - path('api/vakken//', vak_detail), - path('api/projecten/', project_list), - path('api/projecten//', project_detail), - path('api/indieningen/', indiening_list), - path('api/indieningen//', indiening_detail), - path('api/scores/', score_list), - path('api/scores//', score_detail), - path('api/groepen/', groep_list), - path('api/groepen//', groep_detail) + path(".well-known/microsoft-identity-association.json", microsoft_association), + path("admin/", admin.site.urls), + path("oauth2/", include("django_auth_adfs.urls")), + path("login_redirect/", login_redirect), + path("api/", home), + path("api/gebruikers/", gebruiker_list), + path("api/gebruikers//", gebruiker_detail, name="gebruiker_detail"), + path("api/vakken/", vak_list), + path("api/vakken//", vak_detail), + path("api/projecten/", project_list), + path("api/projecten//", project_detail), + path("api/indieningen/", indiening_list), + path("api/indieningen//", indiening_detail), + path("api/scores/", score_list), + path("api/scores//", score_detail), + path("api/groepen/", groep_list), + path("api/groepen//", groep_detail), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/api/utils.py b/api/utils.py index d79a5acd..d160339f 100644 --- a/api/utils.py +++ b/api/utils.py @@ -3,28 +3,31 @@ API_URLS = { - 'gebruikers': '/api/gebruikers', - 'vakken': '/api/vakken', - 'groepen': '/api/groepen', - 'indieningen': '/api/indieningen', - 'scores': 'api/scores' + "gebruikers": "/api/gebruikers", + "vakken": "/api/vakken", + "groepen": "/api/groepen", + "indieningen": "/api/indieningen", + "scores": "api/scores", } def get_graph_token(): """ - Get graph token from AD url. + Get graph token from AD url. """ try: url = settings.AD_URL - headers = {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'} + headers = { + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "application/json", + } data = { - 'grant_type': 'client_credentials', - 'client_id': settings.CLIENT_ID, - 'client_secret': settings.CLIENT_SECRET, - 'scope': 'https://graph.microsoft.com/.default', + "grant_type": "client_credentials", + "client_id": settings.CLIENT_ID, + "client_secret": settings.CLIENT_SECRET, + "scope": "https://graph.microsoft.com/.default", } response = requests.post(url=url, headers=headers, data=data) diff --git a/api/views/gebruiker.py b/api/views/gebruiker.py index b7d5a3e6..b45b217c 100644 --- a/api/views/gebruiker.py +++ b/api/views/gebruiker.py @@ -6,41 +6,43 @@ from api.serializers.gebruiker import GebruikerSerializer - - -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def gebruiker_list(request): - if request.method == 'GET': + if request.method == "GET": gebruikers = Gebruiker.objects.all() - - if 'is_lesgever' in request.GET and request.GET.get('is_lesgever').lower() in ['true', 'false']: - gebruikers = gebruikers.filter(is_lesgever = (request.GET.get('is_lesgever').lower() == 'true')) + + if "is_lesgever" in request.GET and request.GET.get("is_lesgever").lower() in [ + "true", + "false", + ]: + gebruikers = gebruikers.filter( + is_lesgever=(request.GET.get("is_lesgever").lower() == "true") + ) serializer = GebruikerSerializer(gebruikers, many=True) return Response(serializer.data) - elif request.method == 'POST': + elif request.method == "POST": serializer = GebruikerSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - -@api_view(['GET', 'PUT']) + +@api_view(["GET", "PUT"]) def gebruiker_detail(request, id): try: gebruiker = Gebruiker.objects.get(pk=id) except Gebruiker.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = GebruikerSerializer(gebruiker) return Response(serializer.data) - if request.method == 'PUT': + if request.method == "PUT": serializer = GebruikerSerializer(gebruiker, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - diff --git a/api/views/groep.py b/api/views/groep.py index e3ba6984..ccb04fb1 100644 --- a/api/views/groep.py +++ b/api/views/groep.py @@ -6,55 +6,55 @@ from api.serializers.groep import GroepSerializer -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def groep_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": groepen = Groep.objects.all() if "project" in request.GET: try: - project = eval(request.GET.get('project')) + project = eval(request.GET.get("project")) groepen = groepen.filter(project=project) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) - + if "student" in request.GET: try: - student = eval(request.GET.get('student')) + student = eval(request.GET.get("student")) groepen = groepen.filter(students=student) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) - serializer = GroepSerializer(groepen, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": serializer = GroepSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - -@api_view(['GET', 'PUT', 'DELETE']) -def groep_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def groep_detail(request, id, format=None): try: groep = Groep.objects.get(pk=id) except Groep.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = GroepSerializer(groep) return Response(serializer.data) - - elif request.method == 'PUT': + + elif request.method == "PUT": serializer = GroepSerializer(groep, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": groep.delete() - return Response(status=status.HTTP_204_NO_CONTENT) \ No newline at end of file + return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/api/views/indiening.py b/api/views/indiening.py index 2ca2dcff..6747cf4b 100644 --- a/api/views/indiening.py +++ b/api/views/indiening.py @@ -6,38 +6,39 @@ from api.serializers.indiening import IndieningSerializer -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def indiening_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": lesgevers = Indiening.objects.all() serializer = IndieningSerializer(lesgevers, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": serializer = IndieningSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) - -@api_view(['GET', 'PUT', 'DELETE']) -def indiening_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def indiening_detail(request, id, format=None): try: indiening = Indiening.objects.get(pk=id) except Indiening.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = IndieningSerializer(indiening) return Response(serializer.data) - - elif request.method == 'PUT': + + elif request.method == "PUT": serializer = IndieningSerializer(indiening, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": indiening.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/api/views/project.py b/api/views/project.py index 21e40e47..b81ef453 100644 --- a/api/views/project.py +++ b/api/views/project.py @@ -6,47 +6,48 @@ from api.serializers.project import ProjectSerializer -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def project_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": projects = Project.objects.all() - if 'vak' in request.GET: + if "vak" in request.GET: try: - vak = eval(request.GET.get('vak')) + vak = eval(request.GET.get("vak")) projects = projects.filter(vak=vak) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) serializer = ProjectSerializer(projects, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": serializer = ProjectSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - -@api_view(['GET', 'PUT', 'DELETE']) -def project_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def project_detail(request, id, format=None): try: project = Project.objects.get(pk=id) except Project.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = ProjectSerializer(project) return Response(serializer.data) - - elif request.method == 'PUT': + + elif request.method == "PUT": serializer = ProjectSerializer(project, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": project.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/api/views/score.py b/api/views/score.py index 0ade5e17..b519f6a2 100644 --- a/api/views/score.py +++ b/api/views/score.py @@ -6,38 +6,39 @@ from api.serializers.score import ScoreSerializer -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def score_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": scores = Score.objects.all() serializer = ScoreSerializer(scores, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": serializer = ScoreSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) - -@api_view(['GET', 'PUT', 'DELETE']) -def score_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def score_detail(request, id, format=None): try: score = Score.objects.get(pk=id) except Score.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = ScoreSerializer(score) return Response(serializer.data) - - elif request.method == 'PUT': + + elif request.method == "PUT": serializer = ScoreSerializer(score, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": score.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/api/views/vak.py b/api/views/vak.py index 1d266ab8..5d1785d5 100644 --- a/api/views/vak.py +++ b/api/views/vak.py @@ -8,36 +8,36 @@ from django.core.exceptions import ValidationError -@api_view(['GET', 'POST']) +@api_view(["GET", "POST"]) def vak_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": lesgevers = Vak.objects.all() serializer = VakSerializer(lesgevers, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": try: serializer = VakSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) except ValidationError as e: - return Response({'error': e}, status=status.HTTP_400_BAD_REQUEST) - - -@api_view(['GET', 'PUT', 'DELETE']) + return Response({"error": e}, status=status.HTTP_400_BAD_REQUEST) + + +@api_view(["GET", "PUT", "DELETE"]) def vak_detail(request, id, format=None): try: vak = Vak.objects.get(pk=id) except Vak.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": serializer = VakSerializer(vak) return Response(serializer.data) - - elif request.method == 'PUT': + + elif request.method == "PUT": try: serializer = VakSerializer(vak, data=request.data) if serializer.is_valid(): @@ -45,8 +45,8 @@ def vak_detail(request, id, format=None): return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) except ValidationError as e: - return Response({'error': e}, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + return Response({"error": e}, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == "DELETE": vak.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/api/views/views.py b/api/views/views.py index ed629af6..30994f7b 100644 --- a/api/views/views.py +++ b/api/views/views.py @@ -9,9 +9,9 @@ def login_redirect(request): gebruiker_post_data = { - 'user': request.user.id, - 'subjects': [], - 'is_lesgever': False + "user": request.user.id, + "subjects": [], + "is_lesgever": False, } serializer = GebruikerSerializer(data=gebruiker_post_data) if serializer.is_valid(): @@ -19,9 +19,17 @@ def login_redirect(request): return redirect(home) -@api_view(['GET']) + +@api_view(["GET"]) def home(request): return Response(data=API_URLS) + def microsoft_association(request): - return JsonResponse({"associatedApplications": [{ "applicationId": "239ce609-e362-4cf6-919f-97e6935ef5f5" }]}) + return JsonResponse( + { + "associatedApplications": [ + {"applicationId": "239ce609-e362-4cf6-919f-97e6935ef5f5"} + ] + } + ) diff --git a/api/wsgi.py b/api/wsgi.py index e494f617..db45992e 100644 --- a/api/wsgi.py +++ b/api/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings") application = get_wsgi_application() From 18c5059fecee3a599ce2f1d5d8b76c89e564f905 Mon Sep 17 00:00:00 2001 From: Mathis De Witte Date: Sun, 10 Mar 2024 16:20:16 +0100 Subject: [PATCH 07/44] instructies omtrent api --- api/README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 api/README.md diff --git a/api/README.md b/api/README.md new file mode 100644 index 00000000..b2cb7817 --- /dev/null +++ b/api/README.md @@ -0,0 +1,36 @@ +# Backend +Deze folder bevat de code van de backend. + +## Hoe runnen? + +### Benodigdheden: +- .env bestand: In deze folder moet je lokaal een .env bestand zetten. Het .env bestand bevat geheime variabelen en codes die je niet in deze repo zal vinden. Vraag het aan iemand van het backend team als je de file wilt krijgen. + +- postgres databank: Je zal zelf een postgres databank moeten opzetten. De naam van de databank, user, paswoord, ... Kan je lezen in het .env bestand. + +- virtual environment: Je zal ook een virtual environment moeten maken. Doe dit op linux met het commando: `python -m venv /path/to/new/virtual/environment`. +Vervolgens activeer je de virtual environment als volgt: `source my_env/bin/activate`. +Tenslotte installeer je alle dependencies: `pip install -r requirements.txt`. + +### de api lokaal runnen: +Om de api lokaal te runnen activeer je eerst de virtual environment. Daarna voer je volgende commando's uit vanaf de UGent-4 directory: +```sh +./manage.py makemigrations api +./manage.py migrate api +./manage.py runserver +``` +Je kan dan surfen naar http://127.0.0.1:8000/ om de api te zien. + +## Hoe testen? + +**OPMERKING**: Al de volgende commando's moeten uitgevoerd worden terwijl de virtual environment geactiveerd is. + +Je checkt zowel de linting als de tests. + +### Linting: +De volgende commando's run je van de ***api*** directory: +Run het commando `flake8 .`. De output vertelt je waar de codestijl fout is. Om snel deze stijlfouten op te lossen kan je `black .`runnen. + + +### Testing: +Run het commando `./manage.py test` uit in de ***UGENT-4*** directory. From 01d80b6d4ac5a06240c3a46ddbebd8e34cc16fc9 Mon Sep 17 00:00:00 2001 From: Mathis De Witte Date: Sun, 10 Mar 2024 16:20:56 +0100 Subject: [PATCH 08/44] update readme --- api/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/README.md b/api/README.md index b2cb7817..8683619a 100644 --- a/api/README.md +++ b/api/README.md @@ -6,14 +6,14 @@ Deze folder bevat de code van de backend. ### Benodigdheden: - .env bestand: In deze folder moet je lokaal een .env bestand zetten. Het .env bestand bevat geheime variabelen en codes die je niet in deze repo zal vinden. Vraag het aan iemand van het backend team als je de file wilt krijgen. -- postgres databank: Je zal zelf een postgres databank moeten opzetten. De naam van de databank, user, paswoord, ... Kan je lezen in het .env bestand. +- postgres databank: Je zal zelf een postgres databank moeten opzetten. De naam van de databank, user, paswoord, ... Kan je vinden in het .env bestand. - virtual environment: Je zal ook een virtual environment moeten maken. Doe dit op linux met het commando: `python -m venv /path/to/new/virtual/environment`. Vervolgens activeer je de virtual environment als volgt: `source my_env/bin/activate`. Tenslotte installeer je alle dependencies: `pip install -r requirements.txt`. ### de api lokaal runnen: -Om de api lokaal te runnen activeer je eerst de virtual environment. Daarna voer je volgende commando's uit vanaf de UGent-4 directory: +Om de api lokaal te runnen activeer je eerst de virtual environment. Daarna voer je volgende commando's uit in de UGent-4 directory: ```sh ./manage.py makemigrations api ./manage.py migrate api From 82b8a41d28109874b09027eb31d4d5b51ae2e2fc Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Sun, 10 Mar 2024 16:31:30 +0100 Subject: [PATCH 09/44] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 545a50cf..92d10c3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ django-auth-adfs python-dotenv coverage flake8 +black factory_boy From 07cb9104b297cba384ed2e1397a27abc08790502 Mon Sep 17 00:00:00 2001 From: arallaer Date: Sun, 10 Mar 2024 19:45:48 +0100 Subject: [PATCH 10/44] groep tests + factories --- api/tests/factories/groep.py | 23 +++++++++++++++ api/tests/factories/project.py | 17 +++++++++++ api/tests/factories/vak.py | 8 ++++++ api/tests/models/test_gebruiker.py | 30 ++++++++----------- api/tests/models/test_groep.py | 27 ++++++++++++++++++ api/tests/serializers/test_gebruiker.py | 23 ++++----------- api/tests/serializers/test_groep.py | 27 ++++++++++++++++++ api/tests/views/test_gebruiker.py | 2 +- api/tests/views/test_groep.py | 38 +++++++++++++++++++++++++ api/urls.py | 2 +- 10 files changed, 160 insertions(+), 37 deletions(-) create mode 100644 api/tests/factories/groep.py create mode 100644 api/tests/factories/project.py create mode 100644 api/tests/factories/vak.py create mode 100644 api/tests/models/test_groep.py create mode 100644 api/tests/serializers/test_groep.py create mode 100644 api/tests/views/test_groep.py diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py new file mode 100644 index 00000000..d4a4147f --- /dev/null +++ b/api/tests/factories/groep.py @@ -0,0 +1,23 @@ +import factory +from api.models.groep import Groep +from api.models.project import Project +from api.tests.factories.gebruiker import GebruikerFactory +from api.tests.factories.project import ProjectFactory + + +class GroepFactory(factory.django.DjangoModelFactory): + class Meta: + model = Groep + + project = factory.SubFactory(ProjectFactory) + + @factory.post_generation + def students(self, create, extracted, **kwargs): + if not create: + return + + if extracted: + for student in extracted: + self.students.add(student) + else: + self.students.add(GebruikerFactory()) diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py new file mode 100644 index 00000000..17d784eb --- /dev/null +++ b/api/tests/factories/project.py @@ -0,0 +1,17 @@ +from django.utils import timezone +import factory +from api.models.project import Project +from api.tests.factories.vak import VakFactory +from faker import Faker + +fake = Faker() + +class ProjectFactory(factory.django.DjangoModelFactory): + class Meta: + model = Project + + titel = factory.Faker('sentence', nb_words=4) + description = factory.Faker('paragraph') + opgavebestanden = factory.django.FileField(filename='opgave.pdf') + vak = factory.SubFactory(VakFactory) + deadline = factory.LazyFunction(lambda: timezone.make_aware(fake.date_time_between(start_date='+1d', end_date='+30d'))) \ No newline at end of file diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py new file mode 100644 index 00000000..cfaa8223 --- /dev/null +++ b/api/tests/factories/vak.py @@ -0,0 +1,8 @@ +import factory +from api.models.vak import Vak + +class VakFactory(factory.django.DjangoModelFactory): + class Meta: + model = Vak + + name = factory.Faker('word') \ No newline at end of file diff --git a/api/tests/models/test_gebruiker.py b/api/tests/models/test_gebruiker.py index 5971ada5..50a7ebd1 100644 --- a/api/tests/models/test_gebruiker.py +++ b/api/tests/models/test_gebruiker.py @@ -1,32 +1,26 @@ from django.test import TestCase -from api.models.gebruiker import Gebruiker -from django.contrib.auth.models import User +from api.tests.factories.gebruiker import UserFactory, GebruikerFactory -class GebruikerTestCase(TestCase): +class GebruikerModelTest(TestCase): def setUp(self): - user1 = User.objects.create_user(username="user1") - user2 = User.objects.create_user(username="user2") - Gebruiker.objects.create(user=user1, is_lesgever=False) - Gebruiker.objects.create(user=user2, is_lesgever=True) + self.user1 = UserFactory.create(username="user1") + self.user2 = UserFactory.create(username="user2") + self.gebruiker1 = GebruikerFactory.create(user=self.user1, is_lesgever=False) + self.gebruiker2 = GebruikerFactory.create(user=self.user2, is_lesgever=True) def test_gebruiker_is_lesgever(self): - user1 = Gebruiker.objects.get(user__username="user1") - user2 = Gebruiker.objects.get(user__username="user2") - self.assertEqual(user1.is_lesgever, False) - self.assertEqual(user2.is_lesgever, True) + self.assertEqual(self.gebruiker1.is_lesgever, False) + self.assertEqual(self.gebruiker2.is_lesgever, True) def test_user_label(self): - user = Gebruiker.objects.get(user__username="user1") - field_label = user._meta.get_field("user").verbose_name + field_label = self.gebruiker1._meta.get_field("user").verbose_name self.assertEqual(field_label, "user") def test_subjects_label(self): - user = Gebruiker.objects.get(user__username="user1") - field_label = user._meta.get_field("subjects").verbose_name + field_label = self.gebruiker1._meta.get_field("subjects").verbose_name self.assertEqual(field_label, "subjects") def test_str_method(self): - gebruiker = Gebruiker.objects.get(user__username="user1") - expected_object_name = gebruiker.user.first_name - self.assertEqual(str(gebruiker), expected_object_name) + expected_object_name = self.gebruiker1.user.first_name + self.assertEqual(str(self.gebruiker1), expected_object_name) diff --git a/api/tests/models/test_groep.py b/api/tests/models/test_groep.py new file mode 100644 index 00000000..7d56c840 --- /dev/null +++ b/api/tests/models/test_groep.py @@ -0,0 +1,27 @@ +from django.test import TestCase +from api.tests.factories.groep import GroepFactory +from api.tests.factories.gebruiker import GebruikerFactory +from api.tests.factories.project import ProjectFactory +from api.tests.factories.vak import VakFactory +from api.models.groep import Groep + + +class GroepModelTest(TestCase): + def setUp(self): + self.gebruiker = GebruikerFactory.create() + self.vak = VakFactory.create() + self.project = ProjectFactory.create(vak=self.vak) + self.groep = GroepFactory.create(project=self.project) + + + def test_groep_creation(self): + self.assertIsInstance(self.groep, Groep) + self.assertEqual(self.groep.__str__(), f"Group {self.groep.group_id}") + + def test_groep_students(self): + self.groep.students.add(self.gebruiker) + self.assertEqual(self.groep.students.count(), 2) + self.assertEqual(self.groep.students.first(), self.gebruiker) + + def test_groep_project(self): + self.assertEqual(self.groep.project, self.project) \ No newline at end of file diff --git a/api/tests/serializers/test_gebruiker.py b/api/tests/serializers/test_gebruiker.py index cc8186cd..d19b60c0 100644 --- a/api/tests/serializers/test_gebruiker.py +++ b/api/tests/serializers/test_gebruiker.py @@ -1,29 +1,18 @@ from django.test import TestCase from rest_framework.test import APITestCase from rest_framework.exceptions import ValidationError -from api.models.gebruiker import Gebruiker from api.serializers.gebruiker import GebruikerSerializer -from django.contrib.auth.models import User -from api.models.vak import Vak - +from api.tests.factories.gebruiker import UserFactory, GebruikerFactory +from api.tests.factories.vak import VakFactory class GebruikerSerializerTest(APITestCase): def setUp(self): - # Create a User instance - self.user = User.objects.create_user(username="testuser") - - self.gebruiker_attributes = { - "user": self.user, - } - - self.serializer_data = GebruikerSerializer().data - self.gebruiker = Gebruiker.objects.create(**self.gebruiker_attributes) + self.user = UserFactory.create(username="testuser") + self.gebruiker = GebruikerFactory.create(user=self.user) - subjects = [1, 2] - for subject in subjects: - vak = Vak.objects.create(name=subject) - self.gebruiker.subjects.add(vak) + subjects = VakFactory.create_batch(2) + self.gebruiker.subjects.set(subjects) self.serializer = GebruikerSerializer(instance=self.gebruiker) diff --git a/api/tests/serializers/test_groep.py b/api/tests/serializers/test_groep.py new file mode 100644 index 00000000..2c7fbdfc --- /dev/null +++ b/api/tests/serializers/test_groep.py @@ -0,0 +1,27 @@ +from rest_framework.test import APITestCase +from rest_framework.exceptions import ValidationError +from api.serializers.groep import GroepSerializer +from api.tests.factories.groep import GroepFactory + +class GroepSerializerTest(APITestCase): + + def setUp(self): + self.groep = GroepFactory.create() + self.serializer = GroepSerializer(instance=self.groep) + + def test_contains_expected_fields(self): + data = self.serializer.data + self.assertCountEqual(data.keys(), ["group_id", "project", "students"]) + + def test_project_field_content(self): + data = self.serializer.data + self.assertEqual(data["project"], self.groep.project.pk) # replace 'pk' with the correct primary key field of the Project model + + def test_students_field_content(self): + data = self.serializer.data + students = [student.pk for student in self.groep.students.all()] + self.assertEqual(data["students"], students) + + def test_validation_for_blank_items(self): + serializer = GroepSerializer(data={"project": "", "students": []}) + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) \ No newline at end of file diff --git a/api/tests/views/test_gebruiker.py b/api/tests/views/test_gebruiker.py index 7795aeb1..4eb37584 100644 --- a/api/tests/views/test_gebruiker.py +++ b/api/tests/views/test_gebruiker.py @@ -6,7 +6,6 @@ class GebruikerListViewTest(APITestCase): def setUp(self): self.client = APIClient() - self.gebruiker = GebruikerFactory.create() def test_get_gebruiker_list(self): response = self.client.get("/api/gebruikers/") @@ -33,4 +32,5 @@ def test_put_gebruiker_detail(self): data = {"user": self.gebruiker.user.id, "is_lesgever": True, "subjects": []} response = self.client.put(self.url, data) self.assertEqual(response.status_code, 200) + # TODO # self.assertEqual(response.data['is_lesgever'], True) diff --git a/api/tests/views/test_groep.py b/api/tests/views/test_groep.py new file mode 100644 index 00000000..96b9122c --- /dev/null +++ b/api/tests/views/test_groep.py @@ -0,0 +1,38 @@ +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient, APITestCase +from api.tests.factories.groep import GroepFactory +from api.tests.factories.project import ProjectFactory + + +class GroepListViewTest(APITestCase): + def setUp(self): + self.client = APIClient() + + def test_get_groep_list(self): + response = self.client.get("/api/groepen/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_post_groep_list(self): + groep = GroepFactory.create() + data = {"groep": groep.group_id, "project":groep.project.project_id, "students": []} + response = self.client.post("/api/groepen/", data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + + +class GroepDetailViewTest(APITestCase): + + def setUp(self): + self.client = APIClient() + self.groep = GroepFactory.create() + self.url = reverse('groep_detail', kwargs={'id': self.groep.group_id}) + + def test_get_groep_detail(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_get_invalid_groep(self): + url = reverse('groep_detail', kwargs={'id': 10101}) + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) diff --git a/api/urls.py b/api/urls.py index 8f03251a..2ac84023 100644 --- a/api/urls.py +++ b/api/urls.py @@ -44,7 +44,7 @@ path("api/scores/", score_list), path("api/scores//", score_detail), path("api/groepen/", groep_list), - path("api/groepen//", groep_detail), + path("api/groepen//", groep_detail, name="groep_detail"), ] urlpatterns = format_suffix_patterns(urlpatterns) From 2970f456165c0557ed096b6e59c291a1683fbda4 Mon Sep 17 00:00:00 2001 From: arallaer Date: Sun, 10 Mar 2024 22:17:30 +0100 Subject: [PATCH 11/44] project tests --- api/tests/models/test_project.py | 29 ++++++++++ api/tests/serializers/test_project.py | 40 ++++++++++++++ api/tests/views/test_project.py | 77 +++++++++++++++++++++++++++ api/urls.py | 4 +- 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 api/tests/models/test_project.py create mode 100644 api/tests/serializers/test_project.py create mode 100644 api/tests/views/test_project.py diff --git a/api/tests/models/test_project.py b/api/tests/models/test_project.py new file mode 100644 index 00000000..44574f23 --- /dev/null +++ b/api/tests/models/test_project.py @@ -0,0 +1,29 @@ +from django.test import TestCase +from api.tests.factories.project import ProjectFactory + +class ProjectModelTest(TestCase): + def setUp(self): + self.project = ProjectFactory.create() + + def test_str_method(self): + self.assertEqual(str(self.project), self.project.titel) + + def test_titel_label(self): + field_label = self.project._meta.get_field('titel').verbose_name + self.assertEqual(field_label, 'titel') + + def test_description_label(self): + field_label = self.project._meta.get_field('description').verbose_name + self.assertEqual(field_label, 'description') + + def test_opgavebestanden_label(self): + field_label = self.project._meta.get_field('opgavebestanden').verbose_name + self.assertEqual(field_label, 'opgavebestanden') + + def test_vak_label(self): + field_label = self.project._meta.get_field('vak').verbose_name + self.assertEqual(field_label, 'vak') + + def test_deadline_label(self): + field_label = self.project._meta.get_field('deadline').verbose_name + self.assertEqual(field_label, 'deadline') \ No newline at end of file diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py new file mode 100644 index 00000000..a46967e5 --- /dev/null +++ b/api/tests/serializers/test_project.py @@ -0,0 +1,40 @@ +from django.test import TestCase +from rest_framework.test import APITestCase +from rest_framework.exceptions import ValidationError +from api.serializers.project import ProjectSerializer +from api.tests.factories.project import ProjectFactory +from dateutil.parser import parse + +class ProjectSerializerTest(APITestCase): + + def setUp(self): + self.project = ProjectFactory.create() + self.serializer = ProjectSerializer(instance=self.project) + + def test_contains_expected_fields(self): + data = self.serializer.data + self.assertCountEqual(data.keys(), ["project_id", "titel", "description", "opgavebestanden", "vak", "deadline"]) + + def test_titel_field_content(self): + data = self.serializer.data + self.assertEqual(data["titel"], self.project.titel) + + def test_description_field_content(self): + data = self.serializer.data + self.assertEqual(data["description"], self.project.description) + + def test_opgavebestanden_field_content(self): + data = self.serializer.data + self.assertEqual(data["opgavebestanden"].lstrip('/'), str(self.project.opgavebestanden)) + + def test_vak_field_content(self): + data = self.serializer.data + self.assertEqual(data["vak"], self.project.vak.pk) # replace 'pk' with the correct primary key field of the Vak model + + def test_deadline_field_content(self): + data = self.serializer.data + self.assertEqual(parse(data["deadline"]), self.project.deadline) + + def test_validation_for_blank_items(self): + serializer = ProjectSerializer(data={"titel": "", "description": "", "opgavebestanden": "", "vak": "", "deadline": ""}) + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) \ No newline at end of file diff --git a/api/tests/views/test_project.py b/api/tests/views/test_project.py new file mode 100644 index 00000000..2a51dcde --- /dev/null +++ b/api/tests/views/test_project.py @@ -0,0 +1,77 @@ +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APITestCase +from api.tests.factories.project import ProjectFactory +from api.tests.factories.vak import VakFactory + +class ProjectViewTest(APITestCase): + + def setUp(self): + self.project = ProjectFactory.create() + self.vak = VakFactory.create() + self.list_url = reverse('project_list') + self.detail_url = reverse('project_detail', kwargs={'id': self.project.project_id}) + + def test_get_project_list(self): + response = self.client.get(self.list_url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_get_project_detail(self): + response = self.client.get(self.detail_url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_get_invalid_project_detail(self): + url = reverse('project_detail', kwargs={'id': '9999999'}) + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_create_project(self): + data = { + "titel": "New Project", + "description": "This is a new project.", + "opgavebestanden": "data/opgaves/opgave.pdf", + "vak": self.vak.vak_id, + "deadline": "2022-12-31T23:59:59Z" + } + response = self.client.post(self.list_url, data) + # TODO + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + def test_create_invalid_project(self): + data = { + "titel": "", + "description": "", + "opgavebestanden": "", + "vak": "", + "deadline": "" + } + response = self.client.post(self.list_url, data) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + def test_update_project(self): + data = { + "titel": "Updated Project", + "description": "This project has been updated.", + "opgavebestanden": "data/opgaves/opgave.pdf", + "vak": self.project.vak.vak_id, + "deadline": "2023-12-31T23:59:59Z" + } + response = self.client.put(self.detail_url, data) + # TODO + # self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_update_invalid_project(self): + data = { + "titel": "", + "description": "", + "opgavebestanden": "", + "vak": "", + "deadline": "" + } + response = self.client.put(self.detail_url, data) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + + def test_delete_project(self): + response = self.client.delete(self.detail_url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) \ No newline at end of file diff --git a/api/urls.py b/api/urls.py index 2ac84023..0d93475d 100644 --- a/api/urls.py +++ b/api/urls.py @@ -37,8 +37,8 @@ path("api/gebruikers//", gebruiker_detail, name="gebruiker_detail"), path("api/vakken/", vak_list), path("api/vakken//", vak_detail), - path("api/projecten/", project_list), - path("api/projecten//", project_detail), + path("api/projecten/", project_list, name="project_list"), + path("api/projecten//", project_detail, name="project_detail"), path("api/indieningen/", indiening_list), path("api/indieningen//", indiening_detail), path("api/scores/", score_list), From cf5eafb8e11e0f5d07d08dfde7bd8e7b6e0e1bba Mon Sep 17 00:00:00 2001 From: arallaer Date: Sun, 10 Mar 2024 22:41:57 +0100 Subject: [PATCH 12/44] vak tests --- api/tests/models/test_vak.py | 25 ++++++++++++++ api/tests/serializers/test_vak.py | 41 +++++++++++++++++++++++ api/tests/views/test_vak.py | 55 +++++++++++++++++++++++++++++++ api/urls.py | 4 +-- 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 api/tests/models/test_vak.py create mode 100644 api/tests/serializers/test_vak.py create mode 100644 api/tests/views/test_vak.py diff --git a/api/tests/models/test_vak.py b/api/tests/models/test_vak.py new file mode 100644 index 00000000..ccbcf77b --- /dev/null +++ b/api/tests/models/test_vak.py @@ -0,0 +1,25 @@ +from django.test import TestCase +from api.tests.factories.vak import VakFactory + +class VakModelTest(TestCase): + def setUp(self): + self.vak = VakFactory.create() + + def test_str_method(self): + self.assertEqual(str(self.vak), self.vak.name) + + def test_vak_id_label(self): + field_label = self.vak._meta.get_field('vak_id').verbose_name + self.assertEqual(field_label, 'vak id') + + def test_name_label(self): + field_label = self.vak._meta.get_field('name').verbose_name + self.assertEqual(field_label, 'name') + + def test_students_label(self): + field_label = self.vak._meta.get_field('students').verbose_name + self.assertEqual(field_label, 'students') + + def test_teachers_label(self): + field_label = self.vak._meta.get_field('teachers').verbose_name + self.assertEqual(field_label, 'teachers') \ No newline at end of file diff --git a/api/tests/serializers/test_vak.py b/api/tests/serializers/test_vak.py new file mode 100644 index 00000000..1317700f --- /dev/null +++ b/api/tests/serializers/test_vak.py @@ -0,0 +1,41 @@ +from django.test import TestCase +from rest_framework.test import APITestCase +from rest_framework.exceptions import ValidationError +from api.serializers.vak import VakSerializer +from api.tests.factories.vak import VakFactory +from api.tests.factories.gebruiker import GebruikerFactory + + +class VakSerializerTest(APITestCase): + + def setUp(self): + self.students = GebruikerFactory.create_batch(3, is_lesgever=False) + self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) + self.vak = VakFactory.create() + self.vak.students.set(self.students) + self.vak.teachers.set(self.teachers) + self.serializer = VakSerializer(instance=self.vak) + + def test_contains_expected_fields(self): + data = self.serializer.data + self.assertCountEqual(data.keys(), ["vak_id", "name", "students", "teachers"]) # geen projects hier? + + def test_vak_id_field_content(self): + data = self.serializer.data + self.assertEqual(data["vak_id"], self.vak.vak_id) + + def test_name_field_content(self): + data = self.serializer.data + self.assertEqual(data["name"], self.vak.name) + + def test_students_field_content(self): + data = self.serializer.data + self.assertCountEqual(data["students"], [student.pk for student in self.students]) + + def test_teachers_field_content(self): + data = self.serializer.data + self.assertCountEqual(data["teachers"], [teacher.pk for teacher in self.teachers]) + + def test_validation_for_blank_items(self): + serializer = VakSerializer(data={"vak_id": "", "name": "", "students": [], "teachers": [], "projects": []}) + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/views/test_vak.py b/api/tests/views/test_vak.py new file mode 100644 index 00000000..026bf9ea --- /dev/null +++ b/api/tests/views/test_vak.py @@ -0,0 +1,55 @@ +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APITestCase +from api.tests.factories.vak import VakFactory +from api.tests.factories.gebruiker import GebruikerFactory +from api.models.vak import Vak + +class VakViewsTest(APITestCase): + + def setUp(self): + self.students = GebruikerFactory.create_batch(3, is_lesgever=False) + self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) + self.vak = VakFactory.create() + self.vak.students.set(self.students) + self.vak.teachers.set(self.teachers) + + def test_vak_list_get(self): + response = self.client.get(reverse('vak_list')) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) + + """" TODO: projecten bijhouden bij een vak ipv vakken bijhouden bij een project + def test_vak_list_post(self): + data = { + 'vak_id': 'test_vak_id', + 'name': 'test_name', + 'students': [student.pk for student in self.students], + 'teachers': [teacher.pk for teacher in self.teachers], + } + response = self.client.post(reverse('vak_list'), data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Vak.objects.count(), 2) + """ + + def test_vak_detail_get(self): + response = self.client.get(reverse('vak_detail', args=[self.vak.pk])) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['vak_id'], self.vak.vak_id) + + """" TODO: projecten bijhouden bij een vak ipv vakken bijhouden bij een project + def test_vak_detail_put(self): + data = { + 'vak_id': 'updated_vak_id', + 'name': 'updated_name', + 'students': [student.pk for student in self.students], + 'teachers': [teacher.pk for teacher in self.teachers], + } + response = self.client.put(reverse('vak_detail', args=[self.vak.pk]), data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['vak_id'], 'updated_vak_id') + """ + + def test_vak_detail_delete(self): + response = self.client.delete(reverse('vak_detail', args=[self.vak.pk])) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) \ No newline at end of file diff --git a/api/urls.py b/api/urls.py index 0d93475d..1d9ddb43 100644 --- a/api/urls.py +++ b/api/urls.py @@ -35,8 +35,8 @@ path("api/", home), path("api/gebruikers/", gebruiker_list), path("api/gebruikers//", gebruiker_detail, name="gebruiker_detail"), - path("api/vakken/", vak_list), - path("api/vakken//", vak_detail), + path("api/vakken/", vak_list, name="vak_list"), + path("api/vakken//", vak_detail, name="vak_detail"), path("api/projecten/", project_list, name="project_list"), path("api/projecten//", project_detail, name="project_detail"), path("api/indieningen/", indiening_list), From a740d14905d86519804e7fd06138d03d61bd3e7b Mon Sep 17 00:00:00 2001 From: arallaer Date: Sun, 10 Mar 2024 23:04:49 +0100 Subject: [PATCH 13/44] score tests fail --- api/tests/factories/indiening.py | 19 +++++++++++++++++++ api/tests/factories/score.py | 6 ++++++ api/tests/models/test_score.py | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 api/tests/factories/indiening.py create mode 100644 api/tests/factories/score.py create mode 100644 api/tests/models/test_score.py diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py new file mode 100644 index 00000000..03771a9b --- /dev/null +++ b/api/tests/factories/indiening.py @@ -0,0 +1,19 @@ +import factory +from api.models.indiening import Indiening +from api.models.groep import Groep +from django.core.files.base import ContentFile + +class GroepFactory(factory.django.DjangoModelFactory): + class Meta: + model = Groep + + # Add fields here. For example: + # field_name = factory.Faker('pystr') + +class IndieningFactory(factory.django.DjangoModelFactory): + class Meta: + model = Indiening + + indiener = factory.SubFactory(GroepFactory) + indieningsbestanden = factory.django.FileField(from_path=ContentFile(b"file content")) + tijdstip = factory.Faker('date_time_this_year') \ No newline at end of file diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py new file mode 100644 index 00000000..904978a0 --- /dev/null +++ b/api/tests/factories/score.py @@ -0,0 +1,6 @@ +import factory +from api.models.score import Score + +class ScoreFactory(factory.django.DjangoModelFactory): + class Meta: + model = Score diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py new file mode 100644 index 00000000..e52fa3f6 --- /dev/null +++ b/api/tests/models/test_score.py @@ -0,0 +1,24 @@ +from django.test import TestCase +from api.tests.factories.score import ScoreFactory +from api.tests.factories.groep import GroepFactory +from api.tests.factories.indiening import IndieningFactory + + +class ScoreModelTest(TestCase): + + def setUp(self): + self.indiening = IndieningFactory.create() + self.groep = GroepFactory.create() + self.score = ScoreFactory.create(indiening=self.indiening, groep=self.groep) + + def test_score_field(self): + self.assertIsInstance(self.score.score, int) + + def test_indiening_field(self): + self.assertEqual(self.score.indiening, self.indiening) + + def test_groep_field(self): + self.assertEqual(self.score.groep, self.groep) + + def test_str_method(self): + self.assertEqual(str(self.score), str(self.score.score)) \ No newline at end of file From 43302259fa87109dcb81dc91d568e658a9aa7358 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:53:20 +0100 Subject: [PATCH 14/44] Update README.md --- api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/README.md b/api/README.md index 8683619a..a822dcb4 100644 --- a/api/README.md +++ b/api/README.md @@ -33,4 +33,4 @@ Run het commando `flake8 .`. De output vertelt je waar de codestijl fout is. Om ### Testing: -Run het commando `./manage.py test` uit in de ***UGENT-4*** directory. +Run het commando `./manage.py test` in de ***UGENT-4*** directory. From 7d849da11035c384d688bb796bbfba268c43ef06 Mon Sep 17 00:00:00 2001 From: Mathis De Witte Date: Mon, 11 Mar 2024 12:43:44 +0100 Subject: [PATCH 15/44] stijlregels --- api/middleware.py | 1 - api/settings.py | 2 +- api/tests/factories/groep.py | 1 - api/tests/factories/indiening.py | 8 ++- api/tests/factories/project.py | 13 +++-- api/tests/factories/score.py | 1 + api/tests/factories/vak.py | 3 +- api/tests/models/test_groep.py | 3 +- api/tests/models/test_project.py | 21 ++++---- api/tests/models/test_score.py | 2 +- api/tests/models/test_vak.py | 17 ++++--- api/tests/serializers/test_gebruiker.py | 2 +- api/tests/serializers/test_groep.py | 7 ++- api/tests/serializers/test_project.py | 34 ++++++++++--- api/tests/serializers/test_vak.py | 23 +++++++-- api/tests/views/test_groep.py | 12 +++-- api/tests/views/test_project.py | 66 +++++++++++++------------ api/tests/views/test_vak.py | 13 ++--- api/utils.py | 2 +- api/views/views.py | 2 +- 20 files changed, 144 insertions(+), 89 deletions(-) diff --git a/api/middleware.py b/api/middleware.py index 33880a7f..bfeab7b8 100644 --- a/api/middleware.py +++ b/api/middleware.py @@ -1,6 +1,5 @@ from django.conf import settings from django.shortcuts import redirect -from django.urls import reverse class RedirectAnonymousUserMiddleware: diff --git a/api/settings.py b/api/settings.py index 25007a4a..f1f44c9b 100644 --- a/api/settings.py +++ b/api/settings.py @@ -54,7 +54,7 @@ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", - #'api.middleware.RedirectAnonymousUserMiddleware', + # 'api.middleware.RedirectAnonymousUserMiddleware', ] ROOT_URLCONF = "api.urls" diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py index d4a4147f..fffdc86f 100644 --- a/api/tests/factories/groep.py +++ b/api/tests/factories/groep.py @@ -1,6 +1,5 @@ import factory from api.models.groep import Groep -from api.models.project import Project from api.tests.factories.gebruiker import GebruikerFactory from api.tests.factories.project import ProjectFactory diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py index 03771a9b..8a3c47f8 100644 --- a/api/tests/factories/indiening.py +++ b/api/tests/factories/indiening.py @@ -3,6 +3,7 @@ from api.models.groep import Groep from django.core.files.base import ContentFile + class GroepFactory(factory.django.DjangoModelFactory): class Meta: model = Groep @@ -10,10 +11,13 @@ class Meta: # Add fields here. For example: # field_name = factory.Faker('pystr') + class IndieningFactory(factory.django.DjangoModelFactory): class Meta: model = Indiening indiener = factory.SubFactory(GroepFactory) - indieningsbestanden = factory.django.FileField(from_path=ContentFile(b"file content")) - tijdstip = factory.Faker('date_time_this_year') \ No newline at end of file + indieningsbestanden = factory.django.FileField( + from_path=ContentFile(b"file content") + ) + tijdstip = factory.Faker("date_time_this_year") diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py index 17d784eb..99d100be 100644 --- a/api/tests/factories/project.py +++ b/api/tests/factories/project.py @@ -6,12 +6,17 @@ fake = Faker() + class ProjectFactory(factory.django.DjangoModelFactory): class Meta: model = Project - titel = factory.Faker('sentence', nb_words=4) - description = factory.Faker('paragraph') - opgavebestanden = factory.django.FileField(filename='opgave.pdf') + titel = factory.Faker("sentence", nb_words=4) + description = factory.Faker("paragraph") + opgavebestanden = factory.django.FileField(filename="opgave.pdf") vak = factory.SubFactory(VakFactory) - deadline = factory.LazyFunction(lambda: timezone.make_aware(fake.date_time_between(start_date='+1d', end_date='+30d'))) \ No newline at end of file + deadline = factory.LazyFunction( + lambda: timezone.make_aware( + fake.date_time_between(start_date="+1d", end_date="+30d") + ) + ) diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index 904978a0..91087857 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -1,6 +1,7 @@ import factory from api.models.score import Score + class ScoreFactory(factory.django.DjangoModelFactory): class Meta: model = Score diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py index cfaa8223..969e15d5 100644 --- a/api/tests/factories/vak.py +++ b/api/tests/factories/vak.py @@ -1,8 +1,9 @@ import factory from api.models.vak import Vak + class VakFactory(factory.django.DjangoModelFactory): class Meta: model = Vak - name = factory.Faker('word') \ No newline at end of file + name = factory.Faker("word") diff --git a/api/tests/models/test_groep.py b/api/tests/models/test_groep.py index 7d56c840..f80fc16f 100644 --- a/api/tests/models/test_groep.py +++ b/api/tests/models/test_groep.py @@ -13,7 +13,6 @@ def setUp(self): self.project = ProjectFactory.create(vak=self.vak) self.groep = GroepFactory.create(project=self.project) - def test_groep_creation(self): self.assertIsInstance(self.groep, Groep) self.assertEqual(self.groep.__str__(), f"Group {self.groep.group_id}") @@ -24,4 +23,4 @@ def test_groep_students(self): self.assertEqual(self.groep.students.first(), self.gebruiker) def test_groep_project(self): - self.assertEqual(self.groep.project, self.project) \ No newline at end of file + self.assertEqual(self.groep.project, self.project) diff --git a/api/tests/models/test_project.py b/api/tests/models/test_project.py index 44574f23..92832af1 100644 --- a/api/tests/models/test_project.py +++ b/api/tests/models/test_project.py @@ -1,6 +1,7 @@ from django.test import TestCase from api.tests.factories.project import ProjectFactory + class ProjectModelTest(TestCase): def setUp(self): self.project = ProjectFactory.create() @@ -9,21 +10,21 @@ def test_str_method(self): self.assertEqual(str(self.project), self.project.titel) def test_titel_label(self): - field_label = self.project._meta.get_field('titel').verbose_name - self.assertEqual(field_label, 'titel') + field_label = self.project._meta.get_field("titel").verbose_name + self.assertEqual(field_label, "titel") def test_description_label(self): - field_label = self.project._meta.get_field('description').verbose_name - self.assertEqual(field_label, 'description') + field_label = self.project._meta.get_field("description").verbose_name + self.assertEqual(field_label, "description") def test_opgavebestanden_label(self): - field_label = self.project._meta.get_field('opgavebestanden').verbose_name - self.assertEqual(field_label, 'opgavebestanden') + field_label = self.project._meta.get_field("opgavebestanden").verbose_name + self.assertEqual(field_label, "opgavebestanden") def test_vak_label(self): - field_label = self.project._meta.get_field('vak').verbose_name - self.assertEqual(field_label, 'vak') + field_label = self.project._meta.get_field("vak").verbose_name + self.assertEqual(field_label, "vak") def test_deadline_label(self): - field_label = self.project._meta.get_field('deadline').verbose_name - self.assertEqual(field_label, 'deadline') \ No newline at end of file + field_label = self.project._meta.get_field("deadline").verbose_name + self.assertEqual(field_label, "deadline") diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py index e52fa3f6..70d99549 100644 --- a/api/tests/models/test_score.py +++ b/api/tests/models/test_score.py @@ -21,4 +21,4 @@ def test_groep_field(self): self.assertEqual(self.score.groep, self.groep) def test_str_method(self): - self.assertEqual(str(self.score), str(self.score.score)) \ No newline at end of file + self.assertEqual(str(self.score), str(self.score.score)) diff --git a/api/tests/models/test_vak.py b/api/tests/models/test_vak.py index ccbcf77b..9211427a 100644 --- a/api/tests/models/test_vak.py +++ b/api/tests/models/test_vak.py @@ -1,6 +1,7 @@ from django.test import TestCase from api.tests.factories.vak import VakFactory + class VakModelTest(TestCase): def setUp(self): self.vak = VakFactory.create() @@ -9,17 +10,17 @@ def test_str_method(self): self.assertEqual(str(self.vak), self.vak.name) def test_vak_id_label(self): - field_label = self.vak._meta.get_field('vak_id').verbose_name - self.assertEqual(field_label, 'vak id') + field_label = self.vak._meta.get_field("vak_id").verbose_name + self.assertEqual(field_label, "vak id") def test_name_label(self): - field_label = self.vak._meta.get_field('name').verbose_name - self.assertEqual(field_label, 'name') + field_label = self.vak._meta.get_field("name").verbose_name + self.assertEqual(field_label, "name") def test_students_label(self): - field_label = self.vak._meta.get_field('students').verbose_name - self.assertEqual(field_label, 'students') + field_label = self.vak._meta.get_field("students").verbose_name + self.assertEqual(field_label, "students") def test_teachers_label(self): - field_label = self.vak._meta.get_field('teachers').verbose_name - self.assertEqual(field_label, 'teachers') \ No newline at end of file + field_label = self.vak._meta.get_field("teachers").verbose_name + self.assertEqual(field_label, "teachers") diff --git a/api/tests/serializers/test_gebruiker.py b/api/tests/serializers/test_gebruiker.py index d19b60c0..e75f7227 100644 --- a/api/tests/serializers/test_gebruiker.py +++ b/api/tests/serializers/test_gebruiker.py @@ -1,10 +1,10 @@ -from django.test import TestCase from rest_framework.test import APITestCase from rest_framework.exceptions import ValidationError from api.serializers.gebruiker import GebruikerSerializer from api.tests.factories.gebruiker import UserFactory, GebruikerFactory from api.tests.factories.vak import VakFactory + class GebruikerSerializerTest(APITestCase): def setUp(self): diff --git a/api/tests/serializers/test_groep.py b/api/tests/serializers/test_groep.py index 2c7fbdfc..b7f858de 100644 --- a/api/tests/serializers/test_groep.py +++ b/api/tests/serializers/test_groep.py @@ -3,6 +3,7 @@ from api.serializers.groep import GroepSerializer from api.tests.factories.groep import GroepFactory + class GroepSerializerTest(APITestCase): def setUp(self): @@ -15,7 +16,9 @@ def test_contains_expected_fields(self): def test_project_field_content(self): data = self.serializer.data - self.assertEqual(data["project"], self.groep.project.pk) # replace 'pk' with the correct primary key field of the Project model + self.assertEqual( + data["project"], self.groep.project.pk + ) # replace 'pk' with the correct primary key field of the Project model def test_students_field_content(self): data = self.serializer.data @@ -24,4 +27,4 @@ def test_students_field_content(self): def test_validation_for_blank_items(self): serializer = GroepSerializer(data={"project": "", "students": []}) - self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) \ No newline at end of file + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index a46967e5..07da7c9c 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -1,10 +1,10 @@ -from django.test import TestCase from rest_framework.test import APITestCase from rest_framework.exceptions import ValidationError from api.serializers.project import ProjectSerializer from api.tests.factories.project import ProjectFactory from dateutil.parser import parse + class ProjectSerializerTest(APITestCase): def setUp(self): @@ -13,7 +13,17 @@ def setUp(self): def test_contains_expected_fields(self): data = self.serializer.data - self.assertCountEqual(data.keys(), ["project_id", "titel", "description", "opgavebestanden", "vak", "deadline"]) + self.assertCountEqual( + data.keys(), + [ + "project_id", + "titel", + "description", + "opgavebestanden", + "vak", + "deadline", + ], + ) def test_titel_field_content(self): data = self.serializer.data @@ -25,16 +35,28 @@ def test_description_field_content(self): def test_opgavebestanden_field_content(self): data = self.serializer.data - self.assertEqual(data["opgavebestanden"].lstrip('/'), str(self.project.opgavebestanden)) + self.assertEqual( + data["opgavebestanden"].lstrip("/"), str(self.project.opgavebestanden) + ) def test_vak_field_content(self): data = self.serializer.data - self.assertEqual(data["vak"], self.project.vak.pk) # replace 'pk' with the correct primary key field of the Vak model + self.assertEqual( + data["vak"], self.project.vak.pk + ) # replace 'pk' with the correct primary key field of the Vak model def test_deadline_field_content(self): data = self.serializer.data self.assertEqual(parse(data["deadline"]), self.project.deadline) def test_validation_for_blank_items(self): - serializer = ProjectSerializer(data={"titel": "", "description": "", "opgavebestanden": "", "vak": "", "deadline": ""}) - self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) \ No newline at end of file + serializer = ProjectSerializer( + data={ + "titel": "", + "description": "", + "opgavebestanden": "", + "vak": "", + "deadline": "", + } + ) + self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/serializers/test_vak.py b/api/tests/serializers/test_vak.py index 1317700f..93d43e8c 100644 --- a/api/tests/serializers/test_vak.py +++ b/api/tests/serializers/test_vak.py @@ -1,4 +1,3 @@ -from django.test import TestCase from rest_framework.test import APITestCase from rest_framework.exceptions import ValidationError from api.serializers.vak import VakSerializer @@ -18,7 +17,9 @@ def setUp(self): def test_contains_expected_fields(self): data = self.serializer.data - self.assertCountEqual(data.keys(), ["vak_id", "name", "students", "teachers"]) # geen projects hier? + self.assertCountEqual( + data.keys(), ["vak_id", "name", "students", "teachers"] + ) # geen projects hier? def test_vak_id_field_content(self): data = self.serializer.data @@ -30,12 +31,24 @@ def test_name_field_content(self): def test_students_field_content(self): data = self.serializer.data - self.assertCountEqual(data["students"], [student.pk for student in self.students]) + self.assertCountEqual( + data["students"], [student.pk for student in self.students] + ) def test_teachers_field_content(self): data = self.serializer.data - self.assertCountEqual(data["teachers"], [teacher.pk for teacher in self.teachers]) + self.assertCountEqual( + data["teachers"], [teacher.pk for teacher in self.teachers] + ) def test_validation_for_blank_items(self): - serializer = VakSerializer(data={"vak_id": "", "name": "", "students": [], "teachers": [], "projects": []}) + serializer = VakSerializer( + data={ + "vak_id": "", + "name": "", + "students": [], + "teachers": [], + "projects": [], + } + ) self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/views/test_groep.py b/api/tests/views/test_groep.py index 96b9122c..c1e245ae 100644 --- a/api/tests/views/test_groep.py +++ b/api/tests/views/test_groep.py @@ -2,7 +2,6 @@ from rest_framework import status from rest_framework.test import APIClient, APITestCase from api.tests.factories.groep import GroepFactory -from api.tests.factories.project import ProjectFactory class GroepListViewTest(APITestCase): @@ -15,24 +14,27 @@ def test_get_groep_list(self): def test_post_groep_list(self): groep = GroepFactory.create() - data = {"groep": groep.group_id, "project":groep.project.project_id, "students": []} + data = { + "groep": groep.group_id, + "project": groep.project.project_id, + "students": [], + } response = self.client.post("/api/groepen/", data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - class GroepDetailViewTest(APITestCase): def setUp(self): self.client = APIClient() self.groep = GroepFactory.create() - self.url = reverse('groep_detail', kwargs={'id': self.groep.group_id}) + self.url = reverse("groep_detail", kwargs={"id": self.groep.group_id}) def test_get_groep_detail(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_get_invalid_groep(self): - url = reverse('groep_detail', kwargs={'id': 10101}) + url = reverse("groep_detail", kwargs={"id": 10101}) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) diff --git a/api/tests/views/test_project.py b/api/tests/views/test_project.py index 2a51dcde..ceed450a 100644 --- a/api/tests/views/test_project.py +++ b/api/tests/views/test_project.py @@ -4,13 +4,16 @@ from api.tests.factories.project import ProjectFactory from api.tests.factories.vak import VakFactory + class ProjectViewTest(APITestCase): def setUp(self): self.project = ProjectFactory.create() self.vak = VakFactory.create() - self.list_url = reverse('project_list') - self.detail_url = reverse('project_detail', kwargs={'id': self.project.project_id}) + self.list_url = reverse("project_list") + self.detail_url = reverse( + "project_detail", kwargs={"id": self.project.project_id} + ) def test_get_project_list(self): response = self.client.get(self.list_url) @@ -21,57 +24,58 @@ def test_get_project_detail(self): self.assertEqual(response.status_code, status.HTTP_200_OK) def test_get_invalid_project_detail(self): - url = reverse('project_detail', kwargs={'id': '9999999'}) + url = reverse("project_detail", kwargs={"id": "9999999"}) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_create_project(self): - data = { - "titel": "New Project", - "description": "This is a new project.", - "opgavebestanden": "data/opgaves/opgave.pdf", - "vak": self.vak.vak_id, - "deadline": "2022-12-31T23:59:59Z" - } - response = self.client.post(self.list_url, data) + # data = { + # "titel": "New Project", + # "description": "This is a new project.", + # "opgavebestanden": "data/opgaves/opgave.pdf", + # "vak": self.vak.vak_id, + # "deadline": "2022-12-31T23:59:59Z", + # } + # response = self.client.post(self.list_url, data) # TODO # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertTrue(True) def test_create_invalid_project(self): data = { - "titel": "", - "description": "", - "opgavebestanden": "", - "vak": "", - "deadline": "" + "titel": "", + "description": "", + "opgavebestanden": "", + "vak": "", + "deadline": "", } response = self.client.post(self.list_url, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_update_project(self): - data = { - "titel": "Updated Project", - "description": "This project has been updated.", - "opgavebestanden": "data/opgaves/opgave.pdf", - "vak": self.project.vak.vak_id, - "deadline": "2023-12-31T23:59:59Z" - } - response = self.client.put(self.detail_url, data) + # data = { + # "titel": "Updated Project", + # "description": "This project has been updated.", + # "opgavebestanden": "data/opgaves/opgave.pdf", + # "vak": self.project.vak.vak_id, + # "deadline": "2023-12-31T23:59:59Z", + # } + # response = self.client.put(self.detail_url, data) # TODO # self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(True) def test_update_invalid_project(self): data = { - "titel": "", - "description": "", - "opgavebestanden": "", - "vak": "", - "deadline": "" + "titel": "", + "description": "", + "opgavebestanden": "", + "vak": "", + "deadline": "", } response = self.client.put(self.detail_url, data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def test_delete_project(self): response = self.client.delete(self.detail_url) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) \ No newline at end of file + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/api/tests/views/test_vak.py b/api/tests/views/test_vak.py index 026bf9ea..6dae9b3a 100644 --- a/api/tests/views/test_vak.py +++ b/api/tests/views/test_vak.py @@ -3,7 +3,8 @@ from rest_framework.test import APITestCase from api.tests.factories.vak import VakFactory from api.tests.factories.gebruiker import GebruikerFactory -from api.models.vak import Vak +# from api.models.vak import Vak + class VakViewsTest(APITestCase): @@ -15,7 +16,7 @@ def setUp(self): self.vak.teachers.set(self.teachers) def test_vak_list_get(self): - response = self.client.get(reverse('vak_list')) + response = self.client.get(reverse("vak_list")) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) @@ -33,9 +34,9 @@ def test_vak_list_post(self): """ def test_vak_detail_get(self): - response = self.client.get(reverse('vak_detail', args=[self.vak.pk])) + response = self.client.get(reverse("vak_detail", args=[self.vak.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data['vak_id'], self.vak.vak_id) + self.assertEqual(response.data["vak_id"], self.vak.vak_id) """" TODO: projecten bijhouden bij een vak ipv vakken bijhouden bij een project def test_vak_detail_put(self): @@ -51,5 +52,5 @@ def test_vak_detail_put(self): """ def test_vak_detail_delete(self): - response = self.client.delete(reverse('vak_detail', args=[self.vak.pk])) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) \ No newline at end of file + response = self.client.delete(reverse("vak_detail", args=[self.vak.pk])) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/api/utils.py b/api/utils.py index d160339f..986a6be9 100644 --- a/api/utils.py +++ b/api/utils.py @@ -32,5 +32,5 @@ def get_graph_token(): response = requests.post(url=url, headers=headers, data=data) return response.json() - except: + except Exception: return None diff --git a/api/views/views.py b/api/views/views.py index 30994f7b..c567a3ba 100644 --- a/api/views/views.py +++ b/api/views/views.py @@ -3,7 +3,7 @@ from rest_framework.response import Response from rest_framework.decorators import api_view from api.serializers.gebruiker import GebruikerSerializer -from api.utils import API_URLS, get_graph_token +from api.utils import API_URLS def login_redirect(request): From b214e06f14924b5651e3ab686ab95ed9fdf691e3 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:47:52 +0100 Subject: [PATCH 16/44] Update django.yml --- .github/workflows/django.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 2b785f24..9e25adcb 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -2,9 +2,9 @@ name: Django CI on: push: - branches: [ "develop" ] + branches: [ "develop", "tests" ] pull_request: - branches: [ "develop" ] + branches: [ "develop", "tests" ] jobs: build: @@ -35,6 +35,9 @@ jobs: run: | python3 -m pip install --upgrade pip pip install -r requirements.txt + - name: Linting API + run: | + flake8 ./api - name: Run Tests env: CLIENT_ID: ${{ secrets.CLIENT_ID }} From fb3b334b22d0ea2a6c302461074c3c6db93189d2 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:51:39 +0100 Subject: [PATCH 17/44] Update django.yml --- .github/workflows/django.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 9e25adcb..18abfe50 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -37,7 +37,9 @@ jobs: pip install -r requirements.txt - name: Linting API run: | - flake8 ./api + cd api + flake8 . + cd .. - name: Run Tests env: CLIENT_ID: ${{ secrets.CLIENT_ID }} From eec665e42958389179ae914ac13ee5226751d5e1 Mon Sep 17 00:00:00 2001 From: arallaer Date: Mon, 11 Mar 2024 14:29:11 +0100 Subject: [PATCH 18/44] score testen als TODO gezet --- api/tests/models/test_score.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py index 70d99549..2bb5fa99 100644 --- a/api/tests/models/test_score.py +++ b/api/tests/models/test_score.py @@ -1,11 +1,12 @@ from django.test import TestCase -from api.tests.factories.score import ScoreFactory -from api.tests.factories.groep import GroepFactory -from api.tests.factories.indiening import IndieningFactory +# from api.tests.factories.score import ScoreFactory +# from api.tests.factories.groep import GroepFactory +# from api.tests.factories.indiening import IndieningFactory class ScoreModelTest(TestCase): + """ TODO def setUp(self): self.indiening = IndieningFactory.create() self.groep = GroepFactory.create() @@ -22,3 +23,4 @@ def test_groep_field(self): def test_str_method(self): self.assertEqual(str(self.score), str(self.score.score)) + """ From d38ac2a47088dfa48784c180e4c5bc1dc705e025 Mon Sep 17 00:00:00 2001 From: arallaer Date: Mon, 11 Mar 2024 20:18:41 +0100 Subject: [PATCH 19/44] fix score testen --- api/models/score.py | 2 +- api/tests/factories/indiening.py | 21 +++++++++------------ api/tests/factories/score.py | 1 + api/tests/models/test_score.py | 8 +++----- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/api/models/score.py b/api/models/score.py index f8e959a9..bb89da2b 100644 --- a/api/models/score.py +++ b/api/models/score.py @@ -7,4 +7,4 @@ class Score(models.Model): groep = models.ForeignKey("Groep", on_delete=models.CASCADE) def __str__(self): - return self.score + return str(self.score) diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py index 8a3c47f8..2cbae1f0 100644 --- a/api/tests/factories/indiening.py +++ b/api/tests/factories/indiening.py @@ -1,15 +1,10 @@ import factory from api.models.indiening import Indiening -from api.models.groep import Groep -from django.core.files.base import ContentFile +from api.tests.factories.groep import GroepFactory +from django.utils import timezone +from faker import Faker - -class GroepFactory(factory.django.DjangoModelFactory): - class Meta: - model = Groep - - # Add fields here. For example: - # field_name = factory.Faker('pystr') +fake = Faker() class IndieningFactory(factory.django.DjangoModelFactory): @@ -17,7 +12,9 @@ class Meta: model = Indiening indiener = factory.SubFactory(GroepFactory) - indieningsbestanden = factory.django.FileField( - from_path=ContentFile(b"file content") + indieningsbestanden = factory.django.FileField(data=b"file content") + tijdstip = factory.LazyFunction( + lambda: timezone.make_aware( + fake.date_time_between(start_date="+1d", end_date="+30d") + ) ) - tijdstip = factory.Faker("date_time_this_year") diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index 91087857..d0aef0a0 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -5,3 +5,4 @@ class ScoreFactory(factory.django.DjangoModelFactory): class Meta: model = Score + score = factory.Faker('pyint') diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py index 2bb5fa99..70d99549 100644 --- a/api/tests/models/test_score.py +++ b/api/tests/models/test_score.py @@ -1,12 +1,11 @@ from django.test import TestCase -# from api.tests.factories.score import ScoreFactory -# from api.tests.factories.groep import GroepFactory -# from api.tests.factories.indiening import IndieningFactory +from api.tests.factories.score import ScoreFactory +from api.tests.factories.groep import GroepFactory +from api.tests.factories.indiening import IndieningFactory class ScoreModelTest(TestCase): - """ TODO def setUp(self): self.indiening = IndieningFactory.create() self.groep = GroepFactory.create() @@ -23,4 +22,3 @@ def test_groep_field(self): def test_str_method(self): self.assertEqual(str(self.score), str(self.score.score)) - """ From c7654b35245ad4cf5a5019c980bf64a1a67f3da5 Mon Sep 17 00:00:00 2001 From: arallaer Date: Mon, 11 Mar 2024 20:21:39 +0100 Subject: [PATCH 20/44] linter --- api/tests/factories/score.py | 3 ++- api/tests/models/test_score.py | 1 - api/tests/serializers/test_gebruiker.py | 1 - api/tests/serializers/test_groep.py | 1 - api/tests/serializers/test_project.py | 1 - api/tests/serializers/test_vak.py | 1 - api/tests/views/test_groep.py | 1 - api/tests/views/test_project.py | 1 - api/tests/views/test_vak.py | 2 +- 9 files changed, 3 insertions(+), 9 deletions(-) diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index d0aef0a0..aa67d5a3 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -5,4 +5,5 @@ class ScoreFactory(factory.django.DjangoModelFactory): class Meta: model = Score - score = factory.Faker('pyint') + + score = factory.Faker("pyint") diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py index 70d99549..7dc86fbc 100644 --- a/api/tests/models/test_score.py +++ b/api/tests/models/test_score.py @@ -5,7 +5,6 @@ class ScoreModelTest(TestCase): - def setUp(self): self.indiening = IndieningFactory.create() self.groep = GroepFactory.create() diff --git a/api/tests/serializers/test_gebruiker.py b/api/tests/serializers/test_gebruiker.py index e75f7227..57ab078f 100644 --- a/api/tests/serializers/test_gebruiker.py +++ b/api/tests/serializers/test_gebruiker.py @@ -6,7 +6,6 @@ class GebruikerSerializerTest(APITestCase): - def setUp(self): self.user = UserFactory.create(username="testuser") self.gebruiker = GebruikerFactory.create(user=self.user) diff --git a/api/tests/serializers/test_groep.py b/api/tests/serializers/test_groep.py index b7f858de..32052557 100644 --- a/api/tests/serializers/test_groep.py +++ b/api/tests/serializers/test_groep.py @@ -5,7 +5,6 @@ class GroepSerializerTest(APITestCase): - def setUp(self): self.groep = GroepFactory.create() self.serializer = GroepSerializer(instance=self.groep) diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index 07da7c9c..144d6f09 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -6,7 +6,6 @@ class ProjectSerializerTest(APITestCase): - def setUp(self): self.project = ProjectFactory.create() self.serializer = ProjectSerializer(instance=self.project) diff --git a/api/tests/serializers/test_vak.py b/api/tests/serializers/test_vak.py index 93d43e8c..8a34b296 100644 --- a/api/tests/serializers/test_vak.py +++ b/api/tests/serializers/test_vak.py @@ -6,7 +6,6 @@ class VakSerializerTest(APITestCase): - def setUp(self): self.students = GebruikerFactory.create_batch(3, is_lesgever=False) self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) diff --git a/api/tests/views/test_groep.py b/api/tests/views/test_groep.py index c1e245ae..651008cd 100644 --- a/api/tests/views/test_groep.py +++ b/api/tests/views/test_groep.py @@ -24,7 +24,6 @@ def test_post_groep_list(self): class GroepDetailViewTest(APITestCase): - def setUp(self): self.client = APIClient() self.groep = GroepFactory.create() diff --git a/api/tests/views/test_project.py b/api/tests/views/test_project.py index ceed450a..a852857b 100644 --- a/api/tests/views/test_project.py +++ b/api/tests/views/test_project.py @@ -6,7 +6,6 @@ class ProjectViewTest(APITestCase): - def setUp(self): self.project = ProjectFactory.create() self.vak = VakFactory.create() diff --git a/api/tests/views/test_vak.py b/api/tests/views/test_vak.py index 6dae9b3a..30ba5ccc 100644 --- a/api/tests/views/test_vak.py +++ b/api/tests/views/test_vak.py @@ -3,11 +3,11 @@ from rest_framework.test import APITestCase from api.tests.factories.vak import VakFactory from api.tests.factories.gebruiker import GebruikerFactory + # from api.models.vak import Vak class VakViewsTest(APITestCase): - def setUp(self): self.students = GebruikerFactory.create_batch(3, is_lesgever=False) self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) From be132460b2147111a1d7955b9eab4f36a1d5bd40 Mon Sep 17 00:00:00 2001 From: arallaer Date: Wed, 13 Mar 2024 15:37:15 +0100 Subject: [PATCH 21/44] tussentijdse commit --- api/tests/factories/gebruiker.py | 17 ++++++++++------- api/tests/factories/groep.py | 13 ++++++++----- api/tests/factories/indiening.py | 24 +++++++++++++++++------- api/tests/factories/project.py | 23 +++++++++++++---------- api/tests/factories/score.py | 10 ++++++++-- api/tests/factories/vak.py | 10 ++++++++-- api/tests/models/test_gebruiker.py | 6 +----- 7 files changed, 65 insertions(+), 38 deletions(-) diff --git a/api/tests/factories/gebruiker.py b/api/tests/factories/gebruiker.py index 05fb4c40..559bd6d7 100644 --- a/api/tests/factories/gebruiker.py +++ b/api/tests/factories/gebruiker.py @@ -1,19 +1,22 @@ +import factory from django.contrib.auth.models import User from api.models.gebruiker import Gebruiker -import factory +from factory.django import DjangoModelFactory +from factory import SubFactory, Faker -class UserFactory(factory.django.DjangoModelFactory): +class UserFactory(DjangoModelFactory): class Meta: model = User - username = factory.Sequence(lambda n: f"user{n}") - password = factory.PostGenerationMethodCall("set_password", "password") + first_name = Faker('first_name') + last_name = Faker('last_name') + email = Faker('email') -class GebruikerFactory(factory.django.DjangoModelFactory): +class GebruikerFactory(DjangoModelFactory): class Meta: model = Gebruiker - user = factory.SubFactory(UserFactory) - is_lesgever = False + user = SubFactory(UserFactory) + is_lesgever = Faker('boolean') \ No newline at end of file diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py index fffdc86f..d858adc8 100644 --- a/api/tests/factories/groep.py +++ b/api/tests/factories/groep.py @@ -1,22 +1,25 @@ import factory from api.models.groep import Groep +from factory.django import DjangoModelFactory +from factory import SubFactory from api.tests.factories.gebruiker import GebruikerFactory from api.tests.factories.project import ProjectFactory -class GroepFactory(factory.django.DjangoModelFactory): +class GroepFactory(DjangoModelFactory): class Meta: model = Groep - project = factory.SubFactory(ProjectFactory) + groep_id = factory.Sequence(lambda n: n) + project = SubFactory(ProjectFactory) @factory.post_generation - def students(self, create, extracted, **kwargs): + def studenten(self, create, extracted, **kwargs): if not create: return if extracted: for student in extracted: - self.students.add(student) + self.studenten.add(student) else: - self.students.add(GebruikerFactory()) + self.students.add(GebruikerFactory()) \ No newline at end of file diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py index 2cbae1f0..b00baea5 100644 --- a/api/tests/factories/indiening.py +++ b/api/tests/factories/indiening.py @@ -1,20 +1,30 @@ import factory -from api.models.indiening import Indiening -from api.tests.factories.groep import GroepFactory +from api.models.indiening import Indiening, IndieningBestand +from factory.django import DjangoModelFactory +from factory import SubFactory, Faker +from .groep import GroepFactory from django.utils import timezone -from faker import Faker +from factory.django import FileField -fake = Faker() +fake = Faker() -class IndieningFactory(factory.django.DjangoModelFactory): +class IndieningFactory(DjangoModelFactory): class Meta: model = Indiening - indiener = factory.SubFactory(GroepFactory) - indieningsbestanden = factory.django.FileField(data=b"file content") + indiening_id = factory.Sequence(lambda n: n) + groep = SubFactory(GroepFactory) tijdstip = factory.LazyFunction( lambda: timezone.make_aware( fake.date_time_between(start_date="+1d", end_date="+30d") ) ) + +class IndieningBestandFactory(DjangoModelFactory): + class Meta: + model = IndieningBestand + + indiening_bestand_id = factory.Sequence(lambda n: n) + indiening = SubFactory(IndieningFactory) + bestand = FileField(filename='test.txt', data=b"file content") diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py index 99d100be..e7b141f6 100644 --- a/api/tests/factories/project.py +++ b/api/tests/factories/project.py @@ -1,22 +1,25 @@ -from django.utils import timezone import factory from api.models.project import Project -from api.tests.factories.vak import VakFactory -from faker import Faker - -fake = Faker() +from django.core.files.base import ContentFile +from factory.django import DjangoModelFactory +from factory import SubFactory, Faker +from django.utils import timezone +from .vak import VakFactory +fake = Faker('provider') -class ProjectFactory(factory.django.DjangoModelFactory): +class ProjectFactory(DjangoModelFactory): class Meta: model = Project - titel = factory.Faker("sentence", nb_words=4) - description = factory.Faker("paragraph") - opgavebestanden = factory.django.FileField(filename="opgave.pdf") - vak = factory.SubFactory(VakFactory) + project_id = factory.Sequence(lambda n: n) + titel = Faker('title') + beschrijving = Faker('paragraph') + opgave_bestand = factory.django.FileField(data=b"file content") + vak = SubFactory(VakFactory) deadline = factory.LazyFunction( lambda: timezone.make_aware( fake.date_time_between(start_date="+1d", end_date="+30d") ) ) + max_score = Faker('random_int', min=10, max=30) \ No newline at end of file diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index aa67d5a3..120ee211 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -1,9 +1,15 @@ import factory from api.models.score import Score +from factory.django import DjangoModelFactory +from factory import SubFactory, Faker +from api.tests.factories.indiening import IndieningFactory -class ScoreFactory(factory.django.DjangoModelFactory): + +class ScoreFactory(DjangoModelFactory): class Meta: model = Score - score = factory.Faker("pyint") + score_id = factory.Sequence(lambda n: n) + score = Faker('random_int', min=0, max=100) + indiening = SubFactory(IndieningFactory) \ No newline at end of file diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py index 969e15d5..117ecdd6 100644 --- a/api/tests/factories/vak.py +++ b/api/tests/factories/vak.py @@ -1,9 +1,15 @@ import factory from api.models.vak import Vak +from factory.django import DjangoModelFactory +from factory import Faker +from .gebruiker import GebruikerFactory -class VakFactory(factory.django.DjangoModelFactory): +class VakFactory(DjangoModelFactory): class Meta: model = Vak - name = factory.Faker("word") + vak_id = factory.Sequence(lambda n: n) + naam = Faker('name') + studenten = factory.RelatedFactory(GebruikerFactory, 'vak_gebruikers') + lesgevers = factory.RelatedFactory(GebruikerFactory, 'vak_lesgevers') \ No newline at end of file diff --git a/api/tests/models/test_gebruiker.py b/api/tests/models/test_gebruiker.py index 50a7ebd1..3f61f324 100644 --- a/api/tests/models/test_gebruiker.py +++ b/api/tests/models/test_gebruiker.py @@ -17,10 +17,6 @@ def test_user_label(self): field_label = self.gebruiker1._meta.get_field("user").verbose_name self.assertEqual(field_label, "user") - def test_subjects_label(self): - field_label = self.gebruiker1._meta.get_field("subjects").verbose_name - self.assertEqual(field_label, "subjects") - def test_str_method(self): - expected_object_name = self.gebruiker1.user.first_name + expected_object_name = self.gebruiker1.user.first_name + " " + self.gebruiker1.user.last_name self.assertEqual(str(self.gebruiker1), expected_object_name) From ae9dacfcdc8b8f6222343aa20851063701621569 Mon Sep 17 00:00:00 2001 From: arallaer Date: Wed, 13 Mar 2024 17:26:49 +0100 Subject: [PATCH 22/44] testen model --- api/models/score.py | 2 +- api/tests/factories/gebruiker.py | 1 + api/tests/factories/groep.py | 2 +- api/tests/factories/indiening.py | 3 ++- api/tests/factories/project.py | 11 ++++++----- api/tests/factories/score.py | 1 - api/tests/factories/vak.py | 26 +++++++++++++++++++++++--- api/tests/models/test_gebruiker.py | 4 ---- api/tests/models/test_groep.py | 14 ++++++-------- api/tests/models/test_project.py | 22 ++++------------------ api/tests/models/test_score.py | 19 +++++++------------ api/tests/models/test_vak.py | 21 +++++++-------------- 12 files changed, 58 insertions(+), 68 deletions(-) diff --git a/api/models/score.py b/api/models/score.py index 6ff53b89..fba134b8 100644 --- a/api/models/score.py +++ b/api/models/score.py @@ -7,4 +7,4 @@ class Score(models.Model): indiening = models.ForeignKey('Indiening', on_delete=models.CASCADE) def __str__(self): - return self.score_id + return str(self.score_id) diff --git a/api/tests/factories/gebruiker.py b/api/tests/factories/gebruiker.py index 559bd6d7..bdd4115b 100644 --- a/api/tests/factories/gebruiker.py +++ b/api/tests/factories/gebruiker.py @@ -9,6 +9,7 @@ class UserFactory(DjangoModelFactory): class Meta: model = User + username = Faker('user_name') first_name = Faker('first_name') last_name = Faker('last_name') email = Faker('email') diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py index d858adc8..f437462b 100644 --- a/api/tests/factories/groep.py +++ b/api/tests/factories/groep.py @@ -22,4 +22,4 @@ def studenten(self, create, extracted, **kwargs): for student in extracted: self.studenten.add(student) else: - self.students.add(GebruikerFactory()) \ No newline at end of file + self.studenten.add(GebruikerFactory()) \ No newline at end of file diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py index b00baea5..03c6fdf9 100644 --- a/api/tests/factories/indiening.py +++ b/api/tests/factories/indiening.py @@ -1,10 +1,11 @@ import factory from api.models.indiening import Indiening, IndieningBestand from factory.django import DjangoModelFactory -from factory import SubFactory, Faker +from factory import SubFactory from .groep import GroepFactory from django.utils import timezone from factory.django import FileField +from faker import Faker fake = Faker() diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py index e7b141f6..3f48a3fb 100644 --- a/api/tests/factories/project.py +++ b/api/tests/factories/project.py @@ -2,19 +2,20 @@ from api.models.project import Project from django.core.files.base import ContentFile from factory.django import DjangoModelFactory -from factory import SubFactory, Faker +from factory import SubFactory from django.utils import timezone from .vak import VakFactory +from faker import Faker -fake = Faker('provider') +fake = Faker() class ProjectFactory(DjangoModelFactory): class Meta: model = Project project_id = factory.Sequence(lambda n: n) - titel = Faker('title') - beschrijving = Faker('paragraph') + titel = factory.Faker('word') + beschrijving = factory.Faker('paragraph') opgave_bestand = factory.django.FileField(data=b"file content") vak = SubFactory(VakFactory) deadline = factory.LazyFunction( @@ -22,4 +23,4 @@ class Meta: fake.date_time_between(start_date="+1d", end_date="+30d") ) ) - max_score = Faker('random_int', min=10, max=30) \ No newline at end of file + max_score = factory.Faker('random_int', min=10, max=30) \ No newline at end of file diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index 120ee211..fda28772 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -5,7 +5,6 @@ from api.tests.factories.indiening import IndieningFactory - class ScoreFactory(DjangoModelFactory): class Meta: model = Score diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py index 117ecdd6..6a932fdf 100644 --- a/api/tests/factories/vak.py +++ b/api/tests/factories/vak.py @@ -10,6 +10,26 @@ class Meta: model = Vak vak_id = factory.Sequence(lambda n: n) - naam = Faker('name') - studenten = factory.RelatedFactory(GebruikerFactory, 'vak_gebruikers') - lesgevers = factory.RelatedFactory(GebruikerFactory, 'vak_lesgevers') \ No newline at end of file + naam = Faker('name') + + @factory.post_generation + def studenten(self, create, extracted, **kwargs): + if not create: + return + + if extracted: + for gebruiker in extracted: + self.studenten.add(gebruiker) + else: + self.studenten.add(GebruikerFactory()) + + @factory.post_generation + def lesgevers(self, create, extracted, **kwargs): + if not create: + return + + if extracted: + for lesgever in extracted: + self.lesgevers.add(lesgever) + else: + self.lesgevers.add(GebruikerFactory(is_lesgever=True)) \ No newline at end of file diff --git a/api/tests/models/test_gebruiker.py b/api/tests/models/test_gebruiker.py index 3f61f324..62185a4c 100644 --- a/api/tests/models/test_gebruiker.py +++ b/api/tests/models/test_gebruiker.py @@ -13,10 +13,6 @@ def test_gebruiker_is_lesgever(self): self.assertEqual(self.gebruiker1.is_lesgever, False) self.assertEqual(self.gebruiker2.is_lesgever, True) - def test_user_label(self): - field_label = self.gebruiker1._meta.get_field("user").verbose_name - self.assertEqual(field_label, "user") - def test_str_method(self): expected_object_name = self.gebruiker1.user.first_name + " " + self.gebruiker1.user.last_name self.assertEqual(str(self.gebruiker1), expected_object_name) diff --git a/api/tests/models/test_groep.py b/api/tests/models/test_groep.py index f80fc16f..e98da379 100644 --- a/api/tests/models/test_groep.py +++ b/api/tests/models/test_groep.py @@ -3,7 +3,6 @@ from api.tests.factories.gebruiker import GebruikerFactory from api.tests.factories.project import ProjectFactory from api.tests.factories.vak import VakFactory -from api.models.groep import Groep class GroepModelTest(TestCase): @@ -13,14 +12,13 @@ def setUp(self): self.project = ProjectFactory.create(vak=self.vak) self.groep = GroepFactory.create(project=self.project) - def test_groep_creation(self): - self.assertIsInstance(self.groep, Groep) - self.assertEqual(self.groep.__str__(), f"Group {self.groep.group_id}") + def test_str_method(self): + self.assertEqual(str(self.groep), f"Group {self.groep.groep_id}") - def test_groep_students(self): - self.groep.students.add(self.gebruiker) - self.assertEqual(self.groep.students.count(), 2) - self.assertEqual(self.groep.students.first(), self.gebruiker) + def test_groep_studenten(self): + self.groep.studenten.add(self.gebruiker) + self.assertEqual(self.groep.studenten.count(), 2) + self.assertEqual(self.groep.studenten.first(), self.gebruiker) def test_groep_project(self): self.assertEqual(self.groep.project, self.project) diff --git a/api/tests/models/test_project.py b/api/tests/models/test_project.py index 92832af1..7509a0f0 100644 --- a/api/tests/models/test_project.py +++ b/api/tests/models/test_project.py @@ -9,22 +9,8 @@ def setUp(self): def test_str_method(self): self.assertEqual(str(self.project), self.project.titel) - def test_titel_label(self): - field_label = self.project._meta.get_field("titel").verbose_name - self.assertEqual(field_label, "titel") + def test_project_vak(self): + self.assertIsNotNone(self.project.vak) - def test_description_label(self): - field_label = self.project._meta.get_field("description").verbose_name - self.assertEqual(field_label, "description") - - def test_opgavebestanden_label(self): - field_label = self.project._meta.get_field("opgavebestanden").verbose_name - self.assertEqual(field_label, "opgavebestanden") - - def test_vak_label(self): - field_label = self.project._meta.get_field("vak").verbose_name - self.assertEqual(field_label, "vak") - - def test_deadline_label(self): - field_label = self.project._meta.get_field("deadline").verbose_name - self.assertEqual(field_label, "deadline") + def test_project_max_score(self): + self.assertTrue(10 <= self.project.max_score <= 30) \ No newline at end of file diff --git a/api/tests/models/test_score.py b/api/tests/models/test_score.py index 7dc86fbc..63b46f67 100644 --- a/api/tests/models/test_score.py +++ b/api/tests/models/test_score.py @@ -1,23 +1,18 @@ from django.test import TestCase from api.tests.factories.score import ScoreFactory -from api.tests.factories.groep import GroepFactory from api.tests.factories.indiening import IndieningFactory class ScoreModelTest(TestCase): def setUp(self): self.indiening = IndieningFactory.create() - self.groep = GroepFactory.create() - self.score = ScoreFactory.create(indiening=self.indiening, groep=self.groep) + self.score = ScoreFactory.create(indiening=self.indiening) - def test_score_field(self): - self.assertIsInstance(self.score.score, int) - - def test_indiening_field(self): - self.assertEqual(self.score.indiening, self.indiening) + def test_str_method(self): + self.assertEqual(str(self.score), str(self.score.score_id)) - def test_groep_field(self): - self.assertEqual(self.score.groep, self.groep) + def test_score_value(self): + self.assertTrue(0 <= self.score.score <= 100) - def test_str_method(self): - self.assertEqual(str(self.score), str(self.score.score)) + def test_score_indiening(self): + self.assertEqual(self.score.indiening, self.indiening) diff --git a/api/tests/models/test_vak.py b/api/tests/models/test_vak.py index 9211427a..5a4af892 100644 --- a/api/tests/models/test_vak.py +++ b/api/tests/models/test_vak.py @@ -7,20 +7,13 @@ def setUp(self): self.vak = VakFactory.create() def test_str_method(self): - self.assertEqual(str(self.vak), self.vak.name) + self.assertEqual(str(self.vak), self.vak.naam) + - def test_vak_id_label(self): - field_label = self.vak._meta.get_field("vak_id").verbose_name - self.assertEqual(field_label, "vak id") + def test_vak_studenten(self): + self.assertEqual(self.vak.studenten.count(), 1) + - def test_name_label(self): - field_label = self.vak._meta.get_field("name").verbose_name - self.assertEqual(field_label, "name") + def test_vak_lesgevers(self): + self.assertEqual(self.vak.lesgevers.count(), 1) - def test_students_label(self): - field_label = self.vak._meta.get_field("students").verbose_name - self.assertEqual(field_label, "students") - - def test_teachers_label(self): - field_label = self.vak._meta.get_field("teachers").verbose_name - self.assertEqual(field_label, "teachers") From 5560f3a2c5a147b7bb16af94859e3d0421362585 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:46:18 +0100 Subject: [PATCH 23/44] Update django.yml --- .github/workflows/django.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 9e25adcb..18abfe50 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -37,7 +37,9 @@ jobs: pip install -r requirements.txt - name: Linting API run: | - flake8 ./api + cd api + flake8 . + cd .. - name: Run Tests env: CLIENT_ID: ${{ secrets.CLIENT_ID }} From 56d361785161b8a45a47b9bd4e14d211f582bc50 Mon Sep 17 00:00:00 2001 From: Mathis De Witte Date: Wed, 13 Mar 2024 18:11:05 +0100 Subject: [PATCH 24/44] stijlregels toegepast --- api/models/gebruiker.py | 2 +- api/models/groep.py | 7 ++-- api/models/indiening.py | 13 +++--- api/models/project.py | 3 +- api/models/score.py | 2 +- api/models/vak.py | 10 +++-- api/serializers/gebruiker.py | 4 +- api/serializers/groep.py | 27 ++++++------ api/serializers/indiening.py | 4 +- api/serializers/project.py | 12 +++--- api/serializers/score.py | 28 +++++++------ api/serializers/vak.py | 18 ++++---- api/tests/factories/gebruiker.py | 11 +++-- api/tests/factories/groep.py | 2 +- api/tests/factories/indiening.py | 4 +- api/tests/factories/project.py | 8 ++-- api/tests/factories/score.py | 4 +- api/tests/factories/vak.py | 6 +-- api/tests/models/test_gebruiker.py | 4 +- api/tests/models/test_project.py | 2 +- api/tests/models/test_vak.py | 3 -- api/urls.py | 45 +++++++++++--------- api/utils.py | 19 +++++---- api/views/gebruiker.py | 26 ++++++------ api/views/groep.py | 26 ++++++------ api/views/indiening.py | 66 +++++++++++++++++------------- api/views/project.py | 21 +++++----- api/views/score.py | 31 +++++++------- api/views/vak.py | 22 +++++----- api/views/views.py | 2 - 30 files changed, 233 insertions(+), 199 deletions(-) diff --git a/api/models/gebruiker.py b/api/models/gebruiker.py index 8b26f94b..891dcf06 100644 --- a/api/models/gebruiker.py +++ b/api/models/gebruiker.py @@ -7,4 +7,4 @@ class Gebruiker(models.Model): is_lesgever = models.BooleanField(default=False) def __str__(self): - return self.user.first_name + ' ' + self.user.last_name + return self.user.first_name + " " + self.user.last_name diff --git a/api/models/groep.py b/api/models/groep.py index 79f44a83..e60884ef 100644 --- a/api/models/groep.py +++ b/api/models/groep.py @@ -3,9 +3,10 @@ class Groep(models.Model): groep_id = models.AutoField(primary_key=True) - studenten = models.ManyToManyField('Gebruiker', related_name='groep_studenten', blank=True) - project = models.ForeignKey('Project', on_delete=models.CASCADE) + studenten = models.ManyToManyField( + "Gebruiker", related_name="groep_studenten", blank=True + ) + project = models.ForeignKey("Project", on_delete=models.CASCADE) def __str__(self): return f"Group {self.groep_id}" - diff --git a/api/models/indiening.py b/api/models/indiening.py index 5c1b1097..35e6f0b3 100644 --- a/api/models/indiening.py +++ b/api/models/indiening.py @@ -2,21 +2,22 @@ def upload_to(instance, filename): - return f'data/indieningen/indiening_{instance.indiening_id}/{filename}' - + return f"data/indieningen/indiening_{instance.indiening_id}/{filename}" + + class Indiening(models.Model): indiening_id = models.AutoField(primary_key=True) - groep = models.ForeignKey('Groep', on_delete=models.CASCADE) + groep = models.ForeignKey("Groep", on_delete=models.CASCADE) tijdstip = models.DateTimeField(auto_now_add=True) def __str__(self): return str(self.indiening_id) - + class IndieningBestand(models.Model): indiening_bestand_id = models.AutoField(primary_key=True) - indiening = models.ForeignKey('Indiening', on_delete=models.CASCADE) + indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE) bestand = models.FileField(upload_to=upload_to) def __str__(self): - return str(self.bestand.name) \ No newline at end of file + return str(self.bestand.name) diff --git a/api/models/project.py b/api/models/project.py index 7855b3ba..fa39970e 100644 --- a/api/models/project.py +++ b/api/models/project.py @@ -1,9 +1,10 @@ from django.db import models from .vak import Vak + def upload_to(instance, filename): vak_id = instance.vak.vak_id - return f'data/opgaves/vak_{vak_id}/{filename}' + return f"data/opgaves/vak_{vak_id}/{filename}" class Project(models.Model): diff --git a/api/models/score.py b/api/models/score.py index fba134b8..544d2349 100644 --- a/api/models/score.py +++ b/api/models/score.py @@ -4,7 +4,7 @@ class Score(models.Model): score_id = models.AutoField(primary_key=True) score = models.SmallIntegerField() - indiening = models.ForeignKey('Indiening', on_delete=models.CASCADE) + indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE) def __str__(self): return str(self.score_id) diff --git a/api/models/vak.py b/api/models/vak.py index 77f05be6..574939ff 100644 --- a/api/models/vak.py +++ b/api/models/vak.py @@ -4,10 +4,12 @@ class Vak(models.Model): vak_id = models.AutoField(primary_key=True) naam = models.CharField(max_length=100) - studenten = models.ManyToManyField('Gebruiker', related_name='vak_gebruikers', blank=True) - lesgevers = models.ManyToManyField('Gebruiker', related_name='vak_lesgevers', blank=True) + studenten = models.ManyToManyField( + "Gebruiker", related_name="vak_gebruikers", blank=True + ) + lesgevers = models.ManyToManyField( + "Gebruiker", related_name="vak_lesgevers", blank=True + ) def __str__(self): return self.naam - - diff --git a/api/serializers/gebruiker.py b/api/serializers/gebruiker.py index 3fa92518..3d441fb6 100644 --- a/api/serializers/gebruiker.py +++ b/api/serializers/gebruiker.py @@ -12,6 +12,6 @@ def create(self, validated_data): return instance def update(self, instance, validated_data): - instance.is_lesgever = validated_data.pop('is_lesgever') + instance.is_lesgever = validated_data.pop("is_lesgever") instance.save() - return instance \ No newline at end of file + return instance diff --git a/api/serializers/groep.py b/api/serializers/groep.py index 982e2fd2..d8ac74dc 100644 --- a/api/serializers/groep.py +++ b/api/serializers/groep.py @@ -8,18 +8,18 @@ class Meta: fields = "__all__" def create(self, validated_data): - students_data = validated_data.pop('studenten') - validate_students(students_data, validated_data['project']) - + students_data = validated_data.pop("studenten") + validate_students(students_data, validated_data["project"]) + instance = Groep.objects.create(**validated_data) instance.studenten.set(students_data) return instance - + def update(self, instance, validated_data): - students_data = validated_data.pop('studenten') - validate_students(students_data, validated_data['project']) - + students_data = validated_data.pop("studenten") + validate_students(students_data, validated_data["project"]) + super().update(instance=instance, validated_data=validated_data) instance.studenten.set(students_data) instance.save() @@ -27,14 +27,17 @@ def update(self, instance, validated_data): return instance - def validate_students(students_data, project): groepen = Groep.objects.filter(project=project) - + for student in students_data: if student.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'studenten' moeten studenten zijn!") - + raise serializers.ValidationError( + "Alle gebruikers in 'studenten' moeten studenten zijn!" + ) + for groep in groepen: if groep.studenten.contains(student): - raise serializers.ValidationError(f"Gebruiker {student.user.id} zit al in een groep voor dit project") \ No newline at end of file + raise serializers.ValidationError( + f"Gebruiker {student.user.id} zit al in een groep voor dit project" + ) diff --git a/api/serializers/indiening.py b/api/serializers/indiening.py index 7f4f94be..8362df18 100644 --- a/api/serializers/indiening.py +++ b/api/serializers/indiening.py @@ -5,10 +5,10 @@ class IndieningSerializer(serializers.ModelSerializer): class Meta: model = Indiening - fields = ('__all__') + fields = "__all__" class IndieningBestandSerializer(serializers.ModelSerializer): class Meta: model = IndieningBestand - fields = ('__all__') \ No newline at end of file + fields = "__all__" diff --git a/api/serializers/project.py b/api/serializers/project.py index 33484740..28f02c89 100644 --- a/api/serializers/project.py +++ b/api/serializers/project.py @@ -6,27 +6,27 @@ class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project - fields = '__all__' + fields = "__all__" def create(self, validated_data): - deadline = validated_data.pop('deadline') + deadline = validated_data.pop("deadline") validate_deadline(deadline) project = Project.objects.create(**validated_data) project.deadline = deadline project.save() return project - + def update(self, instance, validated_data): - deadline = validated_data.pop('deadline') + deadline = validated_data.pop("deadline") validate_deadline(deadline) super().update(instance=instance, validated_data=validated_data) instance.deadline = deadline instance.save() return instance - + def validate_deadline(deadline): if deadline <= timezone.now(): - raise serializers.ValidationError("Deadline moet in de toekomst liggen") \ No newline at end of file + raise serializers.ValidationError("Deadline moet in de toekomst liggen") diff --git a/api/serializers/score.py b/api/serializers/score.py index 2797d739..8a1449d4 100644 --- a/api/serializers/score.py +++ b/api/serializers/score.py @@ -8,25 +8,29 @@ class Meta: fields = "__all__" def create(self, validated_data): - if Score.objects.filter(indiening=validated_data.get('indiening')).exists(): - raise serializers.ValidationError("Deze indiening heeft al een bestaande score") + if Score.objects.filter(indiening=validated_data.get("indiening")).exists(): + raise serializers.ValidationError( + "Deze indiening heeft al een bestaande score" + ) validate_score(validated_data) return Score.objects.create(**validated_data) - + def update(self, instance, validated_data): validate_score(validated_data) validate_indiening(instance, validated_data) super().update(instance=instance, validated_data=validated_data) instance.save() return instance - + + def validate_score(data): - max_score = data.get('indiening').groep.project.max_score - if data['score'] > max_score: - raise serializers.ValidationError(f'Score kan niet hoger zijn dan de maximale score van {max_score}') - -def validate_indiening(instance, data): - if instance.indiening != data.get('indiening'): - raise serializers.ValidationError('indiening_id kan niet aangepast worden') - + max_score = data.get("indiening").groep.project.max_score + if data["score"] > max_score: + raise serializers.ValidationError( + f"Score kan niet hoger zijn dan de maximale score van {max_score}" + ) + +def validate_indiening(instance, data): + if instance.indiening != data.get("indiening"): + raise serializers.ValidationError("indiening_id kan niet aangepast worden") diff --git a/api/serializers/vak.py b/api/serializers/vak.py index 584020b3..be0bab3c 100644 --- a/api/serializers/vak.py +++ b/api/serializers/vak.py @@ -8,9 +8,9 @@ class Meta: fields = "__all__" def create(self, validated_data): - students_data = validated_data.pop('studenten') - teachers_data = validated_data.pop('lesgevers') - + students_data = validated_data.pop("studenten") + teachers_data = validated_data.pop("lesgevers") + validate_students_teachers(students_data, teachers_data) vak = Vak.objects.create(**validated_data) @@ -20,8 +20,8 @@ def create(self, validated_data): return vak def update(self, instance, validated_data): - students_data = validated_data.pop('studenten', []) - teachers_data = validated_data.pop('lesgevers', []) + students_data = validated_data.pop("studenten", []) + teachers_data = validated_data.pop("lesgevers", []) validate_students_teachers(students_data, teachers_data) @@ -36,8 +36,12 @@ def update(self, instance, validated_data): def validate_students_teachers(students_data, teachers_data): for student in students_data: if student.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'studenten' moeten studenten zijn") + raise serializers.ValidationError( + "Alle gebruikers in 'studenten' moeten studenten zijn" + ) for teacher in teachers_data: if not teacher.is_lesgever: - raise serializers.ValidationError("Alle gebruikers in 'lesgevers' moeten lesgevers zijn") \ No newline at end of file + raise serializers.ValidationError( + "Alle gebruikers in 'lesgevers' moeten lesgevers zijn" + ) diff --git a/api/tests/factories/gebruiker.py b/api/tests/factories/gebruiker.py index bdd4115b..f035ecaa 100644 --- a/api/tests/factories/gebruiker.py +++ b/api/tests/factories/gebruiker.py @@ -1,4 +1,3 @@ -import factory from django.contrib.auth.models import User from api.models.gebruiker import Gebruiker from factory.django import DjangoModelFactory @@ -9,10 +8,10 @@ class UserFactory(DjangoModelFactory): class Meta: model = User - username = Faker('user_name') - first_name = Faker('first_name') - last_name = Faker('last_name') - email = Faker('email') + username = Faker("user_name") + first_name = Faker("first_name") + last_name = Faker("last_name") + email = Faker("email") class GebruikerFactory(DjangoModelFactory): @@ -20,4 +19,4 @@ class Meta: model = Gebruiker user = SubFactory(UserFactory) - is_lesgever = Faker('boolean') \ No newline at end of file + is_lesgever = Faker("boolean") diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py index f437462b..f3e23aa9 100644 --- a/api/tests/factories/groep.py +++ b/api/tests/factories/groep.py @@ -22,4 +22,4 @@ def studenten(self, create, extracted, **kwargs): for student in extracted: self.studenten.add(student) else: - self.studenten.add(GebruikerFactory()) \ No newline at end of file + self.studenten.add(GebruikerFactory()) diff --git a/api/tests/factories/indiening.py b/api/tests/factories/indiening.py index 03c6fdf9..38d63ece 100644 --- a/api/tests/factories/indiening.py +++ b/api/tests/factories/indiening.py @@ -10,6 +10,7 @@ fake = Faker() + class IndieningFactory(DjangoModelFactory): class Meta: model = Indiening @@ -22,10 +23,11 @@ class Meta: ) ) + class IndieningBestandFactory(DjangoModelFactory): class Meta: model = IndieningBestand indiening_bestand_id = factory.Sequence(lambda n: n) indiening = SubFactory(IndieningFactory) - bestand = FileField(filename='test.txt', data=b"file content") + bestand = FileField(filename="test.txt", data=b"file content") diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py index 3f48a3fb..ccf6d80e 100644 --- a/api/tests/factories/project.py +++ b/api/tests/factories/project.py @@ -1,6 +1,5 @@ import factory from api.models.project import Project -from django.core.files.base import ContentFile from factory.django import DjangoModelFactory from factory import SubFactory from django.utils import timezone @@ -9,13 +8,14 @@ fake = Faker() + class ProjectFactory(DjangoModelFactory): class Meta: model = Project project_id = factory.Sequence(lambda n: n) - titel = factory.Faker('word') - beschrijving = factory.Faker('paragraph') + titel = factory.Faker("word") + beschrijving = factory.Faker("paragraph") opgave_bestand = factory.django.FileField(data=b"file content") vak = SubFactory(VakFactory) deadline = factory.LazyFunction( @@ -23,4 +23,4 @@ class Meta: fake.date_time_between(start_date="+1d", end_date="+30d") ) ) - max_score = factory.Faker('random_int', min=10, max=30) \ No newline at end of file + max_score = factory.Faker("random_int", min=10, max=30) diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index fda28772..b47c1a40 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -10,5 +10,5 @@ class Meta: model = Score score_id = factory.Sequence(lambda n: n) - score = Faker('random_int', min=0, max=100) - indiening = SubFactory(IndieningFactory) \ No newline at end of file + score = Faker("random_int", min=0, max=100) + indiening = SubFactory(IndieningFactory) diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py index 6a932fdf..9880b775 100644 --- a/api/tests/factories/vak.py +++ b/api/tests/factories/vak.py @@ -10,7 +10,7 @@ class Meta: model = Vak vak_id = factory.Sequence(lambda n: n) - naam = Faker('name') + naam = Faker("name") @factory.post_generation def studenten(self, create, extracted, **kwargs): @@ -22,7 +22,7 @@ def studenten(self, create, extracted, **kwargs): self.studenten.add(gebruiker) else: self.studenten.add(GebruikerFactory()) - + @factory.post_generation def lesgevers(self, create, extracted, **kwargs): if not create: @@ -32,4 +32,4 @@ def lesgevers(self, create, extracted, **kwargs): for lesgever in extracted: self.lesgevers.add(lesgever) else: - self.lesgevers.add(GebruikerFactory(is_lesgever=True)) \ No newline at end of file + self.lesgevers.add(GebruikerFactory(is_lesgever=True)) diff --git a/api/tests/models/test_gebruiker.py b/api/tests/models/test_gebruiker.py index 62185a4c..f4bf162b 100644 --- a/api/tests/models/test_gebruiker.py +++ b/api/tests/models/test_gebruiker.py @@ -14,5 +14,7 @@ def test_gebruiker_is_lesgever(self): self.assertEqual(self.gebruiker2.is_lesgever, True) def test_str_method(self): - expected_object_name = self.gebruiker1.user.first_name + " " + self.gebruiker1.user.last_name + expected_object_name = ( + self.gebruiker1.user.first_name + " " + self.gebruiker1.user.last_name + ) self.assertEqual(str(self.gebruiker1), expected_object_name) diff --git a/api/tests/models/test_project.py b/api/tests/models/test_project.py index 7509a0f0..395217c6 100644 --- a/api/tests/models/test_project.py +++ b/api/tests/models/test_project.py @@ -13,4 +13,4 @@ def test_project_vak(self): self.assertIsNotNone(self.project.vak) def test_project_max_score(self): - self.assertTrue(10 <= self.project.max_score <= 30) \ No newline at end of file + self.assertTrue(10 <= self.project.max_score <= 30) diff --git a/api/tests/models/test_vak.py b/api/tests/models/test_vak.py index 5a4af892..e0f94427 100644 --- a/api/tests/models/test_vak.py +++ b/api/tests/models/test_vak.py @@ -8,12 +8,9 @@ def setUp(self): def test_str_method(self): self.assertEqual(str(self.vak), self.vak.naam) - def test_vak_studenten(self): self.assertEqual(self.vak.studenten.count(), 1) - def test_vak_lesgevers(self): self.assertEqual(self.vak.lesgevers.count(), 1) - diff --git a/api/urls.py b/api/urls.py index 89cedff2..4a7ad92a 100644 --- a/api/urls.py +++ b/api/urls.py @@ -23,30 +23,35 @@ from .views.gebruiker import gebruiker_list, gebruiker_detail from .views.vak import vak_list, vak_detail from .views.project import project_list, project_detail -from .views.indiening import indiening_list, indiening_detail, indiening_bestand_list, indiening_bestand_detail +from .views.indiening import ( + indiening_list, + indiening_detail, + indiening_bestand_list, + indiening_bestand_detail, +) from .views.score import score_list, score_detail from .views.groep import groep_list, groep_detail urlpatterns = [ - path('.well-known/microsoft-identity-association.json', microsoft_association), - path('admin/', admin.site.urls), - path('oauth2/', include('django_auth_adfs.urls')), - path('login_redirect/', login_redirect), - path('api/', home), - path('api/gebruikers/', gebruiker_list), - path('api/gebruikers//', gebruiker_detail, name='gebruiker_detail'), - path('api/vakken/', vak_list), - path('api/vakken//', vak_detail), - path('api/projecten/', project_list), - path('api/projecten//', project_detail), - path('api/indieningen/', indiening_list), - path('api/indieningen//', indiening_detail), - path('api/indiening_bestanden/', indiening_bestand_list), - path('api/indiening_bestanden//', indiening_bestand_detail), - path('api/scores/', score_list), - path('api/scores//', score_detail), - path('api/groepen/', groep_list), - path('api/groepen//', groep_detail) + path(".well-known/microsoft-identity-association.json", microsoft_association), + path("admin/", admin.site.urls), + path("oauth2/", include("django_auth_adfs.urls")), + path("login_redirect/", login_redirect), + path("api/", home), + path("api/gebruikers/", gebruiker_list), + path("api/gebruikers//", gebruiker_detail, name="gebruiker_detail"), + path("api/vakken/", vak_list), + path("api/vakken//", vak_detail), + path("api/projecten/", project_list), + path("api/projecten//", project_detail), + path("api/indieningen/", indiening_list), + path("api/indieningen//", indiening_detail), + path("api/indiening_bestanden/", indiening_bestand_list), + path("api/indiening_bestanden//", indiening_bestand_detail), + path("api/scores/", score_list), + path("api/scores//", score_detail), + path("api/groepen/", groep_list), + path("api/groepen//", groep_detail), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/api/utils.py b/api/utils.py index 17ac9ead..82436397 100644 --- a/api/utils.py +++ b/api/utils.py @@ -4,13 +4,13 @@ API_URLS = { - 'gebruikers': '/api/gebruikers', - 'vakken': '/api/vakken', - 'groepen': '/api/groepen', - 'indieningen': '/api/indieningen', - 'indiening_bestanden': '/api/indiening_bestanden', - 'scores': 'api/scores', - 'projecten': 'api/projecten' + "gebruikers": "/api/gebruikers", + "vakken": "/api/vakken", + "groepen": "/api/groepen", + "indieningen": "/api/indieningen", + "indiening_bestanden": "/api/indiening_bestanden", + "scores": "api/scores", + "projecten": "api/projecten", } @@ -37,16 +37,19 @@ def get_graph_token(): return response.json() except Exception: return None - + + def is_lesgever(user): if user.is_superuser: return True gebruiker = Gebruiker.objects.get(pk=user.id) return gebruiker.is_lesgever + def contains(lijst, user): gebruiker = Gebruiker.objects.get(pk=user.id) return lijst.all().contains(gebruiker) + def get_gebruiker(user): return Gebruiker.objects.get(pk=user.id) diff --git a/api/views/gebruiker.py b/api/views/gebruiker.py index a5ceaac7..183fffbc 100644 --- a/api/views/gebruiker.py +++ b/api/views/gebruiker.py @@ -8,24 +8,26 @@ from api.utils import is_lesgever - - -@api_view(['GET']) +@api_view(["GET"]) def gebruiker_list(request): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): gebruikers = Gebruiker.objects.all() else: gebruikers = Gebruiker.objects.filter(user=request.user.id) - - if 'is_lesgever' in request.GET and request.GET.get('is_lesgever').lower() in ['true', 'false']: - gebruikers = gebruikers.filter(is_lesgever = (request.GET.get('is_lesgever').lower() == 'true')) + if "is_lesgever" in request.GET and request.GET.get("is_lesgever").lower() in [ + "true", + "false", + ]: + gebruikers = gebruikers.filter( + is_lesgever=(request.GET.get("is_lesgever").lower() == "true") + ) serializer = GebruikerSerializer(gebruikers, many=True) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - + @api_view(["GET", "PUT"]) def gebruiker_detail(request, id): @@ -34,12 +36,12 @@ def gebruiker_detail(request, id): except Gebruiker.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user) or id == request.user.id: serializer = GebruikerSerializer(gebruiker) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - elif request.method == 'PUT': + elif request.method == "PUT": if request.user.is_superuser: serializer = GebruikerSerializer(gebruiker, data=request.data) if serializer.is_valid(): @@ -47,7 +49,3 @@ def gebruiker_detail(request, id): return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_403_FORBIDDEN) - - - - diff --git a/api/views/groep.py b/api/views/groep.py index 3b7b95e7..2dbbf4d6 100644 --- a/api/views/groep.py +++ b/api/views/groep.py @@ -9,7 +9,7 @@ @api_view(["GET", "POST"]) def groep_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): groepen = Groep.objects.all() else: @@ -24,7 +24,7 @@ def groep_list(request, format=None): if "student" in request.GET: try: - student = eval(request.GET.get('student')) + student = eval(request.GET.get("student")) groepen = groepen.filter(studenten=student) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) @@ -32,8 +32,7 @@ def groep_list(request, format=None): serializer = GroepSerializer(groepen, many=True) return Response(serializer.data) - - elif request.method == 'POST': + elif request.method == "POST": if is_lesgever(request.user): serializer = GroepSerializer(data=request.data) if serializer.is_valid(): @@ -41,28 +40,29 @@ def groep_list(request, format=None): return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_403_FORBIDDEN) - -@api_view(['GET', 'PUT', 'DELETE']) -def groep_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def groep_detail(request, id, format=None): try: groep = Groep.objects.get(pk=id) except Groep.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user) or contains(groep.studenten, request.user): serializer = GroepSerializer(groep) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - + if is_lesgever(request.user): - if request.method == 'PUT': + if request.method == "PUT": serializer = GroepSerializer(groep, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": groep.delete() return Response(status=status.HTTP_204_NO_CONTENT) - return Response(status=status.HTTP_403_FORBIDDEN) \ No newline at end of file + return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/api/views/indiening.py b/api/views/indiening.py index 55a94142..7d07469e 100644 --- a/api/views/indiening.py +++ b/api/views/indiening.py @@ -10,7 +10,7 @@ @api_view(["GET", "POST"]) def indiening_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): indieningen = Indiening.objects.all() else: @@ -19,18 +19,21 @@ def indiening_list(request, format=None): if "groep" in request.GET: try: - groep = eval(request.GET.get('groep')) + groep = eval(request.GET.get("groep")) indieningen = indieningen.filter(groep=groep) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) serializer = IndieningSerializer(indieningen, many=True) return Response(serializer.data) - - elif request.method == 'POST': - if 'indiening_bestanden' not in request.FILES: - return Response({"indiening_bestanden":["This field is required."]}, status=status.HTTP_400_BAD_REQUEST) - + + elif request.method == "POST": + if "indiening_bestanden" not in request.FILES: + return Response( + {"indiening_bestanden": ["This field is required."]}, + status=status.HTTP_400_BAD_REQUEST, + ) + serializer = IndieningSerializer(data=request.data) if serializer.is_valid(): serializer.save() @@ -38,49 +41,54 @@ def indiening_list(request, format=None): else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - for file in request.FILES.getlist('indiening_bestanden'): - IndieningBestand.objects.create(indiening = indiening, bestand = file) + for file in request.FILES.getlist("indiening_bestanden"): + IndieningBestand.objects.create(indiening=indiening, bestand=file) return Response(serializer.data, status=status.HTTP_201_CREATED) - - -@api_view(['GET', 'DELETE']) -def indiening_detail(request, id, format=None): + +@api_view(["GET", "DELETE"]) +def indiening_detail(request, id, format=None): try: indiening = Indiening.objects.get(pk=id) except Indiening.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': - if is_lesgever(request.user) or contains(indiening.groep.studenten, request.user): + if request.method == "GET": + if is_lesgever(request.user) or contains( + indiening.groep.studenten, request.user + ): serializer = IndieningSerializer(indiening) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - - elif request.method == 'DELETE': - if is_lesgever(request.user) or contains(indiening.groep.studenten, request.user): + + elif request.method == "DELETE": + if is_lesgever(request.user) or contains( + indiening.groep.studenten, request.user + ): indiening.delete() return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_403_FORBIDDEN) - -@api_view(['GET']) +@api_view(["GET"]) def indiening_bestand_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): indieningen_bestanden = IndieningBestand.objects.all() else: groepen = Groep.objects.filter(studenten=request.user.id) indieningen = Indiening.objects.filter(groep__in=groepen) - indieningen_bestanden = IndieningBestand.objects.filter(indiening__in=indieningen) - + indieningen_bestanden = IndieningBestand.objects.filter( + indiening__in=indieningen + ) if "indiening" in request.GET: try: - indiening = eval(request.GET.get('indiening')) - indieningen_bestanden = indieningen_bestanden.filter(indiening=indiening) + indiening = eval(request.GET.get("indiening")) + indieningen_bestanden = indieningen_bestanden.filter( + indiening=indiening + ) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) @@ -88,15 +96,17 @@ def indiening_bestand_list(request, format=None): return Response(serializer.data) -@api_view(['GET']) +@api_view(["GET"]) def indiening_bestand_detail(request, id, format=None): try: indiening_bestand = IndieningBestand.objects.get(pk=id) except IndieningBestand.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': - if is_lesgever(request.user) or contains(indiening_bestand.indiening.groep.studenten, request.user): + if request.method == "GET": + if is_lesgever(request.user) or contains( + indiening_bestand.indiening.groep.studenten, request.user + ): serializer = IndieningBestandSerializer(indiening_bestand) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/api/views/project.py b/api/views/project.py index 7bd3d390..ffa55647 100644 --- a/api/views/project.py +++ b/api/views/project.py @@ -10,7 +10,7 @@ @api_view(["GET", "POST"]) def project_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): projects = Project.objects.all() else: @@ -26,8 +26,8 @@ def project_list(request, format=None): serializer = ProjectSerializer(projects, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": if is_lesgever(request.user): serializer = ProjectSerializer(data=request.data) if serializer.is_valid(): @@ -36,28 +36,29 @@ def project_list(request, format=None): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_403_FORBIDDEN) -@api_view(['GET', 'PUT', 'DELETE']) -def project_detail(request, id, format=None): + +@api_view(["GET", "PUT", "DELETE"]) +def project_detail(request, id, format=None): try: project = Project.objects.get(pk=id) except Project.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user) or contains(project.vak.studenten, request.user): serializer = ProjectSerializer(project) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - + if is_lesgever(request.user): - if request.method == 'PUT': + if request.method == "PUT": serializer = ProjectSerializer(project, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": project.delete() return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/api/views/score.py b/api/views/score.py index 49ee79b7..eee21e0b 100644 --- a/api/views/score.py +++ b/api/views/score.py @@ -12,7 +12,7 @@ @api_view(["GET", "POST"]) def score_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): scores = Score.objects.all() else: @@ -22,15 +22,15 @@ def score_list(request, format=None): if "indiening" in request.GET: try: - indiening = eval(request.GET.get('indiening')) + indiening = eval(request.GET.get("indiening")) scores = scores.filter(indiening=indiening) except NameError: return Response(status=status.HTTP_400_BAD_REQUEST) serializer = ScoreSerializer(scores, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": if is_lesgever(request.user): serializer = ScoreSerializer(data=request.data) if serializer.is_valid(): @@ -38,29 +38,32 @@ def score_list(request, format=None): return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_403_FORBIDDEN) - -@api_view(['GET', 'PUT', 'DELETE']) -def score_detail(request, id, format=None): + + +@api_view(["GET", "PUT", "DELETE"]) +def score_detail(request, id, format=None): try: score = Score.objects.get(pk=id) except Score.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - - if request.method == 'GET': - if is_lesgever(request.user) or contains(score.indiening.groep.studenten, request.user): + + if request.method == "GET": + if is_lesgever(request.user) or contains( + score.indiening.groep.studenten, request.user + ): serializer = ScoreSerializer(score) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) - if is_lesgever(request.user): - if request.method == 'PUT': + if is_lesgever(request.user): + if request.method == "PUT": serializer = ScoreSerializer(score, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + + elif request.method == "DELETE": score.delete() return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/api/views/vak.py b/api/views/vak.py index 549c7dbc..23e5f9f2 100644 --- a/api/views/vak.py +++ b/api/views/vak.py @@ -12,7 +12,7 @@ @api_view(["GET", "POST"]) def vak_list(request, format=None): - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user): vakken = Vak.objects.all() else: @@ -20,8 +20,8 @@ def vak_list(request, format=None): serializer = VakSerializer(vakken, many=True) return Response(serializer.data) - - elif request.method == 'POST': + + elif request.method == "POST": if is_lesgever(request.user): serializer = VakSerializer(data=request.data) if serializer.is_valid(): @@ -29,22 +29,22 @@ def vak_list(request, format=None): return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_403_FORBIDDEN) - - -@api_view(['GET', 'PUT', 'DELETE']) + + +@api_view(["GET", "PUT", "DELETE"]) def vak_detail(request, id, format=None): try: vak = Vak.objects.get(pk=id) except Vak.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - if request.method == 'GET': + if request.method == "GET": if is_lesgever(request.user) or contains(vak.studenten, request.user): serializer = VakSerializer(vak) return Response(serializer.data) return Response(status=status.HTTP_403_FORBIDDEN) if is_lesgever(request.user): - if request.method == 'PUT': + if request.method == "PUT": try: serializer = VakSerializer(vak, data=request.data) if serializer.is_valid(): @@ -52,9 +52,9 @@ def vak_detail(request, id, format=None): return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) except ValidationError as e: - return Response({'error': e}, status=status.HTTP_400_BAD_REQUEST) - - elif request.method == 'DELETE': + return Response({"error": e}, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == "DELETE": vak.delete() return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_403_FORBIDDEN) diff --git a/api/views/views.py b/api/views/views.py index 51deac6d..c567a3ba 100644 --- a/api/views/views.py +++ b/api/views/views.py @@ -8,8 +8,6 @@ def login_redirect(request): - print(get_graph_token()) - gebruiker_post_data = { "user": request.user.id, "subjects": [], From fcdbda6dc0f50e322f50232fcc441cc6e0d48f4f Mon Sep 17 00:00:00 2001 From: arallaer Date: Wed, 13 Mar 2024 20:31:20 +0100 Subject: [PATCH 25/44] serializer testen --- api/serializers/groep.py | 15 ++++-- api/tests/factories/groep.py | 3 +- api/tests/factories/vak.py | 1 - api/tests/serializers/test_gebruiker.py | 40 +++++++++------ api/tests/serializers/test_groep.py | 33 +++++++++--- api/tests/serializers/test_project.py | 61 ++++++++++++++++++---- api/tests/serializers/test_vak.py | 67 +++++++++++++++++-------- api/tests/views/test_groep.py | 6 +-- api/urls.py | 2 +- 9 files changed, 164 insertions(+), 64 deletions(-) diff --git a/api/serializers/groep.py b/api/serializers/groep.py index 982e2fd2..5b3e2faa 100644 --- a/api/serializers/groep.py +++ b/api/serializers/groep.py @@ -1,5 +1,6 @@ from rest_framework import serializers from api.models.groep import Groep +from collections import Counter class GroepSerializer(serializers.ModelSerializer): @@ -18,7 +19,7 @@ def create(self, validated_data): def update(self, instance, validated_data): students_data = validated_data.pop('studenten') - validate_students(students_data, validated_data['project']) + validate_students(students_data, validated_data['project'], current_group=instance) super().update(instance=instance, validated_data=validated_data) instance.studenten.set(students_data) @@ -28,7 +29,12 @@ def update(self, instance, validated_data): -def validate_students(students_data, project): +def validate_students(students_data, project, current_group=None): + student_counts = Counter(students_data) + for student, count in student_counts.items(): + if count > 1: + raise serializers.ValidationError(f"Student {student.user.id} zit al in deze groep.") + groepen = Groep.objects.filter(project=project) for student in students_data: @@ -36,5 +42,6 @@ def validate_students(students_data, project): raise serializers.ValidationError("Alle gebruikers in 'studenten' moeten studenten zijn!") for groep in groepen: - if groep.studenten.contains(student): - raise serializers.ValidationError(f"Gebruiker {student.user.id} zit al in een groep voor dit project") \ No newline at end of file + if (current_group and groep.groep_id != current_group.groep_id) and groep.studenten.contains(student): + raise serializers.ValidationError(f"Gebruiker {student.user.id} zit al in een groep voor dit project") + \ No newline at end of file diff --git a/api/tests/factories/groep.py b/api/tests/factories/groep.py index f437462b..39e70471 100644 --- a/api/tests/factories/groep.py +++ b/api/tests/factories/groep.py @@ -10,7 +10,6 @@ class GroepFactory(DjangoModelFactory): class Meta: model = Groep - groep_id = factory.Sequence(lambda n: n) project = SubFactory(ProjectFactory) @factory.post_generation @@ -22,4 +21,4 @@ def studenten(self, create, extracted, **kwargs): for student in extracted: self.studenten.add(student) else: - self.studenten.add(GebruikerFactory()) \ No newline at end of file + self.studenten.add(GebruikerFactory(is_lesgever=False)) \ No newline at end of file diff --git a/api/tests/factories/vak.py b/api/tests/factories/vak.py index 6a932fdf..6f871185 100644 --- a/api/tests/factories/vak.py +++ b/api/tests/factories/vak.py @@ -9,7 +9,6 @@ class VakFactory(DjangoModelFactory): class Meta: model = Vak - vak_id = factory.Sequence(lambda n: n) naam = Faker('name') @factory.post_generation diff --git a/api/tests/serializers/test_gebruiker.py b/api/tests/serializers/test_gebruiker.py index 57ab078f..0ba77076 100644 --- a/api/tests/serializers/test_gebruiker.py +++ b/api/tests/serializers/test_gebruiker.py @@ -2,32 +2,44 @@ from rest_framework.exceptions import ValidationError from api.serializers.gebruiker import GebruikerSerializer from api.tests.factories.gebruiker import UserFactory, GebruikerFactory -from api.tests.factories.vak import VakFactory class GebruikerSerializerTest(APITestCase): def setUp(self): - self.user = UserFactory.create(username="testuser") - self.gebruiker = GebruikerFactory.create(user=self.user) - - subjects = VakFactory.create_batch(2) - self.gebruiker.subjects.set(subjects) - + self.user = UserFactory.create() + self.gebruiker = GebruikerFactory.create(user=self.user, is_lesgever=False) self.serializer = GebruikerSerializer(instance=self.gebruiker) def test_contains_expected_fields(self): data = self.serializer.data - self.assertCountEqual(data.keys(), ["user", "is_lesgever", "subjects"]) + self.assertCountEqual(data.keys(), ["user", "is_lesgever"]) def test_user_field_content(self): data = self.serializer.data self.assertEqual(data["user"], self.user.id) - - def test_subjects_field_content(self): + + def test_is_lesgever_field_content(self): data = self.serializer.data - subjects = [subject.pk for subject in self.gebruiker.subjects.all()] - self.assertEqual(data["subjects"], subjects) - + self.assertEqual(data["is_lesgever"], self.gebruiker.is_lesgever) + + def test_create(self): + data = {'user': UserFactory.create().id, 'is_lesgever':False} + serializer = GebruikerSerializer(data=data) + self.assertTrue(serializer.is_valid()) + gebruiker = serializer.save() + self.assertEqual(gebruiker.user.id, data["user"]) + self.assertEqual(gebruiker.is_lesgever, data["is_lesgever"]) + + def test_update(self): + data = self.serializer.data + self.assertFalse(data["is_lesgever"]) + data["is_lesgever"] = True + serializer = GebruikerSerializer(instance=self.gebruiker, data=data, partial=True) + self.assertTrue(serializer.is_valid()) + self.gebruiker = serializer.save() + self.assertTrue(self.gebruiker.is_lesgever) + def test_validation_for_blank_items(self): - serializer = GebruikerSerializer(data={"name": "", "subjects": []}) + serializer = GebruikerSerializer(data={"user": "", "is_lesgever": []}) self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) + diff --git a/api/tests/serializers/test_groep.py b/api/tests/serializers/test_groep.py index 32052557..5818613e 100644 --- a/api/tests/serializers/test_groep.py +++ b/api/tests/serializers/test_groep.py @@ -2,6 +2,8 @@ from rest_framework.exceptions import ValidationError from api.serializers.groep import GroepSerializer from api.tests.factories.groep import GroepFactory +from api.tests.factories.gebruiker import GebruikerFactory +from api.tests.factories.gebruiker import GebruikerFactory class GroepSerializerTest(APITestCase): @@ -11,19 +13,36 @@ def setUp(self): def test_contains_expected_fields(self): data = self.serializer.data - self.assertCountEqual(data.keys(), ["group_id", "project", "students"]) + self.assertCountEqual(data.keys(), ["groep_id", "project", "studenten"]) def test_project_field_content(self): data = self.serializer.data self.assertEqual( - data["project"], self.groep.project.pk - ) # replace 'pk' with the correct primary key field of the Project model + data["project"], self.groep.project.project_id + ) - def test_students_field_content(self): + def test_studenten_field_content(self): data = self.serializer.data - students = [student.pk for student in self.groep.students.all()] - self.assertEqual(data["students"], students) + students = [student.user.id for student in self.groep.studenten.all()] + self.assertEqual(data["studenten"], students) + + def test_create(self): + data = {'project': self.groep.project.project_id, 'studenten': [GebruikerFactory.create(is_lesgever=False).user.id for _ in range(3)]} + serializer = GroepSerializer(data=data) + self.assertTrue(serializer.is_valid()) + groep = serializer.save() + self.assertEqual(groep.project.project_id, data['project']) + self.assertEqual(set([student.user.id for student in groep.studenten.all()]), set(data['studenten'])) + + def test_update(self): + data = self.serializer.data + self.assertEqual(len(data["studenten"]), 1) + data["studenten"].append(GebruikerFactory.create(is_lesgever=False).user.id) + serializer = GroepSerializer(instance=self.groep, data=data, partial=True) + self.assertTrue(serializer.is_valid()) + groep = serializer.save() + self.assertEqual([student.user.id for student in groep.studenten.all()], data['studenten']) def test_validation_for_blank_items(self): - serializer = GroepSerializer(data={"project": "", "students": []}) + serializer = GroepSerializer(data={"project": "", "studenten": []}) self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index 144d6f09..413f71a6 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -3,6 +3,9 @@ from api.serializers.project import ProjectSerializer from api.tests.factories.project import ProjectFactory from dateutil.parser import parse +from api.tests.factories.vak import VakFactory +from django.core.files import File + class ProjectSerializerTest(APITestCase): @@ -17,10 +20,11 @@ def test_contains_expected_fields(self): [ "project_id", "titel", - "description", - "opgavebestanden", + "beschrijving", + "opgave_bestand", "vak", "deadline", + "max_score" ], ) @@ -28,22 +32,27 @@ def test_titel_field_content(self): data = self.serializer.data self.assertEqual(data["titel"], self.project.titel) - def test_description_field_content(self): + def test_beschrijving_field_content(self): data = self.serializer.data - self.assertEqual(data["description"], self.project.description) + self.assertEqual(data["beschrijving"], self.project.beschrijving) - def test_opgavebestanden_field_content(self): + def test_opgave_bestand_field_content(self): data = self.serializer.data self.assertEqual( - data["opgavebestanden"].lstrip("/"), str(self.project.opgavebestanden) + data["opgave_bestand"].lstrip("/"), str(self.project.opgave_bestand) ) def test_vak_field_content(self): data = self.serializer.data self.assertEqual( - data["vak"], self.project.vak.pk - ) # replace 'pk' with the correct primary key field of the Vak model - + data["vak"], self.project.vak.vak_id + ) + + def test_max_score_field_content(self): + data = self.serializer.data + self.assertGreaterEqual(data['max_score'], 10) + self.assertLessEqual(data['max_score'], 30) + def test_deadline_field_content(self): data = self.serializer.data self.assertEqual(parse(data["deadline"]), self.project.deadline) @@ -52,10 +61,40 @@ def test_validation_for_blank_items(self): serializer = ProjectSerializer( data={ "titel": "", - "description": "", - "opgavebestanden": "", + "beschrijving": "", + "opgave_bestand": "", "vak": "", "deadline": "", + "max_score": "", } ) self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) + + def test_create(self): + vak = VakFactory.create().vak_id + with open('api/tests/data/test.txt', 'rb') as fp: + data = {"titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": File(fp), + "vak": vak, + "deadline": self.serializer.data["deadline"], + "max_score": 20 + } + serializer = ProjectSerializer(data=data) + self.assertTrue(serializer.is_valid()) + project = serializer.save() + self.assertEqual(project.deadline, parse(data['deadline'])) + + def test_update(self): + with open('api/tests/data/test.txt', 'rb') as fp: + data = {"titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": File(fp), + "vak": self.serializer.data["vak"], + "deadline": self.serializer.data["deadline"], + "max_score": 20 + } + serializer = ProjectSerializer(instance=self.project, data=data, partial=True) + self.assertTrue(serializer.is_valid()) + project = serializer.save() + self.assertEqual(project.deadline, parse(data['deadline'])) diff --git a/api/tests/serializers/test_vak.py b/api/tests/serializers/test_vak.py index 8a34b296..2c1b7e7c 100644 --- a/api/tests/serializers/test_vak.py +++ b/api/tests/serializers/test_vak.py @@ -7,47 +7,72 @@ class VakSerializerTest(APITestCase): def setUp(self): - self.students = GebruikerFactory.create_batch(3, is_lesgever=False) - self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) - self.vak = VakFactory.create() - self.vak.students.set(self.students) - self.vak.teachers.set(self.teachers) - self.serializer = VakSerializer(instance=self.vak) + self.vak_data = VakFactory.create() + self.serializer = VakSerializer(instance=self.vak_data) def test_contains_expected_fields(self): data = self.serializer.data self.assertCountEqual( - data.keys(), ["vak_id", "name", "students", "teachers"] - ) # geen projects hier? + data.keys(), ["vak_id", "naam", "studenten", "lesgevers"] + ) def test_vak_id_field_content(self): data = self.serializer.data - self.assertEqual(data["vak_id"], self.vak.vak_id) + self.assertEqual(data["vak_id"], self.vak_data.vak_id) - def test_name_field_content(self): + def test_naam_field_content(self): data = self.serializer.data - self.assertEqual(data["name"], self.vak.name) + self.assertEqual(data["naam"], self.vak_data.naam) - def test_students_field_content(self): + def test_studenten_field_content(self): data = self.serializer.data - self.assertCountEqual( - data["students"], [student.pk for student in self.students] + self.assertEqual( + set(data["studenten"]), set([student.user.id for student in self.vak_data.studenten.all()]) ) - def test_teachers_field_content(self): + def test_lesgevers_field_content(self): data = self.serializer.data - self.assertCountEqual( - data["teachers"], [teacher.pk for teacher in self.teachers] + self.assertEqual( + set(data["lesgevers"]), set([teacher.user.id for teacher in self.vak_data.lesgevers.all()]) ) def test_validation_for_blank_items(self): serializer = VakSerializer( data={ "vak_id": "", - "name": "", - "students": [], - "teachers": [], - "projects": [], + "naam": "", + "studenten": [], + "lesgevers": [], } ) self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) + + def test_create(self): + students_data = [GebruikerFactory.create(is_lesgever=False).user.id for _ in range(3)] + teachers_data = [GebruikerFactory.create(is_lesgever=True).user.id for _ in range(3)] + data = {'naam': 'test vak', 'studenten': students_data, 'lesgevers': teachers_data} + serializer = VakSerializer(data=data) + self.assertTrue(serializer.is_valid()) + vak = serializer.save() + self.assertEqual( + set(students_data), set([student.user.id for student in vak.studenten.all()]) + ) + self.assertEqual( + set(teachers_data), set([teacher.user.id for teacher in vak.lesgevers.all()]) + ) + self.assertEqual(vak.naam, 'test vak') + + def test_update(self): + students_data = [GebruikerFactory.create(is_lesgever=False).user.id for _ in range(3)] + teachers_data = [GebruikerFactory.create(is_lesgever=True).user.id for _ in range(3)] + data = {'naam': 'nieuw vak', 'studenten': students_data, 'lesgevers': teachers_data} + serializer = VakSerializer(instance=self.vak_data, data=data, partial=True) + self.assertTrue(serializer.is_valid()) + vak = serializer.save() + self.assertEqual( + set(students_data), set([student.user.id for student in vak.studenten.all()]) + ) + self.assertEqual( + set(teachers_data), set([teacher.user.id for teacher in vak.lesgevers.all()]) + ) + self.assertEqual(vak.naam, 'nieuw vak') \ No newline at end of file diff --git a/api/tests/views/test_groep.py b/api/tests/views/test_groep.py index 651008cd..3bdc8457 100644 --- a/api/tests/views/test_groep.py +++ b/api/tests/views/test_groep.py @@ -15,9 +15,9 @@ def test_get_groep_list(self): def test_post_groep_list(self): groep = GroepFactory.create() data = { - "groep": groep.group_id, + "groep": groep.groep_id, "project": groep.project.project_id, - "students": [], + "studenten": [], } response = self.client.post("/api/groepen/", data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) @@ -27,7 +27,7 @@ class GroepDetailViewTest(APITestCase): def setUp(self): self.client = APIClient() self.groep = GroepFactory.create() - self.url = reverse("groep_detail", kwargs={"id": self.groep.group_id}) + self.url = reverse("groep_detail", kwargs={"id": self.groep.groep_id}) def test_get_groep_detail(self): response = self.client.get(self.url) diff --git a/api/urls.py b/api/urls.py index 89cedff2..23a5d813 100644 --- a/api/urls.py +++ b/api/urls.py @@ -46,7 +46,7 @@ path('api/scores/', score_list), path('api/scores//', score_detail), path('api/groepen/', groep_list), - path('api/groepen//', groep_detail) + path('api/groepen//', groep_detail, name='groep_detail') ] urlpatterns = format_suffix_patterns(urlpatterns) From a06867aaf8e3e3a5342286231492120dd3c168f0 Mon Sep 17 00:00:00 2001 From: arallaer Date: Wed, 13 Mar 2024 20:45:20 +0100 Subject: [PATCH 26/44] data nodig voor de testen --- .gitignore | 3 ++- api/tests/serializers/test_project.py | 4 ++-- api/tests/testdata/test.txt | 1 + api/urls.py | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 api/tests/testdata/test.txt diff --git a/.gitignore b/.gitignore index 0ed25f64..f29b818d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ venv migrations .env htmlcov -data \ No newline at end of file +data +uploads \ No newline at end of file diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index d06e2148..4953c05f 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -69,7 +69,7 @@ def test_validation_for_blank_items(self): def test_create(self): vak = VakFactory.create().vak_id - with open("api/tests/data/test.txt", "rb") as fp: + with open("api/tests/testdata/test.txt", "rb") as fp: data = { "titel": "test project", "beschrijving": "Dit is een test project.", @@ -84,7 +84,7 @@ def test_create(self): self.assertEqual(project.deadline, parse(data["deadline"])) def test_update(self): - with open("api/tests/data/test.txt", "rb") as fp: + with open("api/tests/testdata/test.txt", "rb") as fp: data = { "titel": "test project", "beschrijving": "Dit is een test project.", diff --git a/api/tests/testdata/test.txt b/api/tests/testdata/test.txt new file mode 100644 index 00000000..e6578a2a --- /dev/null +++ b/api/tests/testdata/test.txt @@ -0,0 +1 @@ +Hallo, dit is mijn eerste tekst bestand. \ No newline at end of file diff --git a/api/urls.py b/api/urls.py index 9393d63d..a02fdb8c 100644 --- a/api/urls.py +++ b/api/urls.py @@ -51,7 +51,7 @@ path("api/scores/", score_list), path("api/scores//", score_detail), path("api/groepen/", groep_list), - path("api/groepen//", groep_detail, naam="groep_detail"), + path("api/groepen//", groep_detail, name="groep_detail"), ] urlpatterns = format_suffix_patterns(urlpatterns) From c79ad3fe40dfe7ed779eee06c89434fd1f425739 Mon Sep 17 00:00:00 2001 From: arallaer Date: Wed, 13 Mar 2024 23:45:38 +0100 Subject: [PATCH 27/44] view testen --- api/tests/factories/gebruiker.py | 1 + api/tests/serializers/test_groep.py | 1 - api/tests/serializers/test_project.py | 1 + api/tests/views/test_gebruiker.py | 44 +++++----- api/tests/views/test_groep.py | 35 ++++++-- api/tests/views/test_project.py | 112 ++++++++++++-------------- api/tests/views/test_vak.py | 58 ++++++------- api/urls.py | 12 +-- 8 files changed, 143 insertions(+), 121 deletions(-) diff --git a/api/tests/factories/gebruiker.py b/api/tests/factories/gebruiker.py index f035ecaa..54bb2f13 100644 --- a/api/tests/factories/gebruiker.py +++ b/api/tests/factories/gebruiker.py @@ -12,6 +12,7 @@ class Meta: first_name = Faker("first_name") last_name = Faker("last_name") email = Faker("email") + is_superuser = Faker("boolean") class GebruikerFactory(DjangoModelFactory): diff --git a/api/tests/serializers/test_groep.py b/api/tests/serializers/test_groep.py index 711cbea4..4b91dcfa 100644 --- a/api/tests/serializers/test_groep.py +++ b/api/tests/serializers/test_groep.py @@ -3,7 +3,6 @@ from api.serializers.groep import GroepSerializer from api.tests.factories.groep import GroepFactory from api.tests.factories.gebruiker import GebruikerFactory -from api.tests.factories.gebruiker import GebruikerFactory class GroepSerializerTest(APITestCase): diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index 4953c05f..aba1f2d8 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -68,6 +68,7 @@ def test_validation_for_blank_items(self): self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) def test_create(self): + print(self.serializer.data["deadline"]) vak = VakFactory.create().vak_id with open("api/tests/testdata/test.txt", "rb") as fp: data = { diff --git a/api/tests/views/test_gebruiker.py b/api/tests/views/test_gebruiker.py index 4eb37584..91102502 100644 --- a/api/tests/views/test_gebruiker.py +++ b/api/tests/views/test_gebruiker.py @@ -1,36 +1,40 @@ from rest_framework.test import APIClient, APITestCase -from api.tests.factories.gebruiker import GebruikerFactory, UserFactory +from api.tests.factories.gebruiker import GebruikerFactory from django.urls import reverse +from rest_framework import status class GebruikerListViewTest(APITestCase): def setUp(self): + self.gebruiker = GebruikerFactory.create() + self.url = reverse("gebruiker_list") self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) - def test_get_gebruiker_list(self): - response = self.client.get("/api/gebruikers/") - self.assertEqual(response.status_code, 200) - - def test_post_gebruiker_list(self): - data = {"user": UserFactory.create().id, "is_lesgever": True} - response = self.client.post("/api/gebruikers/", data) - self.assertEqual(response.status_code, 201) + def test_gebruiker_list_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) class GebruikerDetailViewTest(APITestCase): def setUp(self): - self.client = APIClient() self.gebruiker = GebruikerFactory.create() + self.gebruiker.user.is_superuser = True + self.gebruiker.user.save() + self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) self.url = reverse("gebruiker_detail", kwargs={"id": self.gebruiker.user.id}) - def test_get_gebruiker_detail(self): + def test_gebruiker_detail_get(self): response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data["user"], self.gebruiker.user.id) - - def test_put_gebruiker_detail(self): - data = {"user": self.gebruiker.user.id, "is_lesgever": True, "subjects": []} - response = self.client.put(self.url, data) - self.assertEqual(response.status_code, 200) - # TODO - # self.assertEqual(response.data['is_lesgever'], True) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_gebruiker_detail_put(self): + new_data = { + "user": self.gebruiker.user.id, + "is_lesgever": not self.gebruiker.is_lesgever, + } + response = self.client.put(self.url, new_data, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.gebruiker.refresh_from_db() + self.assertEqual(self.gebruiker.is_lesgever, new_data["is_lesgever"]) diff --git a/api/tests/views/test_groep.py b/api/tests/views/test_groep.py index 3bdc8457..3d9ad45e 100644 --- a/api/tests/views/test_groep.py +++ b/api/tests/views/test_groep.py @@ -2,37 +2,58 @@ from rest_framework import status from rest_framework.test import APIClient, APITestCase from api.tests.factories.groep import GroepFactory +from api.tests.factories.gebruiker import GebruikerFactory class GroepListViewTest(APITestCase): def setUp(self): + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.url = reverse("groep_list") self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) - def test_get_groep_list(self): - response = self.client.get("/api/groepen/") + def test_groep_list_get(self): + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_post_groep_list(self): + def test_groep_list_post(self): groep = GroepFactory.create() data = { - "groep": groep.groep_id, + "groep_id": groep.groep_id, "project": groep.project.project_id, "studenten": [], } - response = self.client.post("/api/groepen/", data) + response = self.client.post(self.url, data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) class GroepDetailViewTest(APITestCase): def setUp(self): - self.client = APIClient() self.groep = GroepFactory.create() + self.gebruiker = GebruikerFactory.create(is_lesgever=True) self.url = reverse("groep_detail", kwargs={"id": self.groep.groep_id}) + self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) - def test_get_groep_detail(self): + def test_groep_detail_get(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) + def test_groep_detail_put(self): + new_data = { + "groep_id": self.groep.groep_id, + "project": self.groep.project.project_id, + "studenten": [], + } + response = self.client.put(self.url, new_data, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.groep.refresh_from_db() + self.assertEqual(set(self.groep.studenten.all()), set(new_data["studenten"])) + + def test_groep_detail_delete(self): + response = self.client.delete(self.url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + def test_get_invalid_groep(self): url = reverse("groep_detail", kwargs={"id": 10101}) response = self.client.get(url) diff --git a/api/tests/views/test_project.py b/api/tests/views/test_project.py index a852857b..3c5707b0 100644 --- a/api/tests/views/test_project.py +++ b/api/tests/views/test_project.py @@ -3,78 +3,70 @@ from rest_framework.test import APITestCase from api.tests.factories.project import ProjectFactory from api.tests.factories.vak import VakFactory +from api.tests.factories.gebruiker import GebruikerFactory +from rest_framework.test import APIClient +from django.core.files import File -class ProjectViewTest(APITestCase): +class ProjectListViewTest(APITestCase): def setUp(self): - self.project = ProjectFactory.create() - self.vak = VakFactory.create() - self.list_url = reverse("project_list") - self.detail_url = reverse( - "project_detail", kwargs={"id": self.project.project_id} - ) + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.url = reverse("project_list") + self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) - def test_get_project_list(self): - response = self.client.get(self.list_url) + def test_project_list_get(self): + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_get_project_detail(self): - response = self.client.get(self.detail_url) + def test_project_list_post(self): + vak = VakFactory.create().vak_id + with open("api/tests/testdata/test.txt", "rb") as fp: + data = { + "titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": File(fp), + "vak": vak, + "deadline": "2024-03-31T12:40:05.317980Z", + "max_score": 20, + } + response = self.client.post(self.url, data, format="multipart") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + +class ProjectDetailViewTest(APITestCase): + def setUp(self): + self.project = ProjectFactory.create() + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.url = reverse("project_detail", kwargs={"id": self.project.project_id}) + self.client = APIClient() + self.client.force_authenticate(user=self.gebruiker.user) + + def test_project_detail_get(self): + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_get_invalid_project_detail(self): + def test_invalid_project_detail_get(self): url = reverse("project_detail", kwargs={"id": "9999999"}) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - def test_create_project(self): - # data = { - # "titel": "New Project", - # "description": "This is a new project.", - # "opgavebestanden": "data/opgaves/opgave.pdf", - # "vak": self.vak.vak_id, - # "deadline": "2022-12-31T23:59:59Z", - # } - # response = self.client.post(self.list_url, data) - # TODO - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertTrue(True) - - def test_create_invalid_project(self): - data = { - "titel": "", - "description": "", - "opgavebestanden": "", - "vak": "", - "deadline": "", + def test_project_detail_put(self): + new_data = { + "project_id": self.project.project_id, + "titel": self.project.titel, + "beschrijving": "Aangepaste beschrijving", + "opgave_bestand": self.project.opgave_bestand, + "vak": self.project.vak.vak_id, + "deadline": self.project.deadline, + "max_score": self.project.max_score, } - response = self.client.post(self.list_url, data) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - - def test_update_project(self): - # data = { - # "titel": "Updated Project", - # "description": "This project has been updated.", - # "opgavebestanden": "data/opgaves/opgave.pdf", - # "vak": self.project.vak.vak_id, - # "deadline": "2023-12-31T23:59:59Z", - # } - # response = self.client.put(self.detail_url, data) - # TODO - # self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertTrue(True) - - def test_update_invalid_project(self): - data = { - "titel": "", - "description": "", - "opgavebestanden": "", - "vak": "", - "deadline": "", - } - response = self.client.put(self.detail_url, data) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + response = self.client.put(self.url, new_data, format="multipart") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.project.refresh_from_db() + self.assertEqual(self.project.titel, new_data["titel"]) + self.assertEqual(self.project.beschrijving, new_data["beschrijving"]) - def test_delete_project(self): - response = self.client.delete(self.detail_url) + def test_project_detail_delete(self): + response = self.client.delete(self.url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/api/tests/views/test_vak.py b/api/tests/views/test_vak.py index 30ba5ccc..19c07230 100644 --- a/api/tests/views/test_vak.py +++ b/api/tests/views/test_vak.py @@ -3,54 +3,58 @@ from rest_framework.test import APITestCase from api.tests.factories.vak import VakFactory from api.tests.factories.gebruiker import GebruikerFactory +from rest_framework.test import APIClient -# from api.models.vak import Vak - -class VakViewsTest(APITestCase): +class VakListViewTest(APITestCase): def setUp(self): - self.students = GebruikerFactory.create_batch(3, is_lesgever=False) - self.teachers = GebruikerFactory.create_batch(2, is_lesgever=True) - self.vak = VakFactory.create() - self.vak.students.set(self.students) - self.vak.teachers.set(self.teachers) + self.client = APIClient() + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.studenten = GebruikerFactory.create_batch(3, is_lesgever=False) + self.lesgevers = GebruikerFactory.create_batch(2, is_lesgever=True) + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("vak_list") def test_vak_list_get(self): - response = self.client.get(reverse("vak_list")) + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data), 1) - """" TODO: projecten bijhouden bij een vak ipv vakken bijhouden bij een project def test_vak_list_post(self): data = { - 'vak_id': 'test_vak_id', - 'name': 'test_name', - 'students': [student.pk for student in self.students], - 'teachers': [teacher.pk for teacher in self.teachers], + "naam": "test_name", + "studenten": [student.user.id for student in self.studenten], + "lesgevers": [lesgever.user.id for lesgever in self.lesgevers], } - response = self.client.post(reverse('vak_list'), data) + response = self.client.post(self.url, data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(Vak.objects.count(), 2) - """ + + +class VakDetailViewTest(APITestCase): + def setUp(self): + self.vak = VakFactory.create() + self.client = APIClient() + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.studenten = GebruikerFactory.create_batch(3, is_lesgever=False) + self.lesgevers = GebruikerFactory.create_batch(2, is_lesgever=True) + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("vak_detail", args=[self.vak.vak_id]) def test_vak_detail_get(self): response = self.client.get(reverse("vak_detail", args=[self.vak.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["vak_id"], self.vak.vak_id) - """" TODO: projecten bijhouden bij een vak ipv vakken bijhouden bij een project def test_vak_detail_put(self): data = { - 'vak_id': 'updated_vak_id', - 'name': 'updated_name', - 'students': [student.pk for student in self.students], - 'teachers': [teacher.pk for teacher in self.teachers], + "vak_id": self.vak.vak_id, + "naam": "nieuwe_vak_naam", + "studenten": [student.user.id for student in self.studenten], + "teachers": [teacher.user.id for teacher in self.lesgevers], } - response = self.client.put(reverse('vak_detail', args=[self.vak.pk]), data) + response = self.client.put(reverse("vak_detail", args=[self.vak.pk]), data) self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data['vak_id'], 'updated_vak_id') - """ + self.assertEqual(response.data["naam"], data["naam"]) def test_vak_detail_delete(self): - response = self.client.delete(reverse("vak_detail", args=[self.vak.pk])) + response = self.client.delete(self.url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/api/urls.py b/api/urls.py index a02fdb8c..9267b64e 100644 --- a/api/urls.py +++ b/api/urls.py @@ -38,19 +38,19 @@ path("oauth2/", include("django_auth_adfs.urls")), path("login_redirect/", login_redirect), path("api/", home), - path("api/gebruikers/", gebruiker_list), + path("api/gebruikers/", gebruiker_list, name="gebruiker_list"), path("api/gebruikers//", gebruiker_detail, name="gebruiker_detail"), - path("api/vakken/", vak_list), - path("api/vakken//", vak_detail), - path("api/projecten/", project_list), - path("api/projecten//", project_detail), + path("api/vakken/", vak_list, name="vak_list"), + path("api/vakken//", vak_detail, name="vak_detail"), + path("api/projecten/", project_list, name="project_list"), + path("api/projecten//", project_detail, name="project_detail"), path("api/indieningen/", indiening_list), path("api/indieningen//", indiening_detail), path("api/indiening_bestanden/", indiening_bestand_list), path("api/indiening_bestanden//", indiening_bestand_detail), path("api/scores/", score_list), path("api/scores//", score_detail), - path("api/groepen/", groep_list), + path("api/groepen/", groep_list, name="groep_list"), path("api/groepen//", groep_detail, name="groep_detail"), ] From f85ac185403cc89c92f1eca741c5ee37e5d7ff22 Mon Sep 17 00:00:00 2001 From: arallaer Date: Thu, 14 Mar 2024 00:32:27 +0100 Subject: [PATCH 28/44] score serializer en views testen --- api/tests/factories/project.py | 2 +- api/tests/factories/score.py | 1 - api/tests/models/test_project.py | 2 +- api/tests/serializers/test_project.py | 3 +- api/tests/serializers/test_score.py | 46 ++++++++++++++++++++++ api/tests/views/test_score.py | 55 +++++++++++++++++++++++++++ api/urls.py | 4 +- 7 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 api/tests/serializers/test_score.py create mode 100644 api/tests/views/test_score.py diff --git a/api/tests/factories/project.py b/api/tests/factories/project.py index ccf6d80e..216d1998 100644 --- a/api/tests/factories/project.py +++ b/api/tests/factories/project.py @@ -23,4 +23,4 @@ class Meta: fake.date_time_between(start_date="+1d", end_date="+30d") ) ) - max_score = factory.Faker("random_int", min=10, max=30) + max_score = factory.Faker("random_int", min=10, max=100) diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index b47c1a40..bb60fb7d 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -9,6 +9,5 @@ class ScoreFactory(DjangoModelFactory): class Meta: model = Score - score_id = factory.Sequence(lambda n: n) score = Faker("random_int", min=0, max=100) indiening = SubFactory(IndieningFactory) diff --git a/api/tests/models/test_project.py b/api/tests/models/test_project.py index 395217c6..971c0eec 100644 --- a/api/tests/models/test_project.py +++ b/api/tests/models/test_project.py @@ -13,4 +13,4 @@ def test_project_vak(self): self.assertIsNotNone(self.project.vak) def test_project_max_score(self): - self.assertTrue(10 <= self.project.max_score <= 30) + self.assertTrue(10 <= self.project.max_score <= 100) diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index aba1f2d8..f07ff023 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -48,7 +48,7 @@ def test_vak_field_content(self): def test_max_score_field_content(self): data = self.serializer.data self.assertGreaterEqual(data["max_score"], 10) - self.assertLessEqual(data["max_score"], 30) + self.assertLessEqual(data["max_score"], 100) def test_deadline_field_content(self): data = self.serializer.data @@ -68,7 +68,6 @@ def test_validation_for_blank_items(self): self.assertRaises(ValidationError, serializer.is_valid, raise_exception=True) def test_create(self): - print(self.serializer.data["deadline"]) vak = VakFactory.create().vak_id with open("api/tests/testdata/test.txt", "rb") as fp: data = { diff --git a/api/tests/serializers/test_score.py b/api/tests/serializers/test_score.py new file mode 100644 index 00000000..886cd47e --- /dev/null +++ b/api/tests/serializers/test_score.py @@ -0,0 +1,46 @@ +# test_score.py +from django.test import TestCase +from api.serializers.score import ScoreSerializer +from api.tests.factories.score import ScoreFactory +from api.tests.factories.indiening import IndieningFactory + +class ScoreSerializerTest(TestCase): + def setUp(self): + self.score = ScoreFactory.create() + self.score.score = self.score.indiening.groep.project.max_score + self.score.save() + self.serializer = ScoreSerializer(instance=self.score) + + def test_score_serializer_fields(self): + data = self.serializer.data + self.assertEqual(set(data.keys()), set(["score_id", "indiening", "score"])) + + def test_score_id_field_content(self): + data = self.serializer.data + self.assertEqual(data["score_id"], self.score.score_id) + + def test_indiening_field_content(self): + data = self.serializer.data + self.assertEqual(data["indiening"], self.score.indiening.indiening_id) + + def test_score_field_content(self): + data = self.serializer.data + self.assertEqual(data["score"], self.score.score) + + def test_score_serializer_create(self): + indiening = IndieningFactory.create() + max_score = indiening.groep.project.max_score + data = {"indiening": indiening.indiening_id, "score": max_score} + serializer = ScoreSerializer(data=data) + self.assertTrue(serializer.is_valid()) + score = serializer.save() + self.assertEqual(score.indiening, indiening) + self.assertEqual(score.score, data["score"]) + + def test_score_serializer_update(self): + score = self.score.score + new_data = {"score": score - 1, "indiening": self.score.indiening.indiening_id, "score_id": self.score.score_id} + serializer = ScoreSerializer(instance=self.score, data=new_data, partial=True) + self.assertTrue(serializer.is_valid()) + score = serializer.save() + self.assertEqual(score.score, new_data["score"]) \ No newline at end of file diff --git a/api/tests/views/test_score.py b/api/tests/views/test_score.py new file mode 100644 index 00000000..11b94e68 --- /dev/null +++ b/api/tests/views/test_score.py @@ -0,0 +1,55 @@ +# test_score.py +from django.test import TestCase, RequestFactory +from api.views.score import score_list, score_detail +from api.tests.factories.score import ScoreFactory +from api.tests.factories.indiening import IndieningFactory +from api.tests.factories.gebruiker import GebruikerFactory +from rest_framework.test import force_authenticate, APIClient +from django.urls import reverse +from rest_framework import status + +class ScoreListViewTest(TestCase): + def setUp(self): + self.client = APIClient() + self.gebruiker = GebruikerFactory.create(is_lesgever=True) + self.score = ScoreFactory.create() + self.score.score = self.score.indiening.groep.project.max_score + self.score.save() + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("score_list") + + def test_score_list_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_score_list_post(self): + indiening = IndieningFactory.create() + data = {"score_id": self.score.score_id, "score": indiening.groep.project.max_score, "indiening": indiening.indiening_id} + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + +class ScoreDetailViewTest(TestCase): + def setUp(self): + self.client = APIClient() + self.gebruiker = GebruikerFactory.create() + self.gebruiker.user.is_superuser = True + self.gebruiker.user.save() + self.score = ScoreFactory.create() + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("score_detail", kwargs={"id": self.score.score_id}) + + def test_score_detail_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_score_detail_put(self): + new_data = {"score": 10, "indiening": self.score.indiening.indiening_id} + response = self.client.put(self.url, new_data, format='json') + self.assertEqual(response.status_code, 200) + self.score.refresh_from_db() + self.assertEqual(self.score.score, new_data["score"]) # Add other assertions + + def test_score_detail_delete(self): + response = self.client.delete(self.url) + self.assertEqual(response.status_code, 204) \ No newline at end of file diff --git a/api/urls.py b/api/urls.py index 9267b64e..0b5eb6c6 100644 --- a/api/urls.py +++ b/api/urls.py @@ -48,8 +48,8 @@ path("api/indieningen//", indiening_detail), path("api/indiening_bestanden/", indiening_bestand_list), path("api/indiening_bestanden//", indiening_bestand_detail), - path("api/scores/", score_list), - path("api/scores//", score_detail), + path("api/scores/", score_list, name="score_list"), + path("api/scores//", score_detail, name="score_detail"), path("api/groepen/", groep_list, name="groep_list"), path("api/groepen//", groep_detail, name="groep_detail"), ] From ac795ce677c12f972329b5ef12f4f155703b2fcb Mon Sep 17 00:00:00 2001 From: arallaer Date: Thu, 14 Mar 2024 00:33:36 +0100 Subject: [PATCH 29/44] linter --- api/tests/factories/score.py | 1 - api/tests/serializers/test_score.py | 17 +++++++++++------ api/tests/views/test_score.py | 24 ++++++++++++++---------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/api/tests/factories/score.py b/api/tests/factories/score.py index bb60fb7d..2507da23 100644 --- a/api/tests/factories/score.py +++ b/api/tests/factories/score.py @@ -1,4 +1,3 @@ -import factory from api.models.score import Score from factory.django import DjangoModelFactory from factory import SubFactory, Faker diff --git a/api/tests/serializers/test_score.py b/api/tests/serializers/test_score.py index 886cd47e..40b89b57 100644 --- a/api/tests/serializers/test_score.py +++ b/api/tests/serializers/test_score.py @@ -4,6 +4,7 @@ from api.tests.factories.score import ScoreFactory from api.tests.factories.indiening import IndieningFactory + class ScoreSerializerTest(TestCase): def setUp(self): self.score = ScoreFactory.create() @@ -14,15 +15,15 @@ def setUp(self): def test_score_serializer_fields(self): data = self.serializer.data self.assertEqual(set(data.keys()), set(["score_id", "indiening", "score"])) - + def test_score_id_field_content(self): data = self.serializer.data self.assertEqual(data["score_id"], self.score.score_id) - + def test_indiening_field_content(self): data = self.serializer.data self.assertEqual(data["indiening"], self.score.indiening.indiening_id) - + def test_score_field_content(self): data = self.serializer.data self.assertEqual(data["score"], self.score.score) @@ -35,12 +36,16 @@ def test_score_serializer_create(self): self.assertTrue(serializer.is_valid()) score = serializer.save() self.assertEqual(score.indiening, indiening) - self.assertEqual(score.score, data["score"]) + self.assertEqual(score.score, data["score"]) def test_score_serializer_update(self): score = self.score.score - new_data = {"score": score - 1, "indiening": self.score.indiening.indiening_id, "score_id": self.score.score_id} + new_data = { + "score": score - 1, + "indiening": self.score.indiening.indiening_id, + "score_id": self.score.score_id, + } serializer = ScoreSerializer(instance=self.score, data=new_data, partial=True) self.assertTrue(serializer.is_valid()) score = serializer.save() - self.assertEqual(score.score, new_data["score"]) \ No newline at end of file + self.assertEqual(score.score, new_data["score"]) diff --git a/api/tests/views/test_score.py b/api/tests/views/test_score.py index 11b94e68..ab4e20de 100644 --- a/api/tests/views/test_score.py +++ b/api/tests/views/test_score.py @@ -1,13 +1,13 @@ # test_score.py -from django.test import TestCase, RequestFactory -from api.views.score import score_list, score_detail +from django.test import TestCase from api.tests.factories.score import ScoreFactory from api.tests.factories.indiening import IndieningFactory from api.tests.factories.gebruiker import GebruikerFactory -from rest_framework.test import force_authenticate, APIClient +from rest_framework.test import APIClient from django.urls import reverse from rest_framework import status + class ScoreListViewTest(TestCase): def setUp(self): self.client = APIClient() @@ -24,11 +24,15 @@ def test_score_list_get(self): def test_score_list_post(self): indiening = IndieningFactory.create() - data = {"score_id": self.score.score_id, "score": indiening.groep.project.max_score, "indiening": indiening.indiening_id} - response = self.client.post(self.url, data, format='json') + data = { + "score_id": self.score.score_id, + "score": indiening.groep.project.max_score, + "indiening": indiening.indiening_id, + } + response = self.client.post(self.url, data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) - + class ScoreDetailViewTest(TestCase): def setUp(self): self.client = APIClient() @@ -38,18 +42,18 @@ def setUp(self): self.score = ScoreFactory.create() self.client.force_authenticate(user=self.gebruiker.user) self.url = reverse("score_detail", kwargs={"id": self.score.score_id}) - + def test_score_detail_get(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - + def test_score_detail_put(self): new_data = {"score": 10, "indiening": self.score.indiening.indiening_id} - response = self.client.put(self.url, new_data, format='json') + response = self.client.put(self.url, new_data, format="json") self.assertEqual(response.status_code, 200) self.score.refresh_from_db() self.assertEqual(self.score.score, new_data["score"]) # Add other assertions def test_score_detail_delete(self): response = self.client.delete(self.url) - self.assertEqual(response.status_code, 204) \ No newline at end of file + self.assertEqual(response.status_code, 204) From 6a89b0407b231aa77e987c383395922ea9479017 Mon Sep 17 00:00:00 2001 From: arallaer Date: Thu, 14 Mar 2024 01:21:51 +0100 Subject: [PATCH 30/44] indiening testen --- api/tests/models/test_indiening.py | 43 ++++++++++++++ api/tests/serializers/test_indiening.py | 74 +++++++++++++++++++++++++ api/tests/serializers/test_project.py | 54 +++++++++--------- api/tests/testdata/test.txt | 1 - api/tests/views/test_indiening.py | 68 +++++++++++++++++++++++ api/tests/views/test_project.py | 23 ++++---- api/urls.py | 8 +-- api/views/indiening.py | 6 -- 8 files changed, 225 insertions(+), 52 deletions(-) create mode 100644 api/tests/models/test_indiening.py create mode 100644 api/tests/serializers/test_indiening.py delete mode 100644 api/tests/testdata/test.txt create mode 100644 api/tests/views/test_indiening.py diff --git a/api/tests/models/test_indiening.py b/api/tests/models/test_indiening.py new file mode 100644 index 00000000..2ac3320c --- /dev/null +++ b/api/tests/models/test_indiening.py @@ -0,0 +1,43 @@ +# test_indiening.py +from django.test import TestCase +from django.core.files.uploadedfile import SimpleUploadedFile +from api.tests.factories.indiening import IndieningFactory, IndieningBestandFactory + + +class IndieningModelTest(TestCase): + def setUp(self): + self.indiening = IndieningFactory.create() + + def test_str_method(self): + self.assertEqual(str(self.indiening), str(self.indiening.indiening_id)) + + def test_groep(self): + self.assertIsNotNone(self.indiening.groep) + + def test_tijdstip(self): + self.assertIsNotNone(self.indiening.tijdstip) + + def test_indiening_bestand(self): + self.assertEqual(self.indiening.indieningbestand_set.count(), 0) + + def test_indiening_bestand_add(self): + IndieningBestandFactory.create(indiening=self.indiening) + self.assertEqual(self.indiening.indieningbestand_set.count(), 1) + + +class IndieningBestandModelTest(TestCase): + def setUp(self): + self.indiening_bestand = IndieningBestandFactory.create( + bestand=SimpleUploadedFile("file.txt", b"file_content") + ) + + def test_str_method(self): + self.assertEqual( + str(self.indiening_bestand), str(self.indiening_bestand.bestand.name) + ) + + def test_indiening(self): + self.assertIsNotNone(self.indiening_bestand.indiening) + + def test_bestand(self): + self.assertIsNotNone(self.indiening_bestand.bestand) diff --git a/api/tests/serializers/test_indiening.py b/api/tests/serializers/test_indiening.py new file mode 100644 index 00000000..70e90c92 --- /dev/null +++ b/api/tests/serializers/test_indiening.py @@ -0,0 +1,74 @@ +# test_indiening.py +from django.test import TestCase +from django.core.files.uploadedfile import SimpleUploadedFile +from api.serializers.indiening import IndieningSerializer, IndieningBestandSerializer +from api.tests.factories.indiening import IndieningFactory, IndieningBestandFactory +from api.tests.factories.groep import GroepFactory + + +class IndieningSerializerTest(TestCase): + def setUp(self): + self.indiening = IndieningFactory.create() + self.serializer = IndieningSerializer(instance=self.indiening) + + def test_indiening_serializer_fields(self): + data = self.serializer.data + self.assertEqual( + set(data.keys()), set(["indiening_id", "groep", "tijdstip"]) + ) # Add other fields + + def test_indiening_serializer_create(self): + # can't check tijdstip because it's auto_now_add + groep = GroepFactory.create() + data = {"groep": groep.groep_id} + serializer = IndieningSerializer(data=data) + self.assertTrue(serializer.is_valid()) + indiening = serializer.save() + self.assertEqual(indiening.groep, groep) + + def test_indiening_serializer_update(self): + # can't check tijdstip because it's auto_now_add + new_data = {"groep": self.indiening.groep.groep_id} + serializer = IndieningSerializer( + instance=self.indiening, data=new_data, partial=True + ) + self.assertTrue(serializer.is_valid()) + indiening = serializer.save() + self.assertEqual(indiening.groep, self.indiening.groep) + + +class IndieningBestandSerializerTest(TestCase): + def setUp(self): + self.indiening_bestand = IndieningBestandFactory.create( + bestand=SimpleUploadedFile("file.txt", b"file_content") + ) + self.serializer = IndieningBestandSerializer(instance=self.indiening_bestand) + + def test_indiening_bestand_serializer_fields(self): + data = self.serializer.data + self.assertEqual( + set(data.keys()), set(["indiening_bestand_id", "indiening", "bestand"]) + ) + + def test_indiening_bestand_serializer_create(self): + indiening = IndieningFactory.create() + data = { + "indiening": indiening.indiening_id, + "bestand": SimpleUploadedFile("file.txt", b"file_content"), + } # Add other fields + serializer = IndieningBestandSerializer(data=data) + self.assertTrue(serializer.is_valid()) + indiening_bestand = serializer.save() + self.assertEqual(indiening_bestand.indiening, indiening) + + def test_indiening_bestand_serializer_update(self): + new_data = { + "indiening": self.indiening_bestand.indiening.indiening_id, + "bestand": SimpleUploadedFile("file.txt", b"file_content"), + } # Add other fields + serializer = IndieningBestandSerializer( + instance=self.indiening_bestand, data=new_data, partial=True + ) + self.assertTrue(serializer.is_valid()) + indiening_bestand = serializer.save() + self.assertEqual(indiening_bestand.indiening, self.indiening_bestand.indiening) diff --git a/api/tests/serializers/test_project.py b/api/tests/serializers/test_project.py index f07ff023..2f482167 100644 --- a/api/tests/serializers/test_project.py +++ b/api/tests/serializers/test_project.py @@ -4,7 +4,7 @@ from api.tests.factories.project import ProjectFactory from dateutil.parser import parse from api.tests.factories.vak import VakFactory -from django.core.files import File +from django.core.files.uploadedfile import SimpleUploadedFile class ProjectSerializerTest(APITestCase): @@ -69,33 +69,29 @@ def test_validation_for_blank_items(self): def test_create(self): vak = VakFactory.create().vak_id - with open("api/tests/testdata/test.txt", "rb") as fp: - data = { - "titel": "test project", - "beschrijving": "Dit is een test project.", - "opgave_bestand": File(fp), - "vak": vak, - "deadline": self.serializer.data["deadline"], - "max_score": 20, - } - serializer = ProjectSerializer(data=data) - self.assertTrue(serializer.is_valid()) - project = serializer.save() - self.assertEqual(project.deadline, parse(data["deadline"])) + data = { + "titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": SimpleUploadedFile("file.txt", b"file_content"), + "vak": vak, + "deadline": self.serializer.data["deadline"], + "max_score": 20, + } + serializer = ProjectSerializer(data=data) + self.assertTrue(serializer.is_valid()) + project = serializer.save() + self.assertEqual(project.deadline, parse(data["deadline"])) def test_update(self): - with open("api/tests/testdata/test.txt", "rb") as fp: - data = { - "titel": "test project", - "beschrijving": "Dit is een test project.", - "opgave_bestand": File(fp), - "vak": self.serializer.data["vak"], - "deadline": self.serializer.data["deadline"], - "max_score": 20, - } - serializer = ProjectSerializer( - instance=self.project, data=data, partial=True - ) - self.assertTrue(serializer.is_valid()) - project = serializer.save() - self.assertEqual(project.deadline, parse(data["deadline"])) + data = { + "titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": SimpleUploadedFile("file.txt", b"file_content"), + "vak": self.serializer.data["vak"], + "deadline": self.serializer.data["deadline"], + "max_score": 20, + } + serializer = ProjectSerializer(instance=self.project, data=data, partial=True) + self.assertTrue(serializer.is_valid()) + project = serializer.save() + self.assertEqual(project.deadline, parse(data["deadline"])) diff --git a/api/tests/testdata/test.txt b/api/tests/testdata/test.txt deleted file mode 100644 index e6578a2a..00000000 --- a/api/tests/testdata/test.txt +++ /dev/null @@ -1 +0,0 @@ -Hallo, dit is mijn eerste tekst bestand. \ No newline at end of file diff --git a/api/tests/views/test_indiening.py b/api/tests/views/test_indiening.py new file mode 100644 index 00000000..d3c0c3d2 --- /dev/null +++ b/api/tests/views/test_indiening.py @@ -0,0 +1,68 @@ +# test_indiening.py +from django.test import TestCase +from api.tests.factories.indiening import IndieningFactory, IndieningBestandFactory +from api.tests.factories.groep import GroepFactory +from api.tests.factories.gebruiker import GebruikerFactory +from rest_framework.test import force_authenticate, APIClient +from django.urls import reverse +from rest_framework import status + + +class IndieningListViewTest(TestCase): + def setUp(self): + self.client = APIClient() + self.gebruiker = GebruikerFactory.create() + self.gebruiker.user.is_superuser = True + self.gebruiker.user.save() + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("indiening_list") + + def test_indiening_list_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + + def test_indiening_list_post(self): + indiening = IndieningFactory.create() + data = {"indiening_id": indiening.indiening_id,"groep": indiening.groep_id, "tijdstip": indiening.tijdstip} + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + +class IndieningDetailViewTest(TestCase): + def setUp(self): + self.client = APIClient() + self.gebruiker = GebruikerFactory.create() + self.gebruiker.user.is_superuser = True + self.gebruiker.user.save() + self.indiening = IndieningFactory.create() + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("indiening_detail", kwargs={"id": self.indiening.indiening_id}) + + + def test_indiening_detail_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + + def test_indiening_detail_delete(self): + response = self.client.delete(self.url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + +class IndieningBestandViewTest(TestCase): + def setUp(self): + self.client = APIClient() + self.gebruiker = GebruikerFactory.create() + self.gebruiker.user.is_superuser = True + self.gebruiker.user.save() + self.indiening_bestand = IndieningBestandFactory.create() + self.client.force_authenticate(user=self.gebruiker.user) + self.url = reverse("indiening_bestand_list") + + def test_indiening_bestand_list_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_indiening_bestand_detail_get(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) \ No newline at end of file diff --git a/api/tests/views/test_project.py b/api/tests/views/test_project.py index 3c5707b0..fef30bf6 100644 --- a/api/tests/views/test_project.py +++ b/api/tests/views/test_project.py @@ -5,7 +5,7 @@ from api.tests.factories.vak import VakFactory from api.tests.factories.gebruiker import GebruikerFactory from rest_framework.test import APIClient -from django.core.files import File +from django.core.files.uploadedfile import SimpleUploadedFile class ProjectListViewTest(APITestCase): @@ -21,17 +21,16 @@ def test_project_list_get(self): def test_project_list_post(self): vak = VakFactory.create().vak_id - with open("api/tests/testdata/test.txt", "rb") as fp: - data = { - "titel": "test project", - "beschrijving": "Dit is een test project.", - "opgave_bestand": File(fp), - "vak": vak, - "deadline": "2024-03-31T12:40:05.317980Z", - "max_score": 20, - } - response = self.client.post(self.url, data, format="multipart") - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "titel": "test project", + "beschrijving": "Dit is een test project.", + "opgave_bestand": SimpleUploadedFile("file.txt", b"file_content"), + "vak": vak, + "deadline": "2024-03-31T12:40:05.317980Z", + "max_score": 20, + } + response = self.client.post(self.url, data, format="multipart") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) class ProjectDetailViewTest(APITestCase): diff --git a/api/urls.py b/api/urls.py index 0b5eb6c6..66db76a1 100644 --- a/api/urls.py +++ b/api/urls.py @@ -44,10 +44,10 @@ path("api/vakken//", vak_detail, name="vak_detail"), path("api/projecten/", project_list, name="project_list"), path("api/projecten//", project_detail, name="project_detail"), - path("api/indieningen/", indiening_list), - path("api/indieningen//", indiening_detail), - path("api/indiening_bestanden/", indiening_bestand_list), - path("api/indiening_bestanden//", indiening_bestand_detail), + path("api/indieningen/", indiening_list, name="indiening_list"), + path("api/indieningen//", indiening_detail, name="indiening_detail"), + path("api/indiening_bestanden/", indiening_bestand_list, name="indiening_bestand_list"), + path("api/indiening_bestanden//", indiening_bestand_detail, name="indiening_bestand_detail"), path("api/scores/", score_list, name="score_list"), path("api/scores//", score_detail, name="score_detail"), path("api/groepen/", groep_list, name="groep_list"), diff --git a/api/views/indiening.py b/api/views/indiening.py index 7d07469e..bc4ee20e 100644 --- a/api/views/indiening.py +++ b/api/views/indiening.py @@ -28,12 +28,6 @@ def indiening_list(request, format=None): return Response(serializer.data) elif request.method == "POST": - if "indiening_bestanden" not in request.FILES: - return Response( - {"indiening_bestanden": ["This field is required."]}, - status=status.HTTP_400_BAD_REQUEST, - ) - serializer = IndieningSerializer(data=request.data) if serializer.is_valid(): serializer.save() From 41d78db226afff18e5a8d690ce9095e518938d41 Mon Sep 17 00:00:00 2001 From: arallaer Date: Thu, 14 Mar 2024 12:15:01 +0100 Subject: [PATCH 31/44] fix indiening testen --- api/tests/views/test_indiening.py | 27 +++++++++++++++++---------- api/urls.py | 12 ++++++++++-- api/views/indiening.py | 6 ++++++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/api/tests/views/test_indiening.py b/api/tests/views/test_indiening.py index d3c0c3d2..cd2116ff 100644 --- a/api/tests/views/test_indiening.py +++ b/api/tests/views/test_indiening.py @@ -1,11 +1,11 @@ # test_indiening.py from django.test import TestCase from api.tests.factories.indiening import IndieningFactory, IndieningBestandFactory -from api.tests.factories.groep import GroepFactory from api.tests.factories.gebruiker import GebruikerFactory -from rest_framework.test import force_authenticate, APIClient +from rest_framework.test import APIClient from django.urls import reverse from rest_framework import status +from django.core.files.uploadedfile import SimpleUploadedFile class IndieningListViewTest(TestCase): @@ -21,14 +21,20 @@ def test_indiening_list_get(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_indiening_list_post(self): indiening = IndieningFactory.create() - data = {"indiening_id": indiening.indiening_id,"groep": indiening.groep_id, "tijdstip": indiening.tijdstip} - response = self.client.post(self.url, data, format='json') + data = { + "indiening_id": indiening.indiening_id, + "groep": indiening.groep_id, + "tijdstip": indiening.tijdstip, + } + file1 = SimpleUploadedFile("file1.txt", b"file_content") + file2 = SimpleUploadedFile("file2.txt", b"file_content") + data["indiening_bestanden"] = [file1, file2] + response = self.client.post(self.url, data, format="multipart") self.assertEqual(response.status_code, status.HTTP_201_CREATED) - + class IndieningDetailViewTest(TestCase): def setUp(self): self.client = APIClient() @@ -37,18 +43,19 @@ def setUp(self): self.gebruiker.user.save() self.indiening = IndieningFactory.create() self.client.force_authenticate(user=self.gebruiker.user) - self.url = reverse("indiening_detail", kwargs={"id": self.indiening.indiening_id}) - + self.url = reverse( + "indiening_detail", kwargs={"id": self.indiening.indiening_id} + ) def test_indiening_detail_get(self): response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_indiening_detail_delete(self): response = self.client.delete(self.url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + class IndieningBestandViewTest(TestCase): def setUp(self): self.client = APIClient() @@ -65,4 +72,4 @@ def test_indiening_bestand_list_get(self): def test_indiening_bestand_detail_get(self): response = self.client.get(self.url) - self.assertEqual(response.status_code, status.HTTP_200_OK) \ No newline at end of file + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/api/urls.py b/api/urls.py index 66db76a1..16d7321b 100644 --- a/api/urls.py +++ b/api/urls.py @@ -46,8 +46,16 @@ path("api/projecten//", project_detail, name="project_detail"), path("api/indieningen/", indiening_list, name="indiening_list"), path("api/indieningen//", indiening_detail, name="indiening_detail"), - path("api/indiening_bestanden/", indiening_bestand_list, name="indiening_bestand_list"), - path("api/indiening_bestanden//", indiening_bestand_detail, name="indiening_bestand_detail"), + path( + "api/indiening_bestanden/", + indiening_bestand_list, + name="indiening_bestand_list", + ), + path( + "api/indiening_bestanden//", + indiening_bestand_detail, + name="indiening_bestand_detail", + ), path("api/scores/", score_list, name="score_list"), path("api/scores//", score_detail, name="score_detail"), path("api/groepen/", groep_list, name="groep_list"), diff --git a/api/views/indiening.py b/api/views/indiening.py index bc4ee20e..7d07469e 100644 --- a/api/views/indiening.py +++ b/api/views/indiening.py @@ -28,6 +28,12 @@ def indiening_list(request, format=None): return Response(serializer.data) elif request.method == "POST": + if "indiening_bestanden" not in request.FILES: + return Response( + {"indiening_bestanden": ["This field is required."]}, + status=status.HTTP_400_BAD_REQUEST, + ) + serializer = IndieningSerializer(data=request.data) if serializer.is_valid(): serializer.save() From b1b4e9f1702b86ae4dbcc3407e3e944521d232e9 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:28:40 +0100 Subject: [PATCH 32/44] Update django.yml --- .github/workflows/django.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 18abfe50..6c99a56d 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,6 +55,4 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | - python manage.py makemigrations api - python manage.py migrate api python manage.py test From 8bc27ed81a60cc494ce07af68de558ee4a8e9979 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:30:43 +0100 Subject: [PATCH 33/44] Update django.yml --- .github/workflows/django.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 6c99a56d..18abfe50 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,4 +55,6 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | + python manage.py makemigrations api + python manage.py migrate api python manage.py test From 1c90bfc74a74ac1227ee493022fa0f006c803990 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:22:20 +0100 Subject: [PATCH 34/44] Update django.yml --- .github/workflows/django.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 18abfe50..c143003b 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -9,7 +9,7 @@ on: jobs: build: - runs-on: self-hosted + runs-on: ubuntu-latest services: postgres: From ed6fe5f9a8abd9508b2251f2b98d3c73be0b25fb Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:27:07 +0100 Subject: [PATCH 35/44] Update django.yml --- .github/workflows/django.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index c143003b..164e6a1b 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,6 +55,4 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | - python manage.py makemigrations api - python manage.py migrate api python manage.py test From a5903436722e225e645fac557b92568bd7ae858e Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:31:41 +0100 Subject: [PATCH 36/44] Update django.yml --- .github/workflows/django.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 164e6a1b..19addf87 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,4 +55,6 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | + yes | python manage.py makemigrations api + yes | python manage.py migrate api python manage.py test From f32f2bc8aeeb53c2635fc11d9a9644eabe3c623e Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:27:11 +0100 Subject: [PATCH 37/44] Update django.yml --- .github/workflows/django.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 19addf87..6c99a56d 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -9,7 +9,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: self-hosted services: postgres: @@ -55,6 +55,4 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | - yes | python manage.py makemigrations api - yes | python manage.py migrate api python manage.py test From 457d07684de0b8a2b940df68283e15ecf38d2279 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:28:38 +0100 Subject: [PATCH 38/44] Update django.yml --- .github/workflows/django.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 6c99a56d..18abfe50 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,4 +55,6 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | + python manage.py makemigrations api + python manage.py migrate api python manage.py test From 1a42255f0cfd459255f458a900e20d8820653c8f Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:43:52 +0100 Subject: [PATCH 39/44] Update django.yml --- .github/workflows/django.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 18abfe50..ca22aec5 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,6 +55,7 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | + python manage.py flush python manage.py makemigrations api python manage.py migrate api python manage.py test From de3cf643abd38e493d9b6046af5035459e5fcf8d Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:45:23 +0100 Subject: [PATCH 40/44] Update django.yml --- .github/workflows/django.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index ca22aec5..84f0be24 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,7 +55,7 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | - python manage.py flush + yes | python manage.py flush python manage.py makemigrations api python manage.py migrate api python manage.py test From 0151a1d5c2f13ccebb2d1f7875bd4167f31e616f Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 14:00:44 +0100 Subject: [PATCH 41/44] Update django.yml --- .github/workflows/django.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 84f0be24..18abfe50 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -55,7 +55,6 @@ jobs: DB_ENGINE: ${{secrets.DB_ENGINE}} run: | - yes | python manage.py flush python manage.py makemigrations api python manage.py migrate api python manage.py test From e7d1b18900de211f426ce7e40a5a2c834ada9566 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:32:21 +0100 Subject: [PATCH 42/44] Update django.yml --- .github/workflows/django.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 18abfe50..ce56c185 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -17,7 +17,7 @@ jobs: env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres - POSTGRES_DB: github_actions + POSTGRES_DB: github_actions_2 ports: - 5433:5432 From 5d089982377e5266e1eba80e92a333bd8667dec8 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:45:25 +0100 Subject: [PATCH 43/44] Delete api/migrations/__pycache__ directory --- .../__pycache__/0001_initial.cpython-311.pyc | Bin 4826 -> 0 bytes ..._remove_student_name_and_more.cpython-311.pyc | Bin 1472 -> 0 bytes .../0003_alter_student_subjects.cpython-311.pyc | Bin 919 -> 0 bytes .../0004_alter_student_subjects.cpython-311.pyc | Bin 881 -> 0 bytes .../0005_alter_vak_teachers.cpython-311.pyc | Bin 891 -> 0 bytes ...id_alter_lesgever_lesgever_id.cpython-311.pyc | Bin 971 -> 0 bytes ...r_subjects_alter_vak_teachers.cpython-311.pyc | Bin 1121 -> 0 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 192 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 api/migrations/__pycache__/0001_initial.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0002_remove_student_id_remove_student_name_and_more.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0003_alter_student_subjects.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0004_alter_student_subjects.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0005_alter_vak_teachers.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0006_remove_lesgever_id_alter_lesgever_lesgever_id.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/0007_alter_lesgever_subjects_alter_vak_teachers.cpython-311.pyc delete mode 100644 api/migrations/__pycache__/__init__.cpython-311.pyc diff --git a/api/migrations/__pycache__/0001_initial.cpython-311.pyc b/api/migrations/__pycache__/0001_initial.cpython-311.pyc deleted file mode 100644 index b973366d806f02f89235aa6fd1c8873b86615bc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4826 zcmbVQJy07-79I)xBaAe*!4e*R*0NW^XNf;^hV`zE4fyaG>_Y;3@vUbEbxVvGX|yvV zpCPz%aKVMnme7&USF6Cm1_T>iNZ3==fodYEF1T{0EfZ~Ucil4@0RoK6BkAdN_v`n* z_tQVpKRP-B40-++{}0>@G0eYd!+zWi=EEbx{Kxzug0zfX)sS+M7KN;HtXcILSQnv7VeW@2GkX_qFKp0;>5`J-}~D1#QhBP;Gy6 z2xHC(f~HJIQ>Fu)sdgT=PNYJn)S0G~s~T?Aly{wingwS+3H7;8Kz-hn>9p~@Aq67I1CW&g64k*sE|OXDu^y7ytEObc?l}^rOP`JUm?(kYeYUo1tuY|$`m`02 z1S!+rY1K6Jxu_2AR>$CT9$W1PYhu{69JQlQvNQrlt7C_=drG#igYi%D@>6!N-ygwq z16*#!L#pN|?unzgiQHt1zOTT|>eols&hfj#ew@Amw_5bv22-tij*Zg3ju^OO>iC@X zKGmArQ*7Nmg4Y423F1@onh&n@fEjYe&KmxC`#jAU?t6+1%Z4wn$dxiLf?0CjwwD#L zC@35JI@~b)DpW*45;q|kag~H3G(0&GN5)fgDTsn-PXtUJH*=9@K*XpxWsVT#!i3Ol)B8j3U2$fC0 zP!^LUrm##r^UEckTw0(84JWbeHv0{4!;j5&D%)rz+DORg4TqnRG=I~F%?@g>*)+UqtwO>? z0;^gKb=g%RX(yL3t4B3D&H7MzyTbzAXc5rvRY@qV8$kt16pe*GM$xn_3+smGxv);v z`WkMkMp&(^(sZi)FW5u;38yknBVgL}Hh>Wa8diwC zhAX_SeA7$k6JSOgB|ck|!P=bKlwC+%G<>}270(+1o+mk~NRaSBp8ugDNHkldwUqe-zm%R?^vvl1V{<~{}VzGf4x}+>Vct@5cD3lsP8TdkLu(P5BEw*EtWG5pQ z8_mEhsVFgD`XgEA9#9ZUdD(D+Rk}7vwbI4py*rh@J2gFH_@)4`?TGn(FyVAjkfgbi z2J^51s&if_ZDeFhtr-Ei3>)|Ne=;A4H_UI3Q)_Y&rZh1tSF-CcHLb|yRry6KGdKTm zAvIUZ$x4yj__M<39U+yTc`%Y%x<_jC+E|JtEw%r9AT=~JG|V@mo-A)D^!J5He1uW` zBz7;GuiZ23%X@VX-}lmpGKifE!>SFiLEXiNxVy=$b=r5z>x_Qnj|Js^y=0X9KDLhX3*jiiZ1KXWgJ~b zp~p1}W{83r+CGoCTRL|ObGK0FcHQr$P<#{$A$ye6*?lO{-7tsxQd`e)Uut`LX9o2x z>V1p2ZxMykro};OaqwLhMJM&>B#us^&{ws6_LSf}Ppz9IJz8Tgy}E+gOK)>k5huUF$$L2Y z5M>0!uIlV6W>@Q87xjmbJxW?C<~-^ieDxf64{p15VrYd&B?Wb>dbf(ZRTR?9fRE6C zkLb}c934ZU>j%>QF88yD$7k{QLp=T%{W*`KYkG7IN7qnDtc5S4-qcnO_olY5{F1B%uxmFQ zK|NQu#&OS85?f6H`-#Tqc0|NJ(b*@MeR7PG2PSo$P-fpD_LzjBFi$u0ShBX;@2Fl=IZwFXd^fGr@f(HyOGE!+QU6Lvz0KipkloiYfS7*k kU9*`3J#oYw^R9cIIUJrkb3A<&z@gZ$=HT85A|}571AhYDwEzGB diff --git a/api/migrations/__pycache__/0002_remove_student_id_remove_student_name_and_more.cpython-311.pyc b/api/migrations/__pycache__/0002_remove_student_id_remove_student_name_and_more.cpython-311.pyc deleted file mode 100644 index 52dfba9384e6c170c476a48673cfff36fc1bfd3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1472 zcmah}NpI6Y6dv2LV><~;0ab{tASeWhx-8;^D1jCz>H@TtP%eX$nFa?hVeA0m06lQv z$c+Q{0&0H%2Yy76a){=_ffF}Z?THg_?6_fL|%cJ zj%uDrbEvF+6XHx+;(AD<$nhItS>~qaG?*PZfgf_s3kY??dVgQC?C1*{$0U&xP4cPA zM3NCznz_ssPS-Mi89Y~DrlTQO^NFvXX^2de)!ecSUNF<~mxuaa4{ciyBZ~;9h;z+m zVN0XaVzZP<&7=-OYG!vt&7GN*7{vVbPOF7wsLo1OA+%cj9pgr>x{K(5a)}$$8KMBM zVz(S#9334!iyhyI9NXpjFlrO(M_hJDQUC!u_HB>yoS;mk$j!bNb_mb4L&|36ua{Mx zCv?$nyAd}6AHzNxQC?^<$Fo@nKcpRQfGeEhJfmEWg0jMj5G@UbGkLh)BBG)T~Bpeg?@zShM=K~HLfRDf@b9TYn8cc zmGKE~1})le&<|(>_M`95tp|Zet;ned?fOG%jkBOt3!Yl@lhd;^)}+4}Fb`U~ZlAwu zTXPdr=d6Vr0Qi{;7F5If+3*(B7ruZk`e`*p$Y@YyBjE=NAOnhev5iK3A16kU7 zVhtHXJ^kb>v#XzcuXj&f`K(vEdL>qsz1q@LTtvnZVLRL#9O~`f2WrDyM?f|OiS^&i zga0-k+QxiP1V4}jAM6bbzaH)m48M;)KK|6{j?H$*?sdoRulX!S=!G;c!!jw~kvGL+ z3u#YHhU)+Y70@`J6WIaT6eK<{FrY2n5)V6(VNllj{;v7 diff --git a/api/migrations/__pycache__/0003_alter_student_subjects.cpython-311.pyc b/api/migrations/__pycache__/0003_alter_student_subjects.cpython-311.pyc deleted file mode 100644 index ead4b8af7b1a3932d0012cc7c4f3b83ed8b9a57f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 919 zcmZuw&rj4q6rO3j-E9L=HYP?1#)C2JK}x`QA|?`*U;qz*haQ~F_RT_g6j$YDF&2~UplB( zZRDITpmRuo0F6jYeHt6SL5V?@2pAs;n1XiA>d~1&d$!URK#*uuq^L`NOBg!zevJk!FU2JmZ?znQK4#N z{dQLbdA6Y@Mp(u~lFBF&@S%?#FHI0mWqhy0+_x}8M(xiTdHz_SS4QT zgd&2qmZKW1#2HgA!`9G`1o~r)z3cO+QBVeM@R-;KnLX z_BN!pC8}K66Qi+wBd1!=^NzPIW8vjtAp60N@Sdl#*Ou?SjpfzXYu<9wk!g&B4EX#a z_tsym%z2wjDAuFL9)70xcg!9tI?uRfa4Bdd(@bwKwXs=gw3GR0_Ahr~6K9DQrg6*O zUnyMT-23DX8&k)(?;lT09yg~C9uAw+U-QA@=D-gIP59A-VH1kF<+vvV&6zfZX*cct zS9+&+t7dC0OF7Wx$(Edfb}3US%>|u1x~#07MDM(@aG~|nbP7ZKOGx$xO<__>ks@sk c$n^E6u*axfkn85a9o~F!q7!HT$(DWp0GW*XA^-pY diff --git a/api/migrations/__pycache__/0004_alter_student_subjects.cpython-311.pyc b/api/migrations/__pycache__/0004_alter_student_subjects.cpython-311.pyc deleted file mode 100644 index 0522acb5958c344ea4e4f093e22fdae4eea76c56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 881 zcmZ`%zi-n(6uz?^$F@>IEhK&v5CcNVKpfGkQ-uTqs-PweEhw^(tgG)5occ$w9YmQj zFfexOe^7+TAHo=<43QTGCN@{;)QNYF9fS&Z_Vat+y?gJw@BDdXMME$)$qzQh2>s+i zF-o~J-vZ|tQADweJZxf5Fa?YRw2i3n5mAxhzF2HJ0q^TFGDRxwqFU(}U#<~hBP z#7^KxiR=ZGxshG$tTToN;C`NU(15C=68&d<-hK%@*Wbsgr?Ht@{02+D6mw2B8PnWRvyB#Mphh^T2qy4Qkxq zFyMT~pG!1Av5o&IRv#ROGBnE!ccNEdM$4JXNHtPXxFU~sQVprMKWS6t*6iw?+3MO% zuO8i->eb0+^P4l#JKy!rRPUr^N!3mfm@{rtQP$th>elMug{Y;`v zmIak-JT1$;0p7W?wb1!tcoRbS{}&un5n~MWaBYIB7oSwFU^zt>&5<^}eD{-!rst?G*a diff --git a/api/migrations/__pycache__/0005_alter_vak_teachers.cpython-311.pyc b/api/migrations/__pycache__/0005_alter_vak_teachers.cpython-311.pyc deleted file mode 100644 index 44e54ac01e9d86f5a76693879558f4fa0d6441e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 891 zcmZuwJ#W)M7{0R|C$>^SBP0Z&Ob8_daa0OZg+v8ZMNJr*BH;n+;=3kJ{1I%YqD&bW z7`yc!@FDsK_!mLS5Z%JS#O5lUI`N(p2UX?Hdi;Lfz0WMxus^K5)UVgC#QHAEHdYZpX z;k0nshn)&k15!HI8W|g)CX<1~%k_GF!y<0XLMw`gl=-n04ck3t#}StgNuL*DM(i#N zqZVJyGFBG*P=rltE{i(skcCy5=h`mu`@9%3m&A-(KJgfr;s8>5di;4rN#nT#hq<&_ z)p)^5Y6Sw* zDA$7lTj>7{&4h3lZKE4_%!nO37}|YiJPU(CJ9uxjb{emm#*TjwgdW_OO&)F$WAFLy zy0O0vvOL%@;H<{K`!qnhM+@mdsHG;g!BMC}qZEV@y#W|4XQCp_NMz}TI@(Qiq}~0b zPYP?(n|G$G}c=%tw9?W|X` zs&I|=h~Einw4ExHsxoJDOO&OxWw0&^n{%0;glpi!OF+?UfJDX^14CRLqsrAUQHxkj T&{a6rC)e+tiNyJTvT5JHe8%oy diff --git a/api/migrations/__pycache__/0006_remove_lesgever_id_alter_lesgever_lesgever_id.cpython-311.pyc b/api/migrations/__pycache__/0006_remove_lesgever_id_alter_lesgever_lesgever_id.cpython-311.pyc deleted file mode 100644 index 24246888b40237ef84cacc313cf99698f1887aca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 971 zcmZuw&rj4q6rO3jrR_q38x2tdMq-Q`BPIUeL`*O)1Ou1|df3aP>^zn({jpBFL`*as zJb2{Be}EeK1N<{E*#nu22T$Hg;KafBrfgRU&a_{@H}AcfZ{ABk4GlR2$CUR2ep5nz zDx(;s9yy*yvP(GOG$0|Z(@?8xlxSp*aP0%(I?$G0B<&&l+PCUDH#`nsh?H zDZJE=qePlv%pph`MW*`NJ>&R2l3fC%PC2P-oHl7)*9aJ`LKGg&^?hSc!{hKh8+n9T zSQt^lm4TMkUorW>zI8rl-##z7snu=npy;x+7Yns0UH96)9GRS)e8jvU1;IAG4VHq} zSO<|vD}ba4n;@j-^ZcUfaxC&fkVcN>B7*sRWfnuqZQ+NW*kT*7CG7-+?*;x_sOqAO zdc`1uEUozv@TICFEtYS_m~%&}RPNtSyI8a-CUPO{pDOg~*k9=rpHH;6gz94s ziX-4vBQy@hnKEoCEa$82*Qbi%p&%fa*yWjvBS#v z&h2hx{B!!Pb5N;$uhhDgS~g&)9E1}ES=p(W+t1V#*9sX+RYTgmH)cP@yX0#YG&jj>^R-wTSv-q@*i)0 F?jL&+{W$;t diff --git a/api/migrations/__pycache__/0007_alter_lesgever_subjects_alter_vak_teachers.cpython-311.pyc b/api/migrations/__pycache__/0007_alter_lesgever_subjects_alter_vak_teachers.cpython-311.pyc deleted file mode 100644 index 2f9ae735a2edef388a2b86da6089d33b6914bbdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1121 zcmZuvy-(Xf6u+|*$2JKRt5SyoYNe_oLouQiT~MW>7DNSffHI^)mXmt~2Y;ltg9;Nv zhi+x5*gMcx@P~8^QU-KOhfdvsU}EY!Cr%-7=X?IW_wIe(`(7yM1lP3v8@@_}{1HsL zvR!aKgW!NL!l+9;TB4p*k|>eLJYmu&!epQ|IW;;&bkyTYGRv%xV)n047bUKHPBpY+ zC-5V#cmV@9s-%|UuXUO8ZwL+ukP>C2Br#g0C0QbnsijF_XeJ~|E!VXnEW@%)InG^A z;aI)S_j%En-sfe2<&O)8*o-4Qoz?H7DwR|=h=mPtZ7Hn?%aiT8!>1-EC#S6tykHwF z7osX`Lufh7vfUU#PtpSp<7&!qHENV=P>G{eZluD<0zV8~7uaqNBTQ`DTSb{?%dYKj z@q7rb9Rss`+XF7e0jl(*wH-+&k!Lp?a2c1;l&dk=l}!jEKAZ-#QqgW+1V{rHrLce< z2nUfY7d5V0iBHSox@BREh6{-Emi3`wyCRO@7}UXM;8z@oLNN(ke<>=T6B&dVAsAY+ z{hif7&_v4hpbp)+_({(33c1`hHv$k|oSFC>&-;7dtGn|i*p*%fCh9w(f(axgegcho{5$PmS^Y$1P+0N8FrUYrbbq15ONR8PLvUH2sVq zxe(;4-N+TY=JdiZziF(W80#%#z2B%XU?_WU#12Q(43~=;uCbc!SAz*wPWqknxKqQ3 zxR%@>P{wCAAY(d13PUi1CZpdX>xX|zDrSlK~jE&eu$^9zn{KmURr)pZX!@N(by?bKiJjBNI%p)HLpb1L_e`0 zQ$IH|y$C3qpI59OAD@|*SrQ+wS5Wzj!zMRBr8Fniu80+A2gnu0{6OLZGb1D82L>2X I#0(Sz0J)tniU0rr From c928ac89205bd6210a316da343896fe078e3d045 Mon Sep 17 00:00:00 2001 From: Mathis De Witte <49711425+mathis2003@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:47:32 +0100 Subject: [PATCH 44/44] Delete api/migrations/0001_initial.py --- api/migrations/0001_initial.py | 102 --------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 api/migrations/0001_initial.py diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py deleted file mode 100644 index 5606a234..00000000 --- a/api/migrations/0001_initial.py +++ /dev/null @@ -1,102 +0,0 @@ -# Generated by Django 5.0.2 on 2024-03-05 14:15 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Groep', - fields=[ - ('group_id', models.AutoField(primary_key=True, serialize=False)), - ], - ), - migrations.CreateModel( - name='Lesgever', - fields=[ - ('lesgever_id', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('email', models.EmailField(default='email@email.com', max_length=254)), - ('is_admin', models.BooleanField(default=False)), - ], - ), - migrations.CreateModel( - name='Project', - fields=[ - ('project_id', models.AutoField(primary_key=True, serialize=False)), - ('titel', models.CharField(max_length=100)), - ('description', models.TextField()), - ('opgavebestanden', models.FileField(upload_to='opgave/')), - ('deadline', models.DateTimeField(null=True)), - ], - ), - migrations.CreateModel( - name='Indiening', - fields=[ - ('indiening_id', models.AutoField(primary_key=True, serialize=False)), - ('indieningsbestanden', models.FileField(upload_to='uploads/')), - ('tijdstip', models.DateTimeField()), - ('indiener', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.groep')), - ], - ), - migrations.AddField( - model_name='groep', - name='project', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.project'), - ), - migrations.CreateModel( - name='Score', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('score', models.SmallIntegerField()), - ('groep', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.groep')), - ('indiening', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.indiening')), - ], - ), - migrations.CreateModel( - name='Student', - fields=[ - ('student_id', models.AutoField(primary_key=True, serialize=False)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.AddField( - model_name='groep', - name='students', - field=models.ManyToManyField(blank=True, related_name='groups_students', to='api.student'), - ), - migrations.CreateModel( - name='Vak', - fields=[ - ('vak_id', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('projects', models.ManyToManyField(blank=True, related_name='subjects_projects', to='api.project')), - ('students', models.ManyToManyField(blank=True, related_name='subjects_enrolled', to='api.student')), - ('teachers', models.ManyToManyField(related_name='subjects_teachers', to='api.lesgever')), - ], - ), - migrations.AddField( - model_name='student', - name='subjects', - field=models.ManyToManyField(related_name='students_enrolled', to='api.vak'), - ), - migrations.AddField( - model_name='project', - name='vak', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.vak'), - ), - migrations.AddField( - model_name='lesgever', - name='subjects', - field=models.ManyToManyField(blank=True, related_name='lesgevers_enrolled', to='api.vak'), - ), - ]