diff --git a/server/vbv_lernwelt/course/models.py b/server/vbv_lernwelt/course/models.py index f735998f..4b6b1c2d 100644 --- a/server/vbv_lernwelt/course/models.py +++ b/server/vbv_lernwelt/course/models.py @@ -266,7 +266,6 @@ class CourseSessionUser(models.Model): class Role(models.TextChoices): MEMBER = "MEMBER", _("Teilnehmer") EXPERT = "EXPERT", _("Experte/Trainer") - SESSION_SUPERVISOR = "SESSION_SUPERVISOR", _("Regionalleiter") TUTOR = "TUTOR", _("Lernbegleitung") role = models.CharField(choices=Role.choices, max_length=255, default=Role.MEMBER) diff --git a/server/vbv_lernwelt/dashboard/graphql/queries.py b/server/vbv_lernwelt/dashboard/graphql/queries.py index fd508198..a708ca45 100644 --- a/server/vbv_lernwelt/dashboard/graphql/queries.py +++ b/server/vbv_lernwelt/dashboard/graphql/queries.py @@ -1,27 +1,22 @@ import graphene -from vbv_lernwelt.course.models import Course, CourseSessionUser -from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseDashboardType +from vbv_lernwelt.course.models import Course +from vbv_lernwelt.dashboard.graphql.types.dashboard import CourseStatisticsType class DashboardQuery(graphene.ObjectType): - course_dashboard = graphene.List( - CourseDashboardType, course_id=graphene.ID(required=False) + course_statistics = graphene.List( + CourseStatisticsType, course_id=graphene.ID(required=True) ) - def resolve_course_dashboard(root, info, course_id: str | None = None): - user = info.context.user + def resolve_course_statistics(root, info, course_id: str): query = Course.objects.filter( - coursesession__coursesessionuser__user=user, - coursesession__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, + id=course_id ) - if course_id: - query = query.filter(id=course_id) - courses = query.distinct() 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 ] diff --git a/server/vbv_lernwelt/dashboard/graphql/types/assignment.py b/server/vbv_lernwelt/dashboard/graphql/types/assignment.py index 07ad0ead..d42d14ad 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/assignment.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/assignment.py @@ -124,10 +124,8 @@ def create_record( ) -def assignments(course_id, user) -> Assignments: +def assignments(course_id) -> Assignments: course_sessions = CourseSession.objects.filter( - coursesessionuser__user=user, - coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, course_id=course_id, ) diff --git a/server/vbv_lernwelt/dashboard/graphql/types/attendance.py b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py index 3db5fa69..40620769 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/attendance.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py @@ -4,7 +4,6 @@ from typing import List import graphene from django.utils import timezone -from vbv_lernwelt.core.models import User from vbv_lernwelt.course.models import CourseSessionUser from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus @@ -31,13 +30,9 @@ class AttendanceDayPresences(graphene.ObjectType): summary = graphene.Field(AttendanceSummary) -def attendance_day_presences( - course_id: graphene.String(), user: User -) -> AttendanceDayPresences: +def attendance_day_presences(course_id: graphene.String()) -> AttendanceDayPresences: completed = CourseSessionAttendanceCourse.objects.filter( 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(), ).order_by("-due_date__end") diff --git a/server/vbv_lernwelt/dashboard/graphql/types/competence.py b/server/vbv_lernwelt/dashboard/graphql/types/competence.py index adb3898f..aad79e28 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/competence.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/competence.py @@ -1,10 +1,8 @@ import graphene -from vbv_lernwelt.core.models import User from vbv_lernwelt.course.models import ( CourseCompletion, CourseCompletionStatus, - CourseSessionUser, ) @@ -26,18 +24,22 @@ class Competences(graphene.ObjectType): summary = graphene.Field(CompletionSummary) -def competences(course_id: graphene.String(), user: User) -> Competences: +def competences(course_id: graphene.String()) -> Competences: completions = CourseCompletion.objects.filter( course_session__course_id=course_id, - course_session__coursesessionuser__user=user, - course_session__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, page_type="competence.PerformanceCriteria", ) competence_performances = {} + circle_cache = {} + 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: competence_performances[circle.id] = CompetencePerformance( course_session_id=c.course_session.id, # noqa diff --git a/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py index 0e94fe2b..a69cdfc6 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py @@ -1,6 +1,6 @@ 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.attendance import ( attendance_day_presences, @@ -31,7 +31,7 @@ class CourseSessionProperties(graphene.ObjectType): circles = graphene.List(CircleData) -class CourseDashboardType(graphene.ObjectType): +class CourseStatisticsType(graphene.ObjectType): course_id = graphene.String() course_title = graphene.String() course_session_properties = graphene.Field(CourseSessionProperties) @@ -41,25 +41,26 @@ class CourseDashboardType(graphene.ObjectType): competences = graphene.Field(Competences) 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: - return feedback_responses(root.course_id, info.context.user) + return feedback_responses(root.course_id) def resolve_competences(root, info) -> Competences: - return competences(root.course_id, info.context.user) + return competences(root.course_id) - def resolve_assignments(root, info): - return assignments(root.course_id, info.context.user) + def resolve_assignments(root, info) -> Assignments: + return assignments(root.course_id) def resolve_course_session_properties(root, info): course_session_data = [] circle_data = [] generations = set() + # TODO: Use course session group app to get all + # relevant course sessions for info.context.user + course_sessions = CourseSession.objects.filter( - coursesessionuser__user=info.context.user, - coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, course_id=root.course_id, ) diff --git a/server/vbv_lernwelt/dashboard/graphql/types/feedback.py b/server/vbv_lernwelt/dashboard/graphql/types/feedback.py index 231e8803..c04199e5 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/feedback.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/feedback.py @@ -2,8 +2,7 @@ from typing import List import graphene -from vbv_lernwelt.core.models import User -from vbv_lernwelt.course.models import CourseSession, CourseSessionUser +from vbv_lernwelt.course.models import CourseSession from vbv_lernwelt.feedback.models import FeedbackResponse from vbv_lernwelt.feedback.utils import feedback_users @@ -27,11 +26,9 @@ class FeedbackResponses(graphene.ObjectType): 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 course_sessions = CourseSession.objects.filter( - coursesessionuser__user=user, - coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, course_id=course_id, ) @@ -70,7 +67,10 @@ def circle_feedback_average( for fb in feedbacks: 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: circle_data[circle_id]["total"] += satisfaction diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_assignment.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_assignment.py index 8f22f855..6151e4f0 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_assignment.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_assignment.py @@ -26,8 +26,8 @@ from vbv_lernwelt.learnpath.models import Circle class AssignmentTestCase(GraphQLTestCase): GRAPHQL_URL = "/server/graphql/" - GRAPHQL_QUERY = f"""query($course_id: ID) {{ - course_dashboard(course_id: $course_id) {{ + GRAPHQL_QUERY = f"""query($course_id: ID!) {{ + course_statistics(course_id: $course_id) {{ assignments{{ summary{{ completed_count @@ -60,11 +60,6 @@ class AssignmentTestCase(GraphQLTestCase): self.circle, _ = create_circle(title="Circle", course_page=self.course_page) 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") add_course_session_user( @@ -149,7 +144,7 @@ class AssignmentTestCase(GraphQLTestCase): # THEN self.assertResponseNoErrors(response) - dashboard = response.json()["data"]["course_dashboard"] + dashboard = response.json()["data"]["course_statistics"] records = dashboard[0]["assignments"]["records"] self.assertEqual(len(records), 1) @@ -191,7 +186,7 @@ class AssignmentTestCase(GraphQLTestCase): # THEN self.assertResponseNoErrors(response) - dashboard = response.json()["data"]["course_dashboard"] + dashboard = response.json()["data"]["course_statistics"] records = dashboard[0]["assignments"]["records"] self.assertEqual(len(records), 0) @@ -280,7 +275,7 @@ class AssignmentTestCase(GraphQLTestCase): # THEN self.assertResponseNoErrors(response) - dashboard = response.json()["data"]["course_dashboard"] + dashboard = response.json()["data"]["course_statistics"] # 1 -> incomplete (not counted for average) # 2 -> complete 66% passed ... diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py index 5b490898..0148508a 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py @@ -23,14 +23,9 @@ class DashboardAttendanceTestCase(GraphQLTestCase): course, course_page = create_course("Test Course") 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") - 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) m1 = create_user("member_1") @@ -77,8 +72,8 @@ class DashboardAttendanceTestCase(GraphQLTestCase): self.client.force_login(supervisor) query = f""" - query($course_id: ID) {{ - course_dashboard(course_id: $course_id) {{ + query($course_id: ID!) {{ + course_statistics(course_id: $course_id) {{ attendance_day_presences{{ summary{{ days_completed @@ -105,7 +100,7 @@ class DashboardAttendanceTestCase(GraphQLTestCase): data = response.json()["data"] - attendance_day_presences = data["course_dashboard"][0][ + attendance_day_presences = data["course_statistics"][0][ "attendance_day_presences" ] diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_competence.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_competence.py index 5d91c1c1..047e54d6 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_competence.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_competence.py @@ -20,14 +20,9 @@ class DashboardCompetenceTestCase(GraphQLTestCase): course, course_page = create_course("Test Course") 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") - add_course_session_user( - course_session=course_session, - user=supervisor, - role=CourseSessionUser.Role.SESSION_SUPERVISOR, - ) - member_one = create_user("member one") add_course_session_user( course_session=course_session, @@ -64,16 +59,16 @@ class DashboardCompetenceTestCase(GraphQLTestCase): self.client.force_login(supervisor) - query = f"""query($course_id: ID) {{ - course_dashboard(course_id: $course_id) {{ + query = f"""query($course_id: ID!) {{ + course_statistics(course_id: $course_id) {{ course_id competences {{ performances {{ course_session_id generation - circle_id + circle_id success_count - fail_count + fail_count }} summary {{ success_total @@ -91,7 +86,7 @@ class DashboardCompetenceTestCase(GraphQLTestCase): # THEN self.assertResponseNoErrors(response) - competences = response.json()["data"]["course_dashboard"][0]["competences"] + competences = response.json()["data"]["course_statistics"][0]["competences"] performances = competences["performances"] diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py index afea64f4..cd86629e 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py @@ -1,9 +1,6 @@ from graphene_django.utils import GraphQLTestCase -from vbv_lernwelt.course.models import CourseSessionUser from vbv_lernwelt.dashboard.tests.graphql.utils import ( - add_course_session_user, - create_circle, create_course, create_course_session, create_user, @@ -13,121 +10,21 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import ( class DashboardTestCase(GraphQLTestCase): GRAPHQL_URL = "/server/graphql/" - def test_course_dashboard(self): + def test_course_statistics_id(self): # 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") - 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 + # TODO: Give this guy the right permissions, once we have them supervisor = create_user("supervisor") course_1, _ = create_course("Test Course 1") course_2, _ = create_course("Test Course 2") - course_session_1 = create_course_session( - course=course_1, title="Test Course 1 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, - ) + + create_course_session(course=course_1, title="Test Course 1 Session") + create_course_session(course=course_2, title="Test Course 2 Session") self.client.force_login(supervisor) - query = f"""query($course_id: ID) {{ - course_dashboard(course_id: $course_id) {{ + query = f"""query($course_id: ID!) {{ + course_statistics(course_id: $course_id) {{ course_id }} }} @@ -140,7 +37,7 @@ class DashboardTestCase(GraphQLTestCase): # THEN 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(course_dashboard[0]["course_id"], str(course_2.id)) + self.assertEqual(len(course_statistics), 1) + self.assertEqual(course_statistics[0]["course_id"], str(course_2.id)) diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py index cef2b066..1158c05a 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py @@ -19,14 +19,9 @@ class DashboardFeedbackTestCase(GraphQLTestCase): course, course_page = create_course("Test Course") 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") - add_course_session_user( - course_session=course_session, - user=supervisor, - role=CourseSessionUser.Role.SESSION_SUPERVISOR, - ) - member = create_user("member") add_course_session_user( course_session=course_session, @@ -70,16 +65,16 @@ class DashboardFeedbackTestCase(GraphQLTestCase): self.client.force_login(supervisor) - query = f"""query($course_id: ID) {{ - course_dashboard(course_id: $course_id) {{ + query = f"""query($course_id: ID!) {{ + course_statistics(course_id: $course_id) {{ course_id feedback_responses {{ records {{ course_session_id generation - circle_id + circle_id satisfaction_average - satisfaction_max + satisfaction_max }} summary {{ satisfaction_average @@ -98,8 +93,8 @@ class DashboardFeedbackTestCase(GraphQLTestCase): # THEN self.assertResponseNoErrors(response) - course_dashboard = response.json()["data"]["course_dashboard"] - feedback_responses = course_dashboard[0]["feedback_responses"] + course_statistics = response.json()["data"]["course_statistics"] + feedback_responses = course_statistics[0]["feedback_responses"] records = feedback_responses["records"] self.assertEqual(len(records), 2)