Skip to content

Commit 5aca835

Browse files
Fix problem editor margins and borders (openedx#203)
* fix: fix border and allow customizing of tinymce style * fix: make tinymce widget look like on figma * fix: update settingsoptions card border * fix: header typography * fix: spacings * chore: update snapshots * Update src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * Update src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * Update src/editors/containers/ProblemEditor/components/EditProblemView/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * Update src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> * fix: html and react problems in problem editor * chore: update snapshots * chore: apply pr suggestions * chore: fix test coverage * chore: fix lint * chore: fix tests * chore: fix lint Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
1 parent d6d3363 commit 5aca835

File tree

23 files changed

+577
-464
lines changed

23 files changed

+577
-464
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@edx/frontend-platform": "2.4.0",
3939
"@edx/paragon": "^20.27.0",
4040
"@testing-library/dom": "^8.13.0",
41-
"@testing-library/react": "12.1.1",
41+
"@testing-library/react": "^12.1.1",
4242
"@testing-library/user-event": "^13.5.0",
4343
"codecov": "3.8.3",
4444
"enzyme": "3.11.0",

src/colors.scss

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/AnswersContainer.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Add } from '@edx/paragon/icons';
66
import { FormattedMessage } from '@edx/frontend-platform/i18n';
77

88
import messages from './messages';
9-
import { initializeAnswerContainer } from '../../../hooks';
9+
import { useAnswerContainer, isSingleAnswerProblem } from './hooks';
1010
import { actions, selectors } from '../../../../../data/redux';
1111
import { answerOptionProps } from '../../../../../data/services/cms/types';
1212
import AnswerOption from './AnswerOption';
@@ -18,9 +18,12 @@ export const AnswersContainer = ({
1818
addAnswer,
1919
updateField,
2020
}) => {
21-
const { hasSingleAnswer } = initializeAnswerContainer({ answers, problemType, updateField });
21+
const hasSingleAnswer = isSingleAnswerProblem(problemType);
22+
23+
useAnswerContainer({ answers, problemType, updateField });
24+
2225
return (
23-
<div className="border rounded border-light-700 py-4 pl-4 pr-3">
26+
<div className="border border-light-700 rounded py-4 pl-4 pr-3">
2427
{answers.map((answer) => (
2528
<AnswerOption
2629
key={answer.id}

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/AnswersContainer.test.jsx

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1+
/* eslint-disable react/prop-types */
12
import React from 'react';
23
import { shallow } from 'enzyme';
4+
import { act, render, waitFor } from '@testing-library/react';
5+
36
import { actions, selectors } from '../../../../../data/redux';
47

58
import * as module from './AnswersContainer';
69

10+
import { AnswersContainer as AnswersContainerWithoutHOC } from './AnswersContainer';
11+
12+
jest.mock('@edx/frontend-platform/i18n', () => ({
13+
FormattedMessage: ({ defaultMessage }) => (<p>{defaultMessage}</p>),
14+
injectIntl: (args) => args,
15+
intlShape: {},
16+
}));
17+
18+
jest.mock('./AnswerOption', () => () => <div>MockAnswerOption</div>);
19+
720
jest.mock('../../../../../data/redux', () => ({
821
actions: {
922
problem: {
@@ -25,10 +38,37 @@ describe('AnswersContainer', () => {
2538
};
2639
describe('render', () => {
2740
test('snapshot: renders correct default', () => {
28-
expect(shallow(<module.AnswersContainer {...props} />)).toMatchSnapshot();
41+
act(() => {
42+
expect(shallow(<module.AnswersContainer {...props} />)).toMatchSnapshot();
43+
});
2944
});
3045
test('snapshot: renders correctly with answers', () => {
31-
expect(shallow(<module.AnswersContainer answers={[{ id: 'a', title: 'sOMetITlE', correct: true }, { id: 'b', title: 'sOMetITlE', correct: true }]} {...props} />)).toMatchSnapshot();
46+
act(() => {
47+
expect(shallow(
48+
<module.AnswersContainer
49+
{...props}
50+
answers={[{ id: 'a', title: 'sOMetITlE', correct: true }, { id: 'b', title: 'sOMetITlE', correct: true }]}
51+
/>,
52+
)).toMatchSnapshot();
53+
});
54+
});
55+
56+
test('with react-testing-library', async () => {
57+
let container = null;
58+
await act(async () => {
59+
const wrapper = render(
60+
<AnswersContainerWithoutHOC
61+
{...props}
62+
answers={[{ id: 'a', title: 'sOMetITlE', correct: true }, { id: 'b', title: 'sOMetITlE', correct: true }]}
63+
/>,
64+
);
65+
container = wrapper.container;
66+
});
67+
68+
await waitFor(() => expect(container.querySelector('button')).toBeTruthy());
69+
await new Promise(resolve => setTimeout(resolve, 500));
70+
71+
expect(props.updateField).toHaveBeenCalledWith(expect.objectContaining({ correctAnswerCount: 2 }));
3272
});
3373
});
3474
describe('mapStateToProps', () => {

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/__snapshots__/AnswersContainer.test.jsx.snap

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
exports[`AnswersContainer render snapshot: renders correct default 1`] = `
44
<div
5-
className="border rounded border-light-700 py-4 pl-4 pr-3"
5+
className="border border-light-700 rounded py-4 pl-4 pr-3"
66
>
77
<Button
88
className="pl-0 text-primary-500"
@@ -20,8 +20,30 @@ exports[`AnswersContainer render snapshot: renders correct default 1`] = `
2020

2121
exports[`AnswersContainer render snapshot: renders correctly with answers 1`] = `
2222
<div
23-
className="border rounded border-light-700 py-4 pl-4 pr-3"
23+
className="border border-light-700 rounded py-4 pl-4 pr-3"
2424
>
25+
<Component
26+
answer={
27+
Object {
28+
"correct": true,
29+
"id": "a",
30+
"title": "sOMetITlE",
31+
}
32+
}
33+
hasSingleAnswer={false}
34+
key="a"
35+
/>
36+
<Component
37+
answer={
38+
Object {
39+
"correct": true,
40+
"id": "b",
41+
"title": "sOMetITlE",
42+
}
43+
}
44+
hasSingleAnswer={false}
45+
key="b"
46+
/>
2547
<Button
2648
className="pl-0 text-primary-500"
2749
onClick={[MockFunction]}

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/hook.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useEffect } from 'react';
22
import { MockUseState } from '../../../../../../testUtils';
3+
import { ProblemTypeKeys } from '../../../../../data/constants/problem';
34
import * as module from './hooks';
45

56
jest.mock('react', () => {
@@ -52,4 +53,15 @@ describe('Answer Options Hooks', () => {
5253
expect(state.setState[key]).toHaveBeenCalledWith(true);
5354
});
5455
});
56+
describe('isSingleAnswerProblem()', () => {
57+
test('singleSelect', () => {
58+
expect(module.isSingleAnswerProblem(ProblemTypeKeys.SINGLESELECT)).toBe(true);
59+
});
60+
test('multiSelect', () => {
61+
expect(module.isSingleAnswerProblem(ProblemTypeKeys.MULTISELECT)).toBe(false);
62+
});
63+
test('dropdown', () => {
64+
expect(module.isSingleAnswerProblem(ProblemTypeKeys.DROPDOWN)).toBe(true);
65+
});
66+
});
5567
});

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/hooks.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
22
import { StrictDict } from '../../../../../utils';
33
import * as module from './hooks';
44
import { actions } from '../../../../../data/redux';
5+
import { ProblemTypeKeys } from '../../../../../data/constants/problem';
56

67
export const state = StrictDict({
78
isFeedbackVisible: (val) => useState(val),
@@ -37,6 +38,22 @@ export const prepareFeedback = (answer) => {
3738
};
3839
};
3940

41+
export const isSingleAnswerProblem = (problemType) => (
42+
problemType === ProblemTypeKeys.DROPDOWN || problemType === ProblemTypeKeys.SINGLESELECT
43+
);
44+
45+
export const useAnswerContainer = ({ answers, updateField }) => {
46+
useEffect(() => {
47+
let answerCount = 0;
48+
answers.forEach(answer => {
49+
if (answer.correct) {
50+
answerCount += 1;
51+
}
52+
});
53+
updateField({ correctAnswerCount: answerCount });
54+
}, []);
55+
};
56+
4057
export default {
41-
state, removeAnswer, setAnswer, prepareFeedback,
58+
state, removeAnswer, setAnswer, prepareFeedback, isSingleAnswerProblem, useAnswerContainer,
4259
};

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const AnswerWidget = ({
1515
const problemStaticData = ProblemTypes[problemType];
1616
return (
1717
<div>
18-
<div className="p-3 text-primary-500">
18+
<div className="mt-4 mb-3 text-primary-500">
1919
<div className="h4">
2020
<FormattedMessage {...messages.answerWidgetTitle} />
2121
</div>

src/editors/containers/ProblemEditor/components/EditProblemView/AnswerWidget/index.scss

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@import '../../../../../../colors.scss';
2-
31
.answer-option {
42
.answer-option-flex-item-1 {
53
flex-basis: 8.33%;
@@ -27,8 +25,8 @@
2725
}
2826

2927
&:focus, &:hover {
30-
border-bottom: 1px solid $black;
28+
border-bottom: 1px solid #000;
3129
}
3230
}
3331
}
34-
}
32+
}

0 commit comments

Comments
 (0)