chore: add course progress for progress dashboard
This commit is contained in:
parent
a97628c28c
commit
2908e3cbf0
|
|
@ -9,11 +9,11 @@ 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 (
|
||||||
CourseStatisticsType,
|
CourseStatisticsType,
|
||||||
DashboardConfigType,
|
DashboardConfigType,
|
||||||
DashboardType,
|
DashboardType, CourseProgressType,
|
||||||
)
|
)
|
||||||
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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,6 +21,11 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
course_statistics = graphene.Field(
|
course_statistics = graphene.Field(
|
||||||
CourseStatisticsType, course_id=graphene.ID(required=True)
|
CourseStatisticsType, course_id=graphene.ID(required=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
course_progress = graphene.Field(
|
||||||
|
CourseProgressType, course_id=graphene.ID(required=True)
|
||||||
|
)
|
||||||
|
|
||||||
dashboard_config = graphene.List(
|
dashboard_config = graphene.List(
|
||||||
graphene.NonNull(DashboardConfigType), required=True
|
graphene.NonNull(DashboardConfigType), required=True
|
||||||
)
|
)
|
||||||
|
|
@ -60,6 +65,30 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
|
|
||||||
return statistic_dashboards + course_session_dashboards
|
return statistic_dashboards + course_session_dashboards
|
||||||
|
|
||||||
|
def resolve_course_progress(root, info, course_id: str): # noqa
|
||||||
|
"""
|
||||||
|
Slightly fragile but could be good enough: most only have one
|
||||||
|
course session per course anyway but if there are multiple, we
|
||||||
|
just pick the newest one (by generation) as best guess.
|
||||||
|
"""
|
||||||
|
|
||||||
|
user = info.context.user
|
||||||
|
newest: CourseSession | None = None
|
||||||
|
|
||||||
|
for course_session in CourseSession.objects.filter(course_id=course_id):
|
||||||
|
if can_view_course_session_progress(user=user, course_session=course_session):
|
||||||
|
generation_newest = newest.generation if newest else None
|
||||||
|
if generation_newest is None or course_session.generation > generation_newest:
|
||||||
|
newest = course_session
|
||||||
|
|
||||||
|
if not newest:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return CourseProgressType(
|
||||||
|
id=course_id, # noqa
|
||||||
|
session_to_continue_id=newest.id # noqa
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_user_statistics_dashboards(user: User) -> Tuple[List[Dict[str, str]], Set[int]]:
|
def get_user_statistics_dashboards(user: User) -> Tuple[List[Dict[str, str]], Set[int]]:
|
||||||
course_index = set()
|
course_index = set()
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,19 @@ class DashboardType(Enum):
|
||||||
|
|
||||||
|
|
||||||
class DashboardConfigType(graphene.ObjectType):
|
class DashboardConfigType(graphene.ObjectType):
|
||||||
id = graphene.ID(required=True)
|
id = graphene.ID(required=True) # course_id, named id for urql
|
||||||
name = graphene.String(required=True)
|
name = graphene.String(required=True)
|
||||||
slug = graphene.String(required=True)
|
slug = graphene.String(required=True)
|
||||||
dashboard_type = graphene.Field(DashboardType, required=True)
|
dashboard_type = graphene.Field(DashboardType, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
class CourseProgressType(graphene.ObjectType):
|
||||||
|
id = graphene.ID(required=True) # course_id, named id for urql
|
||||||
|
session_to_continue_id = graphene.ID(required=True)
|
||||||
|
|
||||||
|
|
||||||
class CourseStatisticsType(graphene.ObjectType):
|
class CourseStatisticsType(graphene.ObjectType):
|
||||||
id = graphene.ID(required=True)
|
id = graphene.ID(required=True) # course_id, named id for urql
|
||||||
course_title = graphene.String(required=True)
|
course_title = graphene.String(required=True)
|
||||||
course_session_properties = graphene.Field(CourseSessionProperties, required=True)
|
course_session_properties = graphene.Field(CourseSessionProperties, required=True)
|
||||||
course_session_selection_ids = graphene.List(graphene.ID, required=True)
|
course_session_selection_ids = graphene.List(graphene.ID, required=True)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,55 @@ 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_progress(self):
|
||||||
|
# GIVEN
|
||||||
|
course, _ = create_course("Test Course")
|
||||||
|
|
||||||
|
cs_1 = create_course_session(
|
||||||
|
course=course, title="Test Course Session 1", generation=""
|
||||||
|
)
|
||||||
|
cs_2 = create_course_session(
|
||||||
|
course=course, title="Test Course Session 2", generation="2020"
|
||||||
|
)
|
||||||
|
cs_3 = create_course_session(
|
||||||
|
course=course, title="Test Course Session 3", generation="1984"
|
||||||
|
)
|
||||||
|
|
||||||
|
member = create_user("sepp")
|
||||||
|
|
||||||
|
add_course_session_user(
|
||||||
|
course_session=cs_1, user=member, role=CourseSessionUser.Role.MEMBER
|
||||||
|
)
|
||||||
|
add_course_session_user(
|
||||||
|
course_session=cs_2, user=member, role=CourseSessionUser.Role.MEMBER
|
||||||
|
)
|
||||||
|
add_course_session_user(
|
||||||
|
course_session=cs_3, user=member, role=CourseSessionUser.Role.MEMBER
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client.force_login(member)
|
||||||
|
|
||||||
|
query = f"""query($course_id: ID!) {{
|
||||||
|
course_progress(course_id: $course_id) {{
|
||||||
|
id
|
||||||
|
session_to_continue_id
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
|
||||||
|
variables = {"course_id": str(course.id)}
|
||||||
|
|
||||||
|
# WHEN
|
||||||
|
response = self.query(query, variables=variables)
|
||||||
|
|
||||||
|
# THEN
|
||||||
|
self.assertResponseNoErrors(response)
|
||||||
|
|
||||||
|
course_progress = response.json()["data"]["course_progress"]
|
||||||
|
|
||||||
|
self.assertEqual(course_progress["id"], str(course.id))
|
||||||
|
self.assertEqual(course_progress["session_to_continue_id"], str(cs_2.id))
|
||||||
|
|
||||||
def test_dashboard_config(self):
|
def test_dashboard_config(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
course_1, _ = create_course("Test Course 1")
|
course_1, _ = create_course("Test Course 1")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue