Skip to content

Commit b3c5c03

Browse files
authored
fix: fix save question in order (#78)
1 parent 6aec4b6 commit b3c5c03

File tree

8 files changed

+1150
-907
lines changed

8 files changed

+1150
-907
lines changed

commitlint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {extends: ['@commitlint/config-conventional']}

cypress/e2e/Admin/create/createView.cy.js

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,34 @@ import {
66
CREATE_QUESTION_SELECT_TYPE_CY,
77
CREATE_QUESTION_TITLE_CY,
88
CREATE_VIEW_DELETE_BUTTON_CY,
9+
QUESTION_BAR_ADD_NEW_BUTTON_CLASSNAME,
10+
QUESTION_STEP_CLASSNAME,
911
QUESTION_BAR_CY,
1012
QUESTION_BAR_NEXT_CY,
1113
QUESTION_BAR_PREV_CY,
1214
buildQuestionStepCy,
1315
dataCyWrapper,
1416
} from '../../../../src/config/selectors';
1517
import { APP_SETTINGS } from '../../../fixtures/appSettings';
18+
import { fillMultipleChoiceQuestion } from './multipleChoices.cy';
19+
20+
const newMultipleChoiceData = {
21+
question: 'new question text',
22+
choices: [
23+
{
24+
value: 'new choice 1',
25+
isCorrect: true,
26+
},
27+
{
28+
value: 'new choice 2',
29+
isCorrect: true,
30+
},
31+
],
32+
explanation: 'my new explanation',
33+
};
1634

1735
describe('Create View', () => {
18-
it('Empty data', () => {
36+
beforeEach(() => {
1937
cy.setUpApi({
2038
database: {
2139
appSettings: [],
@@ -26,6 +44,9 @@ describe('Create View', () => {
2644
},
2745
});
2846
cy.visit('/');
47+
});
48+
49+
it('Empty data', () => {
2950
cy.get(dataCyWrapper(ADD_NEW_QUESTION_TITLE_CY)).should('be.visible');
3051
cy.get(dataCyWrapper(CREATE_QUESTION_TITLE_CY))
3152
.should('be.visible')
@@ -39,6 +60,28 @@ describe('Create View', () => {
3960
cy.get(dataCyWrapper(QUESTION_BAR_PREV_CY)).should('be.disabled');
4061
});
4162

63+
it('Add questions from empty quiz', () => {
64+
// Add three questions and make sure they are added to the QuestionTopBar
65+
cy.get(dataCyWrapper(ADD_NEW_QUESTION_TITLE_CY)).should('be.visible');
66+
fillMultipleChoiceQuestion(newMultipleChoiceData);
67+
cy.wait(2000); // Wait for the new question to appear
68+
cy.get(`.${QUESTION_BAR_ADD_NEW_BUTTON_CLASSNAME}`).click();
69+
cy.get(dataCyWrapper(CREATE_QUESTION_TITLE_CY))
70+
.should('be.visible')
71+
.should('have.value', '');
72+
fillMultipleChoiceQuestion(newMultipleChoiceData);
73+
cy.wait(2000);
74+
cy.get(`.${QUESTION_BAR_ADD_NEW_BUTTON_CLASSNAME}`).click();
75+
cy.get(dataCyWrapper(CREATE_QUESTION_TITLE_CY))
76+
.should('be.visible')
77+
.should('have.value', '');
78+
fillMultipleChoiceQuestion(newMultipleChoiceData);
79+
// Verify the questions are added to the order list by checking the number of
80+
// question nodes in the QuestionTopBar, as we cannot check the app settings directly
81+
cy.get('html').find(`.${QUESTION_STEP_CLASSNAME}`).should('have.length', 3);
82+
});
83+
84+
4285
describe('Create View', () => {
4386
beforeEach(() => {
4487
cy.setUpApi({
@@ -107,5 +150,25 @@ describe('Create View', () => {
107150
cy.get(dataCyWrapper(CREATE_VIEW_DELETE_BUTTON_CY)).should('be.disabled');
108151
cy.get(dataCyWrapper(ADD_NEW_QUESTION_TITLE_CY)).should('be.visible');
109152
});
153+
154+
it('Add question from existing quiz', () => {
155+
const currentQuestion = APP_SETTINGS[1];
156+
cy.get(dataCyWrapper(buildQuestionStepCy(currentQuestion.id))).click();
157+
// click new question and come back
158+
cy.get(`.${QUESTION_BAR_ADD_NEW_BUTTON_CLASSNAME}`).click();
159+
160+
// New question title should be visible
161+
cy.get(dataCyWrapper(ADD_NEW_QUESTION_TITLE_CY)).should('be.visible');
162+
cy.get(dataCyWrapper(CREATE_QUESTION_TITLE_CY))
163+
.should('be.visible')
164+
.should('have.value', '');
165+
cy.get(`${dataCyWrapper(CREATE_QUESTION_SELECT_TYPE_CY)} input`).should(
166+
'have.value',
167+
DEFAULT_QUESTION_TYPE
168+
);
169+
cy.get(dataCyWrapper(QUESTION_BAR_CY)).should('be.visible');
170+
fillMultipleChoiceQuestion(newMultipleChoiceData);
171+
cy.get('html').find(`.${QUESTION_STEP_CLASSNAME}`).should('have.length', 5);
172+
});
110173
});
111174
});

cypress/e2e/Admin/create/multipleChoices.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const newMultipleChoiceData = {
5353
explanation: 'my new explanation',
5454
};
5555

56-
const fillMultipleChoiceQuestion = (
56+
export const fillMultipleChoiceQuestion = (
5757
{ choices, question, explanation },
5858
{ shouldSave = true } = {}
5959
) => {

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"react-plotly.js": "2.6.0",
2727
"react-scripts": "5.0.1",
2828
"react-toastify": "9.1.3",
29+
"uuid": "^9.0.0",
2930
"web-vitals": "^3.3.2"
3031
},
3132
"scripts": {
@@ -74,8 +75,9 @@
7475
"@types/node": "18.16.19",
7576
"@types/react": "18.2.14",
7677
"@types/react-dom": "18.2.6",
77-
"@typescript-eslint/eslint-plugin": "5.59.11",
78-
"@typescript-eslint/parser": "5.59.11",
78+
"@types/uuid": "^9.0.2",
79+
"@typescript-eslint/eslint-plugin": "5.62.0",
80+
"@typescript-eslint/parser": "5.62.0",
7981
"cypress": "12.14.0",
8082
"env-cmd": "10.1.0",
8183
"eslint": "^8.3.0",

src/components/context/QuizContext.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const QuizProvider = ({ children }: Props) => {
4141
const { mutate: deleteAppSetting } = mutations.useDeleteAppSetting();
4242
const { mutateAsync: postAppSettingAsync, mutate: postAppSetting } =
4343
mutations.usePostAppSetting();
44-
const { mutate: patchAppSetting } = mutations.usePatchAppSetting();
44+
const { mutateAsync: patchAppSetting } = mutations.usePatchAppSetting();
4545
// current question idx
4646
// -1 if we are adding a new question
4747
const [currentIdx, setCurrentIdx] = useState(0);
@@ -51,6 +51,7 @@ export const QuizProvider = ({ children }: Props) => {
5151
const [currentQuestion, setCurrentQuestion] =
5252
useState<QuestionDataAppSettingRecord>(DEFAULT_QUESTION);
5353

54+
5455
const setCurrentIdxBounded = (newIdx: number) => {
5556
const computedIdx = Math.min(Math.max(0, newIdx), order.size - 1);
5657
setCurrentIdx(computedIdx);
@@ -82,6 +83,7 @@ export const QuizProvider = ({ children }: Props) => {
8283
setCurrentIdx(-1);
8384
};
8485

86+
// Saves Data of current question in db and adds its id to order list (at the end)
8587
const saveQuestion = async (newData: QuestionDataRecord) => {
8688
// add new question
8789
if (!currentQuestion?.id) {
@@ -99,7 +101,7 @@ export const QuizProvider = ({ children }: Props) => {
99101
} else {
100102
patchAppSetting({
101103
id: orderSetting.id,
102-
data: { list: order.push(newQuestion.id) },
104+
data: { list: order.push(newQuestion.id).toJS() },
103105
});
104106
}
105107
setCurrentIdx(order.size);
@@ -166,7 +168,6 @@ export const QuizProvider = ({ children }: Props) => {
166168
APP_SETTING_NAMES.QUESTION
167169
) as List<QuestionDataAppSettingRecord>)
168170
: List<QuestionDataAppSettingRecord>();
169-
170171
return {
171172
order,
172173
questions,

src/components/navigation/QuestionTopBar.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
QUESTION_BAR_CY,
2424
QUESTION_BAR_NEXT_CY,
2525
QUESTION_BAR_PREV_CY,
26+
QUESTION_STEP_CLASSNAME,
2627
buildQuestionStepCy,
2728
} from '../../config/selectors';
2829
import { QuizContext } from '../context/QuizContext';
@@ -128,7 +129,9 @@ const QuestionTopBar = ({ additionalSteps }: Props) => {
128129
sx={{ pb: 3 }}
129130
>
130131
{order?.map((qId: string, index: number) => (
131-
<Step key={qId} data-cy={buildQuestionStepCy(qId)}>
132+
<Step key={qId} data-cy={buildQuestionStepCy(qId)} className={
133+
QUESTION_STEP_CLASSNAME
134+
}>
132135
{renderLabel(qId, index)}
133136
</Step>
134137
))}

src/config/selectors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export const buildMultipleChoiceAnswerCy = (idx) =>
1010
`multipleChoiceAnswer-${idx}`;
1111
export const MULTIPLE_CHOICES_ANSWER_CORRECTNESS_CLASSNAME =
1212
'multipleChoicesAnswerCorrectness';
13+
export const QUESTION_STEP_CLASSNAME =
14+
'questionStep';
1315
export const buildMultipleChoiceDeleteAnswerButtonCy = (idx) =>
1416
`multipleChoiceDeleteAnswerButton-${idx}`;
1517
export const CREATE_VIEW_SAVE_BUTTON_CY = 'createViewSaveButton';

0 commit comments

Comments
 (0)