short_answer= tested and implemented; local preview works, but canvas isn't getting the answers

This commit is contained in:
Adam Teichert
2025-01-15 17:42:39 -07:00
parent ade3f4dca4
commit 5f11fe76f1
4 changed files with 131 additions and 23 deletions

View File

@@ -11,6 +11,7 @@ export enum QuestionType {
SHORT_ANSWER = "short_answer",
MATCHING = "matching",
NONE = "",
SHORT_ANSWER_WITH_ANSWERS = "short_answer=",
}
export const zodQuestionType = z.enum([
@@ -20,6 +21,7 @@ export const zodQuestionType = z.enum([
QuestionType.SHORT_ANSWER,
QuestionType.MATCHING,
QuestionType.NONE,
QuestionType.SHORT_ANSWER_WITH_ANSWERS,
]);
export interface LocalQuizQuestion {

View File

@@ -69,6 +69,11 @@ const getQuestionType = (
"short_answer"
)
return QuestionType.SHORT_ANSWER;
if (
linesWithoutPoints[linesWithoutPoints.length - 1].toLowerCase().trim() ===
"short_answer="
)
return QuestionType.SHORT_ANSWER_WITH_ANSWERS;
const answerLines = getAnswerStringsWithMultilineSupport(
linesWithoutPoints,
@@ -97,6 +102,7 @@ const getAnswers = (
questionIndex: number,
questionType: string
): LocalQuizQuestionAnswer[] => {
if (questionType == QuestionType.SHORT_ANSWER_WITH_ANSWERS) linesWithoutPoints = linesWithoutPoints.slice(0, linesWithoutPoints.length - 1);
const answerLines = getAnswerStringsWithMultilineSupport(
linesWithoutPoints,
questionIndex
@@ -149,6 +155,8 @@ export const quizQuestionMarkdownUtils = {
question.questionType === "essay" ||
question.questionType === "short_answer"
? question.questionType
: question.questionType === QuestionType.SHORT_ANSWER_WITH_ANSWERS
? `\n${QuestionType.SHORT_ANSWER_WITH_ANSWERS}`
: "";
return `Points: ${question.points}\n${question.text}\n${answersText}${distractorText}${questionTypeIndicator}`;
@@ -214,6 +222,7 @@ export const quizQuestionMarkdownUtils = {
"multiple_choice",
"multiple_answers",
"matching",
"short_answer=",
];
const answers = typesWithAnswers.includes(questionType)
? getAnswers(linesWithoutPoints, questionIndex, questionType)

View File

@@ -1,4 +1,5 @@
import { QuestionType } from "../../quiz/localQuizQuestion";
import { getQuestionType } from "@/services/canvas/canvasQuizService";
import { QuestionType, zodQuestionType } from "../../quiz/localQuizQuestion";
import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils";
import { quizQuestionMarkdownUtils } from "../../quiz/utils/quizQuestionMarkdownUtils";
import { describe, it, expect } from "vitest";
@@ -83,6 +84,39 @@ short_answer`;
expect(questionMarkdown).toContain(expectedMarkdown);
});
it("short_answer= to markdown is correct", () => {
const name = "Test Quiz"
const rawMarkdownQuiz = `
ShuffleAnswers: true
OneQuestionAtATime: false
DueAt: 08/21/2023 23:59:00
LockAt: 08/21/2023 23:59:00
AssignmentGroup: Assignments
AllowedAttempts: -1
Description: this is the
multi line
description
---
Which events are triggered when the user clicks on an input field?
*a) yes
*b) Yes
short_answer=
`;
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0];
const questionMarkdown =
quizQuestionMarkdownUtils.toMarkdown(firstQuestion);
const expectedMarkdown = `Points: 1
Which events are triggered when the user clicks on an input field?
*a) yes
*b) Yes
short_answer=`;
expect(questionMarkdown).toContain(expectedMarkdown);
});
it("essay question to markdown is correct", () => {
const name = "Test Quiz"
const rawMarkdownQuiz = `
@@ -111,28 +145,85 @@ essay`;
expect(questionMarkdown).toContain(expectedMarkdown);
});
// it("Can parse short answer with auto graded answers", () => {
// const rawMarkdownQuiz = `
// Name: Test Quiz
// ShuffleAnswers: true
// OneQuestionAtATime: false
// DueAt: 08/21/2023 23:59:00
// LockAt: 08/21/2023 23:59:00
// AssignmentGroup: Assignments
// AllowedAttempts: -1
// Description: this is the
// multi line
// description
// ---
// Which events are triggered when the user clicks on an input field?
// *a) test
// short_answer=
// `;
it("Can parse short answer with auto graded answers", () => {
const name = "Test Quiz"
const rawMarkdownQuiz = `
ShuffleAnswers: true
OneQuestionAtATime: false
DueAt: 08/21/2023 23:59:00
LockAt: 08/21/2023 23:59:00
AssignmentGroup: Assignments
AllowedAttempts: -1
Description: this is the
multi line
description
---
Which events are triggered when the user clicks on an input field?
*a) test
*b) other
short_answer=
`;
// const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
// const firstQuestion = quiz.questions[0];
// expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER_WITH_ANSWERS)
// });
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0];
expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER_WITH_ANSWERS)
expect(firstQuestion.answers.length).toBe(2);
expect(firstQuestion.answers[0].text).toBe("test");
expect(firstQuestion.answers[1].text).toBe("other");
});
it("Can parse short answer with auto graded answers", () => {
const name = "Test Quiz"
const rawMarkdownQuiz = `
ShuffleAnswers: true
OneQuestionAtATime: false
DueAt: 08/21/2023 23:59:00
LockAt: 08/21/2023 23:59:00
AssignmentGroup: Assignments
AllowedAttempts: -1
Description: this is the
multi line
description
---
Which events are triggered when the user clicks on an input field?
*a) test
*b) other
short_answer=
`;
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0];
expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER_WITH_ANSWERS)
expect(firstQuestion.answers.length).toBe(2);
expect(firstQuestion.answers[0].text).toBe("test");
expect(firstQuestion.answers[1].text).toBe("other");
});
it("Has short_answer= type at the same position in types and zod types", () => {
expect(Object.values(zodQuestionType.Enum)).toEqual(Object.values(QuestionType));
});
it("Associates short_answer= questions with short_answer_question canvas question type", () => {
const name = "Test Quiz"
const rawMarkdownQuiz = `
ShuffleAnswers: true
OneQuestionAtATime: false
DueAt: 08/21/2023 23:59:00
LockAt: 08/21/2023 23:59:00
AssignmentGroup: Assignments
AllowedAttempts: -1
Description: this is the
multi line
description
---
Which events are triggered when the user clicks on an input field?
*a) test
*b) other
short_answer=
`;
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const firstQuestion = quiz.questions[0];
expect(getQuestionType(firstQuestion)).toBe("short_answer_question");
});
});

View File

@@ -28,6 +28,12 @@ const getAnswers = (
}));
};
export const getQuestionType = (
question: LocalQuizQuestion
) => {
return `${question.questionType.replace("=", "")}_question`;
}
const createQuestionOnly = async (
canvasCourseId: number,
canvasQuizId: number,
@@ -41,7 +47,7 @@ const createQuestionOnly = async (
const body = {
question: {
question_text: markdownToHTMLSafe(question.text, settings),
question_type: `${question.questionType}_question`,
question_type: getQuestionType(question),
points_possible: question.points,
position,
answers: getAnswers(question, settings),