fix: filter feedback users

This commit is contained in:
Reto Aebersold 2023-10-19 15:52:37 +02:00
parent 69c56dfb9a
commit 577746bff1
7 changed files with 133 additions and 36 deletions

View File

@ -56,8 +56,8 @@ class CourseDashboardType(graphene.ObjectType):
for course_session in course_sessions:
course_session_data.append(
CourseSessionData(
session_id=course_session.id,
session_title=course_session.title,
session_id=course_session.id, # noqa
session_title=course_session.title, # noqa
)
)
generations.add(course_session.generation)
@ -78,9 +78,9 @@ class CourseDashboardType(graphene.ObjectType):
for circle in circles:
circle_data.append(
CircleData(
circle_id=circle.id,
circle_title=circle.title,
experts=[
circle_id=circle.id, # noqa
circle_title=circle.title, # noqa
experts=[ # noqa
f"{su.user.first_name} {su.user.last_name}"
for su in circle.expert.all()
],
@ -88,7 +88,7 @@ class CourseDashboardType(graphene.ObjectType):
)
return CourseSessionProperties(
sessions=course_session_data,
generations=list(generations),
circles=circle_data,
sessions=course_session_data, # noqa
generations=list(generations), # noqa
circles=circle_data, # noqa
)

View File

@ -5,22 +5,25 @@ import graphene
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.feedback.utils import feedback_users
class FeedbackSummary(graphene.ObjectType):
satisfaction_average = graphene.Float()
satisfaction_total = graphene.Int()
satisfaction_max = graphene.Int()
total_responses = graphene.Int()
class Record(graphene.ObjectType):
class FeedbackRecord(graphene.ObjectType):
course_session_id = graphene.ID()
generation = graphene.String()
circle_id = graphene.ID()
satisfaction_average = graphene.Float()
satisfaction_max = graphene.Int()
class FeedbackResponses(graphene.ObjectType):
records = graphene.List(Record)
records = graphene.List(FeedbackRecord)
summary = graphene.Field(FeedbackSummary)
@ -32,22 +35,38 @@ def feedback_responses(course_id: graphene.String(), user: User):
course_id=course_id,
)
circle_feedbacks = []
for course_session in course_sessions:
fbs = FeedbackResponse.objects.filter(
submitted=True,
course_session=course_session,
# Only get feedbacks from members
feedback_user__in=CourseSessionUser.objects.filter(
course_session=course_session, role=CourseSessionUser.Role.MEMBER
).values_list("user", flat=True),
feedback_user__in=feedback_users(course_session.id),
)
circle_feedbacks = circle_feedback_average(fbs)
return FeedbackResponses()
circle_feedbacks.extend(
circle_feedback_average(fbs, course_session.id, course_session.generation)
)
avg = sum([fb.satisfaction_average for fb in circle_feedbacks]) / len(
circle_feedbacks
)
return FeedbackResponses(
records=circle_feedbacks, # noqa
summary=FeedbackSummary( # noqa
satisfaction_average=avg, # noqa
satisfaction_max=4, # noqa
total_responses=len(fbs), # noqa
),
)
def circle_feedback_average(feedbacks: List[FeedbackResponse]):
def circle_feedback_average(
feedbacks: List[FeedbackResponse], course_session_id, generation: str
):
circle_data = {}
records = []
for fb in feedbacks:
circle_id = fb.circle.id
@ -60,6 +79,14 @@ def circle_feedback_average(feedbacks: List[FeedbackResponse]):
circle_data[circle_id] = {"total": satisfaction, "count": 1}
for circle_id, data in circle_data.items():
circle_data[circle_id]["avg_satisfaction"] = data["total"] / data["count"]
records.append(
FeedbackRecord(
course_session_id=course_session_id, # noqa
generation=generation, # noqa
circle_id=circle_id, # noqa
satisfaction_average=data["total"] / data["count"], # noqa
satisfaction_max=4, # noqa
)
)
return circle_data
return records

View File

@ -52,13 +52,13 @@ class DashboardTestCase(GraphQLTestCase):
course_dashboard {{
course_id
course_title
course_session_properties{{
sessions{{
course_session_properties {{
sessions {{
session_id
session_title
}}
generations
circles{{
circles {{
circle_id
circle_title
experts

View File

@ -1,7 +1,6 @@
from graphene_django.utils import GraphQLTestCase
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.dashboard.graphql.types.feedback import feedback_responses
from vbv_lernwelt.dashboard.tests.graphql.utils import (
add_course_session_user,
create_circle,
@ -29,6 +28,11 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
)
member = create_user("member")
add_course_session_user(
course_session=course_session,
user=member,
role=CourseSessionUser.Role.MEMBER,
)
circle1, _ = create_circle(title="Test Circle 1", course_page=course_page)
circle2, _ = create_circle(title="Test Circle 2", course_page=course_page)
@ -38,29 +42,83 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
data={"satisfaction": 3},
circle=circle1,
course_session=course_session,
submitted=True,
)
FeedbackResponse.objects.create(
feedback_user=member,
data={"satisfaction": 4},
circle=circle1,
course_session=course_session,
submitted=True,
)
# Create Feedbacks for circle2
FeedbackResponse.objects.create(
feedback_user=member,
data={"satisfaction": 5},
data={"satisfaction": 1},
circle=circle2,
course_session=course_session,
submitted=True,
)
FeedbackResponse.objects.create(
feedback_user=member,
data={"satisfaction": 2},
circle=circle2,
course_session=course_session,
submitted=True,
)
# Get average satisfaction per circle
result = feedback_responses(course.id, supervisor)
self.client.force_login(supervisor)
query = f"""query($course_id: ID) {{
course_dashboard(course_id: $course_id) {{
course_id
feedback_responses {{
records {{
course_session_id
generation
circle_id
satisfaction_average
satisfaction_max
}}
summary {{
satisfaction_average
satisfaction_max
total_responses
}}
}}
}}
}}
"""
variables = {"course_id": str(course.id)}
# WHEN
response = self.query(query, variables=variables)
# THEN
self.assertResponseNoErrors(response)
course_dashboard = response.json()["data"]["course_dashboard"]
feedback_responses = course_dashboard[0]["feedback_responses"]
records = feedback_responses["records"]
self.assertEqual(len(records), 2)
circle1_record = next(
(r for r in records if r["circle_id"] == str(circle1.id)), None
)
self.assertEqual(circle1_record["satisfaction_average"], 3.5)
self.assertEqual(circle1_record["course_session_id"], str(course_session.id))
self.assertEqual(circle1_record["generation"], "2023")
circle2_record = next(
(r for r in records if r["circle_id"] == str(circle2.id)), None
)
self.assertEqual(circle2_record["satisfaction_average"], 1.5)
self.assertEqual(circle2_record["course_session_id"], str(course_session.id))
self.assertEqual(circle2_record["generation"], "2023")
summary = feedback_responses["summary"]
self.assertEqual(summary["satisfaction_average"], 2.5)
self.assertEqual(summary["satisfaction_max"], 4)
self.assertEqual(summary["total_responses"], 4)

View File

@ -0,0 +1,15 @@
from django.db.models import Q
from vbv_lernwelt.core.constants import ADMIN_USER_ID
from vbv_lernwelt.course.models import CourseSessionUser
def feedback_users(course_session_id):
"""
Solely accept feedback originating from members of the course session and the illustrious
administrative user, who serves as the repository for feedbacks heretofore submitted anonymously ;-)
"""
return CourseSessionUser.objects.filter(
Q(course_session_id=course_session_id, role=CourseSessionUser.Role.MEMBER)
| Q(user__id=ADMIN_USER_ID)
).values_list("user", flat=True)

View File

@ -5,9 +5,9 @@ from rest_framework.decorators import api_view
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.course.permissions import is_course_session_expert
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.feedback.utils import feedback_users
logger = structlog.get_logger(__name__)
@ -58,10 +58,7 @@ def get_feedback_for_circle(request, course_session_id, circle_id):
course_session__id=course_session_id,
submitted=True,
circle_id=circle_id,
# filter out experts that might have submitted just for testing
feedback_user__in=CourseSessionUser.objects.filter(
course_session_id=course_session_id, role=CourseSessionUser.Role.MEMBER
).values_list("user", flat=True),
feedback_user__in=feedback_users(course_session_id),
).order_by("created_at")
# I guess this is ok for the üK case