From 90a8f851d221a1660d9002050e3a48d7dc602dfc Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Mon, 16 Oct 2023 09:23:25 +0200 Subject: [PATCH] feat: add dashboard API --- server/vbv_lernwelt/core/schema.py | 2 + server/vbv_lernwelt/course/models.py | 1 + server/vbv_lernwelt/dashboard/__init__.py | 0 .../dashboard/graphql/__init__.py | 0 .../vbv_lernwelt/dashboard/graphql/queries.py | 20 ++++++ .../vbv_lernwelt/dashboard/graphql/types.py | 16 +++++ .../vbv_lernwelt/dashboard/tests/__init__.py | 0 .../dashboard/tests/test_graphql.py | 61 +++++++++++++++++++ server/vbv_lernwelt/dashboard/tests/utils.py | 42 +++++++++++++ 9 files changed, 142 insertions(+) create mode 100644 server/vbv_lernwelt/dashboard/__init__.py create mode 100644 server/vbv_lernwelt/dashboard/graphql/__init__.py create mode 100644 server/vbv_lernwelt/dashboard/graphql/queries.py create mode 100644 server/vbv_lernwelt/dashboard/graphql/types.py create mode 100644 server/vbv_lernwelt/dashboard/tests/__init__.py create mode 100644 server/vbv_lernwelt/dashboard/tests/test_graphql.py create mode 100644 server/vbv_lernwelt/dashboard/tests/utils.py diff --git a/server/vbv_lernwelt/core/schema.py b/server/vbv_lernwelt/core/schema.py index c336e533..be4de6f0 100644 --- a/server/vbv_lernwelt/core/schema.py +++ b/server/vbv_lernwelt/core/schema.py @@ -6,6 +6,7 @@ from vbv_lernwelt.competence.graphql.queries import CompetenceCertificateQuery from vbv_lernwelt.course.graphql.queries import CourseQuery from vbv_lernwelt.course_session.graphql.mutations import CourseSessionMutation from vbv_lernwelt.course_session.graphql.queries import CourseSessionQuery +from vbv_lernwelt.dashboard.graphql.queries import DashboardQuery from vbv_lernwelt.feedback.graphql.mutations import FeedbackMutation from vbv_lernwelt.learnpath.graphql.queries import LearningPathQuery @@ -16,6 +17,7 @@ class Query( CourseQuery, CourseSessionQuery, LearningPathQuery, + DashboardQuery, graphene.ObjectType, ): pass diff --git a/server/vbv_lernwelt/course/models.py b/server/vbv_lernwelt/course/models.py index 4b6b1c2d..f735998f 100644 --- a/server/vbv_lernwelt/course/models.py +++ b/server/vbv_lernwelt/course/models.py @@ -266,6 +266,7 @@ class CourseSessionUser(models.Model): class Role(models.TextChoices): MEMBER = "MEMBER", _("Teilnehmer") EXPERT = "EXPERT", _("Experte/Trainer") + SESSION_SUPERVISOR = "SESSION_SUPERVISOR", _("Regionalleiter") TUTOR = "TUTOR", _("Lernbegleitung") role = models.CharField(choices=Role.choices, max_length=255, default=Role.MEMBER) diff --git a/server/vbv_lernwelt/dashboard/__init__.py b/server/vbv_lernwelt/dashboard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/dashboard/graphql/__init__.py b/server/vbv_lernwelt/dashboard/graphql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/dashboard/graphql/queries.py b/server/vbv_lernwelt/dashboard/graphql/queries.py new file mode 100644 index 00000000..d245b20a --- /dev/null +++ b/server/vbv_lernwelt/dashboard/graphql/queries.py @@ -0,0 +1,20 @@ +import graphene + +from vbv_lernwelt.course.models import Course, CourseSessionUser +from vbv_lernwelt.dashboard.graphql.types import CourseDashboardType + + +class DashboardQuery(graphene.ObjectType): + course_dashboard = graphene.List(CourseDashboardType) + + def resolve_course_dashboard(root, info, course_id: str | None = None): + user = info.context.user + courses = Course.objects.filter( + coursesession__coursesessionuser__user=user, + coursesession__coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ).distinct() + + return [ + CourseDashboardType(course_id=course.id, course_title=course.title) + for course in courses + ] diff --git a/server/vbv_lernwelt/dashboard/graphql/types.py b/server/vbv_lernwelt/dashboard/graphql/types.py new file mode 100644 index 00000000..e22c2489 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/graphql/types.py @@ -0,0 +1,16 @@ +import graphene + + +class CourseSessionDashboardType(graphene.ObjectType): + session_id = graphene.String() + + +class CourseDashboardType(graphene.ObjectType): + course_id = graphene.String() + course_title = graphene.String() + course_sessions = graphene.List(CourseSessionDashboardType) + + def resolve_course_sessions(self, info): + session = [] + + return [CourseSessionDashboardType() for s in session] diff --git a/server/vbv_lernwelt/dashboard/tests/__init__.py b/server/vbv_lernwelt/dashboard/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/dashboard/tests/test_graphql.py b/server/vbv_lernwelt/dashboard/tests/test_graphql.py new file mode 100644 index 00000000..de399939 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/tests/test_graphql.py @@ -0,0 +1,61 @@ +from graphene_django.utils import GraphQLTestCase + +from vbv_lernwelt.course.models import CourseSessionUser +from vbv_lernwelt.dashboard.tests.utils import ( + add_course_session_user, + create_course, + create_course_session, + create_user, +) + + +class DashboardTestCase(GraphQLTestCase): + GRAPHQL_URL = "/server/graphql/" + + def setUp(self): + self.trainer = create_user("supervisor") + self.course = create_course("Test Course") + self.course_session = create_course_session( + course=self.course, title="Test Bern 2022 a" + ) + add_course_session_user( + course_session=self.course_session, + user=self.trainer, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + + def test_courses(self): + # GIVEN + 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=self.trainer, + role=CourseSessionUser.Role.MEMBER, + ) + + self.client.force_login(self.trainer) + + query = f""" + query {{ + course_dashboard {{ + course_id + course_sessions{{ + session_id + }} + }} + }} + """ + + # 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(self.course.id)) diff --git a/server/vbv_lernwelt/dashboard/tests/utils.py b/server/vbv_lernwelt/dashboard/tests/utils.py new file mode 100644 index 00000000..26f67be2 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/tests/utils.py @@ -0,0 +1,42 @@ +from django.contrib.auth.hashers import make_password +from django.utils import timezone +from django.utils.text import slugify + +from vbv_lernwelt.core.models import User +from vbv_lernwelt.course.models import Course, CourseSession, CourseSessionUser + + +def create_course(title: str) -> Course: + return Course.objects.create( + title=title, slug=slugify(title), category_name="Handlungsfeld" + ) + + +def create_user(username: str) -> User: + user = User.objects.create_user( + username="username", + password=make_password("test"), + email=f"{username}@example.com", + language="de", + ) + + return user + + +def create_course_session(course: Course, title: str) -> CourseSession: + return CourseSession.objects.create( + course=course, + title=title, + import_id=title, + start_date=timezone.now(), + ) + + +def add_course_session_user( + course_session: CourseSession, user: User, role: CourseSessionUser.Role +) -> CourseSessionUser: + return CourseSessionUser.objects.create( + course_session=course_session, + user=user, + role=role, + )