Skip to content

Commit

Permalink
Merge pull request #331 from SELab-2/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
sPAICEcake authored May 23, 2024
2 parents c5b603b + 57ced79 commit 58b6ba4
Show file tree
Hide file tree
Showing 167 changed files with 22,967 additions and 8,161 deletions.
Binary file modified .coverage
Binary file not shown.
72 changes: 34 additions & 38 deletions .github/workflows/django.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ name: Django CI

on:
push:

branches: [ "develop", "tests", "main" ]
branches: ["develop", "tests", "main"]
pull_request:
branches: [ "develop", "tests", "main" ]

branches: ["develop", "tests", "main"]

jobs:
build:

runs-on: self-hosted

services:
Expand All @@ -26,37 +23,36 @@ jobs:

options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5


steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: '3.10'
- name: Install Dependencies
run: |
python3 -m pip install --upgrade pip
pip install -r requirements.txt
- name: Linting API
run: |
cd api
flake8 .
cd ..
- name: Run Tests
env:
CLIENT_ID: ${{ secrets.CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
TENANT_ID: ${{ secrets.TENANT_ID }}
AD_URL: ${{ secrets.AD_URL }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
DB_NAME: ${{ secrets.DB_NAME }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_HOST: ${{ secrets.DB_HOST }}
DB_PORT: ${{ secrets.DB_PORT }}
DB_ENGINE: ${{secrets.DB_ENGINE}}
run: |
python manage.py makemigrations api
python manage.py migrate api
python manage.py test
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install Dependencies
run: |
python3 -m pip install --upgrade pip
pip install -r requirements.txt
- name: Linting API
run: |
cd api
flake8 .
cd ..
- name: Run Tests
env:
CLIENT_ID: ${{ secrets.CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
TENANT_ID: ${{ secrets.TENANT_ID }}
AD_URL: ${{ secrets.AD_URL }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
DB_NAME: ${{ secrets.DB_NAME }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_HOST: ${{ secrets.DB_HOST }}
DB_PORT: ${{ secrets.DB_PORT }}
DB_ENGINE: ${{secrets.DB_ENGINE}}

run: |
python manage.py makemigrations api
python manage.py migrate api
python manage.py test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ htmlcov
data
uploads
/data/
cypress/screenshots
/package-lock.json
/frontend/package-lock.json
/frontend/frontend/package-lock.json
package-lock.json
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

# Wiki

- Raadpleeg de wiki voor uitgebreidere informatie, waaronder Use-Cases en API-Documentatie en Website-documentatie.
- Raadpleeg de [Wiki](https://github.com/SELab-2/UGent-4/wiki) voor uitgebreidere informatie, waaronder Use-Cases, API-Documentatie en Website-documentatie.

# Deployment diagram
![image](https://github.com/SELab-2/UGent-4/assets/49711425/805e37c4-fd67-4e68-8b8a-1310efce7864)


# Frontend

Expand All @@ -24,7 +28,9 @@ Er kan niet gepushed worden als er nog linting errors aanwezig zijn.

### Testen:

- WIP
Je kan visueel in de browser de testen volgen door het commando `npm run cypress-open` te runnen. Je zal dan ook de keuze krijgen om te kiezen tussen E2E testen of om component testen te volgen.

`npm run cypress-e2e` en `cypress-component` zullen de e2e testen en de component testen runnen en in de terminal tonen of ze slagen.

# Backend

Expand Down Expand Up @@ -60,4 +66,15 @@ Run het commando `flake8 .`. De output vertelt je waar de codestijl fout is. Om


### Testing:
## Backend testing:
Run het commando `./manage.py test` in de ***UGENT-4*** directory.
Om de coverage te raadplegen kan het commando `coverage run manage.py test -v 2 && coverage report && coverage html` gebruikt worden. Dit runt alle testen en toont per bestand de coverage. Ook wordt er voor elk bestand een html gemaakt waar je per lijn kan zien of die door de testen gecovered wordt.
## Frontend testing:
Door het commando `npm run cypress-component` uit te voeren, worden de component testen gerund.
Voor de end-to-end testen verloopt het een beetje anders:
- Eerst en vooral zorg je ervoor dat je een lokale backend en frontend hebt lopen. In axios.config verander je de baseURL naar `baseURL: 'http://localhost:8000/api/'`, dit zorgt ervoor dat de lokale backend wordt aangesproken. De e2e testen vereisen een lege databank.
- Met het commando `npm run cypress-component` open je een interactieve cypress browser. Hierin selecteer je e2e (je kan hier ook de component testen interactief runnen).
- Vervolgens open je een nieuwe terminal en run je het commando `sudo bash switch_test.sh true`. Hiermee zet je de test environment op voor een lesgever. Nu voer je de testen 'course', 'project' en 'groups' (in deze volgorde) uit.
- Hierna switchen we naar de test environment voor een student door 2 maal `sudo bash switch_test.sh` te runnen.
- In cypress voer je nu de 'group' en 'submission' testen uit (opnieuw in deze volgorde). Ten slotte zet je weer de test environment op voor een lesgever door 2 maal het commando `sudo bash switch_test.sh true` uit te voeren. Nu kan je in cypress de testen 'score' en 'archive' (in deze volgorde) uitvoeren.
- Alle e2e testen uitgevoerd en kan je de lokale backend en frontend stopzetten, de baseURL terug veranderen naar `baseURL: 'https://sel2-4.ugent.be/api/'` en de test omgeving verlaten met `sudo bash switch_test.sh`.
5 changes: 3 additions & 2 deletions api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
from api.models.vak import Vak
from api.models.groep import Groep
from api.models.project import Project
from api.models.indiening import Indiening, IndieningBestand
from api.models.indiening import Indiening
from api.models.score import Score
from api.models.restrictie import Restrictie
from api.models.template import Template

admin.site.register(Gebruiker)
admin.site.register(Vak)
admin.site.register(Groep)
admin.site.register(Project)
admin.site.register(Indiening)
admin.site.register(Score)
admin.site.register(IndieningBestand)
admin.site.register(Restrictie)
admin.site.register(Template)
12 changes: 12 additions & 0 deletions api/base_templates/file_name.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

#@param
# Vul hieronder de naam in dat het ingediende bestand moet hebben
file_name="verslag.pdf"


if [ -e "$file_name" ]; then
echo "$file_name present: OK"
else
echo "$file_name not present: FAIL"
fi
20 changes: 20 additions & 0 deletions api/base_templates/file_type.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

#@param
# Vul hieronder het type dat het bestand moet hebben
file_type="pdf"


file_exists=false
for file in *.$file_type; do
if [ -e "$file" ]; then
file_exists=true
break
fi
done

if [ "$file_exists" = true ]; then
echo "$file_type: OK"
else
echo "$file_type: FAIL"
fi
20 changes: 20 additions & 0 deletions api/base_templates/zip_contains_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

#@param
# Vul hieronder de namen van de bestanden in die je in de gezipte folder wilt vinden.
file_names=("testfile1.txt" "testfile2.txt")

#@param
# Vul hieronder de naam van het zip bestand waarin je de files wil vinden
zip_file_name="file.zip"


for file_name in "${file_names[@]}"; do
unzip -l $zip_file_name | grep -q $file_name;
if [ "$?" == "0" ]
then
echo "$file_name present: OK"
else
echo "$file_name not present: FAIL"
fi;
done
2 changes: 1 addition & 1 deletion api/docker/python_entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ def run_tests_on(indiening_id, project_id):
child.sendline(dot_env_values.get("SUDO_PASSWORD"))
output = child.read().decode("utf-8")
child.close()
return ": FAIL" in output, output
return output
2 changes: 1 addition & 1 deletion api/docker/rundocker.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
yes | docker system prune -a >&2
docker build -t script-demo -f api/docker/Dockerfile .
docker run --mount type=bind,source="$(pwd)"/data/restricties/project_$2,target=/data/restricties --mount type=bind,source="$(pwd)"/data/indieningen/indiening_$1,target=/data --name demo -d script-demo
docker run --mount type=bind,source="$(pwd)"/data/restricties/project_$2,target=/restricties --mount type=bind,source="$(pwd)"/data/indieningen/indiening_$1,target=/data --name demo -d script-demo
docker logs demo -f
6 changes: 5 additions & 1 deletion api/docker/testing_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/bash
cd data
mkdir artefacten

for filename in ./restricties/*; do
for filename in ../restricties/*; do
echo -n "Testing ${filename}: "

if [[ "$filename" == *.sh ]]
Expand All @@ -12,3 +13,6 @@ for filename in ./restricties/*; do
python3 $filename
fi
done

zip -r artefacten.zip artefacten
rm -rf artefacten
23 changes: 23 additions & 0 deletions api/middleware.py → api/middleware/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
from django.contrib.auth.models import User
from api.models.gebruiker import Gebruiker
from api.serializers.gebruiker import GebruikerSerializer
from api.serializers.template import TemplateSerializer
from django.core.files import File
import requests
import os

URL = "https://graph.microsoft.com/v1.0/me"

Expand Down Expand Up @@ -59,6 +62,16 @@ def __call__(self, request):
try:
Gebruiker.objects.get(pk=request.user.id)
except Gebruiker.DoesNotExist:
directory_path = "api/base_templates"
for filename in os.listdir(directory_path):
file_path = os.path.join(directory_path, filename)
with open(file_path, "rb") as f:
django_file = File(f)
template_data = {"user": request.user.id, "bestand": django_file}
serializer = TemplateSerializer(data=template_data)
if serializer.is_valid():
serializer.save()

gebruiker_post_data = {
"user": request.user.id,
"subjects": [],
Expand All @@ -69,3 +82,13 @@ def __call__(self, request):
serializer.save()

return self.get_response(request)


class DisableCSRFMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
setattr(request, "_dont_enforce_csrf_checks", True)
response = self.get_response(request)
return response
73 changes: 73 additions & 0 deletions api/middleware/middleware_lesgever_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.contrib.auth.models import User
from api.models.gebruiker import Gebruiker
from api.serializers.gebruiker import GebruikerSerializer
from api.serializers.template import TemplateSerializer
from django.core.files import File
import os


class AuthenticationUserMiddleware:
"""
Middleware voor authenticatie van gebruikers en het aanmaken van gebruikersindeling.
Args:
get_response (callable): De volgende middleware in de keten.
Returns:
HttpResponse: Een HTTP-response-object.
Raises:
Redirect: Redirect naar de inlog-URL als er geen autorisatiegegevens zijn.
"""

def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):

mail = "[email protected]"
try:
user = User.objects.get(username=mail)
except User.DoesNotExist:
user = User.objects.create_user(
username=mail,
email=mail,
first_name="Lesgever",
last_name="Testing",
)

request.user = user

try:
Gebruiker.objects.get(pk=request.user.id)
except Gebruiker.DoesNotExist:
directory_path = "api/base_templates"
for filename in os.listdir(directory_path):
file_path = os.path.join(directory_path, filename)
with open(file_path, "rb") as f:
django_file = File(f)
template_data = {"user": request.user.id, "bestand": django_file}
serializer = TemplateSerializer(data=template_data)
if serializer.is_valid():
serializer.save()

gebruiker_post_data = {
"user": request.user.id,
"subjects": [],
"is_lesgever": True,
}
serializer = GebruikerSerializer(data=gebruiker_post_data)
if serializer.is_valid():
serializer.save()

return self.get_response(request)


class DisableCSRFMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
setattr(request, "_dont_enforce_csrf_checks", True)
response = self.get_response(request)
return response
Loading

0 comments on commit 58b6ba4

Please sign in to comment.