From e208fdabbc0e9804a4eacffc5c369a134e8cc610 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 14 Jul 2023 16:56:59 +0200 Subject: [PATCH] Change after making UUIDs --- client/src/gql/gql.ts | 8 ++--- client/src/gql/graphql.ts | 29 ++++++++++-------- client/src/gql/schema.graphql | 19 +++++++----- client/src/gql/typenames.ts | 1 + client/src/graphql/mutations.ts | 2 +- client/src/graphql/queries.ts | 2 +- cypress/support/commands.js | 30 +++++++++++-------- .../assignment/graphql/mutations.py | 2 +- .../assignment/graphql/queries.py | 2 +- .../assignment/tests/test_graphql.py | 5 ++-- server/vbv_lernwelt/course/serializers.py | 2 +- .../course_session/graphql/mutations.py | 2 +- .../course_session/graphql/types.py | 2 +- .../course_session/services/attendance.py | 2 +- .../course_session/tests/test_attendance.py | 7 +++-- .../course_session/tests/test_graphql.py | 4 +-- .../feedback/creators/create_demo_feedback.py | 4 +-- server/vbv_lernwelt/feedback/factories.py | 2 +- server/vbv_lernwelt/feedback/models.py | 3 +- .../feedback/tests/test_feedback_api.py | 25 +++++++++------- .../notify/migrations/0001_initial.py | 5 ++-- server/vbv_lernwelt/notify/models.py | 5 ++-- .../notify/tests/test_notify_api.py | 2 +- 23 files changed, 93 insertions(+), 72 deletions(-) diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index d7be8c29..679e7998 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -14,8 +14,8 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document- */ const documents = { "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n send_feedback(input: $input) {\n feedback_response {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, - "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, - "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, }; @@ -40,11 +40,11 @@ export function graphql(source: "\n mutation SendFeedbackMutation($input: SendF /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"]; +export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"]; +export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 606269c6..f0e7a382 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -34,6 +34,11 @@ export type Scalars = { * schema (one of the key benefits of GraphQL). */ JSONString: { input: any; output: any; } + /** + * Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects + * in fields, resolvers and input. + */ + UUID: { input: any; output: any; } }; /** An enumeration. */ @@ -73,7 +78,7 @@ export type AssignmentCompletionObjectType = { evaluation_points?: Maybe; evaluation_submitted_at?: Maybe; evaluation_user?: Maybe; - id: Scalars['ID']['output']; + id: Scalars['UUID']['output']; learning_content_page_id?: Maybe; submitted_at?: Maybe; updated_at: Scalars['DateTime']['output']; @@ -116,7 +121,7 @@ export type AttendanceCourseUserMutation = { export type AttendanceUserInputType = { status: AttendanceUserStatus; - user_id: Scalars['ID']['input']; + user_id: Scalars['UUID']['input']; }; /** An enumeration. */ @@ -130,7 +135,7 @@ export type AttendanceUserType = { first_name?: Maybe; last_name?: Maybe; status: AttendanceUserStatus; - user_id: Scalars['ID']['output']; + user_id: Scalars['UUID']['output']; }; /** An enumeration. */ @@ -242,7 +247,7 @@ export type MutationUpdateCourseSessionAttendanceCourseUsersArgs = { export type MutationUpsertAssignmentCompletionArgs = { assignment_id: Scalars['ID']['input']; - assignment_user_id?: InputMaybe; + assignment_user_id?: InputMaybe; completion_data_string?: InputMaybe; completion_status?: InputMaybe; course_session_id: Scalars['ID']['input']; @@ -274,7 +279,7 @@ export type QueryAssignmentArgs = { export type QueryAssignmentCompletionArgs = { assignment_id: Scalars['ID']['input']; - assignment_user_id?: InputMaybe; + assignment_user_id?: InputMaybe; course_session_id: Scalars['ID']['input']; learning_content_page_id?: InputMaybe; }; @@ -310,7 +315,7 @@ export type UserType = { avatar_url: Scalars['String']['output']; email: Scalars['String']['output']; first_name: Scalars['String']['output']; - id: Scalars['ID']['output']; + id: Scalars['UUID']['output']; language: CoreUserLanguageChoices; last_name: Scalars['String']['output']; /** Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_. */ @@ -328,7 +333,7 @@ export type UpsertAssignmentCompletionMutationVariables = Exact<{ assignmentId: Scalars['ID']['input']; courseSessionId: Scalars['ID']['input']; learningContentId?: InputMaybe; - assignmentUserId?: InputMaybe; + assignmentUserId?: InputMaybe; completionStatus: AssignmentCompletionStatus; completionDataString: Scalars['String']['input']; evaluationGrade?: InputMaybe; @@ -336,17 +341,17 @@ export type UpsertAssignmentCompletionMutationVariables = Exact<{ }>; -export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; +export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; export type AssignmentCompletionQueryQueryVariables = Exact<{ assignmentId: Scalars['ID']['input']; courseSessionId: Scalars['ID']['input']; learningContentId?: InputMaybe; - assignmentUserId?: InputMaybe; + assignmentUserId?: InputMaybe; }>; -export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: string } | null, assignment_user: { __typename?: 'UserType', id: string } } | null }; +export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; export type CourseQueryQueryVariables = Exact<{ courseId: Scalars['Int']['input']; @@ -357,6 +362,6 @@ export type CourseQueryQuery = { __typename?: 'Query', course?: { __typename?: ' export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SendFeedbackInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; -export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]} as unknown as DocumentNode; +export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index c83d90ee..15cea857 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -2,7 +2,7 @@ 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!, learning_content_page_id: ID, assignment_user_id: ID): AssignmentCompletionObjectType + assignment_completion(assignment_id: ID!, course_session_id: ID!, learning_content_page_id: ID, assignment_user_id: UUID): AssignmentCompletionObjectType } type CourseSessionAttendanceCourseType { @@ -25,13 +25,19 @@ value as specified by scalar DateTime type AttendanceUserType { - user_id: ID! + user_id: UUID! status: AttendanceUserStatus! first_name: String last_name: String email: String } +""" +Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects +in fields, resolvers and input. +""" +scalar UUID + """An enumeration.""" enum AttendanceUserStatus { PRESENT @@ -98,14 +104,13 @@ interface CoursePageInterface { } type UserType { - id: ID! - """ Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_. """ username: String! first_name: String! last_name: String! + id: UUID! avatar_url: String! email: String! language: CoreUserLanguageChoices! @@ -164,7 +169,7 @@ enum AssignmentAssignmentAssignmentTypeChoices { scalar JSONStreamField type AssignmentCompletionObjectType { - id: ID! + id: UUID! created_at: DateTime! updated_at: DateTime! submitted_at: DateTime @@ -213,7 +218,7 @@ scalar JSONString type Mutation { send_feedback(input: SendFeedbackInput!): SendFeedbackPayload update_course_session_attendance_course_users(attendance_user_list: [AttendanceUserInputType]!, id: ID!): AttendanceCourseUserMutation - upsert_assignment_completion(assignment_id: ID!, assignment_user_id: ID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_grade: Float, evaluation_points: Float, learning_content_page_id: ID): AssignmentCompletionMutation + upsert_assignment_completion(assignment_id: ID!, assignment_user_id: UUID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_grade: Float, evaluation_points: Float, learning_content_page_id: ID): AssignmentCompletionMutation } type SendFeedbackPayload { @@ -254,7 +259,7 @@ type AttendanceCourseUserMutation { } input AttendanceUserInputType { - user_id: ID! + user_id: UUID! status: AttendanceUserStatus! } diff --git a/client/src/gql/typenames.ts b/client/src/gql/typenames.ts index 7743de82..e4fd7627 100644 --- a/client/src/gql/typenames.ts +++ b/client/src/gql/typenames.ts @@ -29,4 +29,5 @@ export const Query = "Query"; export const SendFeedbackInput = "SendFeedbackInput"; export const SendFeedbackPayload = "SendFeedbackPayload"; export const String = "String"; +export const UUID = "UUID"; export const UserType = "UserType"; diff --git a/client/src/graphql/mutations.ts b/client/src/graphql/mutations.ts index 4f0663e8..eb485ac6 100644 --- a/client/src/graphql/mutations.ts +++ b/client/src/graphql/mutations.ts @@ -5,7 +5,7 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` $assignmentId: ID! $courseSessionId: ID! $learningContentId: ID - $assignmentUserId: ID + $assignmentUserId: UUID $completionStatus: AssignmentCompletionStatus! $completionDataString: String! $evaluationGrade: Float diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index b19bc9b0..ac39348a 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -5,7 +5,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(` $assignmentId: ID! $courseSessionId: ID! $learningContentId: ID - $assignmentUserId: ID + $assignmentUserId: UUID ) { assignment(id: $assignmentId) { assignment_type diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 8c7c5821..fde5a99c 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -80,7 +80,13 @@ Cypress.Commands.add("manageShellCommand", (command) => { return cy.manageCommand(`shell -c '${command}'`); }); -function loadObjectJson(key, value, djangoModelPath, serializerModelPath) { +function loadObjectJson( + key, + value, + djangoModelPath, + serializerModelPath, + valueAsString = false +) { const djangoModel = _.last(djangoModelPath.split(".")); const djangoModelImportPath = _.initial(djangoModelPath.split(".")).join("."); const serializerModel = _.last(serializerModelPath.split(".")); @@ -89,10 +95,18 @@ function loadObjectJson(key, value, djangoModelPath, serializerModelPath) { ).join("."); let filterPart = `${key}=${value}`; + if (valueAsString) { + filterPart = `${key}=\\"${value}\\"`; + } + if (_.isArray(key)) { filterPart = _.zip(key, value) .map(([k, v]) => { - return `${k}=${v}`; + if (valueAsString) { + return `${k}=\\"${v}\\"`; + } else { + return `${k}=${v}`; + } }) .join(","); } @@ -116,7 +130,8 @@ Cypress.Commands.add("loadAssignmentCompletion", (key, value) => { key, value, "vbv_lernwelt.assignment.models.AssignmentCompletion", - "vbv_lernwelt.assignment.serializers.AssignmentCompletionSerializer" + "vbv_lernwelt.assignment.serializers.AssignmentCompletionSerializer", + true ); }); @@ -136,15 +151,6 @@ Cypress.Commands.add("makeSelfEvaluation", (answers) => { } }); -// Cypress.Commands.add('loadApiClientRequestResponseLog', (key, value) => { -// return loadObjectJson( -// key, -// value, -// 'myservice.apps.apiclient.models.ApiClientRequestResponseLog', -// 'myservice.apps.apiclient.serializers.ApiClientRequestResponseLogSerializer' -// ); -// }); - Cypress.Commands.add("learningContentMultiLayoutNextStep", () => { return cy.get('[data-cy="next-step"]').click({ force: true }); }); diff --git a/server/vbv_lernwelt/assignment/graphql/mutations.py b/server/vbv_lernwelt/assignment/graphql/mutations.py index 1385bc24..038d355b 100644 --- a/server/vbv_lernwelt/assignment/graphql/mutations.py +++ b/server/vbv_lernwelt/assignment/graphql/mutations.py @@ -22,7 +22,7 @@ class AssignmentCompletionMutation(graphene.Mutation): assignment_id = graphene.ID(required=True) course_session_id = graphene.ID(required=True) learning_content_page_id = graphene.ID() - assignment_user_id = graphene.ID() + assignment_user_id = graphene.UUID() completion_status = graphene.Argument( graphene.Enum.from_enum(AssignmentCompletionStatus) diff --git a/server/vbv_lernwelt/assignment/graphql/queries.py b/server/vbv_lernwelt/assignment/graphql/queries.py index 86c6ce57..035e478f 100644 --- a/server/vbv_lernwelt/assignment/graphql/queries.py +++ b/server/vbv_lernwelt/assignment/graphql/queries.py @@ -24,7 +24,7 @@ class AssignmentQuery(object): assignment_id=graphene.ID(required=True), course_session_id=graphene.ID(required=True), learning_content_page_id=graphene.ID(required=False), - assignment_user_id=graphene.ID(required=False), + assignment_user_id=graphene.UUID(required=False), ) def resolve_assignment_completion( diff --git a/server/vbv_lernwelt/assignment/tests/test_graphql.py b/server/vbv_lernwelt/assignment/tests/test_graphql.py index 6c8bf3ad..036d28e2 100644 --- a/server/vbv_lernwelt/assignment/tests/test_graphql.py +++ b/server/vbv_lernwelt/assignment/tests/test_graphql.py @@ -224,7 +224,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} - assignment_user_id: {self.student.id} + assignment_user_id: "{self.student.id}" course_session_id: {self.course_session.id} completion_status: EVALUATION_IN_PROGRESS completion_data_string: "{completion_data_string}" @@ -240,6 +240,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): }} """ + print(query) response = self.query(query) self.assertResponseNoErrors(response) @@ -289,7 +290,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} - assignment_user_id: {self.student.id} + assignment_user_id: "{self.student.id}" course_session_id: {self.course_session.id} completion_status: EVALUATION_SUBMITTED completion_data_string: "{completion_data_string}" diff --git a/server/vbv_lernwelt/course/serializers.py b/server/vbv_lernwelt/course/serializers.py index 676aeeda..69d326b2 100644 --- a/server/vbv_lernwelt/course/serializers.py +++ b/server/vbv_lernwelt/course/serializers.py @@ -146,4 +146,4 @@ class DocumentUploadStartInputSerializer(serializers.Serializer): class DocumentUploadFinishInputSerializer(serializers.Serializer): - file_id = serializers.IntegerField() + file_id = serializers.UUIDField() diff --git a/server/vbv_lernwelt/course_session/graphql/mutations.py b/server/vbv_lernwelt/course_session/graphql/mutations.py index 64e6c15f..e8bedaac 100644 --- a/server/vbv_lernwelt/course_session/graphql/mutations.py +++ b/server/vbv_lernwelt/course_session/graphql/mutations.py @@ -14,7 +14,7 @@ logger = structlog.get_logger(__name__) class AttendanceUserInputType(graphene.InputObjectType): - user_id = graphene.ID(required=True) + user_id = graphene.UUID(required=True) status = graphene.Field( graphene.Enum.from_enum(AttendanceUserStatus), required=True ) diff --git a/server/vbv_lernwelt/course_session/graphql/types.py b/server/vbv_lernwelt/course_session/graphql/types.py index 36dd82f1..bc1a0f4c 100644 --- a/server/vbv_lernwelt/course_session/graphql/types.py +++ b/server/vbv_lernwelt/course_session/graphql/types.py @@ -6,7 +6,7 @@ from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus class AttendanceUserType(graphene.ObjectType): - user_id = graphene.ID(required=True) + user_id = graphene.UUID(required=True) status = graphene.Field( graphene.Enum.from_enum(AttendanceUserStatus), required=True ) diff --git a/server/vbv_lernwelt/course_session/services/attendance.py b/server/vbv_lernwelt/course_session/services/attendance.py index 22802943..8af7f7e1 100644 --- a/server/vbv_lernwelt/course_session/services/attendance.py +++ b/server/vbv_lernwelt/course_session/services/attendance.py @@ -30,7 +30,7 @@ def update_attendance_list( if u is not None: result_user_list.append( { - "user_id": u.id, + "user_id": str(u.id), "status": attendance_user.get( "status", AttendanceUserStatus.PRESENT ).value, diff --git a/server/vbv_lernwelt/course_session/tests/test_attendance.py b/server/vbv_lernwelt/course_session/tests/test_attendance.py index 841da952..347d1795 100644 --- a/server/vbv_lernwelt/course_session/tests/test_attendance.py +++ b/server/vbv_lernwelt/course_session/tests/test_attendance.py @@ -1,5 +1,6 @@ from django.test import TestCase +from vbv_lernwelt.core.constants import TEST_STUDENT1_USER_ID from vbv_lernwelt.core.create_default_users import create_default_users from vbv_lernwelt.core.models import User from vbv_lernwelt.course.creators.test_course import create_test_course @@ -35,7 +36,7 @@ class AttendanceServicesTestCase(TestCase): id=self.attendance_course.id ) self.assertEqual( - attendance_course.attendance_user_list[0]["user_id"], student.id + attendance_course.attendance_user_list[0]["user_id"], str(student.id) ) self.assertEqual( attendance_course.attendance_user_list, @@ -43,7 +44,7 @@ class AttendanceServicesTestCase(TestCase): { "email": "test-student1@example.com", "status": "PRESENT", - "user_id": -21, + "user_id": TEST_STUDENT1_USER_ID, "last_name": "Student1", "first_name": "Test", } @@ -68,7 +69,7 @@ class AttendanceServicesTestCase(TestCase): { "email": "test-student1@example.com", "status": "PRESENT", - "user_id": "-21", + "user_id": TEST_STUDENT1_USER_ID, "last_name": "Student1", "first_name": "Test", } diff --git a/server/vbv_lernwelt/course_session/tests/test_graphql.py b/server/vbv_lernwelt/course_session/tests/test_graphql.py index fcb4aab0..3790ffe5 100644 --- a/server/vbv_lernwelt/course_session/tests/test_graphql.py +++ b/server/vbv_lernwelt/course_session/tests/test_graphql.py @@ -49,8 +49,8 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): update_course_session_attendance_course_users( id:{self.attendance_course.id}, attendance_user_list:[ - {{user_id: {student.id}, status: PRESENT}}, - {{user_id: "123123123", status: PRESENT}}, + {{user_id: "{student.id}", status: PRESENT}}, + {{user_id: "3372836c-1c95-4721-881d-5342a60a3bfe", status: PRESENT}}, ] ) {{ course_session_attendance_course {{ diff --git a/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py b/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py index 586b2989..f71a6b55 100644 --- a/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py +++ b/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py @@ -1,8 +1,8 @@ from vbv_lernwelt.course.models import CourseSession -from vbv_lernwelt.feedback.factories import FeedbackFactory +from vbv_lernwelt.feedback.factories import FeedbackResponseFactory from vbv_lernwelt.learnpath.models import Circle def create_feedback(circle: Circle, course_session: CourseSession, amount: int): for _i in range(amount): - FeedbackFactory(circle=circle, course_session=course_session).save() + FeedbackResponseFactory(circle=circle, course_session=course_session).save() diff --git a/server/vbv_lernwelt/feedback/factories.py b/server/vbv_lernwelt/feedback/factories.py index d55d830f..d44622c7 100644 --- a/server/vbv_lernwelt/feedback/factories.py +++ b/server/vbv_lernwelt/feedback/factories.py @@ -5,7 +5,7 @@ from factory.fuzzy import FuzzyChoice, FuzzyInteger from vbv_lernwelt.feedback.models import FeedbackResponse -class FeedbackFactory(DjangoModelFactory): +class FeedbackResponseFactory(DjangoModelFactory): data = Dict( { "satisfaction": FuzzyInteger(2, 4), diff --git a/server/vbv_lernwelt/feedback/models.py b/server/vbv_lernwelt/feedback/models.py index b3d687ce..f7f56444 100644 --- a/server/vbv_lernwelt/feedback/models.py +++ b/server/vbv_lernwelt/feedback/models.py @@ -45,7 +45,8 @@ class FeedbackResponse(models.Model): HUNDRED = 100, "100%" def save(self, *args, **kwargs): - if not self.id: + if self._state.adding: + # with `id=UUIDField` it is always set... course_session_users = CourseSessionUser.objects.filter( role="EXPERT", course_session=self.course_session, expert=self.circle ) diff --git a/server/vbv_lernwelt/feedback/tests/test_feedback_api.py b/server/vbv_lernwelt/feedback/tests/test_feedback_api.py index 6ad2136c..c302ca5c 100644 --- a/server/vbv_lernwelt/feedback/tests/test_feedback_api.py +++ b/server/vbv_lernwelt/feedback/tests/test_feedback_api.py @@ -5,7 +5,8 @@ from vbv_lernwelt.core.models import User from vbv_lernwelt.course.consts import COURSE_TEST_ID from vbv_lernwelt.course.creators.test_course import create_test_course from vbv_lernwelt.course.models import CourseSession, CourseSessionUser -from vbv_lernwelt.feedback.factories import FeedbackFactory +from vbv_lernwelt.feedback.factories import FeedbackResponseFactory +from vbv_lernwelt.feedback.models import FeedbackResponse from vbv_lernwelt.learnpath.models import Circle from vbv_lernwelt.notify.models import Notification @@ -61,7 +62,9 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") csu.expert.add(basis_circle) - FeedbackFactory(circle=basis_circle, course_session=csu.course_session).save() + FeedbackResponse.objects.create( + circle=basis_circle, course_session=csu.course_session + ) notifications = Notification.objects.all() self.assertEqual(len(notifications), 1) @@ -84,7 +87,7 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") csu.expert.add(basis_circle) - feedback = FeedbackFactory( + feedback = FeedbackResponseFactory( circle=basis_circle, course_session=csu.course_session ) feedback.save() @@ -113,12 +116,12 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): csu.expert.add(reisen_circle) for i in range(number_reisen_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=reisen_circle, course_session=csu.course_session ).save() for i in range(number_fahrzeug_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -146,12 +149,12 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): reisen_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") for i in range(number_basis_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=reisen_circle, course_session=csu.course_session ).save() for i in range(number_analyse_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -172,7 +175,7 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): user=self.user, ) fahrzeug_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -206,7 +209,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") for i in range(3): - FeedbackFactory( + FeedbackResponseFactory( circle=circle, course_session=csu.course_session, data={ @@ -252,7 +255,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): ) circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") - FeedbackFactory(circle=circle, course_session=csu.course_session).save() + FeedbackResponseFactory(circle=circle, course_session=csu.course_session).save() response = self.client.get( f"/api/core/feedback/{csu.course_session.course.id}/{circle.id}/" @@ -268,7 +271,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): user=self.user, ) circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") - FeedbackFactory(circle=circle, course_session=csu.course_session).save() + FeedbackResponseFactory(circle=circle, course_session=csu.course_session).save() response = self.client.get( f"/api/core/feedback/{csu.course_session.course.id}/{circle.id}/" diff --git a/server/vbv_lernwelt/notify/migrations/0001_initial.py b/server/vbv_lernwelt/notify/migrations/0001_initial.py index ebcd59ce..215843c5 100644 --- a/server/vbv_lernwelt/notify/migrations/0001_initial.py +++ b/server/vbv_lernwelt/notify/migrations/0001_initial.py @@ -1,11 +1,10 @@ -# Generated by Django 3.2.13 on 2023-07-14 12:28 +# Generated by Django 3.2.13 on 2023-07-14 13:08 from django.conf import settings from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import jsonfield.fields -import uuid class Migration(migrations.Migration): @@ -21,6 +20,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Notification', fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('level', models.CharField(choices=[('success', 'success'), ('info', 'info'), ('warning', 'warning'), ('error', 'error')], default='info', max_length=20, verbose_name='level')), ('unread', models.BooleanField(db_index=True, default=True, verbose_name='unread')), ('actor_object_id', models.CharField(max_length=255, verbose_name='actor object id')), @@ -33,7 +33,6 @@ class Migration(migrations.Migration): ('deleted', models.BooleanField(db_index=True, default=False, verbose_name='deleted')), ('emailed', models.BooleanField(db_index=True, default=False, verbose_name='emailed')), ('data', jsonfield.fields.JSONField(blank=True, null=True, verbose_name='data')), - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('notification_type', models.CharField(choices=[('USER_INTERACTION', 'User Interaction'), ('PROGRESS', 'Progress'), ('INFORMATION', 'Information')], default='INFORMATION', max_length=32)), ('target_url', models.URLField(blank=True, null=True)), ('actor_avatar_url', models.URLField(blank=True, null=True)), diff --git a/server/vbv_lernwelt/notify/models.py b/server/vbv_lernwelt/notify/models.py index ece24ca4..dd00ed99 100644 --- a/server/vbv_lernwelt/notify/models.py +++ b/server/vbv_lernwelt/notify/models.py @@ -1,5 +1,3 @@ -import uuid - from django.db import models from django.utils.translation import gettext_lazy as _ from notifications.base.models import AbstractNotification @@ -12,7 +10,8 @@ class NotificationType(models.TextChoices): class Notification(AbstractNotification): - id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + # UUIDs are not supported by the notifications app... + # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) notification_type = models.CharField( max_length=32, diff --git a/server/vbv_lernwelt/notify/tests/test_notify_api.py b/server/vbv_lernwelt/notify/tests/test_notify_api.py index 7f10d785..fa9a2863 100644 --- a/server/vbv_lernwelt/notify/tests/test_notify_api.py +++ b/server/vbv_lernwelt/notify/tests/test_notify_api.py @@ -52,7 +52,7 @@ class TestNotificationApi(APITestCase): self.assertTrue( all( [ - self.alice.id == notification["recipient"] + str(self.alice.id) == notification["recipient"] for notification in data["all_list"] ] )