chore: expose selection metrics (participant / session / expert count)
This commit is contained in:
parent
067c7ac20d
commit
d41bdf84e3
|
|
@ -1,6 +1,6 @@
|
||||||
import graphene
|
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.assignment import Assignments, assignments
|
||||||
from vbv_lernwelt.dashboard.graphql.types.attendance import (
|
from vbv_lernwelt.dashboard.graphql.types.attendance import (
|
||||||
attendance_day_presences,
|
attendance_day_presences,
|
||||||
|
|
@ -25,6 +25,12 @@ class CircleData(graphene.ObjectType):
|
||||||
experts = graphene.List(graphene.String)
|
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):
|
class CourseSessionProperties(graphene.ObjectType):
|
||||||
sessions = graphene.List(CourseSessionData)
|
sessions = graphene.List(CourseSessionData)
|
||||||
generations = graphene.List(graphene.String)
|
generations = graphene.List(graphene.String)
|
||||||
|
|
@ -40,8 +46,9 @@ class DashboardConfigType(graphene.ObjectType):
|
||||||
class CourseStatisticsType(graphene.ObjectType):
|
class CourseStatisticsType(graphene.ObjectType):
|
||||||
course_id = graphene.ID()
|
course_id = graphene.ID()
|
||||||
course_title = graphene.String()
|
course_title = graphene.String()
|
||||||
course_session_selection_ids = graphene.List(graphene.ID)
|
|
||||||
course_session_properties = graphene.Field(CourseSessionProperties)
|
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)
|
attendance_day_presences = graphene.Field(AttendanceDayPresences)
|
||||||
feedback_responses = graphene.Field(FeedbackResponses)
|
feedback_responses = graphene.Field(FeedbackResponses)
|
||||||
assignments = graphene.Field(Assignments)
|
assignments = graphene.Field(Assignments)
|
||||||
|
|
@ -59,15 +66,39 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
def resolve_assignments(root, info) -> Assignments:
|
def resolve_assignments(root, info) -> Assignments:
|
||||||
return assignments(root.course_session_selection_ids)
|
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):
|
def resolve_course_session_properties(root, info):
|
||||||
course_session_data = []
|
course_session_data = []
|
||||||
circle_data = []
|
circle_data = []
|
||||||
generations = set()
|
generations = set()
|
||||||
|
|
||||||
# TODO: Use course session group app to get all
|
|
||||||
# relevant course sessions for info.context.user
|
|
||||||
|
|
||||||
course_sessions = CourseSession.objects.filter(
|
course_sessions = CourseSession.objects.filter(
|
||||||
|
id__in=root.course_session_selection_ids,
|
||||||
course_id=root.course_id,
|
course_id=root.course_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
|
||||||
create_course_session_edoniq_test,
|
create_course_session_edoniq_test,
|
||||||
create_user,
|
create_user,
|
||||||
create_course_session_group,
|
create_course_session_group,
|
||||||
|
add_course_session_group_supervisor,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.learnpath.models import Circle
|
from vbv_lernwelt.learnpath.models import Circle
|
||||||
|
|
||||||
|
|
@ -62,9 +63,8 @@ class AssignmentTestCase(GraphQLTestCase):
|
||||||
|
|
||||||
self.supervisor = create_user("supervisor")
|
self.supervisor = create_user("supervisor")
|
||||||
|
|
||||||
create_course_session_group(
|
group = create_course_session_group(course_session=self.course_session)
|
||||||
course_session=self.course_session, user=self.supervisor
|
add_course_session_group_supervisor(group=group, user=self.supervisor)
|
||||||
)
|
|
||||||
|
|
||||||
self.m1 = create_user("member_1")
|
self.m1 = create_user("member_1")
|
||||||
add_course_session_user(
|
add_course_session_user(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
|
||||||
create_course_session,
|
create_course_session,
|
||||||
create_user,
|
create_user,
|
||||||
create_course_session_group,
|
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")
|
course_session = create_course_session(course=course, title="Test Bern 2022 a")
|
||||||
|
|
||||||
supervisor = create_user("supervisor")
|
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)
|
circle, _ = create_circle(title="Test Circle", course_page=course_page)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
|
||||||
create_performance_criteria_page,
|
create_performance_criteria_page,
|
||||||
create_user,
|
create_user,
|
||||||
create_course_session_group,
|
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")
|
course_session = create_course_session(course=course, title="Test Bern 2022 a")
|
||||||
|
|
||||||
supervisor = create_user("supervisor")
|
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")
|
member_one = create_user("member one")
|
||||||
add_course_session_user(
|
add_course_session_user(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
|
||||||
create_user,
|
create_user,
|
||||||
add_course_session_user,
|
add_course_session_user,
|
||||||
create_course_session_group,
|
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
|
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)
|
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["title"], course_2.title)
|
||||||
self.assertEqual(course_2_config["dashboard_type"], "StatisticsDashboard")
|
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
|
# GIVEN
|
||||||
disallowed_user = create_user("1337_hacker_schorsch")
|
disallowed_user = create_user("1337_hacker_schorsch")
|
||||||
course, _ = create_course("Test Course")
|
course, _ = create_course("Test Course")
|
||||||
|
|
@ -90,7 +92,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
course_statistics = response.json()["data"]["course_statistics"]
|
course_statistics = response.json()["data"]["course_statistics"]
|
||||||
self.assertEqual(course_statistics, None)
|
self.assertEqual(course_statistics, None)
|
||||||
|
|
||||||
def test_course_statistics_id(self):
|
def test_course_statistics_data(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
supervisor = create_user("supervisor")
|
supervisor = create_user("supervisor")
|
||||||
course_1, _ = create_course("Test Course 1")
|
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_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")
|
||||||
|
|
||||||
create_course_session_group(course_session=cs_1, user=supervisor)
|
cs_group_1 = create_course_session_group(course_session=cs_1)
|
||||||
create_course_session_group(course_session=cs_2, user=supervisor)
|
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)
|
self.client.force_login(supervisor)
|
||||||
|
|
||||||
query = f"""query($course_id: ID!) {{
|
query = f"""query($course_id: ID!) {{
|
||||||
course_statistics(course_id: $course_id) {{
|
course_statistics(course_id: $course_id) {{
|
||||||
course_id
|
course_id
|
||||||
|
course_title
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
@ -119,7 +125,9 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
self.assertResponseNoErrors(response)
|
self.assertResponseNoErrors(response)
|
||||||
|
|
||||||
course_statistics = response.json()["data"]["course_statistics"]
|
course_statistics = response.json()["data"]["course_statistics"]
|
||||||
|
|
||||||
self.assertEqual(course_statistics["course_id"], str(course_2.id))
|
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):
|
def find_dashboard_config_by_course_id(dashboard_configs, course_id):
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import (
|
||||||
create_course_session,
|
create_course_session,
|
||||||
create_user,
|
create_user,
|
||||||
create_course_session_group,
|
create_course_session_group,
|
||||||
|
add_course_session_group_supervisor,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.feedback.models import FeedbackResponse
|
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")
|
course_session = create_course_session(course=course, title="Test Bern 2022 a")
|
||||||
|
|
||||||
supervisor = create_user("supervisor")
|
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")
|
member = create_user("member")
|
||||||
add_course_session_user(
|
add_course_session_user(
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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(
|
return CourseSession.objects.create(
|
||||||
course=course,
|
course=course,
|
||||||
title=title,
|
title=title,
|
||||||
import_id=title,
|
import_id=title,
|
||||||
generation="2023",
|
generation=generation,
|
||||||
start_date=timezone.now(),
|
start_date=timezone.now(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -100,17 +102,24 @@ def add_course_session_user(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_course_session_group(
|
def create_course_session_group(course_session: CourseSession) -> CourseSessionGroup:
|
||||||
course_session: CourseSession, user: User
|
group = CourseSessionGroup.objects.create(
|
||||||
) -> CourseSessionGroup:
|
|
||||||
g = CourseSessionGroup.objects.create(
|
|
||||||
course=course_session.course,
|
course=course_session.course,
|
||||||
)
|
)
|
||||||
|
|
||||||
g.course_session.add(course_session)
|
group.course_session.add(course_session)
|
||||||
g.supervisor.add(user)
|
|
||||||
|
|
||||||
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(
|
def create_circle(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue