Skip to content

Commit dd641c4

Browse files
authored
Grading: Viewable Assessment Briefings (#2783)
* Added briefing (long summary) to Grading (#2310) * Updated grading briefing to be inline with backend's camelCase * resolve on some type conflicts * fix for TypeError on test action * Added subtype for GradingQuery with GradingAssessment; added GradingMock data; code cleanup * resolved edited export type Updates the grading query fetched from the backend to include the assessment briefing, as per changes made in source-academy/backend#1059. Also includes a new tab to view briefings during grading.
1 parent 10bbed6 commit dd641c4

File tree

12 files changed

+220
-98
lines changed

12 files changed

+220
-98
lines changed

src/commons/application/ApplicationTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Chapter, Language, SourceError, Variant } from 'js-slang/dist/types';
33
import { AcademyState } from '../../features/academy/AcademyTypes';
44
import { AchievementState } from '../../features/achievement/AchievementTypes';
55
import { DashboardState } from '../../features/dashboard/DashboardTypes';
6-
import { Grading } from '../../features/grading/GradingTypes';
6+
import { GradingQuery } from '../../features/grading/GradingTypes';
77
import { PlaygroundState } from '../../features/playground/PlaygroundTypes';
88
import { PlaybackStatus, RecordingStatus } from '../../features/sourceRecorder/SourceRecorderTypes';
99
import { StoriesEnvState, StoriesState } from '../../features/stories/StoriesTypes';
@@ -508,7 +508,7 @@ export const defaultSession: SessionState = {
508508
sessionId: Date.now(),
509509
githubOctokitObject: { octokit: undefined },
510510
gradingOverviews: undefined,
511-
gradings: new Map<number, Grading>(),
511+
gradings: new Map<number, GradingQuery>(),
512512
notifications: []
513513
};
514514

src/commons/application/actions/SessionActions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { action } from 'typesafe-actions'; // EDITED
22

3-
import { Grading, GradingOverview } from '../../../features/grading/GradingTypes';
3+
import { GradingOverview, GradingQuery } from '../../../features/grading/GradingTypes';
44
import {
55
Assessment,
66
AssessmentConfiguration,
@@ -209,7 +209,7 @@ export const updateGradingOverviews = (overviews: GradingOverview[]) =>
209209
* An extra id parameter is included here because of
210210
* no id for Grading.
211211
*/
212-
export const updateGrading = (submissionId: number, grading: Grading) =>
212+
export const updateGrading = (submissionId: number, grading: GradingQuery) =>
213213
action(UPDATE_GRADING, {
214214
submissionId,
215215
grading

src/commons/application/actions/__tests__/SessionActions.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Chapter, Variant } from 'js-slang/dist/types';
22

3-
import { Grading, GradingOverview } from '../../../../features/grading/GradingTypes';
3+
import { GradingOverview, GradingQuery } from '../../../../features/grading/GradingTypes';
44
import { Assessment, AssessmentOverview } from '../../../assessment/AssessmentTypes';
55
import { Notification } from '../../../notificationBadge/NotificationBadgeTypes';
66
import { GameState, Role, Story } from '../../ApplicationTypes';
@@ -542,26 +542,38 @@ test('updateGradingOverviews generates correct action object', () => {
542542

543543
test('updateGrading generates correct action object', () => {
544544
const submissionId = 3;
545-
const grading: Grading = [
546-
{
547-
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
548-
student: {
549-
name: 'test student',
550-
username: 'E0123456',
551-
id: 234
552-
},
553-
grade: {
554-
xp: 100,
555-
xpAdjustment: 0,
556-
comments: 'Well done.',
557-
grader: {
558-
name: 'HARTIN MENZ',
559-
id: 100
545+
const grading: GradingQuery = {
546+
answers: [
547+
{
548+
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
549+
student: {
550+
name: 'test student',
551+
username: 'E0123456',
552+
id: 234
560553
},
561-
gradedAt: '2019-08-16T13:26:32+00:00'
554+
grade: {
555+
xp: 100,
556+
xpAdjustment: 0,
557+
comments: 'Well done.',
558+
grader: {
559+
name: 'HARTIN MENZ',
560+
id: 100
561+
},
562+
gradedAt: '2019-08-16T13:26:32+00:00'
563+
}
562564
}
565+
],
566+
assessment: {
567+
coverPicture: 'https://i.imgur.com/dR7zBPI.jpeg',
568+
id: 1,
569+
number: '5',
570+
reading: 'reading here',
571+
story: 'story here',
572+
summaryLong: 'long summary here',
573+
summaryShort: 'short summary here',
574+
title: 'assessment title here'
563575
}
564-
];
576+
};
565577

566578
const action = updateGrading(submissionId, grading);
567579
expect(action).toEqual({

src/commons/application/reducers/__tests__/SessionReducer.ts

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Chapter, Variant } from 'js-slang/dist/types';
22

3-
import { Grading, GradingOverview } from '../../../../features/grading/GradingTypes';
3+
import { GradingOverview, GradingQuery } from '../../../../features/grading/GradingTypes';
44
import {
55
Assessment,
66
AssessmentOverview,
@@ -381,37 +381,61 @@ test('UPDATE_ASSESSMENT_OVERVIEWS works correctly in updating assessment overvie
381381
});
382382

383383
// Test data for UPDATE_GRADING
384-
const gradingTest1: Grading = [
385-
{
386-
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
387-
student: {
388-
name: 'test student',
389-
username: 'E0123456',
390-
id: 234
391-
},
392-
grade: {
393-
xp: 100,
394-
xpAdjustment: 0,
395-
comments: 'Well done. Please try the quest!'
384+
const gradingTest1: GradingQuery = {
385+
answers: [
386+
{
387+
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
388+
student: {
389+
name: 'test student',
390+
username: 'E0123456',
391+
id: 234
392+
},
393+
grade: {
394+
xp: 100,
395+
xpAdjustment: 0,
396+
comments: 'Well done. Please try the quest!'
397+
}
396398
}
399+
],
400+
assessment: {
401+
coverPicture: 'test string',
402+
id: 1,
403+
number: 'M1A',
404+
reading: 'test string',
405+
story: 'test string',
406+
summaryLong: 'test string',
407+
summaryShort: 'test string',
408+
title: 'test string'
397409
}
398-
];
410+
};
399411

400-
const gradingTest2: Grading = [
401-
{
402-
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
403-
student: {
404-
name: 'another test student',
405-
username: 'E0000000',
406-
id: 345
407-
},
408-
grade: {
409-
xp: 500,
410-
xpAdjustment: 20,
411-
comments: 'Good job! All the best for the finals.'
412+
const gradingTest2: GradingQuery = {
413+
answers: [
414+
{
415+
question: jest.genMockFromModule('../../../../features/grading/GradingTypes'),
416+
student: {
417+
name: 'another test student',
418+
username: 'E0000000',
419+
id: 345
420+
},
421+
grade: {
422+
xp: 500,
423+
xpAdjustment: 20,
424+
comments: 'Good job! All the best for the finals.'
425+
}
412426
}
427+
],
428+
assessment: {
429+
coverPicture: 'another test string',
430+
id: 2,
431+
number: 'P2',
432+
reading: 'another test string',
433+
story: 'another test string',
434+
summaryLong: 'another test string',
435+
summaryShort: 'another test string',
436+
title: 'another test string'
413437
}
414-
];
438+
};
415439

416440
test('UPDATE_GRADING works correctly in inserting gradings', () => {
417441
const submissionId = 23;
@@ -423,14 +447,14 @@ test('UPDATE_GRADING works correctly in inserting gradings', () => {
423447
}
424448
};
425449

426-
const gradingMap: Map<number, Grading> = SessionsReducer(defaultSession, action).gradings;
450+
const gradingMap: Map<number, GradingQuery> = SessionsReducer(defaultSession, action).gradings;
427451
expect(gradingMap.get(submissionId)).toEqual(gradingTest1);
428452
});
429453

430454
test('UPDATE_GRADING works correctly in inserting gradings and retains old data', () => {
431455
const submissionId1 = 45;
432456
const submissionId2 = 56;
433-
const gradings = new Map<number, Grading>();
457+
const gradings = new Map<number, GradingQuery>();
434458
gradings.set(submissionId1, gradingTest1);
435459

436460
const newDefaultSession = {
@@ -446,14 +470,14 @@ test('UPDATE_GRADING works correctly in inserting gradings and retains old data'
446470
}
447471
};
448472

449-
const gradingMap: Map<number, Grading> = SessionsReducer(newDefaultSession, action).gradings;
473+
const gradingMap: Map<number, GradingQuery> = SessionsReducer(newDefaultSession, action).gradings;
450474
expect(gradingMap.get(submissionId1)).toEqual(gradingTest1);
451475
expect(gradingMap.get(submissionId2)).toEqual(gradingTest2);
452476
});
453477

454478
test('UPDATE_GRADING works correctly in updating gradings', () => {
455479
const submissionId = 23;
456-
const gradings = new Map<number, Grading>();
480+
const gradings = new Map<number, GradingQuery>();
457481
gradings.set(submissionId, gradingTest1);
458482
const newDefaultSession = {
459483
...defaultSession,
@@ -468,7 +492,7 @@ test('UPDATE_GRADING works correctly in updating gradings', () => {
468492
}
469493
};
470494

471-
const gradingMap: Map<number, Grading> = SessionsReducer(newDefaultSession, action).gradings;
495+
const gradingMap: Map<number, GradingQuery> = SessionsReducer(newDefaultSession, action).gradings;
472496
expect(gradingMap.get(submissionId)).toEqual(gradingTest2);
473497
});
474498

src/commons/application/types/SessionTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Octokit } from '@octokit/rest';
22
import { Chapter, Variant } from 'js-slang/dist/types';
33

4-
import { Grading, GradingOverview } from '../../../features/grading/GradingTypes';
4+
import { GradingOverview, GradingQuery } from '../../../features/grading/GradingTypes';
55
import { Device, DeviceSession } from '../../../features/remoteExecution/RemoteExecutionTypes';
66
import {
77
Assessment,
@@ -115,7 +115,7 @@ export type SessionState = {
115115
readonly assessmentOverviews?: AssessmentOverview[];
116116
readonly assessments: Map<number, Assessment>;
117117
readonly gradingOverviews?: GradingOverview[];
118-
readonly gradings: Map<number, Grading>;
118+
readonly gradings: Map<number, GradingQuery>;
119119
readonly notifications: Notification[];
120120
readonly googleUser?: string;
121121
readonly githubAssessment?: MissionRepoData;

src/commons/mocks/BackendMocks.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { SagaIterator } from 'redux-saga';
22
import { call, put, select, takeEvery } from 'redux-saga/effects';
33

44
import { FETCH_GROUP_GRADING_SUMMARY } from '../../features/dashboard/DashboardTypes';
5-
import { Grading, GradingOverview, GradingQuestion } from '../../features/grading/GradingTypes';
5+
import {
6+
GradingOverview,
7+
GradingQuery,
8+
GradingQuestion
9+
} from '../../features/grading/GradingTypes';
610
import {
711
OverallState,
812
Role,
@@ -177,7 +181,7 @@ export function* mockBackendSaga(): SagaIterator {
177181
const accessToken = yield select((state: OverallState) => state.session.accessToken);
178182
const grading = yield call(() => mockFetchGrading(accessToken, submissionId));
179183
if (grading !== null) {
180-
yield put(actions.updateGrading(submissionId, [...grading]));
184+
yield put(actions.updateGrading(submissionId, grading));
181185
}
182186
});
183187

@@ -217,10 +221,10 @@ export function* mockBackendSaga(): SagaIterator {
217221

218222
const { submissionId, questionId, xpAdjustment, comments } = action.payload;
219223
// Now, update the grade for the question in the Grading in the store
220-
const grading: Grading = yield select((state: OverallState) =>
224+
const grading: GradingQuery = yield select((state: OverallState) =>
221225
state.session.gradings.get(submissionId)
222226
);
223-
const newGrading = grading.slice().map((gradingQuestion: GradingQuestion) => {
227+
const newGrading = grading.answers.slice().map((gradingQuestion: GradingQuestion) => {
224228
if (gradingQuestion.question.id === questionId) {
225229
gradingQuestion.grade = {
226230
xpAdjustment,
@@ -230,7 +234,9 @@ export function* mockBackendSaga(): SagaIterator {
230234
}
231235
return gradingQuestion;
232236
});
233-
yield put(actions.updateGrading(submissionId, newGrading));
237+
yield put(
238+
actions.updateGrading(submissionId, { answers: newGrading, assessment: grading.assessment })
239+
);
234240
yield call(showSuccessMessage, 'Submitted!', 1000);
235241
};
236242

src/commons/mocks/GradingMocks.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { GradingSummary } from '../../features/dashboard/DashboardTypes';
2-
import { Grading, GradingOverview } from '../../features/grading/GradingTypes';
2+
import {
3+
GradingAnswer,
4+
GradingAssessment,
5+
GradingOverview,
6+
GradingQuery
7+
} from '../../features/grading/GradingTypes';
38
import { Role } from '../application/ApplicationTypes';
49
import { Testcase, TestcaseTypes } from '../assessment/AssessmentTypes';
510
import { mockLibrary } from './AssessmentMocks';
@@ -102,7 +107,7 @@ export const mockTestcases: Testcase[] = [
102107
{ type: TestcaseTypes.opaque, program: `remainder(17, 23) === 17;`, score: 2, answer: `true` }
103108
];
104109

105-
export const mockGrading: Grading = [
110+
export const mockGradingAnswer: GradingAnswer = [
106111
{
107112
question: {
108113
answer: `function remainder(n, d) {
@@ -386,20 +391,47 @@ New message from **Avenger**!
386391
}
387392
];
388393

394+
export const mockGradingAssessment: GradingAssessment = {
395+
coverPicture: 'https://i.imgur.com/dR7zBPI.jpeg',
396+
id: 1,
397+
number: '10',
398+
reading:
399+
'This is for you to read. Read it carefully. Perhaps you will find the answer to life here.',
400+
story: `Story:
401+
Start of story.
402+
End of story.
403+
The End.
404+
405+
Credits
406+
Starring: Source Academy`,
407+
summaryLong:
408+
'This is the long summary of the assessment. It is a very very very very long summary',
409+
summaryShort: 'This is short summary',
410+
title: 'Assessment 1: Some Title'
411+
};
412+
413+
export const mockGradingQuery: GradingQuery = {
414+
answers: mockGradingAnswer,
415+
assessment: mockGradingAssessment
416+
};
417+
389418
/**
390419
* Mock for fetching a trainer/admin's student grading information.
391420
* A null value is returned for invalid token or role.
392421
*
393422
* @param accessToken a valid access token for the cadet backend.
394423
*/
395-
export const mockFetchGrading = (accessToken: string, submissionId: number): Grading | null => {
424+
export const mockFetchGrading = (
425+
accessToken: string,
426+
submissionId: number
427+
): GradingQuery | null => {
396428
// mocks backend role fetching
397429
const permittedRoles: Role[] = [Role.Admin, Role.Staff];
398430
const role: Role | null = mockFetchRole(accessToken);
399431
if (role === null || !permittedRoles.includes(role)) {
400432
return null;
401433
} else {
402-
return mockGrading;
434+
return mockGradingQuery;
403435
}
404436
};
405437

0 commit comments

Comments
 (0)