Spaces:
Running
Running
File size: 2,574 Bytes
9aee359 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import { describe, expect, it } from 'vitest'
import { extractQuestions, parseQuestionsJson, readJsonFile } from './JSONUploadForm'
const validMCQ = {
question_type: 'mcq',
question_text: 'What is binary search complexity?',
options: ['O(n)', 'O(log n)', 'O(n log n)', 'O(1)'],
correct_answer: 'B',
marks: 1,
negative_marks: 0.33,
subject: 'Algorithms',
}
describe('JSONUploadForm JSON parsing', () => {
it('parses the expected object schema and normalizes question values', () => {
const questions = parseQuestionsJson(JSON.stringify({ questions: [validMCQ] }))
expect(questions).toHaveLength(1)
expect(questions[0]).toMatchObject({
question_type: 'mcq',
question_text: validMCQ.question_text,
options: validMCQ.options,
correct_answer: 'B',
marks: 1,
negative_marks: 0.33,
})
})
it('accepts an array root for pasted questions', () => {
const questions = extractQuestions([validMCQ])
expect(questions).toHaveLength(1)
expect(questions[0].question_text).toBe(validMCQ.question_text)
})
it('normalizes MSQ answers and removes negative marks for non-MCQ questions', () => {
const questions = extractQuestions([
{
...validMCQ,
question_type: 'msq',
correct_answer: 'A, C',
negative_marks: 0.66,
},
])
expect(questions[0].correct_answer).toBe('A,C')
expect(questions[0].negative_marks).toBe(0)
})
it('rejects malformed JSON with a clear error', () => {
expect(() => parseQuestionsJson('{ "questions": [ }')).toThrow(/Invalid JSON:/)
})
it('rejects roots that do not match the expected schema', () => {
expect(() => extractQuestions({ items: [validMCQ] })).toThrow(
'JSON root must be an array or an object with a "questions" array',
)
})
it('rejects empty question arrays', () => {
expect(() => extractQuestions({ questions: [] })).toThrow('JSON does not contain any questions')
})
it('rejects question objects with invalid fields', () => {
expect(() => extractQuestions([{ ...validMCQ, options: ['A', 'B'] }])).toThrow(
'Question 1 options must contain exactly 4 non-empty strings',
)
})
it('reads a JSON file before validation', async () => {
const file = new File([JSON.stringify({ questions: [validMCQ] })], 'questions.json', {
type: 'application/json',
})
const text = await readJsonFile(file)
const questions = parseQuestionsJson(text)
expect(questions).toHaveLength(1)
expect(questions[0].correct_answer).toBe('B')
})
})
|