Add summary endpoint

This commit is contained in:
Christian Cueni 2023-01-23 16:02:47 +01:00
parent 0794a715b3
commit 46710d29b9
7 changed files with 162 additions and 19 deletions

View File

@ -29,7 +29,7 @@ const app = createApp(App);
Sentry.init({
app,
environment: import.meta.env.VITE_SENTRY_ENV,
environment: import.meta.env.VITE_SENTRY_ENV || "http://localhost:8000/server/graphql/",
dsn: "https://2df6096a4fd94bd6b4802124d10e4b8d@o8544.ingest.sentry.io/4504157846372352",
tracesSampleRate: 0.0,
enabled:

View File

@ -7,6 +7,9 @@ from django.urls import include, path, re_path
from django.views import defaults as default_views
from grapple import urls as grapple_urls
from ratelimit.exceptions import Ratelimited
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.views import (
@ -32,10 +35,7 @@ from vbv_lernwelt.course.views import (
request_course_completion,
request_course_completion_for_user,
)
from vbv_lernwelt.feedback.views import get_name
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
from vbv_lernwelt.feedback.views import get_expert_feedbacks_for_course
def raise_example_error(request):
@ -81,7 +81,7 @@ urlpatterns = [
request_course_completion_for_user,
name="request_course_completion_for_user"),
# test
# documents
path(r'api/core/document/start/', document_upload_start,
name='file_upload_start'),
path(r'api/core/document/<str:document_id>/', document_delete,
@ -91,13 +91,16 @@ urlpatterns = [
path(r"api/core/document/local/<str:file_id>/", document_direct_upload,
name='file_upload_local'),
# feedback
path(r'api/core/feedback/summary/<str:course_id>/', get_expert_feedbacks_for_course,
name='feedback_summary'),
# testing and debug
path('server/raise_error/',
user_passes_test(lambda u: u.is_superuser, login_url='/login/')(
raise_example_error), ),
path("server/checkratelimit/", check_rate_limit),
path("server/", include(grapple_urls)),
path(r"your-name/", get_name)
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -32,6 +32,12 @@ class DocumentUploadApiTestCase(APITestCase):
)
csu.expert.add(Circle.objects.get(slug="test-lehrgang-lp-circle-analyse"))
_csu = CourseSessionUser.objects.create(
course_session=self.course_session,
user=self.user,
role=CourseSessionUser.Role.MEMBER,
)
self.test_data = {
"file_name": "test.pdf",
"file_type": "application/pdf",
@ -185,7 +191,6 @@ class DocumentUploadApiTestCase(APITestCase):
response = self.client.delete(f"/api/core/document/{document.id}/")
self.assertEqual(response.status_code, 403)
# expert cannot upload in other course
# expert cannot delete other upload
# exper cannot change course

View File

@ -0,0 +1,8 @@
from factory.django import DjangoModelFactory
from vbv_lernwelt.feedback.models import FeedbackResponse
class FeedbackFactory(DjangoModelFactory):
class Meta:
model = FeedbackResponse

View File

@ -0,0 +1,117 @@
from rest_framework.test import APITestCase
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.consts import COURSE_TEST_ID
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.feedback.factories import FeedbackFactory
from vbv_lernwelt.learnpath.models import Circle
class FeedbackApiTestCase(APITestCase):
def setUp(self) -> None:
create_default_users()
create_test_course()
self.user = User.objects.get(username="student")
self.expert = User.objects.get(
username="patrizia.huggel@eiger-versicherungen.ch"
)
self.course_session = CourseSession.objects.create(
course_id=COURSE_TEST_ID,
title="Test Lehrgang Session",
)
csu = CourseSessionUser.objects.create(
course_session=self.course_session,
user=User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch"),
role=CourseSessionUser.Role.EXPERT,
)
csu.expert.add(Circle.objects.get(slug="test-lehrgang-lp-circle-analyse"))
_csu = CourseSessionUser.objects.create(
course_session=self.course_session,
user=self.user,
role=CourseSessionUser.Role.MEMBER,
)
self.test_data = {
"file_name": "test.pdf",
"file_type": "application/pdf",
"name": "Test",
"course_session": self.course_session.id,
}
self.client.login(
username="patrizia.huggel@eiger-versicherungen.ch", password="myvbv1234"
)
def test_can_get_feedback_summary_for_circles(self):
number_basis_feedback = 5
number_analyse_feedback = 10
csu = CourseSessionUser.objects.get(
course_session=self.course_session,
user=User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch"),
role=CourseSessionUser.Role.EXPERT,
)
analyse_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-analyse")
basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-basis")
csu.expert.add(basis_circle)
for i in range(number_basis_feedback):
FeedbackFactory(circle=basis_circle, course_session=csu.course_session).save()
for i in range(number_analyse_feedback):
FeedbackFactory(circle=analyse_circle, course_session=csu.course_session).save()
response = self.client.get(f"/api/core/feedback/summary/{csu.course_session.course.id}/")
self.assertEqual(response.status_code, 200)
expected = {
analyse_circle.id: {"circle_id": analyse_circle.id, "count": number_analyse_feedback},
basis_circle.id: {"circle_id": basis_circle.id, "count": number_basis_feedback},
}
self.assertEqual(response.data, expected)
def test_can_only_see_feedback_from_own_circle(self):
number_basis_feedback = 5
number_analyse_feedback = 10
csu = CourseSessionUser.objects.get(
course_session=self.course_session,
user=User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch"),
role=CourseSessionUser.Role.EXPERT,
)
analyse_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-analyse")
basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-basis")
for i in range(number_basis_feedback):
FeedbackFactory(circle=basis_circle, course_session=csu.course_session).save()
for i in range(number_analyse_feedback):
FeedbackFactory(circle=analyse_circle, course_session=csu.course_session).save()
response = self.client.get(f"/api/core/feedback/summary/{csu.course_session.course.id}/")
self.assertEqual(response.status_code, 200)
expected = {
analyse_circle.id: {"circle_id": analyse_circle.id, "count": number_analyse_feedback},
}
self.assertEqual(response.data, expected)
def test_student_does_not_see_feedback(self):
self.client.login(username="student", password="test")
csu = CourseSessionUser.objects.get(
course_session=self.course_session,
user=self.user,
)
analyse_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-analyse")
FeedbackFactory(circle=analyse_circle, course_session=csu.course_session).save()
response = self.client.get(f"/api/core/feedback/summary/{csu.course_session.course.id}/")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, {})

View File

@ -1,15 +1,25 @@
from django.http import HttpResponseRedirect
from django.shortcuts import render
import structlog
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .forms import FeedbackForm
from vbv_lernwelt.feedback.models import FeedbackResponse
logger = structlog.get_logger(__name__)
def get_name(request):
if request.method == "POST":
form = FeedbackForm(request.POST)
if form.is_valid():
return HttpResponseRedirect("/thanks/")
else:
form = FeedbackForm()
@api_view(["GET"])
def get_expert_feedbacks_for_course(request, course_id):
feedbacks = FeedbackResponse.objects.filter(course_session__course_id=course_id, circle__expert__user=request.user)
other = list(FeedbackResponse.objects.all())
circle_count = {}
return render(request, "feedback/name.html", {"form": form})
for feedback in feedbacks:
if feedback.circle_id not in circle_count:
circle_count[feedback.circle_id] = {
"circle_id": feedback.circle_id,
"count": 0,
}
circle_count[feedback.circle_id]["count"] += 1
return Response(status=200, data=circle_count)