Files
freeCodeCamp/tools/scripts/seed-exams/exam-schema.js
2023-07-14 10:35:09 -05:00

87 lines
2.3 KiB
JavaScript

import Joi from 'joi';
import JoiObjectId from 'joi-objectid';
Joi.objectId = JoiObjectId(Joi);
const nanoIdRE = new RegExp('[a-z0-9]{10}');
const PrerequisitesJoi = Joi.object().keys({
id: Joi.objectId().required(),
title: Joi.string()
});
const AnswerJoi = Joi.object().keys({
id: Joi.string().regex(nanoIdRE).required(),
deprecated: Joi.bool(),
answer: Joi.string().required()
});
const QuestionJoi = Joi.object().keys({
id: Joi.string().regex(nanoIdRE).required(),
question: Joi.string().required(),
deprecated: Joi.bool(),
wrongAnswers: Joi.array()
.items(AnswerJoi)
.required()
.custom((value, helpers) => {
const nonDeprecatedCount = value.reduce(
(count, answer) => (answer.deprecated ? count : count + 1),
0
);
const minimumAnswers = 4;
if (nonDeprecatedCount < minimumAnswers) {
return helpers.message(
`'wrongAnswers' must have at least ${minimumAnswers} non-deprecated answers.`
);
}
return value;
}),
correctAnswers: Joi.array()
.items(AnswerJoi)
.required()
.custom((value, helpers) => {
const nonDeprecatedCount = value.reduce(
(count, answer) => (answer.deprecated ? count : count + 1),
0
);
const minimumAnswers = 1;
if (nonDeprecatedCount < minimumAnswers) {
return helpers.message(
`'correctAnswers' must have at least ${minimumAnswers} non-deprecated answer.`
);
}
return value;
})
});
const schema = Joi.object().keys({
// TODO: make sure _id and title match what's in the challenge markdown file
_id: Joi.objectId().required(),
title: Joi.string().required(),
numberOfQuestionsInExam: Joi.number()
.min(1)
.max(
Joi.ref('questions', {
adjust: questions => {
const nonDeprecatedCount = questions.reduce(
(count, question) => (question.deprecated ? count : count + 1),
0
);
return nonDeprecatedCount;
}
})
)
.required(),
passingPercent: Joi.number().min(0).max(100).required(),
prerequisites: Joi.array().items(PrerequisitesJoi),
questions: Joi.array().items(QuestionJoi).min(1).required()
});
export const validateExamSchema = exam => {
return schema.validate(exam);
};