chore: expose selection metrics (participant / session / expert count)

This commit is contained in:
Livio Bieri 2023-10-24 17:02:19 +02:00
parent 067c7ac20d
commit d41bdf84e3
8 changed files with 182 additions and 25 deletions

View File

@ -1,6 +1,6 @@
import graphene
from vbv_lernwelt.course.models import CourseSession
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.dashboard.graphql.types.assignment import Assignments, assignments
from vbv_lernwelt.dashboard.graphql.types.attendance import (
attendance_day_presences,
@ -25,6 +25,12 @@ class CircleData(graphene.ObjectType):
experts = graphene.List(graphene.String)
class CourseSessionsSelectionMetrics(graphene.ObjectType):
session_count = graphene.Int(required=True)
participant_count = graphene.Int(required=True)
expert_count = graphene.Int(required=True)
class CourseSessionProperties(graphene.ObjectType):
sessions = graphene.List(CourseSessionData)
generations = graphene.List(graphene.String)
@ -40,8 +46,9 @@ class DashboardConfigType(graphene.ObjectType):
class CourseStatisticsType(graphene.ObjectType):
course_id = graphene.ID()
course_title = graphene.String()
course_session_selection_ids = graphene.List(graphene.ID)
course_session_properties = graphene.Field(CourseSessionProperties)
course_session_selection_ids = graphene.List(graphene.ID)
course_session_selection_metrics = graphene.Field(CourseSessionsSelectionMetrics)
attendance_day_presences = graphene.Field(AttendanceDayPresences)
feedback_responses = graphene.Field(FeedbackResponses)
assignments = graphene.Field(Assignments)
@ -59,15 +66,39 @@ class CourseStatisticsType(graphene.ObjectType):
def resolve_assignments(root, info) -> Assignments:
return assignments(root.course_session_selection_ids)
def resolve_course_session_selection_metrics(
root, info
) -> CourseSessionsSelectionMetrics:
course_session_count = CourseSession.objects.filter(
id__in=root.course_session_selection_ids,
course_id=root.course_id,
).count()
expert_count = CourseSession.objects.filter(
id__in=root.course_session_selection_ids,
course_id=root.course_id,
coursesessionuser__role=CourseSessionUser.Role.EXPERT,
).count()
participant_count = CourseSession.objects.filter(
id__in=root.course_session_selection_ids,
course_id=root.course_id,
coursesessionuser__role=CourseSessionUser.Role.MEMBER,
).count()
return CourseSessionsSelectionMetrics(
session_count=course_session_count, # noqa
participant_count=participant_count, # noqa
expert_count=expert_count, # noqa
)
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(
id__in=root.course_session_selection_ids,
course_id=root.course_id,
)

View File

@ -21,6 +21,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_course_session_edoniq_test,
create_user,
create_course_session_group,
add_course_session_group_supervisor,
)
from vbv_lernwelt.learnpath.models import Circle
@ -62,9 +63,8 @@ class AssignmentTestCase(GraphQLTestCase):
self.supervisor = create_user("supervisor")
create_course_session_group(
course_session=self.course_session, user=self.supervisor
)
group = create_course_session_group(course_session=self.course_session)
add_course_session_group_supervisor(group=group, user=self.supervisor)
self.m1 = create_user("member_1")
add_course_session_user(

View File

@ -13,6 +13,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_course_session,
create_user,
create_course_session_group,
add_course_session_group_supervisor,
)
@ -25,7 +26,9 @@ class DashboardAttendanceTestCase(GraphQLTestCase):
course_session = create_course_session(course=course, title="Test Bern 2022 a")
supervisor = create_user("supervisor")
create_course_session_group(course_session=course_session, user=supervisor)
group = create_course_session_group(course_session=course_session)
add_course_session_group_supervisor(group=group, user=supervisor)
circle, _ = create_circle(title="Test Circle", course_page=course_page)

View File

@ -10,6 +10,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_performance_criteria_page,
create_user,
create_course_session_group,
add_course_session_group_supervisor,
)
@ -22,7 +23,8 @@ class DashboardCompetenceTestCase(GraphQLTestCase):
course_session = create_course_session(course=course, title="Test Bern 2022 a")
supervisor = create_user("supervisor")
create_course_session_group(course_session=course_session, user=supervisor)
group = create_course_session_group(course_session=course_session)
add_course_session_group_supervisor(group=group, user=supervisor)
member_one = create_user("member one")
add_course_session_user(

View File

@ -7,6 +7,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_user,
add_course_session_user,
create_course_session_group,
add_course_session_group_supervisor,
)
@ -29,7 +30,8 @@ class DashboardTestCase(GraphQLTestCase):
course_session=cs_1, user=supervisor, role=CourseSessionUser.Role.MEMBER
)
create_course_session_group(course_session=cs_2, user=supervisor)
group = create_course_session_group(course_session=cs_2)
add_course_session_group_supervisor(group=group, user=supervisor)
self.client.force_login(supervisor)
@ -65,7 +67,7 @@ class DashboardTestCase(GraphQLTestCase):
self.assertEqual(course_2_config["title"], course_2.title)
self.assertEqual(course_2_config["dashboard_type"], "StatisticsDashboard")
def test_course_statistics_deny_not_allowed_users(self):
def test_course_statistics_deny_not_allowed_user(self):
# GIVEN
disallowed_user = create_user("1337_hacker_schorsch")
course, _ = create_course("Test Course")
@ -90,7 +92,7 @@ class DashboardTestCase(GraphQLTestCase):
course_statistics = response.json()["data"]["course_statistics"]
self.assertEqual(course_statistics, None)
def test_course_statistics_id(self):
def test_course_statistics_data(self):
# GIVEN
supervisor = create_user("supervisor")
course_1, _ = create_course("Test Course 1")
@ -99,14 +101,18 @@ class DashboardTestCase(GraphQLTestCase):
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")
create_course_session_group(course_session=cs_1, user=supervisor)
create_course_session_group(course_session=cs_2, user=supervisor)
cs_group_1 = create_course_session_group(course_session=cs_1)
add_course_session_group_supervisor(group=cs_group_1, user=supervisor)
cs_group_2 = create_course_session_group(course_session=cs_2)
add_course_session_group_supervisor(group=cs_group_2, user=supervisor)
self.client.force_login(supervisor)
query = f"""query($course_id: ID!) {{
course_statistics(course_id: $course_id) {{
course_id
course_title
}}
}}
"""
@ -119,7 +125,9 @@ class DashboardTestCase(GraphQLTestCase):
self.assertResponseNoErrors(response)
course_statistics = response.json()["data"]["course_statistics"]
self.assertEqual(course_statistics["course_id"], str(course_2.id))
self.assertEqual(course_statistics["course_title"], course_2.title)
def find_dashboard_config_by_course_id(dashboard_configs, course_id):

View File

@ -8,6 +8,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_course_session,
create_user,
create_course_session_group,
add_course_session_group_supervisor,
)
from vbv_lernwelt.feedback.models import FeedbackResponse
@ -21,7 +22,9 @@ class DashboardFeedbackTestCase(GraphQLTestCase):
course_session = create_course_session(course=course, title="Test Bern 2022 a")
supervisor = create_user("supervisor")
create_course_session_group(course_session=course_session, user=supervisor)
group = create_course_session_group(course_session=course_session)
add_course_session_group_supervisor(group=group, user=supervisor)
member = create_user("member")
add_course_session_user(

View File

@ -0,0 +1,101 @@
from graphene_django.utils import GraphQLTestCase
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.dashboard.tests.graphql.utils import (
create_course,
create_course_session,
create_user,
add_course_session_user,
create_course_session_group,
add_course_session_group_supervisor,
add_course_session_group_course_session,
)
class DashboardTestCase(GraphQLTestCase):
GRAPHQL_URL = "/server/graphql/"
def test_selection_metrics(self):
# GIVEN
course_1, _ = create_course("Test Course 1")
course_2, _ = create_course("Dummy Course 2")
cs_1_a = create_course_session(course=course_1, title="Zug", generation="1984")
cs_1_b = create_course_session(course=course_1, title="Bern", generation="1984")
cs_1_c = create_course_session(course=course_1, title="Wil", generation="1984")
cs_2_a = create_course_session(course=course_2, title="Baar", generation="1984")
member_1 = create_user("member_1")
member_2 = create_user("member_2")
member_3 = create_user("member_3")
member_4 = create_user("member_4")
expert_1 = create_user("expert_1")
expert_2 = create_user("expert_2")
expert_3 = create_user("expert_3")
expert_4 = create_user("expert_4")
# CS 1 A
add_course_session_user(
course_session=cs_1_a, user=member_1, role=CourseSessionUser.Role.MEMBER
)
add_course_session_user(
course_session=cs_1_b, user=member_2, role=CourseSessionUser.Role.MEMBER
)
# CS 1 B
add_course_session_user(
course_session=cs_1_a, user=expert_1, role=CourseSessionUser.Role.EXPERT
)
add_course_session_user(
course_session=cs_1_b, user=expert_2, role=CourseSessionUser.Role.EXPERT
)
# CS 1 C
add_course_session_user(
course_session=cs_1_c, user=member_3, role=CourseSessionUser.Role.MEMBER
)
add_course_session_user(
course_session=cs_1_c, user=expert_3, role=CourseSessionUser.Role.EXPERT
)
# CS 2 A
add_course_session_user(
course_session=cs_2_a, user=member_4, role=CourseSessionUser.Role.MEMBER
)
add_course_session_user(
course_session=cs_2_a, user=expert_4, role=CourseSessionUser.Role.EXPERT
)
# SUPERVISOR of course 1, session a and b BUT NOT
# of course 1, session c or course 2, session a
cs_1_ab_supervisor = create_user("supervisor")
group = create_course_session_group(course_session=cs_1_a)
add_course_session_group_course_session(course_session=cs_1_b, group=group)
add_course_session_group_supervisor(group=group, user=cs_1_ab_supervisor)
self.client.force_login(cs_1_ab_supervisor)
# WHEN
query = f"""query($course_id: ID!) {{
course_statistics(course_id: $course_id) {{
course_session_selection_metrics {{
expert_count
participant_count
session_count
}}
}}
}}"""
variables = {"course_id": str(course_1.id)}
response = self.query(query, variables=variables)
# THEN
self.assertResponseNoErrors(response)
metrics = response.json()["data"]["course_statistics"][
"course_session_selection_metrics"
]
self.assertEqual(metrics["expert_count"], 2)
self.assertEqual(metrics["participant_count"], 2)
self.assertEqual(metrics["session_count"], 2)

View File

@ -80,12 +80,14 @@ def create_user(username: str) -> User:
)
def create_course_session(course: Course, title: str) -> CourseSession:
def create_course_session(
course: Course, title: str, generation: str = "2023"
) -> CourseSession:
return CourseSession.objects.create(
course=course,
title=title,
import_id=title,
generation="2023",
generation=generation,
start_date=timezone.now(),
)
@ -100,17 +102,24 @@ def add_course_session_user(
)
def create_course_session_group(
course_session: CourseSession, user: User
) -> CourseSessionGroup:
g = CourseSessionGroup.objects.create(
def create_course_session_group(course_session: CourseSession) -> CourseSessionGroup:
group = CourseSessionGroup.objects.create(
course=course_session.course,
)
g.course_session.add(course_session)
g.supervisor.add(user)
group.course_session.add(course_session)
return g
return group
def add_course_session_group_supervisor(group: CourseSessionGroup, user: User):
group.supervisor.add(user)
def add_course_session_group_course_session(
group: CourseSessionGroup, course_session: CourseSession
):
group.course_session.add(course_session)
def create_circle(