fix: dedup course dashboard stuff
This commit is contained in:
parent
6f973d7e93
commit
04d40e1f57
|
|
@ -1,5 +1,9 @@
|
||||||
|
from typing import Set, Dict, List, Tuple
|
||||||
|
|
||||||
import graphene
|
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.models import Course, CourseSession
|
||||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||||
from vbv_lernwelt.dashboard.graphql.types.dashboard import (
|
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 (
|
from vbv_lernwelt.iam.permissions import (
|
||||||
can_view_course_session,
|
can_view_course_session,
|
||||||
can_view_course_session_group_statistics,
|
can_view_course_session_group_statistics,
|
||||||
can_view_course_session_progress,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -38,48 +41,86 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return CourseStatisticsType(
|
return CourseStatisticsType(
|
||||||
id=course.id,
|
id=course.id, # noqa
|
||||||
course_title=course.title, # noqa
|
course_title=course.title, # noqa
|
||||||
course_session_selection_ids=list(course_session_ids),
|
course_session_selection_ids=list(course_session_ids), # noqa
|
||||||
) # noqa
|
)
|
||||||
|
|
||||||
def resolve_dashboard_config(root, info): # noqa
|
def resolve_dashboard_config(root, info): # noqa
|
||||||
user = info.context.user
|
user = info.context.user
|
||||||
|
|
||||||
course_index = set()
|
(
|
||||||
dashboards = []
|
statistic_dashboards,
|
||||||
|
statistics_dashboard_course_ids,
|
||||||
|
) = get_user_statistics_dashboards(user=user)
|
||||||
|
|
||||||
for group in CourseSessionGroup.objects.all():
|
course_session_dashboards = get_user_course_session_dashboards(
|
||||||
if can_view_course_session_group_statistics(user=user, group=group):
|
user=user, exclude_course_ids=statistics_dashboard_course_ids
|
||||||
course = group.course
|
)
|
||||||
course_index.add(course)
|
|
||||||
dashboards.append(
|
|
||||||
{
|
|
||||||
"id": str(course.id),
|
|
||||||
"name": course.title,
|
|
||||||
"dashboard_type": DashboardType.STATISTICS_DASHBOARD,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
for course_session in CourseSession.objects.exclude(course__in=course_index):
|
return statistic_dashboards + course_session_dashboards
|
||||||
course = course_session.course
|
|
||||||
if can_view_course_session(user=user, course_session=course_session):
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return dashboards
|
|
||||||
|
def get_user_statistics_dashboards(user: User) -> Tuple[List[Dict[str, str]], Set[int]]:
|
||||||
|
course_index = set()
|
||||||
|
dashboards = []
|
||||||
|
|
||||||
|
for group in CourseSessionGroup.objects.all():
|
||||||
|
if can_view_course_session_group_statistics(user=user, group=group):
|
||||||
|
course = group.course
|
||||||
|
course_index.add(course)
|
||||||
|
dashboards.append(
|
||||||
|
{
|
||||||
|
"id": str(course.id),
|
||||||
|
"name": course.title,
|
||||||
|
"dashboard_type": DashboardType.STATISTICS_DASHBOARD,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
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": resolved_dashboard_type,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return dashboards
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,35 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
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_3, _ = create_course("Test Course 3")
|
||||||
|
|
||||||
cs_1 = create_course_session(course=course_1, title="Test Course 1 Session")
|
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")
|
cs_2 = create_course_session(course=course_2, title="Test Course 2 Session")
|
||||||
|
|
||||||
# Member of course 1 (via cs_1)
|
cs_3_a = create_course_session(course=course_3, title="CS 3 A (as member)")
|
||||||
# Supervisor of course 2 (via cs_2)
|
cs_3_b = create_course_session(course=course_3, title="CS 3 B (as expert)")
|
||||||
|
|
||||||
supervisor = create_user("supervisor")
|
supervisor = create_user("supervisor")
|
||||||
|
|
||||||
|
# CS 1
|
||||||
add_course_session_user(
|
add_course_session_user(
|
||||||
course_session=cs_1, user=supervisor, role=CourseSessionUser.Role.MEMBER
|
course_session=cs_1, user=supervisor, role=CourseSessionUser.Role.MEMBER
|
||||||
)
|
)
|
||||||
|
|
||||||
group = create_course_session_group(course_session=cs_2)
|
# CS 2
|
||||||
add_course_session_group_supervisor(group=group, user=supervisor)
|
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)
|
self.client.force_login(supervisor)
|
||||||
|
|
||||||
|
|
@ -58,7 +73,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(course_1_config)
|
self.assertIsNotNone(course_1_config)
|
||||||
self.assertEqual(course_1_config["name"], course_1.title)
|
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(
|
course_2_config = find_dashboard_config_by_course_id(
|
||||||
dashboard_config, course_2.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["name"], course_2.title)
|
||||||
self.assertEqual(course_2_config["dashboard_type"], "STATISTICS_DASHBOARD")
|
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):
|
def test_course_statistics_deny_not_allowed_user(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
disallowed_user = create_user("1337_hacker_schorsch")
|
disallowed_user = create_user("1337_hacker_schorsch")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue