Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question sources #11658

Merged
merged 17 commits into from
Jan 3, 2024
6 changes: 3 additions & 3 deletions kolibri/core/assets/src/exams/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export function convertV2toV3(questionSources, exam) {
const questions = annotateQuestionsWithItem(questionSources);
return {
section_id: uuidv4(),
section_title: '',
description: '',
section_title: 'Section one',
description: 'Sample description',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to note is that we should probably revert this. It is causing the tests to fail and if we are going to introduce a title and/or description by default we'll need to use a translated string and account for it in the tests. We can handle this in a separate follow-up issue

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! I think I missed it before committing.

resource_pool: [],
questions,
learners_see_fixed_order: exam.learners_see_fixed_order,
Expand All @@ -114,7 +114,7 @@ export function revertV3toV2(questionSources) {

/**
* @param {object} exam - an exam object of any question_sources version
* @returns V2 formatted question_sources
* @returns V3 formatted question_sources
*/
export function convertExamQuestionSourcesToV3(exam, extraArgs = {}) {
if (exam.data_model_version !== 3) {
Expand Down
56 changes: 38 additions & 18 deletions kolibri/plugins/learn/assets/src/modules/examViewer/handlers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ContentNodeResource, ExamResource } from 'kolibri.resources';
import samePageCheckGenerator from 'kolibri.utils.samePageCheckGenerator';
import { convertExamQuestionSources } from 'kolibri.utils.exams';
import { convertExamQuestionSourcesToV3 } from 'kolibri.utils.exams';
import shuffled from 'kolibri.utils.shuffled';
import { ClassesPageNames } from '../../constants';
import { LearnerClassroomResource } from '../../apiResources';
Expand Down Expand Up @@ -30,10 +30,20 @@ export function showExam(store, params, alreadyOnQuiz) {
store.commit('classAssignments/SET_CURRENT_CLASSROOM', classroom);

let contentPromise;
if (exam.question_sources.length) {
let allExerciseIds = [];
if (exam.data_version == 3) {
allExerciseIds = exam.question_sources.reduce((acc, section) => {
console.log(section);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray console.log

acc = [...acc, ...section.questions.map(q => q.exercise_id)];
return acc;
}, []);
} else {
allExerciseIds = exam.question_sources.map(q => q.exercise_id);
}
if (allExerciseIds.length) {
contentPromise = ContentNodeResource.fetchCollection({
getParams: {
ids: exam.question_sources.map(item => item.exercise_id),
ids: allExerciseIds,
},
});
} else {
Expand All @@ -43,26 +53,36 @@ export function showExam(store, params, alreadyOnQuiz) {
contentNodes => {
if (shouldResolve()) {
// If necessary, convert the question source info
let questions = convertExamQuestionSources(exam, { contentNodes });
const question_sources = convertExamQuestionSourcesToV3(exam, { contentNodes });

// When necessary, randomize the questions for the learner.
// Seed based on the user ID so they see a consistent order each time.
if (!exam.learners_see_fixed_order) {
questions = shuffled(questions, store.state.core.session.user_id);
}
question_sources.forEach(section => {
if (!section.learners_see_fixed_order) {
section.questions = shuffled(
section.questions,
store.state.core.session.user_id
);
}
});

const allQuestions = question_sources.reduce((acc, section) => {
acc = [...acc, ...section.questions];
return acc;
}, []);

// Exam is drawing solely on malformed exercise data, best to quit now
if (questions.some(question => !question.question_id)) {
if (allQuestions.some(question => !question.question_id)) {
store.dispatch(
'handleError',
`This quiz cannot be displayed:\nQuestion sources: ${JSON.stringify(
questions
allQuestions
)}\nExam: ${JSON.stringify(exam)}`
);
return;
}
// Illegal question number!
else if (questionNumber >= questions.length) {
else if (questionNumber >= allQuestions.length) {
store.dispatch(
'handleError',
`Question number ${questionNumber} is not valid for this quiz`
Expand All @@ -76,16 +96,16 @@ export function showExam(store, params, alreadyOnQuiz) {
contentNodeMap[node.id] = node;
}

for (const question of questions) {
for (const question of allQuestions) {
question.missing = !contentNodeMap[question.exercise_id];
}

store.commit('examViewer/SET_STATE', {
contentNodeMap,
exam,
questionNumber,
questions,
});
(exam.question_sources = question_sources),
store.commit('examViewer/SET_STATE', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two lines seem odd like this -- should this instead be two separate lines like:

exam.question_sources = question_sources;
store.commit('examViewer/SET_STATE', {

contentNodeMap,
exam,
questionNumber,
questions: allQuestions,
});
store.commit('CORE_SET_PAGE_LOADING', false);
store.commit('CORE_SET_ERROR', null);
}
Expand Down
Loading
Loading