diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 158e17c7..2ffabbbf 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -127,6 +127,15 @@ export type CoursePageInterface = { translation_key?: Maybe; }; +export type CourseSessionAttendanceCourseType = { + __typename?: 'CourseSessionAttendanceCourseType'; + end?: Maybe; + id: Scalars['ID']; + location: Scalars['String']; + start?: Maybe; + trainer: Scalars['String']; +}; + export type CourseType = { __typename?: 'CourseType'; category_name: Scalars['String']['output']; @@ -216,6 +225,7 @@ export type Query = { assignment?: Maybe; assignment_completion?: Maybe; course?: Maybe; + course_session_attendance_course?: Maybe; }; @@ -236,6 +246,12 @@ export type QueryCourseArgs = { id?: InputMaybe; }; + +export type QueryCourse_Session_Attendance_CourseArgs = { + assignment_user_id?: InputMaybe; + id: Scalars['ID']; +}; + export type SendFeedbackInput = { clientMutationId?: InputMaybe; course_session: Scalars['Int']['input']; diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index ab93d32e..bc2d6843 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -1,9 +1,25 @@ type Query { + course_session_attendance_course(id: ID!, assignment_user_id: ID): CourseSessionAttendanceCourseType course(id: Int): CourseType assignment(id: ID, slug: String): AssignmentObjectType assignment_completion(assignment_id: ID!, course_session_id: ID!, assignment_user_id: ID): AssignmentCompletionObjectType } +type CourseSessionAttendanceCourseType { + id: ID! + location: String! + trainer: String! + end: DateTime + start: DateTime +} + +""" +The `DateTime` scalar type represents a DateTime +value as specified by +[iso8601](https://en.wikipedia.org/wiki/ISO_8601). +""" +scalar DateTime + type CourseType { id: ID! title: String! @@ -63,13 +79,6 @@ interface CoursePageInterface { frontend_url: String } -""" -The `DateTime` scalar type represents a DateTime -value as specified by -[iso8601](https://en.wikipedia.org/wiki/ISO_8601). -""" -scalar DateTime - type UserType { id: ID! diff --git a/server/vbv_lernwelt/core/schema.py b/server/vbv_lernwelt/core/schema.py index 69355e81..e2a2476e 100644 --- a/server/vbv_lernwelt/core/schema.py +++ b/server/vbv_lernwelt/core/schema.py @@ -3,10 +3,11 @@ import graphene from vbv_lernwelt.assignment.graphql.mutations import AssignmentMutation from vbv_lernwelt.assignment.graphql.queries import AssignmentQuery from vbv_lernwelt.course.schema import CourseQuery +from vbv_lernwelt.course_session.graphql.queries import CourseSessionQuery from vbv_lernwelt.feedback.graphql.mutations import FeedbackMutation -class Query(AssignmentQuery, CourseQuery, graphene.ObjectType): +class Query(AssignmentQuery, CourseQuery, CourseSessionQuery, graphene.ObjectType): pass diff --git a/server/vbv_lernwelt/course_session/graphql/__init__.py b/server/vbv_lernwelt/course_session/graphql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/course_session/graphql/mutations.py b/server/vbv_lernwelt/course_session/graphql/mutations.py new file mode 100644 index 00000000..24c280cd --- /dev/null +++ b/server/vbv_lernwelt/course_session/graphql/mutations.py @@ -0,0 +1,7 @@ +import structlog + +logger = structlog.get_logger(__name__) + + +class CourseSessionMutation: + pass diff --git a/server/vbv_lernwelt/course_session/graphql/queries.py b/server/vbv_lernwelt/course_session/graphql/queries.py new file mode 100644 index 00000000..66f61994 --- /dev/null +++ b/server/vbv_lernwelt/course_session/graphql/queries.py @@ -0,0 +1,41 @@ +import graphene +from rest_framework.exceptions import PermissionDenied + +from vbv_lernwelt.course.models import CourseSession +from vbv_lernwelt.course.permissions import has_course_access, is_course_session_expert +from vbv_lernwelt.course_session.graphql.types import CourseSessionAttendanceCourseType +from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse + + +class CourseSessionQuery(object): + course_session_attendance_course = graphene.Field( + CourseSessionAttendanceCourseType, + id=graphene.ID(required=True), + assignment_user_id=graphene.ID(required=False), + ) + + def resolve_course_session_attendance_course( + root, + info, + id=None, + user_id=graphene.ID(required=False), + ): + if user_id is None: + user_id = info.context.user.id + + attendance_course = CourseSessionAttendanceCourse.objects.filter( + id=id, + ).first() + + if attendance_course is None: + return None + + if str(user_id) == str(info.context.user.id) or is_course_session_expert( + info.context.user, attendance_course.course_session_id + ): + course_id = CourseSession.objects.get( + id=attendance_course.course_session_id + ).course_id + if has_course_access(info.context.user, course_id): + return attendance_course + raise PermissionDenied() diff --git a/server/vbv_lernwelt/course_session/graphql/types.py b/server/vbv_lernwelt/course_session/graphql/types.py new file mode 100644 index 00000000..4125511d --- /dev/null +++ b/server/vbv_lernwelt/course_session/graphql/types.py @@ -0,0 +1,36 @@ +import graphene +from graphene_django import DjangoObjectType + +from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse + + +class CourseSessionAttendanceCourseType(DjangoObjectType): + course_session_id = graphene.ID(source="course_session_id") + learning_content_id = graphene.ID(source="learning_content_id") + due_date_id = graphene.ID(source="due_date_id") + end = graphene.DateTime() + start = graphene.DateTime() + + class Meta: + model = CourseSessionAttendanceCourse + fields = ( + "id", + "course_session_id", + "learning_content_id", + "due_date_id", + "location", + "trainer", + "start", + "end", + # "attendance_user_list", + ) + + def resolve_start(self, info): + if self.due_date is None: + return None + return self.due_date.start + + def resolve_end(self, info): + if self.due_date is None: + return None + return self.due_date.end diff --git a/server/vbv_lernwelt/course_session/serializers.py b/server/vbv_lernwelt/course_session/serializers.py index defd7c6a..3e176f0c 100644 --- a/server/vbv_lernwelt/course_session/serializers.py +++ b/server/vbv_lernwelt/course_session/serializers.py @@ -14,7 +14,7 @@ class CourseSessionAttendanceCourseSerializer(serializers.ModelSerializer): model = CourseSessionAttendanceCourse fields = [ "id", - "course_session_id", + "course_session", "learning_content_id", "due_date_id", "location", diff --git a/server/vbv_lernwelt/course_session/tests/test_graphql.py b/server/vbv_lernwelt/course_session/tests/test_graphql.py new file mode 100644 index 00000000..6b63c8c7 --- /dev/null +++ b/server/vbv_lernwelt/course_session/tests/test_graphql.py @@ -0,0 +1,26 @@ +import json + +from graphene_django.utils.testing import GraphQLTestCase + + +class MyFancyTestCase(GraphQLTestCase): + def test_some_query(self): + response = self.query( + """ + query { + myModel { + id + name + } + } + """, + op_name="myModel", + ) + + content = json.loads(response.content) + + # This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + # Add some more asserts if you like + ...