Skip to content

Commit 38ea4f9

Browse files
committed
feat(grading) - add prefill to 0 and adjust prefill policies for some question types
- refactor to differentiate question types that can be prefilled either to 0 or max, both or neither (for previous code, only boolean for if it can be prefilled) - TextResponse and Comprehension question types adjusted to allow prefilling to full - add tests for different policies
1 parent 958e986 commit 38ea4f9

2 files changed

Lines changed: 391 additions & 35 deletions

File tree

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import { dispatch, store } from 'store';
2+
3+
import actions, { questionTypes } from '../../../constants';
4+
5+
const answerId = 3;
6+
7+
const buildPayload = ({ questionType, grade, correct, testCases } = {}) => ({
8+
submission: {
9+
pointsAwarded: null,
10+
basePoints: 1000,
11+
submittedAt: '2017-05-11T17:02:17.000+08:00',
12+
bonusEndAt: '2017-05-11T17:02:17.000+08:00',
13+
bonusPoints: 0,
14+
},
15+
assessment: {},
16+
annotations: [],
17+
posts: [],
18+
topics: [],
19+
questions: [{ id: 1, type: questionType, maximumGrade: 10 }],
20+
answers: [
21+
{
22+
id: answerId,
23+
fields: {
24+
id: answerId,
25+
questionId: 1,
26+
},
27+
questionId: 1,
28+
grading: {
29+
grade,
30+
id: answerId,
31+
},
32+
explanation: correct !== undefined ? { correct } : undefined,
33+
testCases,
34+
},
35+
],
36+
});
37+
38+
const dispatchFetchSuccess = (payload) =>
39+
dispatch({ type: actions.FETCH_SUBMISSION_SUCCESS, payload });
40+
41+
const getGrade = () =>
42+
store.getState().assessments.submission.grading.questions[1].grade;
43+
44+
describe('getPrefilledGrade via FETCH_SUBMISSION_SUCCESS', () => {
45+
describe('general behavior', () => {
46+
it('preserves existing grade even if answer is correct', () => {
47+
dispatchFetchSuccess(
48+
buildPayload({
49+
questionType: questionTypes.MultipleChoice,
50+
grade: 5,
51+
correct: true,
52+
}),
53+
);
54+
55+
expect(getGrade()).toBe(5);
56+
});
57+
58+
it('preserves existing grade even if answer is incorrect', () => {
59+
dispatchFetchSuccess(
60+
buildPayload({
61+
questionType: questionTypes.MultipleChoice,
62+
grade: 8,
63+
correct: false,
64+
}),
65+
);
66+
67+
expect(getGrade()).toBe(8);
68+
});
69+
70+
it('leaves grade as null when there is no explanation', () => {
71+
dispatchFetchSuccess(
72+
buildPayload({
73+
questionType: questionTypes.MultipleChoice,
74+
grade: null,
75+
correct: undefined,
76+
}),
77+
);
78+
79+
expect(getGrade()).toBeNull();
80+
});
81+
});
82+
83+
describe('Question Types with ALWAYS_PREFILL_POLICY', () => {
84+
it('prefills maximum grade for an ungraded correct answer', () => {
85+
dispatchFetchSuccess(
86+
buildPayload({
87+
questionType: questionTypes.MultipleChoice,
88+
grade: null,
89+
correct: true,
90+
}),
91+
);
92+
93+
expect(getGrade()).toBe(10);
94+
});
95+
96+
it('prefills 0 for an ungraded incorrect answer', () => {
97+
dispatchFetchSuccess(
98+
buildPayload({
99+
questionType: questionTypes.MultipleChoice,
100+
grade: null,
101+
correct: false,
102+
}),
103+
);
104+
105+
expect(getGrade()).toBe(0);
106+
});
107+
});
108+
109+
describe('Question Types with NEVER_PREFILL_POLICY', () => {
110+
it('does not prefill for an ungraded correct answer', () => {
111+
dispatchFetchSuccess(
112+
buildPayload({
113+
questionType: questionTypes.VoiceResponse,
114+
grade: null,
115+
correct: true,
116+
}),
117+
);
118+
119+
expect(getGrade()).toBeNull();
120+
});
121+
122+
it('does not prefill for an ungraded incorrect answer', () => {
123+
dispatchFetchSuccess(
124+
buildPayload({
125+
questionType: questionTypes.VoiceResponse,
126+
grade: null,
127+
correct: false,
128+
}),
129+
);
130+
131+
expect(getGrade()).toBeNull();
132+
});
133+
});
134+
135+
describe('Question Types with ONLY_PREFILL_FULL_POLICY', () => {
136+
it('prefills maximum grade for an ungraded correct answer', () => {
137+
dispatchFetchSuccess(
138+
buildPayload({
139+
questionType: questionTypes.TextResponse,
140+
grade: null,
141+
correct: true,
142+
}),
143+
);
144+
145+
expect(getGrade()).toBe(10);
146+
});
147+
148+
it('does not prefill 0 for an ungraded incorrect answer', () => {
149+
dispatchFetchSuccess(
150+
buildPayload({
151+
questionType: questionTypes.TextResponse,
152+
grade: null,
153+
correct: false,
154+
}),
155+
);
156+
157+
expect(getGrade()).toBeNull();
158+
});
159+
160+
it('prefills maximum grade for an ungraded fully correct MRQ answer', () => {
161+
dispatchFetchSuccess(
162+
buildPayload({
163+
questionType: questionTypes.MultipleResponse,
164+
grade: null,
165+
correct: true,
166+
}),
167+
);
168+
169+
expect(getGrade()).toBe(10);
170+
});
171+
172+
it('does not prefill 0 for an ungraded incorrect MRQ answer (partial credit possible)', () => {
173+
dispatchFetchSuccess(
174+
buildPayload({
175+
questionType: questionTypes.MultipleResponse,
176+
grade: null,
177+
correct: false,
178+
}),
179+
);
180+
181+
expect(getGrade()).toBeNull();
182+
});
183+
});
184+
185+
describe('Programming', () => {
186+
const withTestCases = {
187+
public_test: [{ identifier: 'test1' }],
188+
};
189+
190+
it('prefills maximum grade when test cases exist and answer is correct', () => {
191+
dispatchFetchSuccess(
192+
buildPayload({
193+
questionType: questionTypes.Programming,
194+
grade: null,
195+
correct: true,
196+
testCases: withTestCases,
197+
}),
198+
);
199+
200+
expect(getGrade()).toBe(10);
201+
});
202+
203+
it('does not prefill 0 when test cases exist and answer is incorrect', () => {
204+
dispatchFetchSuccess(
205+
buildPayload({
206+
questionType: questionTypes.Programming,
207+
grade: null,
208+
correct: false,
209+
testCases: withTestCases,
210+
}),
211+
);
212+
213+
expect(getGrade()).toBeNull();
214+
});
215+
216+
it('leaves grade as null when no test cases exist, even if answer is correct', () => {
217+
dispatchFetchSuccess(
218+
buildPayload({
219+
questionType: questionTypes.Programming,
220+
grade: null,
221+
correct: true,
222+
testCases: null,
223+
}),
224+
);
225+
226+
expect(getGrade()).toBeNull();
227+
});
228+
});
229+
});

0 commit comments

Comments
 (0)