diff --git a/server/vbv_lernwelt/dashboard/graphql/queries.py b/server/vbv_lernwelt/dashboard/graphql/queries.py index ed398951..ad6400f5 100644 --- a/server/vbv_lernwelt/dashboard/graphql/queries.py +++ b/server/vbv_lernwelt/dashboard/graphql/queries.py @@ -1,12 +1,12 @@ import graphene from vbv_lernwelt.course.models import Course, CourseSessionUser -from vbv_lernwelt.dashboard.graphql.types import CourseDashboardType +from vbv_lernwelt.dashboard.graphql.types.attendance import CourseDashboardType class DashboardQuery(graphene.ObjectType): course_dashboard = graphene.List( - CourseDashboardType, course_id=graphene.String(required=False) + CourseDashboardType, course_id=graphene.ID(required=False) ) def resolve_course_dashboard(root, info, course_id: str | None = None): diff --git a/server/vbv_lernwelt/dashboard/graphql/types/__init__.py b/server/vbv_lernwelt/dashboard/graphql/types/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/dashboard/graphql/types.py b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py similarity index 88% rename from server/vbv_lernwelt/dashboard/graphql/types.py rename to server/vbv_lernwelt/dashboard/graphql/types/attendance.py index 72fa81fd..4afff8be 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py @@ -10,26 +10,15 @@ from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus from vbv_lernwelt.notify.email.email_services import format_swiss_datetime -class CircleDashboardType(graphene.ObjectType): - circle_id = graphene.String() - circle_title = graphene.String() - - -class CourseSessionDashboardType(graphene.ObjectType): - session_id = graphene.String() - session_title = graphene.String() - session_generation = graphene.String() - - class AttendanceSummary(graphene.ObjectType): days_completed = graphene.Int() participants_present = graphene.Int() class Record(graphene.ObjectType): - course_session_id = graphene.String() + course_session_id = graphene.ID() generation = graphene.String() - circle_id = graphene.String() + circle_id = graphene.ID() due_date = graphene.String() participants_present = graphene.Int() participants_total = graphene.Int() @@ -60,7 +49,6 @@ def calculate_avg_participation(records: List[Record]) -> float: class CourseDashboardType(graphene.ObjectType): course_id = graphene.String() course_title = graphene.String() - # course_sessions = graphene.List(CourseSessionDashboardType) attendance_day_presences = graphene.Field(AttendanceDayPresences) def resolve_attendance_day_presences(root, info): @@ -69,6 +57,7 @@ class CourseDashboardType(graphene.ObjectType): course_session__coursesessionuser__user=user, course_session__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, due_date__end__lt=datetime.datetime.now(), + course_session__course_id=root.course_id, ).order_by("-due_date__end") _filter = {} diff --git a/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py new file mode 100644 index 00000000..752c23f2 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py @@ -0,0 +1,7 @@ +import graphene + + +class CourseSessionDashboardType(graphene.ObjectType): + session_id = graphene.ID() + session_title = graphene.String() + session_generation = graphene.String() diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/__init__.py b/server/vbv_lernwelt/dashboard/tests/graphql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py new file mode 100644 index 00000000..6c3d62f9 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py @@ -0,0 +1,125 @@ +from datetime import timedelta + +from django.utils import timezone +from graphene_django.utils import GraphQLTestCase + +from vbv_lernwelt.course.models import CourseSessionUser +from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus +from vbv_lernwelt.dashboard.tests.graphql.utils import ( + add_course_session_user, + create_attendance_course, + create_circle, + create_course, + create_course_session, + create_user, +) + + +class DashboardTestCase(GraphQLTestCase): + GRAPHQL_URL = "/server/graphql/" + + def test_attendance_day_presences(self): + # GIVEN + course, course_page = create_course("Test Course") + course_session = create_course_session(course=course, title="Test Bern 2022 a") + + supervisor = create_user("supervisor") + + add_course_session_user( + course_session=course_session, + user=supervisor, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + + circle, _ = create_circle(title="Test Circle", course_page=course_page) + + m1 = create_user("member_1") + add_course_session_user( + course_session=course_session, + user=m1, + role=CourseSessionUser.Role.MEMBER, + ) + + m2 = create_user("member_2") + add_course_session_user( + course_session=course_session, + user=m2, + role=CourseSessionUser.Role.MEMBER, + ) + + m3 = create_user("member_3") + add_course_session_user( + course_session=course_session, + user=m3, + role=CourseSessionUser.Role.MEMBER, + ) + + e1 = create_user("expert_1") + add_course_session_user( + course_session=course_session, + user=e1, + role=CourseSessionUser.Role.EXPERT, + ) + + attendance_user_list = [ + {"user_id": str(m1.id), "status": AttendanceUserStatus.PRESENT.value}, + {"user_id": str(m2.id), "status": AttendanceUserStatus.ABSENT.value}, + ] + + due_date_end = timezone.now() - timedelta(hours=2) + attendance_course = create_attendance_course( + course_session=course_session, + circle=circle, + attendance_user_list=attendance_user_list, + due_date_end=due_date_end, + ) + + self.client.force_login(supervisor) + + query = f""" + query($course_id: ID) {{ + course_dashboard(course_id: $course_id) {{ + attendance_day_presences{{ + summary{{ + days_completed + participants_present + }} + records{{ + course_session_id + generation + circle_id + due_date + participants_present + participants_total + cockpit_url + }} + }} + }} + }} + """ + + # WHEN + response = self.query(query, variables={"course_id": str(course.id)}) + + self.assertResponseNoErrors(response) + + data = response.json()["data"] + + attendance_day_presences = data["course_dashboard"][0][ + "attendance_day_presences" + ] + + record = attendance_day_presences["records"][0] + + self.assertEqual(record["course_session_id"], str(course_session.id)) + self.assertEqual(record["generation"], "2023") + self.assertEqual(record["participants_present"], 1) + self.assertEqual(record["participants_total"], 3) + self.assertEqual( + record["cockpit_url"], + f"/course/test-lehrgang/cockpit/attendance?id={attendance_course.learning_content.id}&courseSessionId={course_session.id}", + ) + + summary = attendance_day_presences["summary"] + self.assertEqual(summary["days_completed"], 1) + self.assertEqual(summary["participants_present"], 34) diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py new file mode 100644 index 00000000..f22bd6c3 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_dashboard.py @@ -0,0 +1,100 @@ +from graphene_django.utils import GraphQLTestCase + +from vbv_lernwelt.course.models import CourseSessionUser +from vbv_lernwelt.dashboard.tests.graphql.utils import ( + add_course_session_user, + create_course, + create_course_session, + create_user, +) + + +class DashboardTestCase(GraphQLTestCase): + GRAPHQL_URL = "/server/graphql/" + + def test_course_dashboard(self): + # GIVEN + supervisor = create_user("supervisor") + course, _ = create_course("Test Course") + course_session = create_course_session(course=course, title="Test Bern 2022 a") + add_course_session_user( + course_session=course_session, + user=supervisor, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + + some_course, _ = create_course("Other Course") + some_course_session = create_course_session( + course=some_course, title="Here is go study" + ) + add_course_session_user( + course_session=some_course_session, + user=supervisor, + role=CourseSessionUser.Role.MEMBER, + ) + + self.client.force_login(supervisor) + + query = f""" + query {{ + course_dashboard {{ + course_id + course_title + }} + }} + """ + + # WHEN + response = self.query(query) + + # THEN + self.assertResponseNoErrors(response) + + course_dashboard = response.json()["data"]["course_dashboard"] + + self.assertEqual(len(course_dashboard), 1) + self.assertEqual(course_dashboard[0]["course_id"], str(course.id)) + self.assertEqual(course_dashboard[0]["course_title"], str(course.title)) + + def test_course_dashboard_id(self): + # GIVEN + supervisor = create_user("supervisor") + course_1, _ = create_course("Test Course 1") + course_2, _ = create_course("Test Course 2") + course_session_1 = create_course_session( + course=course_1, title="Test Course 1 Session" + ) + course_session_2 = create_course_session( + course=course_2, title="Test Course 2 Session" + ) + add_course_session_user( + course_session=course_session_1, + user=supervisor, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + add_course_session_user( + course_session=course_session_2, + user=supervisor, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + + self.client.force_login(supervisor) + + query = f"""query($course_id: ID) {{ + course_dashboard(course_id: $course_id) {{ + course_id + }} + }} + """ + variables = {"course_id": str(course_2.id)} + + # WHEN + response = self.query(query, variables=variables) + + # THEN + self.assertResponseNoErrors(response) + + course_dashboard = response.json()["data"]["course_dashboard"] + + self.assertEqual(len(course_dashboard), 1) + self.assertEqual(course_dashboard[0]["course_id"], str(course_2.id)) diff --git a/server/vbv_lernwelt/dashboard/tests/utils.py b/server/vbv_lernwelt/dashboard/tests/graphql/utils.py similarity index 100% rename from server/vbv_lernwelt/dashboard/tests/utils.py rename to server/vbv_lernwelt/dashboard/tests/graphql/utils.py diff --git a/server/vbv_lernwelt/dashboard/tests/test_graphql.py b/server/vbv_lernwelt/dashboard/tests/test_graphql.py deleted file mode 100644 index bbafaa6d..00000000 --- a/server/vbv_lernwelt/dashboard/tests/test_graphql.py +++ /dev/null @@ -1,253 +0,0 @@ -from datetime import timedelta - -from django.utils import timezone -from graphene_django.utils import GraphQLTestCase - -from vbv_lernwelt.course.models import CourseSessionUser -from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus -from vbv_lernwelt.dashboard.tests.utils import ( - add_course_session_user, - create_attendance_course, - create_circle, - create_course, - create_course_session, - create_user, -) - - -class DashboardTestCase(GraphQLTestCase): - GRAPHQL_URL = "/server/graphql/" - - # def test_course_dashboard(self): - # # GIVEN - # supervisor = create_user("supervisor") - # course = create_course("Test Course") - # course_session = create_course_session( - # course=course, title="Test Bern 2022 a" - # ) - # add_course_session_user( - # course_session=course_session, - # user=supervisor, - # role=CourseSessionUser.Role.SESSION_SUPERVISOR, - # ) - # - # some_course = create_course("Other Course") - # some_course_session = create_course_session( - # course=some_course, title="Here is go study" - # ) - # add_course_session_user( - # course_session=some_course_session, - # user=supervisor, - # role=CourseSessionUser.Role.MEMBER, - # ) - # - # self.client.force_login(supervisor) - # - # query = f""" - # query {{ - # course_dashboard {{ - # course_id - # course_title - # }} - # }} - # """ - # - # # WHEN - # response = self.query(query) - # - # # THEN - # self.assertResponseNoErrors(response) - # - # course_dashboard = response.json()["data"]["course_dashboard"] - # - # self.assertEqual(len(course_dashboard), 1) - # self.assertEqual(course_dashboard[0]["course_id"], str(course.id)) - # self.assertEqual(course_dashboard[0]["course_title"], str(course.title)) - # - # def test_course_dashboard_id(self): - # # GIVEN - # supervisor = create_user("supervisor") - # course_1 = create_course("Test Course 1") - # course_2 = create_course("Test Course 2") - # course_session_1 = create_course_session( - # course=course_1, title="Test Course 1 Session" - # ) - # course_session_2 = create_course_session( - # course=course_2, title="Test Course 2 Session" - # ) - # add_course_session_user( - # course_session=course_session_1, - # user=supervisor, - # role=CourseSessionUser.Role.SESSION_SUPERVISOR, - # ) - # add_course_session_user( - # course_session=course_session_2, - # user=supervisor, - # role=CourseSessionUser.Role.SESSION_SUPERVISOR, - # ) - # - # self.client.force_login(supervisor) - # - # query = f"""query($course_id: String) {{ - # course_dashboard(course_id: $course_id) {{ - # course_id - # }} - # }} - # """ - # variables = {"course_id": str(course_2.id)} - # - # # WHEN - # response = self.query(query, variables=variables) - # - # # THEN - # self.assertResponseNoErrors(response) - # - # course_dashboard = response.json()["data"]["course_dashboard"] - # - # self.assertEqual(len(course_dashboard), 1) - # self.assertEqual(course_dashboard[0]["course_id"], str(course_2.id)) - # - # def test_course_dashboard_sessions(self): - # # GIVEN - # supervisor = create_user("supervisor") - # course = create_course("Test Course") - # course_session = create_course_session( - # course=course, title="Test Bern 2022 a" - # ) - # add_course_session_user( - # course_session=course_session, - # user=supervisor, - # role=CourseSessionUser.Role.SESSION_SUPERVISOR, - # ) - # - # self.client.force_login(supervisor) - # - # query = f""" - # query {{ - # course_dashboard {{ - # course_sessions{{ - # session_id - # session_title - # session_generation - # }} - # }} - # }} - # """ - # - # # WHEN - # response = self.query(query) - # - # # THEN - # self.assertResponseNoErrors(response) - # - # course_dashboard = response.json()["data"]["course_dashboard"][0] - # session = course_dashboard["course_sessions"][0] - # self.assertEqual(session["session_id"], str(course_session.id)) - # self.assertEqual(session["session_title"], str(course_session.title)) - # self.assertEqual(session["session_generation"], str(course_session.generation)) - - def test_attendance_day_presences(self): - # GIVEN - course, course_page = create_course("Test Course") - course_session = create_course_session(course=course, title="Test Bern 2022 a") - - supervisor = create_user("supervisor") - - add_course_session_user( - course_session=course_session, - user=supervisor, - role=CourseSessionUser.Role.SESSION_SUPERVISOR, - ) - - circle, _ = create_circle(title="Test Circle", course_page=course_page) - - m1 = create_user("member_1") - add_course_session_user( - course_session=course_session, - user=m1, - role=CourseSessionUser.Role.MEMBER, - ) - - m2 = create_user("member_2") - add_course_session_user( - course_session=course_session, - user=m2, - role=CourseSessionUser.Role.MEMBER, - ) - - m3 = create_user("member_3") - add_course_session_user( - course_session=course_session, - user=m3, - role=CourseSessionUser.Role.MEMBER, - ) - - e1 = create_user("expert_1") - add_course_session_user( - course_session=course_session, - user=e1, - role=CourseSessionUser.Role.EXPERT, - ) - - attendance_user_list = [ - {"user_id": str(m1.id), "status": AttendanceUserStatus.PRESENT.value}, - {"user_id": str(m2.id), "status": AttendanceUserStatus.ABSENT.value}, - ] - - due_date_end = timezone.now() - timedelta(hours=2) - attendance_course = create_attendance_course( - course_session=course_session, - circle=circle, - attendance_user_list=attendance_user_list, - due_date_end=due_date_end, - ) - - self.client.force_login(supervisor) - - query = f""" - query {{ - course_dashboard {{ - attendance_day_presences{{ - summary{{ - days_completed - participants_present - }} - records{{ - course_session_id - generation - circle_id - due_date - participants_present - participants_total - cockpit_url - }} - }} - }} - }} - """ - - # WHEN - response = self.query(query) - - self.assertResponseNoErrors(response) - - data = response.json()["data"] - - attendance_day_presences = data["course_dashboard"][0][ - "attendance_day_presences" - ] - - record = attendance_day_presences["records"][0] - - self.assertEqual(record["course_session_id"], str(course_session.id)) - self.assertEqual(record["generation"], "2023") - self.assertEqual(record["participants_present"], 1) - self.assertEqual(record["participants_total"], 3) - self.assertEqual( - record["cockpit_url"], - f"/course/test-lehrgang/cockpit/attendance?id={attendance_course.learning_content.id}&courseSessionId={course_session.id}", - ) - - summary = attendance_day_presences["summary"] - self.assertEqual(summary["days_completed"], 1) - self.assertEqual(summary["participants_present"], 34)