fix: dedup course dashboard stuff

This commit is contained in:
Livio Bieri 2023-10-25 12:46:58 +02:00
parent 6f973d7e93
commit 04d40e1f57
2 changed files with 106 additions and 43 deletions

View File

@ -1,5 +1,9 @@
from typing import Set, Dict, List, Tuple
import graphene
from vbv_lernwelt.core.admin import User
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.course.models import Course, CourseSession
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
from vbv_lernwelt.dashboard.graphql.types.dashboard import (
@ -10,7 +14,6 @@ from vbv_lernwelt.dashboard.graphql.types.dashboard import (
from vbv_lernwelt.iam.permissions import (
can_view_course_session,
can_view_course_session_group_statistics,
can_view_course_session_progress,
)
@ -38,14 +41,27 @@ class DashboardQuery(graphene.ObjectType):
return None
return CourseStatisticsType(
id=course.id,
id=course.id, # noqa
course_title=course.title, # noqa
course_session_selection_ids=list(course_session_ids),
) # noqa
course_session_selection_ids=list(course_session_ids), # noqa
)
def resolve_dashboard_config(root, info): # noqa
user = info.context.user
(
statistic_dashboards,
statistics_dashboard_course_ids,
) = get_user_statistics_dashboards(user=user)
course_session_dashboards = get_user_course_session_dashboards(
user=user, exclude_course_ids=statistics_dashboard_course_ids
)
return statistic_dashboards + course_session_dashboards
def get_user_statistics_dashboards(user: User) -> Tuple[List[Dict[str, str]], Set[int]]:
course_index = set()
dashboards = []
@ -61,24 +77,49 @@ class DashboardQuery(graphene.ObjectType):
}
)
for course_session in CourseSession.objects.exclude(course__in=course_index):
course = course_session.course
return dashboards, course_index
def get_user_course_session_dashboards(
user: User, exclude_course_ids: Set[int]
) -> List[Dict[str, str]]:
"""
Edge case: what do we show to users with access to multiple
sessions of a course, but with varying permissions?
-> We just show the simple list dashboard for now.
"""
dashboards = []
course_sessions = CourseSession.objects.exclude(course__in=exclude_course_ids)
roles_by_course: Dict[Course, Set[DashboardType]] = {}
for course_session in course_sessions:
if can_view_course_session(user=user, course_session=course_session):
role = CourseSessionUser.objects.get(
course_session=course_session, user=user
).role
roles_by_course.setdefault(course_session.course, set())
roles_by_course[course_session.course].add(role)
for course, roles in roles_by_course.items():
resolved_dashboard_type = None
if len(roles) == 1:
course_role = roles.pop()
if course_role == CourseSessionUser.Role.EXPERT:
resolved_dashboard_type = DashboardType.SIMPLE_LIST_DASHBOARD
elif course_role == CourseSessionUser.Role.MEMBER:
resolved_dashboard_type = DashboardType.PROGRESS_DASHBOARD
else:
# fallback: just go with simple list dashboard
resolved_dashboard_type = DashboardType.SIMPLE_LIST_DASHBOARD
dashboards.append(
{
"id": str(course.id),
"name": course.title,
"dashboard_type": DashboardType.SIMPLE_LIST_DASHBOARD,
}
)
if can_view_course_session_progress(
user=user, course_session=course_session
):
dashboards.append(
{
"id": str(course.id),
"name": course.title,
"dashboard_type": DashboardType.PROGRESS_DASHBOARD,
"dashboard_type": resolved_dashboard_type,
}
)

View File

@ -18,20 +18,35 @@ class DashboardTestCase(GraphQLTestCase):
# GIVEN
course_1, _ = create_course("Test Course 1")
course_2, _ = create_course("Test Course 2")
course_3, _ = create_course("Test Course 3")
cs_1 = create_course_session(course=course_1, title="Test Course 1 Session")
cs_2 = create_course_session(course=course_2, title="Test Course 2 Session")
# Member of course 1 (via cs_1)
# Supervisor of course 2 (via cs_2)
cs_3_a = create_course_session(course=course_3, title="CS 3 A (as member)")
cs_3_b = create_course_session(course=course_3, title="CS 3 B (as expert)")
supervisor = create_user("supervisor")
# CS 1
add_course_session_user(
course_session=cs_1, user=supervisor, role=CourseSessionUser.Role.MEMBER
)
group = create_course_session_group(course_session=cs_2)
add_course_session_group_supervisor(group=group, user=supervisor)
# CS 2
add_course_session_group_supervisor(
group=create_course_session_group(course_session=cs_2), user=supervisor
)
# CS 3 A
add_course_session_user(
course_session=cs_3_a, user=supervisor, role=CourseSessionUser.Role.MEMBER
)
# CS 3 B
add_course_session_user(
course_session=cs_3_b, user=supervisor, role=CourseSessionUser.Role.EXPERT
)
self.client.force_login(supervisor)
@ -58,7 +73,7 @@ class DashboardTestCase(GraphQLTestCase):
)
self.assertIsNotNone(course_1_config)
self.assertEqual(course_1_config["name"], course_1.title)
self.assertEqual(course_1_config["dashboard_type"], "SIMPLE_LIST_DASHBOARD")
self.assertEqual(course_1_config["dashboard_type"], "PROGRESS_DASHBOARD")
course_2_config = find_dashboard_config_by_course_id(
dashboard_config, course_2.id
@ -67,6 +82,13 @@ class DashboardTestCase(GraphQLTestCase):
self.assertEqual(course_2_config["name"], course_2.title)
self.assertEqual(course_2_config["dashboard_type"], "STATISTICS_DASHBOARD")
course_3_config = find_dashboard_config_by_course_id(
dashboard_config, course_3.id
)
self.assertIsNotNone(course_3_config)
self.assertEqual(course_3_config["name"], course_3.title)
self.assertEqual(course_3_config["dashboard_type"], "SIMPLE_LIST_DASHBOARD")
def test_course_statistics_deny_not_allowed_user(self):
# GIVEN
disallowed_user = create_user("1337_hacker_schorsch")