feat: removes supervisor role plus prod data fixes

This commit is contained in:
Livio Bieri 2023-10-23 16:27:13 +02:00
parent 48677974d2
commit 61c57c4cb4
12 changed files with 65 additions and 198 deletions

View File

@ -266,7 +266,6 @@ class CourseSessionUser(models.Model):
class Role(models.TextChoices): class Role(models.TextChoices):
MEMBER = "MEMBER", _("Teilnehmer") MEMBER = "MEMBER", _("Teilnehmer")
EXPERT = "EXPERT", _("Experte/Trainer") EXPERT = "EXPERT", _("Experte/Trainer")
SESSION_SUPERVISOR = "SESSION_SUPERVISOR", _("Regionalleiter")
TUTOR = "TUTOR", _("Lernbegleitung") TUTOR = "TUTOR", _("Lernbegleitung")
role = models.CharField(choices=Role.choices, max_length=255, default=Role.MEMBER) role = models.CharField(choices=Role.choices, max_length=255, default=Role.MEMBER)

View File

@ -1,27 +1,22 @@
import graphene import graphene
from vbv_lernwelt.course.models import Course, CourseSessionUser from vbv_lernwelt.course.models import Course
from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseDashboardType from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseStatisticsType
class DashboardQuery(graphene.ObjectType): class DashboardQuery(graphene.ObjectType):
course_dashboard = graphene.List( course_statistics = graphene.List(
CourseDashboardType, course_id=graphene.ID(required=False) CourseStatisticsType, course_id=graphene.ID(required=True)
) )
def resolve_course_dashboard(root, info, course_id: str | None = None): def resolve_course_statistics(root, info, course_id: str):
user = info.context.user
query = Course.objects.filter( query = Course.objects.filter(
coursesession__coursesessionuser__user=user, id=course_id
coursesession__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
) )
if course_id:
query = query.filter(id=course_id)
courses = query.distinct() courses = query.distinct()
return [ return [
CourseDashboardType(course_id=course.id, course_title=course.title) # noqa CourseStatisticsType(course_id=course.id, course_title=course.title) # noqa
for course in courses for course in courses
] ]

View File

@ -124,10 +124,8 @@ def create_record(
) )
def assignments(course_id, user) -> Assignments: def assignments(course_id) -> Assignments:
course_sessions = CourseSession.objects.filter( course_sessions = CourseSession.objects.filter(
coursesessionuser__user=user,
coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
course_id=course_id, course_id=course_id,
) )

View File

@ -4,7 +4,6 @@ from typing import List
import graphene import graphene
from django.utils import timezone from django.utils import timezone
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import CourseSessionUser from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus
@ -31,13 +30,9 @@ class AttendanceDayPresences(graphene.ObjectType):
summary = graphene.Field(AttendanceSummary) summary = graphene.Field(AttendanceSummary)
def attendance_day_presences( def attendance_day_presences(course_id: graphene.String()) -> AttendanceDayPresences:
course_id: graphene.String(), user: User
) -> AttendanceDayPresences:
completed = CourseSessionAttendanceCourse.objects.filter( completed = CourseSessionAttendanceCourse.objects.filter(
course_session__course_id=course_id, course_session__course_id=course_id,
course_session__coursesessionuser__user=user,
course_session__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
due_date__end__lt=timezone.now(), due_date__end__lt=timezone.now(),
).order_by("-due_date__end") ).order_by("-due_date__end")

View File

@ -1,10 +1,8 @@
import graphene import graphene
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import ( from vbv_lernwelt.course.models import (
CourseCompletion, CourseCompletion,
CourseCompletionStatus, CourseCompletionStatus,
CourseSessionUser,
) )
@ -26,18 +24,22 @@ class Competences(graphene.ObjectType):
summary = graphene.Field(CompletionSummary) summary = graphene.Field(CompletionSummary)
def competences(course_id: graphene.String(), user: User) -> Competences: def competences(course_id: graphene.String()) -> Competences:
completions = CourseCompletion.objects.filter( completions = CourseCompletion.objects.filter(
course_session__course_id=course_id, course_session__course_id=course_id,
course_session__coursesessionuser__user=user,
course_session__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
page_type="competence.PerformanceCriteria", page_type="competence.PerformanceCriteria",
) )
competence_performances = {} competence_performances = {}
circle_cache = {}
for c in completions: for c in completions:
circle = c.page.specific.learning_unit.get_circle() if c.page.id not in circle_cache:
circle_cache[c.page.id] = c.page.specific.learning_unit.get_circle()
circle = circle_cache[c.page.id]
if circle.id not in competence_performances: if circle.id not in competence_performances:
competence_performances[circle.id] = CompetencePerformance( competence_performances[circle.id] = CompetencePerformance(
course_session_id=c.course_session.id, # noqa course_session_id=c.course_session.id, # noqa

View File

@ -1,6 +1,6 @@
import graphene import graphene
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.dashboard.graphql.types.assignment import Assignments, assignments from vbv_lernwelt.dashboard.graphql.types.assignment import Assignments, assignments
from vbv_lernwelt.dashboard.graphql.types.attendance import ( from vbv_lernwelt.dashboard.graphql.types.attendance import (
attendance_day_presences, attendance_day_presences,
@ -31,7 +31,7 @@ class CourseSessionProperties(graphene.ObjectType):
circles = graphene.List(CircleData) circles = graphene.List(CircleData)
class CourseDashboardType(graphene.ObjectType): class CourseStatisticsType(graphene.ObjectType):
course_id = graphene.String() course_id = graphene.String()
course_title = graphene.String() course_title = graphene.String()
course_session_properties = graphene.Field(CourseSessionProperties) course_session_properties = graphene.Field(CourseSessionProperties)
@ -41,25 +41,26 @@ class CourseDashboardType(graphene.ObjectType):
competences = graphene.Field(Competences) competences = graphene.Field(Competences)
def resolve_attendance_day_presences(root, info) -> AttendanceDayPresences: def resolve_attendance_day_presences(root, info) -> AttendanceDayPresences:
return attendance_day_presences(root.course_id, info.context.user) return attendance_day_presences(root.course_id)
def resolve_feedback_responses(root, info) -> FeedbackResponses: def resolve_feedback_responses(root, info) -> FeedbackResponses:
return feedback_responses(root.course_id, info.context.user) return feedback_responses(root.course_id)
def resolve_competences(root, info) -> Competences: def resolve_competences(root, info) -> Competences:
return competences(root.course_id, info.context.user) return competences(root.course_id)
def resolve_assignments(root, info): def resolve_assignments(root, info) -> Assignments:
return assignments(root.course_id, info.context.user) return assignments(root.course_id)
def resolve_course_session_properties(root, info): def resolve_course_session_properties(root, info):
course_session_data = [] course_session_data = []
circle_data = [] circle_data = []
generations = set() generations = set()
# TODO: Use course session group app to get all
# relevant course sessions for info.context.user
course_sessions = CourseSession.objects.filter( course_sessions = CourseSession.objects.filter(
coursesessionuser__user=info.context.user,
coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
course_id=root.course_id, course_id=root.course_id,
) )

View File

@ -2,8 +2,7 @@ from typing import List
import graphene import graphene
from vbv_lernwelt.core.models import User from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.feedback.models import FeedbackResponse from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.feedback.utils import feedback_users from vbv_lernwelt.feedback.utils import feedback_users
@ -27,11 +26,9 @@ class FeedbackResponses(graphene.ObjectType):
summary = graphene.Field(FeedbackSummary) summary = graphene.Field(FeedbackSummary)
def feedback_responses(course_id: graphene.String(), user: User) -> FeedbackResponses: def feedback_responses(course_id: graphene.String()) -> FeedbackResponses:
# Get all course sessions for this user in the given course # Get all course sessions for this user in the given course
course_sessions = CourseSession.objects.filter( course_sessions = CourseSession.objects.filter(
coursesessionuser__user=user,
coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR,
course_id=course_id, course_id=course_id,
) )
@ -70,7 +67,10 @@ def circle_feedback_average(
for fb in feedbacks: for fb in feedbacks:
circle_id = fb.circle.id circle_id = fb.circle.id
satisfaction = fb.data.get("satisfaction", 0) satisfaction = fb.data.get("satisfaction", None)
if satisfaction is None:
continue
if circle_id in circle_data: if circle_id in circle_data:
circle_data[circle_id]["total"] += satisfaction circle_data[circle_id]["total"] += satisfaction

View File

@ -26,8 +26,8 @@ from vbv_lernwelt.learnpath.models import Circle
class AssignmentTestCase(GraphQLTestCase): class AssignmentTestCase(GraphQLTestCase):
GRAPHQL_URL = "/server/graphql/" GRAPHQL_URL = "/server/graphql/"
GRAPHQL_QUERY = f"""query($course_id: ID) {{ GRAPHQL_QUERY = f"""query($course_id: ID!) {{
course_dashboard(course_id: $course_id) {{ course_statistics(course_id: $course_id) {{
assignments{{ assignments{{
summary{{ summary{{
completed_count completed_count
@ -60,11 +60,6 @@ class AssignmentTestCase(GraphQLTestCase):
self.circle, _ = create_circle(title="Circle", course_page=self.course_page) self.circle, _ = create_circle(title="Circle", course_page=self.course_page)
self.supervisor = create_user("supervisor") self.supervisor = create_user("supervisor")
add_course_session_user(
course_session=self.course_session,
user=self.supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
self.m1 = create_user("member_1") self.m1 = create_user("member_1")
add_course_session_user( add_course_session_user(
@ -149,7 +144,7 @@ class AssignmentTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
dashboard = response.json()["data"]["course_dashboard"] dashboard = response.json()["data"]["course_statistics"]
records = dashboard[0]["assignments"]["records"] records = dashboard[0]["assignments"]["records"]
self.assertEqual(len(records), 1) self.assertEqual(len(records), 1)
@ -191,7 +186,7 @@ class AssignmentTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
dashboard = response.json()["data"]["course_dashboard"] dashboard = response.json()["data"]["course_statistics"]
records = dashboard[0]["assignments"]["records"] records = dashboard[0]["assignments"]["records"]
self.assertEqual(len(records), 0) self.assertEqual(len(records), 0)
@ -280,7 +275,7 @@ class AssignmentTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
dashboard = response.json()["data"]["course_dashboard"] dashboard = response.json()["data"]["course_statistics"]
# 1 -> incomplete (not counted for average) # 1 -> incomplete (not counted for average)
# 2 -> complete 66% passed ... # 2 -> complete 66% passed ...

View File

@ -23,14 +23,9 @@ class DashboardAttendanceTestCase(GraphQLTestCase):
course, course_page = create_course("Test Course") course, course_page = create_course("Test Course")
course_session = create_course_session(course=course, title="Test Bern 2022 a") course_session = create_course_session(course=course, title="Test Bern 2022 a")
# TODO: Give this guy the right permissions, once we have them ;)
supervisor = create_user("supervisor") supervisor = create_user("supervisor")
add_course_session_user(
course_session=course_session,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
circle, _ = create_circle(title="Test Circle", course_page=course_page) circle, _ = create_circle(title="Test Circle", course_page=course_page)
m1 = create_user("member_1") m1 = create_user("member_1")
@ -77,8 +72,8 @@ class DashboardAttendanceTestCase(GraphQLTestCase):
self.client.force_login(supervisor) self.client.force_login(supervisor)
query = f""" query = f"""
query($course_id: ID) {{ query($course_id: ID!) {{
course_dashboard(course_id: $course_id) {{ course_statistics(course_id: $course_id) {{
attendance_day_presences{{ attendance_day_presences{{
summary{{ summary{{
days_completed days_completed
@ -105,7 +100,7 @@ class DashboardAttendanceTestCase(GraphQLTestCase):
data = response.json()["data"] data = response.json()["data"]
attendance_day_presences = data["course_dashboard"][0][ attendance_day_presences = data["course_statistics"][0][
"attendance_day_presences" "attendance_day_presences"
] ]

View File

@ -20,14 +20,9 @@ class DashboardCompetenceTestCase(GraphQLTestCase):
course, course_page = create_course("Test Course") course, course_page = create_course("Test Course")
course_session = create_course_session(course=course, title="Test Bern 2022 a") course_session = create_course_session(course=course, title="Test Bern 2022 a")
# TODO: Give this guy the right permissions, once we have them ;)
supervisor = create_user("supervisor") supervisor = create_user("supervisor")
add_course_session_user(
course_session=course_session,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
member_one = create_user("member one") member_one = create_user("member one")
add_course_session_user( add_course_session_user(
course_session=course_session, course_session=course_session,
@ -64,8 +59,8 @@ class DashboardCompetenceTestCase(GraphQLTestCase):
self.client.force_login(supervisor) self.client.force_login(supervisor)
query = f"""query($course_id: ID) {{ query = f"""query($course_id: ID!) {{
course_dashboard(course_id: $course_id) {{ course_statistics(course_id: $course_id) {{
course_id course_id
competences {{ competences {{
performances {{ performances {{
@ -91,7 +86,7 @@ class DashboardCompetenceTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
competences = response.json()["data"]["course_dashboard"][0]["competences"] competences = response.json()["data"]["course_statistics"][0]["competences"]
performances = competences["performances"] performances = competences["performances"]

View File

@ -1,9 +1,6 @@
from graphene_django.utils import GraphQLTestCase from graphene_django.utils import GraphQLTestCase
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.dashboard.tests.graphql.utils import ( from vbv_lernwelt.dashboard.tests.graphql.utils import (
add_course_session_user,
create_circle,
create_course, create_course,
create_course_session, create_course_session,
create_user, create_user,
@ -13,121 +10,21 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
class DashboardTestCase(GraphQLTestCase): class DashboardTestCase(GraphQLTestCase):
GRAPHQL_URL = "/server/graphql/" GRAPHQL_URL = "/server/graphql/"
def test_course_dashboard(self): def test_course_statistics_id(self):
# GIVEN # GIVEN
supervisor = create_user("supervisor")
course, course_page = create_course("Test Course")
course_session = create_course_session(course=course, title="Test Bern 2022 a")
add_course_session_user(
course_session=course_session,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
some_course, _ = create_course("Other Course") # TODO: Give this guy the right permissions, once we have them
some_course_session = create_course_session(
course=some_course, title="Here is go study"
)
add_course_session_user(
course_session=some_course_session,
user=supervisor,
role=CourseSessionUser.Role.MEMBER,
)
circle, _ = create_circle(title="Test Circle", course_page=course_page)
# expert
expert = create_user("expert")
expert_session_user = add_course_session_user(
course_session=some_course_session,
user=expert,
role=CourseSessionUser.Role.EXPERT,
)
expert_session_user.expert.add(circle)
self.client.force_login(supervisor)
query = f"""
query {{
course_dashboard {{
course_id
course_title
course_session_properties {{
sessions {{
session_id
session_title
}}
generations
circles {{
circle_id
circle_title
experts
}}
}}
}}
}}
"""
# WHEN
response = self.query(query)
# THEN
self.assertResponseNoErrors(response)
course_dashboard = response.json()["data"]["course_dashboard"]
self.assertEqual(len(course_dashboard), 1)
self.assertEqual(course_dashboard[0]["course_id"], str(course.id))
self.assertEqual(course_dashboard[0]["course_title"], str(course.title))
session_properties = course_dashboard[0]["course_session_properties"]
self.assertEqual(len(session_properties["sessions"]), 1)
self.assertEqual(
session_properties["sessions"][0]["session_id"], str(course_session.id)
)
self.assertEqual(
session_properties["sessions"][0]["session_title"],
str(course_session.title),
)
self.assertEqual(len(session_properties["generations"]), 1)
self.assertEqual(
session_properties["generations"][0], str(course_session.generation)
)
self.assertEqual(len(session_properties["circles"]), 1)
self.assertEqual(session_properties["circles"][0]["circle_id"], str(circle.id))
self.assertEqual(
session_properties["circles"][0]["circle_title"], str(circle.title)
)
self.assertEqual(session_properties["circles"][0]["experts"], ["Test Expert"])
def test_course_dashboard_id(self):
# GIVEN
supervisor = create_user("supervisor") supervisor = create_user("supervisor")
course_1, _ = create_course("Test Course 1") course_1, _ = create_course("Test Course 1")
course_2, _ = create_course("Test Course 2") course_2, _ = create_course("Test Course 2")
course_session_1 = create_course_session(
course=course_1, title="Test Course 1 Session" create_course_session(course=course_1, title="Test Course 1 Session")
) create_course_session(course=course_2, title="Test Course 2 Session")
course_session_2 = create_course_session(
course=course_2, title="Test Course 2 Session"
)
add_course_session_user(
course_session=course_session_1,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
add_course_session_user(
course_session=course_session_2,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
self.client.force_login(supervisor) self.client.force_login(supervisor)
query = f"""query($course_id: ID) {{ query = f"""query($course_id: ID!) {{
course_dashboard(course_id: $course_id) {{ course_statistics(course_id: $course_id) {{
course_id course_id
}} }}
}} }}
@ -140,7 +37,7 @@ class DashboardTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
course_dashboard = response.json()["data"]["course_dashboard"] course_statistics = response.json()["data"]["course_statistics"]
self.assertEqual(len(course_dashboard), 1) self.assertEqual(len(course_statistics), 1)
self.assertEqual(course_dashboard[0]["course_id"], str(course_2.id)) self.assertEqual(course_statistics[0]["course_id"], str(course_2.id))

View File

@ -19,14 +19,9 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
course, course_page = create_course("Test Course") course, course_page = create_course("Test Course")
course_session = create_course_session(course=course, title="Test Bern 2022 a") course_session = create_course_session(course=course, title="Test Bern 2022 a")
# TODO: Give this guy the right permissions, once we have them ;)
supervisor = create_user("supervisor") supervisor = create_user("supervisor")
add_course_session_user(
course_session=course_session,
user=supervisor,
role=CourseSessionUser.Role.SESSION_SUPERVISOR,
)
member = create_user("member") member = create_user("member")
add_course_session_user( add_course_session_user(
course_session=course_session, course_session=course_session,
@ -70,8 +65,8 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
self.client.force_login(supervisor) self.client.force_login(supervisor)
query = f"""query($course_id: ID) {{ query = f"""query($course_id: ID!) {{
course_dashboard(course_id: $course_id) {{ course_statistics(course_id: $course_id) {{
course_id course_id
feedback_responses {{ feedback_responses {{
records {{ records {{
@ -98,8 +93,8 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
# THEN # THEN
self.assertResponseNoErrors(response) self.assertResponseNoErrors(response)
course_dashboard = response.json()["data"]["course_dashboard"] course_statistics = response.json()["data"]["course_statistics"]
feedback_responses = course_dashboard[0]["feedback_responses"] feedback_responses = course_statistics[0]["feedback_responses"]
records = feedback_responses["records"] records = feedback_responses["records"]
self.assertEqual(len(records), 2) self.assertEqual(len(records), 2)