From d8b76bec50536f37f63ccd251e46307615824378 Mon Sep 17 00:00:00 2001 From: sjschlapbach Date: Fri, 27 Dec 2024 18:24:32 +0100 Subject: [PATCH] wip: update live quiz cypress workflow to include live quiz evaluation --- .../cypress/e2e/F-live-quiz-workflow.cy.ts | 118 ++++++++++++++++-- packages/graphql/src/ops.schema.json | 14 +-- packages/graphql/src/ops.ts | 10 +- packages/graphql/src/public/schema.graphql | 2 +- packages/graphql/src/schema/evaluation.ts | 13 +- 5 files changed, 126 insertions(+), 31 deletions(-) diff --git a/cypress/cypress/e2e/F-live-quiz-workflow.cy.ts b/cypress/cypress/e2e/F-live-quiz-workflow.cy.ts index 5ea395a6c6..6582a62785 100644 --- a/cypress/cypress/e2e/F-live-quiz-workflow.cy.ts +++ b/cypress/cypress/e2e/F-live-quiz-workflow.cy.ts @@ -1,18 +1,17 @@ -import { v4 as uuid } from 'uuid' import messages from '../../../packages/i18n/messages/en' // questions used in live quiz workflows, including a question with and without sample solution for each supported type -const SCQuestion1Title = 'SC Title ' + uuid() +const SCQuestion1Title = 'SC Title LQ Test 1' const SCQuestion1Content = 'SC Question Content 1' const SCQuestion1Choices = [{ content: '50%' }, { content: '100%' }] -const SCQuestion2Title = 'SC Title ' + uuid() +const SCQuestion2Title = 'SC Title LQ Test 2' const SCQuestion2Content = 'SC Question Content 2' const SCQuestion2Choices = [ { content: '50%', correct: true }, { content: '100%' }, ] -const MCQuestion1Title = 'MC Title ' + uuid() +const MCQuestion1Title = 'MC Title LQ Test 1' const MCQuestion1Content = 'MC Question Content 1' const MCQuestion1Choices = [ { content: '25%' }, @@ -20,7 +19,7 @@ const MCQuestion1Choices = [ { content: '75%' }, { content: '100%' }, ] -const MCQuestion2Title = 'MC Title ' + uuid() +const MCQuestion2Title = 'MC Title LQ Test 2' const MCQuestion2Content = 'MC Question Content 2' const MCQuestion2Choices = [ { content: '25%', correct: false }, @@ -29,7 +28,7 @@ const MCQuestion2Choices = [ { content: '100%' }, ] -const KPRIMQuestion1Title = 'KPRIM Title ' + uuid() +const KPRIMQuestion1Title = 'KPRIM Title LQ Test 1' const KPRIMQuestion1Content = 'KPRIM Question Content 1' const KPRIMQuestion1Choices = [ { content: '10%' }, @@ -37,7 +36,7 @@ const KPRIMQuestion1Choices = [ { content: '80%' }, { content: '100%' }, ] -const KPRIMQuestion2Title = 'KPRIM Title ' + uuid() +const KPRIMQuestion2Title = 'KPRIM Title LQ Test 2' const KPRIMQuestion2Content = 'KPRIM Question Content 2' const KPRIMQuestion2Choices = [ { content: '10%', correct: false }, @@ -46,10 +45,10 @@ const KPRIMQuestion2Choices = [ { content: '100%' }, ] -const NRQuestion1Title = 'NR Title ' + uuid() +const NRQuestion1Title = 'NR Title LQ Test 1' const NRQuestion1Content = 'NR Question Content 1' const NRQuestion1Options = {} -const NRQuestion2Title = 'NR Title ' + uuid() +const NRQuestion2Title = 'NR Title LQ Test 2' const NRQuestion2Content = 'NR Question Content 2' const NRQuestion2Options = { min: '0', @@ -64,10 +63,10 @@ const NRQuestion2Options = { const NRAnswer1 = '50' const NRAnswer2 = '100' -const FTQuestion1Title = 'FT Title ' + uuid() +const FTQuestion1Title = 'FT Title LQ Test 1' const FTQuestion1Content = 'FT Question Content 1' const FTQuestion1Options = {} -const FTQuestion2Title = 'FT Title ' + uuid() +const FTQuestion2Title = 'FT Title LQ Test 2' const FTQuestion2Content = 'FT Question Content 2' const FTQuestion2Options = { maxLength: '100', @@ -913,6 +912,79 @@ describe('Different live-quiz workflows', () => { cy.wait(500) }) + it('Check out evaluation view of live quiz and its content', () => { + cy.loginLecturer() + + cy.get('[data-cy="live-quizzes"]').click() + cy.get(`[data-cy="live-quiz-cockpit-${quizName2}"]`).click() + cy.wait(1000) + + // extract the quiz id from the URL and visit the evaluation view + cy.location('href').then((href) => { + const quizId = href.split('/')[4] + cy.visit(`${Cypress.env('URL_MANAGE')}/quizzes/${quizId}/evaluation`) + }) + + // check content of evaluation view + cy.findByText(SCQuestion1Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(MCQuestion1Content).should('exist') + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.findByText(SCQuestion1Content).should('exist') + + // test instance navigation + cy.get('[data-cy="evaluate-question-select"]') + .should('exist') + .contains(SCQuestion1Title) + cy.get('[data-cy="evaluate-question-select"]').click() + cy.get( + `[data-cy="evaluation-select-instance-${KPRIMQuestion1Title}"]` + ).click() + cy.get('[data-cy="evaluate-question-select"]').contains(KPRIMQuestion1Title) + cy.get('[data-cy="evaluate-question-select"]').click() + cy.get(`[data-cy="evaluation-select-instance-${SCQuestion1Title}"]`).click() + cy.get('[data-cy="evaluate-question-select"]').contains(SCQuestion1Title) + + // navigate forwards and backwards through all questions + cy.get('[data-cy="evaluate-next-question"]').click() + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(KPRIMQuestion1Title).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(NRQuestion1Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(FTQuestion1Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(SCQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(MCQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(KPRIMQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(NRQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-next-question"]').click() + cy.findByText(FTQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.findByText(NRQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.findByText(SCQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.findByText(FTQuestion1Content).should('exist') + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.get('[data-cy="evaluate-previous-question"]').click() + cy.findByText(MCQuestion1Title).should('exist') + + // test navigation through blocks + cy.get('[data-cy="evaluate-stack-1"]').click() + cy.findByText(SCQuestion2Content).should('exist') + cy.get('[data-cy="evaluate-stack-0"]').click() + cy.findByText(SCQuestion1Title).should('exist') + cy.get('[data-cy="evaluate-stack-1"]').click() + cy.findByText(SCQuestion2Content).should('exist') + }) + it('Close block and delete feedback / feedback response', () => { cy.loginLecturer() @@ -931,7 +1003,6 @@ describe('Different live-quiz workflows', () => { it('Check that the deleted feedbacks are not visible anymore', () => { cy.loginStudent() cy.findByText(quizDisplayName2).click() - cy.findByText(feedbackDesktop).should('exist') cy.findByText(feedbackDesktop2).should('exist') cy.findByText(feedbackMobile).should('not.exist') @@ -956,4 +1027,27 @@ describe('Different live-quiz workflows', () => { cy.get(`[data-cy="confirm-delete-live-quiz"]`).click() cy.findByText(quizName2).should('not.exist') }) + + it('Cleanup: Delete the created questions from the question pool for repeated test execution', () => { + cy.loginLecturer() + + const questions = [ + SCQuestion1Title, + MCQuestion1Title, + KPRIMQuestion1Title, + NRQuestion1Title, + FTQuestion1Title, + SCQuestion2Title, + MCQuestion2Title, + KPRIMQuestion2Title, + NRQuestion2Title, + FTQuestion2Title, + ] + questions.forEach((question) => { + cy.get(`[data-cy="element-item-${question}"]`).should('exist') + cy.get(`[data-cy="delete-question-${question}"]`).click() + cy.get('[data-cy="confirm-question-deletion"]').click() + cy.get(`[data-cy="element-item-${question}"]`).should('not.exist') + }) + }) }) diff --git a/packages/graphql/src/ops.schema.json b/packages/graphql/src/ops.schema.json index e40be7b5a4..3ac940e80e 100644 --- a/packages/graphql/src/ops.schema.json +++ b/packages/graphql/src/ops.schema.json @@ -17334,19 +17334,15 @@ "description": null, "args": [], "type": { - "kind": "NON_NULL", + "kind": "LIST", "name": null, "ofType": { - "kind": "LIST", + "kind": "NON_NULL", "name": null, "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "NumericalElementSolutions", - "ofType": null - } + "kind": "OBJECT", + "name": "NumericalElementSolutions", + "ofType": null } } }, diff --git a/packages/graphql/src/ops.ts b/packages/graphql/src/ops.ts index 00469e4c89..f180a435c8 100644 --- a/packages/graphql/src/ops.ts +++ b/packages/graphql/src/ops.ts @@ -1888,7 +1888,7 @@ export type NumericalElementResults = { maxValue?: Maybe; minValue?: Maybe; responseValues: Array; - solutionRanges: Array; + solutionRanges?: Maybe>; totalAnswers: Scalars['Int']['output']; }; @@ -2758,7 +2758,7 @@ export type ElementDataInfoFragment = { __typename?: 'ElementInstance', elementD export type ElementDataWithoutSolutionsFragment = { __typename?: 'ElementInstance', elementData: { __typename: 'ChoicesElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'ChoiceQuestionOptions', displayMode: ElementDisplayMode, choices: Array<{ __typename?: 'Choice', ix: number, value: string }> } } | { __typename: 'ContentElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number } | { __typename?: 'FlashcardElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number } | { __typename: 'FreeTextElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'FreeTextQuestionOptions', restrictions?: { __typename?: 'FreeTextRestrictions', maxLength?: number | null } | null } } | { __typename: 'NumericalElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'NumericalQuestionOptions', accuracy?: number | null, placeholder?: string | null, unit?: string | null, restrictions?: { __typename?: 'NumericalRestrictions', min?: number | null, max?: number | null } | null } } }; -export type EvaluationResultsFragment = { __typename?: 'ActivityEvaluation', results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }>, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> }; +export type EvaluationResultsFragment = { __typename?: 'ActivityEvaluation', results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges?: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }> | null, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> }; export type MicroLearningDataFragment = { __typename?: 'MicroLearning', id: string, name: string, status: PublicationStatus, displayName: string, description?: string | null, pointsMultiplier: number, scheduledStartAt: any, scheduledEndAt: any, course?: { __typename?: 'Course', id: string, displayName: string, color: string } | null, stacks?: Array<{ __typename?: 'ElementStack', id: number, type: ElementStackType, displayName?: string | null, description?: string | null, order?: number | null, elements?: Array<{ __typename?: 'ElementInstance', id: number, type: ElementInstanceType, elementType: ElementType, elementData: { __typename: 'ChoicesElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'ChoiceQuestionOptions', hasSampleSolution?: boolean | null, displayMode: ElementDisplayMode, choices: Array<{ __typename?: 'Choice', ix: number, correct?: boolean | null, feedback?: string | null, value: string }> } } | { __typename: 'ContentElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number } | { __typename: 'FlashcardElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number } | { __typename: 'FreeTextElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'FreeTextQuestionOptions', hasSampleSolution?: boolean | null, solutions?: Array | null, restrictions?: { __typename?: 'FreeTextRestrictions', maxLength?: number | null } | null } } | { __typename: 'NumericalElementData', id: string, elementId: number, name: string, type: ElementType, content: string, explanation?: string | null, pointsMultiplier: number, options: { __typename?: 'NumericalQuestionOptions', hasSampleSolution?: boolean | null, accuracy?: number | null, placeholder?: string | null, unit?: string | null, restrictions?: { __typename?: 'NumericalRestrictions', min?: number | null, max?: number | null } | null, solutionRanges?: Array<{ __typename?: 'NumericalSolutionRange', min?: number | null, max?: number | null }> | null } } }> | null }> | null }; @@ -3871,7 +3871,7 @@ export type GetLiveQuizEvaluationQueryVariables = Exact<{ }>; -export type GetLiveQuizEvaluationQuery = { __typename?: 'Query', liveQuizEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, feedbacks?: Array<{ __typename?: 'Feedback', id: number, isPublished: boolean, isPinned: boolean, isResolved: boolean, content: string, votes: number, resolvedAt?: any | null, createdAt: any, responses?: Array<{ __typename?: 'FeedbackResponse', id: number, createdAt?: any | null, content: string, positiveReactions: number, negativeReactions: number }> | null }> | null, confusionFeedbacks?: Array<{ __typename?: 'ConfusionTimestep', speed: number, difficulty: number, createdAt: any }> | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }>, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null, liveQuizLeaderboard?: Array<{ __typename?: 'LeaderboardEntry', id: number, participantId: string, rank: number, username: string, avatar?: string | null, score: number }> | null }; +export type GetLiveQuizEvaluationQuery = { __typename?: 'Query', liveQuizEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, feedbacks?: Array<{ __typename?: 'Feedback', id: number, isPublished: boolean, isPinned: boolean, isResolved: boolean, content: string, votes: number, resolvedAt?: any | null, createdAt: any, responses?: Array<{ __typename?: 'FeedbackResponse', id: number, createdAt?: any | null, content: string, positiveReactions: number, negativeReactions: number }> | null }> | null, confusionFeedbacks?: Array<{ __typename?: 'ConfusionTimestep', speed: number, difficulty: number, createdAt: any }> | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges?: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }> | null, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null, liveQuizLeaderboard?: Array<{ __typename?: 'LeaderboardEntry', id: number, participantId: string, rank: number, username: string, avatar?: string | null, score: number }> | null }; export type GetLiveQuizHmacQueryVariables = Exact<{ id: Scalars['String']['input']; @@ -3904,7 +3904,7 @@ export type GetMicroLearningEvaluationQueryVariables = Exact<{ }>; -export type GetMicroLearningEvaluationQuery = { __typename?: 'Query', getMicroLearningEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, courseId?: string | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }>, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null }; +export type GetMicroLearningEvaluationQuery = { __typename?: 'Query', getMicroLearningEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, courseId?: string | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges?: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }> | null, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null }; export type GetMicroLearningSummaryQueryVariables = Exact<{ id: Scalars['String']['input']; @@ -3956,7 +3956,7 @@ export type GetPracticeQuizEvaluationQueryVariables = Exact<{ }>; -export type GetPracticeQuizEvaluationQuery = { __typename?: 'Query', getPracticeQuizEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, courseId?: string | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }>, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null }; +export type GetPracticeQuizEvaluationQuery = { __typename?: 'Query', getPracticeQuizEvaluation?: { __typename?: 'ActivityEvaluation', id: string, name: string, displayName?: string | null, description?: string | null, courseId?: string | null, results: Array<{ __typename?: 'StackEvaluation', stackId: number, stackName?: string | null, stackDescription?: string | null, stackOrder: number, instances: Array<{ __typename: 'ChoicesElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ChoicesElementResults', totalAnswers: number, anonymousAnswers: number, choices: Array<{ __typename?: 'ChoiceElementResults', value: string, count: number, correct?: boolean | null, feedback?: string | null }> } } | { __typename: 'ContentElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'ContentElementResults', totalAnswers: number, anonymousAnswers: number } } | { __typename: 'FlashcardElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FlashcardElementResults', totalAnswers: number, anonymousAnswers: number, correctCount: number, partialCount: number, incorrectCount: number } } | { __typename: 'FreeElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'FreeElementResults', totalAnswers: number, anonymousAnswers: number, maxLength?: number | null, solutions?: Array | null, responses: Array<{ __typename?: 'FreeElementResult', value: string, correct?: boolean | null, count: number }> } } | { __typename: 'NumericalElementInstanceEvaluation', id: number, type: ElementType, name: string, content: string, explanation?: string | null, hasSampleSolution: boolean, hasAnswerFeedbacks: boolean, results: { __typename?: 'NumericalElementResults', totalAnswers: number, anonymousAnswers: number, maxValue?: number | null, minValue?: number | null, solutionRanges?: Array<{ __typename?: 'NumericalElementSolutions', min?: number | null, max?: number | null }> | null, responseValues: Array<{ __typename?: 'NumericalElementResult', value: number, correct?: boolean | null, count: number }> }, statistics?: { __typename?: 'Statistics', max: number, mean: number, median: number, min: number, q1: number, q3: number, sd: number } | null }> }> } | null }; export type GetPracticeQuizListQueryVariables = Exact<{ [key: string]: never; }>; diff --git a/packages/graphql/src/public/schema.graphql b/packages/graphql/src/public/schema.graphql index 248c3bff85..abd5c48f01 100644 --- a/packages/graphql/src/public/schema.graphql +++ b/packages/graphql/src/public/schema.graphql @@ -1132,7 +1132,7 @@ type NumericalElementResults { maxValue: Float minValue: Float responseValues: [NumericalElementResult!]! - solutionRanges: [NumericalElementSolutions!]! + solutionRanges: [NumericalElementSolutions!] totalAnswers: Int! } diff --git a/packages/graphql/src/schema/evaluation.ts b/packages/graphql/src/schema/evaluation.ts index 4cdef2b0c4..e9eb2bb9ec 100644 --- a/packages/graphql/src/schema/evaluation.ts +++ b/packages/graphql/src/schema/evaluation.ts @@ -68,12 +68,17 @@ export interface IChoicesElementInstanceEvaluation results: IChoicesElementEvaluationResults } +interface INumericalElementSolutionRange { + min?: number | null + max?: number | null +} + export interface INumericalElementEvaluationResults { totalAnswers: number anonymousAnswers: number maxValue?: number | null minValue?: number | null - solutionRanges: { min?: number | null; max?: number | null }[] + solutionRanges?: INumericalElementSolutionRange[] | null responseValues: { value: number count: number @@ -272,6 +277,7 @@ export const NumericalElementResults = NumericalElementResultsRef.implement({ minValue: t.exposeFloat('minValue', { nullable: true }), solutionRanges: t.expose('solutionRanges', { type: [NumericalElementSolutions], + nullable: true, }), responseValues: t.expose('responseValues', { type: [NumericalElementResult], @@ -279,9 +285,8 @@ export const NumericalElementResults = NumericalElementResultsRef.implement({ }), }) -export const NumericalElementSolutionsRef = builder.objectRef< - INumericalElementEvaluationResults['solutionRanges'][0] ->('NumericalElementSolutions') +export const NumericalElementSolutionsRef = + builder.objectRef('NumericalElementSolutions') export const NumericalElementSolutions = NumericalElementSolutionsRef.implement( { fields: (t) => ({