test: replacing snapshot tests with RTL tests part 9 (#2206)
This commit is contained in:
committed by
GitHub
parent
75ea7500e1
commit
962b30bed9
@@ -1,55 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Checker component with disabled 1`] = `
|
||||
<Fragment>
|
||||
<Radio
|
||||
checked={true}
|
||||
className="pt-2.5"
|
||||
disabled={true}
|
||||
isValid={true}
|
||||
onChange={[Function]}
|
||||
value="A"
|
||||
/>
|
||||
<Form.Label
|
||||
className="pt-2"
|
||||
>
|
||||
A
|
||||
</Form.Label>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Checker component with multiple answers 1`] = `
|
||||
<Fragment>
|
||||
<Form.Checkbox
|
||||
checked={true}
|
||||
className="pt-2.5"
|
||||
disabled={false}
|
||||
isValid={true}
|
||||
onChange={[Function]}
|
||||
value="A"
|
||||
/>
|
||||
<Form.Label
|
||||
className="pt-2"
|
||||
>
|
||||
A
|
||||
</Form.Label>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Checker component with single answer 1`] = `
|
||||
<Fragment>
|
||||
<Radio
|
||||
checked={true}
|
||||
className="pt-2.5"
|
||||
disabled={false}
|
||||
isValid={true}
|
||||
onChange={[Function]}
|
||||
value="A"
|
||||
/>
|
||||
<Form.Label
|
||||
className="pt-2"
|
||||
>
|
||||
A
|
||||
</Form.Label>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -1,27 +0,0 @@
|
||||
import 'CourseAuthoring/editors/setupEditorTest';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import Checker from '.';
|
||||
|
||||
const props = {
|
||||
hasSingleAnswer: true,
|
||||
answer: {
|
||||
id: 'A',
|
||||
title: 'Answer 1',
|
||||
correct: true,
|
||||
selectedFeedback: 'some feedback',
|
||||
},
|
||||
setAnswer: jest.fn(),
|
||||
};
|
||||
describe('Checker component', () => {
|
||||
test('with single answer', () => {
|
||||
expect(shallow(<Checker {...props} />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('with multiple answers', () => {
|
||||
expect(shallow(<Checker {...props} hasSingleAnswer={false} />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('with disabled', () => {
|
||||
expect(shallow(<Checker {...props} disabled />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import {
|
||||
render, screen, initializeMocks, fireEvent,
|
||||
} from '@src/testUtils';
|
||||
import Checker from '.';
|
||||
|
||||
const props = {
|
||||
hasSingleAnswer: true,
|
||||
answer: {
|
||||
id: 1,
|
||||
correct: true,
|
||||
},
|
||||
setAnswer: jest.fn(),
|
||||
};
|
||||
describe('Checker component', () => {
|
||||
beforeEach(() => {
|
||||
initializeMocks();
|
||||
});
|
||||
|
||||
test('renders with single answer', () => {
|
||||
render(<Checker {...props} />);
|
||||
expect(screen.getByText('1')).toBeInTheDocument();
|
||||
expect(screen.getByRole('radio')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('checkbox')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders with multiple answers', () => {
|
||||
render(<Checker {...props} hasSingleAnswer={false} />);
|
||||
expect(screen.getByRole('checkbox')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('radio')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders with disabled radio', () => {
|
||||
render(<Checker {...props} disabled />);
|
||||
expect(screen.getByRole('radio')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls setAnswer when radio button is clicked', () => {
|
||||
render(<Checker {...props} />);
|
||||
expect(screen.getByRole('radio')).toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('radio'), { target: { checked: !props.answer.correct } });
|
||||
expect(props.setAnswer).toHaveBeenCalledWith({ correct: true });
|
||||
});
|
||||
});
|
||||
@@ -1,14 +1,11 @@
|
||||
import 'CourseAuthoring/editors/setupEditorTest';
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { formatMessage } from '../../../../../../testUtils';
|
||||
import {
|
||||
render, screen, initializeMocks,
|
||||
} from '@src/testUtils';
|
||||
import { formatMessage } from '@src/editors/testUtils';
|
||||
import { selectors } from '../../../../../../data/redux';
|
||||
import { ShowAnswerCardInternal as ShowAnswerCard, mapStateToProps, mapDispatchToProps } from './ShowAnswerCard';
|
||||
import { useAnswerSettings } from '../hooks';
|
||||
|
||||
jest.mock('../hooks', () => ({
|
||||
useAnswerSettings: jest.fn(),
|
||||
}));
|
||||
import * as hooks from '../hooks';
|
||||
|
||||
jest.mock('../../../../../../data/redux', () => ({
|
||||
selectors: {
|
||||
@@ -30,33 +27,34 @@ describe('ShowAnswerCard', () => {
|
||||
updateSettings: jest.fn().mockName('args.updateSettings'),
|
||||
intl: { formatMessage },
|
||||
};
|
||||
|
||||
const props = {
|
||||
showAnswer,
|
||||
defaultValue: 'finished',
|
||||
updateSettings: jest.fn(),
|
||||
// injected
|
||||
intl: { formatMessage },
|
||||
// redux
|
||||
studioEndpointUrl: 'SoMEeNDpOinT',
|
||||
learningContextId: 'sOMEcouRseId',
|
||||
isLibrary: false,
|
||||
};
|
||||
|
||||
const useAnswerSettingsProps = {
|
||||
handleShowAnswerChange: jest.fn().mockName('useAnswerSettings.handleShowAnswerChange'),
|
||||
handleAttemptsChange: jest.fn().mockName('useAnswerSettings.handleAttemptsChange'),
|
||||
};
|
||||
|
||||
useAnswerSettings.mockReturnValue(useAnswerSettingsProps);
|
||||
|
||||
describe('behavior', () => {
|
||||
it(' calls useAnswerSettings when initialized', () => {
|
||||
shallow(<ShowAnswerCard {...props} />);
|
||||
expect(useAnswerSettings).toHaveBeenCalledWith(showAnswer, props.updateSettings);
|
||||
describe('renders', () => {
|
||||
beforeEach(() => {
|
||||
initializeMocks();
|
||||
});
|
||||
});
|
||||
|
||||
describe('snapshot', () => {
|
||||
test('snapshot: show answer setting card', () => {
|
||||
expect(shallow(<ShowAnswerCard {...props} />).snapshot).toMatchSnapshot();
|
||||
test('show answer setting card', () => {
|
||||
render(<ShowAnswerCard {...props} />);
|
||||
expect(screen.getByText('Show answer')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls useAnswerSettings when initialized', () => {
|
||||
jest.spyOn(hooks, 'useAnswerSettings');
|
||||
render(<ShowAnswerCard {...props} />);
|
||||
expect(screen.getByText('Show answer')).toBeInTheDocument();
|
||||
expect(hooks.useAnswerSettings).toHaveBeenCalledWith(showAnswer, props.updateSettings);
|
||||
});
|
||||
});
|
||||
describe('mapStateToProps', () => {
|
||||
@@ -64,11 +62,13 @@ describe('ShowAnswerCard', () => {
|
||||
test('studioEndpointUrl from app.studioEndpointUrl', () => {
|
||||
expect(
|
||||
mapStateToProps(testState).studioEndpointUrl,
|
||||
// @ts-ignore
|
||||
).toEqual(selectors.app.studioEndpointUrl(testState));
|
||||
});
|
||||
test('learningContextId from app.learningContextId', () => {
|
||||
expect(
|
||||
mapStateToProps(testState).learningContextId,
|
||||
// @ts-ignore
|
||||
).toEqual(selectors.app.learningContextId(testState));
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import SettingsOption from '../SettingsOption';
|
||||
import { ProblemTypeKeys, ProblemTypes } from '../../../../../../data/constants/problem';
|
||||
import messages from '../messages';
|
||||
@@ -14,9 +14,8 @@ const TypeCard = ({
|
||||
setBlockTitle,
|
||||
updateField,
|
||||
updateAnswer,
|
||||
// inject
|
||||
intl,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const problemTypeKeysArray = Object.values(ProblemTypeKeys).filter(key => key !== ProblemTypeKeys.ADVANCED);
|
||||
|
||||
if (problemType === ProblemTypeKeys.ADVANCED) { return null; }
|
||||
@@ -60,9 +59,6 @@ TypeCard.propTypes = {
|
||||
setBlockTitle: PropTypes.func.isRequired,
|
||||
updateField: PropTypes.func.isRequired,
|
||||
updateAnswer: PropTypes.func.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export const TypeCardInternal = TypeCard; // For testing only
|
||||
export default injectIntl(TypeCard);
|
||||
export default TypeCard;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import 'CourseAuthoring/editors/setupEditorTest';
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { formatMessage } from '../../../../../../testUtils';
|
||||
import { TypeCardInternal as TypeCard } from './TypeCard';
|
||||
import { ProblemTypeKeys } from '../../../../../../data/constants/problem';
|
||||
|
||||
describe('TypeCard', () => {
|
||||
const props = {
|
||||
answers: [],
|
||||
blockTitle: 'BLocktiTLE',
|
||||
correctAnswerCount: 0,
|
||||
problemType: ProblemTypeKeys.TEXTINPUT,
|
||||
setBlockTitle: jest.fn().mockName('args.setBlockTitle'),
|
||||
updateField: jest.fn().mockName('args.updateField'),
|
||||
updateAnswer: jest.fn().mockName('args.updateAnswer'),
|
||||
// injected
|
||||
intl: { formatMessage },
|
||||
};
|
||||
|
||||
describe('snapshot', () => {
|
||||
test('snapshot: renders type setting card', () => {
|
||||
expect(shallow(<TypeCard {...props} />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { render, screen, initializeMocks } from '@src/testUtils';
|
||||
import TypeCard from './TypeCard';
|
||||
import { ProblemTypeKeys } from '../../../../../../data/constants/problem';
|
||||
|
||||
describe('TypeCard', () => {
|
||||
const props = {
|
||||
answers: [],
|
||||
blockTitle: 'BLocktiTLE',
|
||||
correctAnswerCount: 0,
|
||||
problemType: ProblemTypeKeys.TEXTINPUT,
|
||||
setBlockTitle: jest.fn().mockName('args.setBlockTitle'),
|
||||
updateField: jest.fn().mockName('args.updateField'),
|
||||
updateAnswer: jest.fn().mockName('args.updateAnswer'),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
initializeMocks();
|
||||
});
|
||||
|
||||
test('renders type setting card', () => {
|
||||
render(<TypeCard {...props} />);
|
||||
expect(screen.getByText('Type')).toBeInTheDocument();
|
||||
expect(screen.getByText('Text input')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders nothing if problemType is advanced', () => {
|
||||
const { container } = render(<TypeCard {...props} problemType={ProblemTypeKeys.ADVANCED} />);
|
||||
expect(screen.queryByText('Type')).not.toBeInTheDocument();
|
||||
expect(container.firstChild?.textContent).toBe('');
|
||||
});
|
||||
});
|
||||
@@ -1,121 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ShowAnswerCard snapshot snapshot: show answer setting card 1`] = `
|
||||
<SettingsOption
|
||||
className=""
|
||||
extraSections={[]}
|
||||
hasExpandableTextArea={false}
|
||||
summary="After Some Number of Attempts"
|
||||
title="Show answer"
|
||||
>
|
||||
<Fragment>
|
||||
<div
|
||||
className="pb-2"
|
||||
>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
defaultMessage="Define when learners can see the correct answer."
|
||||
description="Show Answer settings card text"
|
||||
id="authoring.problemeditor.settings.showAnswer.text"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="pb-4"
|
||||
>
|
||||
<Hyperlink
|
||||
destination="SoMEeNDpOinT/settings/advanced/sOMEcouRseId#showanswer"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Set a default value in advanced settings"
|
||||
description="Advanced settings link text"
|
||||
id="authoring.problemeditor.settings.advancedSettingLink.text"
|
||||
/>
|
||||
</Hyperlink>
|
||||
</div>
|
||||
<Form.Group
|
||||
className="pb-0 mb-0"
|
||||
>
|
||||
<Form.Control
|
||||
as="select"
|
||||
onChange={[MockFunction useAnswerSettings.handleShowAnswerChange]}
|
||||
value="after_attempts"
|
||||
>
|
||||
<option
|
||||
key="always"
|
||||
value="always"
|
||||
>
|
||||
Always
|
||||
</option>
|
||||
<option
|
||||
key="answered"
|
||||
value="answered"
|
||||
>
|
||||
Answered
|
||||
</option>
|
||||
<option
|
||||
key="attempted"
|
||||
value="attempted"
|
||||
>
|
||||
Attempted or Past Due
|
||||
</option>
|
||||
<option
|
||||
key="closed"
|
||||
value="closed"
|
||||
>
|
||||
Closed
|
||||
</option>
|
||||
<option
|
||||
key="finished"
|
||||
value="finished"
|
||||
>
|
||||
Finished (Default)
|
||||
</option>
|
||||
<option
|
||||
key="correct_or_past_due"
|
||||
value="correct_or_past_due"
|
||||
>
|
||||
Correct or Past Due
|
||||
</option>
|
||||
<option
|
||||
key="past_due"
|
||||
value="past_due"
|
||||
>
|
||||
Past Due
|
||||
</option>
|
||||
<option
|
||||
key="never"
|
||||
value="never"
|
||||
>
|
||||
Never
|
||||
</option>
|
||||
<option
|
||||
key="after_attempts"
|
||||
value="after_attempts"
|
||||
>
|
||||
After Some Number of Attempts
|
||||
</option>
|
||||
<option
|
||||
key="after_all_attempts"
|
||||
value="after_all_attempts"
|
||||
>
|
||||
After All Attempts
|
||||
</option>
|
||||
<option
|
||||
key="after_all_attempts_or_correct"
|
||||
value="after_all_attempts_or_correct"
|
||||
>
|
||||
After All Attempts or Correct
|
||||
</option>
|
||||
<option
|
||||
key="attempted_no_past_due"
|
||||
value="attempted_no_past_due"
|
||||
>
|
||||
Attempted
|
||||
</option>
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
</Fragment>
|
||||
</SettingsOption>
|
||||
`;
|
||||
@@ -1,82 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TypeCard snapshot snapshot: renders type setting card 1`] = `
|
||||
<SettingsOption
|
||||
className=""
|
||||
extraSections={[]}
|
||||
hasExpandableTextArea={false}
|
||||
summary="Text input"
|
||||
title="Type"
|
||||
>
|
||||
<TypeRow
|
||||
answers={[]}
|
||||
blockTitle="BLocktiTLE"
|
||||
correctAnswerCount={0}
|
||||
key="multiplechoiceresponse"
|
||||
label="Single select"
|
||||
lastRow={false}
|
||||
problemType="stringresponse"
|
||||
selected={true}
|
||||
setBlockTitle={[MockFunction args.setBlockTitle]}
|
||||
typeKey="multiplechoiceresponse"
|
||||
updateAnswer={[MockFunction args.updateAnswer]}
|
||||
updateField={[MockFunction args.updateField]}
|
||||
/>
|
||||
<TypeRow
|
||||
answers={[]}
|
||||
blockTitle="BLocktiTLE"
|
||||
correctAnswerCount={0}
|
||||
key="choiceresponse"
|
||||
label="Multi-select"
|
||||
lastRow={false}
|
||||
problemType="stringresponse"
|
||||
selected={true}
|
||||
setBlockTitle={[MockFunction args.setBlockTitle]}
|
||||
typeKey="choiceresponse"
|
||||
updateAnswer={[MockFunction args.updateAnswer]}
|
||||
updateField={[MockFunction args.updateField]}
|
||||
/>
|
||||
<TypeRow
|
||||
answers={[]}
|
||||
blockTitle="BLocktiTLE"
|
||||
correctAnswerCount={0}
|
||||
key="optionresponse"
|
||||
label="Dropdown"
|
||||
lastRow={false}
|
||||
problemType="stringresponse"
|
||||
selected={true}
|
||||
setBlockTitle={[MockFunction args.setBlockTitle]}
|
||||
typeKey="optionresponse"
|
||||
updateAnswer={[MockFunction args.updateAnswer]}
|
||||
updateField={[MockFunction args.updateField]}
|
||||
/>
|
||||
<TypeRow
|
||||
answers={[]}
|
||||
blockTitle="BLocktiTLE"
|
||||
correctAnswerCount={0}
|
||||
key="numericalresponse"
|
||||
label="Numerical input"
|
||||
lastRow={false}
|
||||
problemType="stringresponse"
|
||||
selected={true}
|
||||
setBlockTitle={[MockFunction args.setBlockTitle]}
|
||||
typeKey="numericalresponse"
|
||||
updateAnswer={[MockFunction args.updateAnswer]}
|
||||
updateField={[MockFunction args.updateField]}
|
||||
/>
|
||||
<TypeRow
|
||||
answers={[]}
|
||||
blockTitle="BLocktiTLE"
|
||||
correctAnswerCount={0}
|
||||
key="stringresponse"
|
||||
label="Text input"
|
||||
lastRow={true}
|
||||
problemType="stringresponse"
|
||||
selected={false}
|
||||
setBlockTitle={[MockFunction args.setBlockTitle]}
|
||||
typeKey="stringresponse"
|
||||
updateAnswer={[MockFunction args.updateAnswer]}
|
||||
updateField={[MockFunction args.updateField]}
|
||||
/>
|
||||
</SettingsOption>
|
||||
`;
|
||||
@@ -1,309 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TextEditor snapshots block failed to load, Toast is shown 1`] = `
|
||||
<EditorContainer
|
||||
getContent={
|
||||
{
|
||||
"getContent": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
isDirty={
|
||||
{
|
||||
"isDirty": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClose={[MockFunction props.onClose]}
|
||||
returnFunction={null}
|
||||
>
|
||||
<div
|
||||
className="editor-body h-75 overflow-auto"
|
||||
>
|
||||
<Toast
|
||||
onClose={[MockFunction hooks.nullMethod]}
|
||||
show={true}
|
||||
>
|
||||
Error: Could Not Load Text Content
|
||||
</Toast>
|
||||
<TinyMceWidget
|
||||
disabled={false}
|
||||
editorContentHtml="eDiTablE Text"
|
||||
editorRef={
|
||||
{
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
}
|
||||
}
|
||||
editorType="text"
|
||||
enableImageUpload={true}
|
||||
id={null}
|
||||
images={{}}
|
||||
initializeEditor={[MockFunction args.intializeEditor]}
|
||||
isLibrary={null}
|
||||
learningContextId="course+org+run"
|
||||
lmsEndpointUrl=""
|
||||
maxHeight={500}
|
||||
minHeight={500}
|
||||
onChange={[Function]}
|
||||
setEditorRef={[MockFunction hooks.prepareEditorRef.setEditorRef]}
|
||||
studioEndpointUrl=""
|
||||
/>
|
||||
</div>
|
||||
</EditorContainer>
|
||||
`;
|
||||
|
||||
exports[`TextEditor snapshots loaded, raw editor 1`] = `
|
||||
<EditorContainer
|
||||
getContent={
|
||||
{
|
||||
"getContent": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": true,
|
||||
},
|
||||
}
|
||||
}
|
||||
isDirty={
|
||||
{
|
||||
"isDirty": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": true,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClose={[MockFunction props.onClose]}
|
||||
returnFunction={null}
|
||||
>
|
||||
<div
|
||||
className="editor-body h-75 overflow-auto"
|
||||
>
|
||||
<Toast
|
||||
onClose={[MockFunction hooks.nullMethod]}
|
||||
show={false}
|
||||
>
|
||||
Error: Could Not Load Text Content
|
||||
</Toast>
|
||||
<RawEditor
|
||||
content={
|
||||
{
|
||||
"data": {
|
||||
"data": "eDiTablE Text",
|
||||
},
|
||||
}
|
||||
}
|
||||
editorRef={
|
||||
{
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
}
|
||||
}
|
||||
lang="html"
|
||||
/>
|
||||
</div>
|
||||
</EditorContainer>
|
||||
`;
|
||||
|
||||
exports[`TextEditor snapshots not yet loaded, Spinner appears 1`] = `
|
||||
<EditorContainer
|
||||
getContent={
|
||||
{
|
||||
"getContent": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
isDirty={
|
||||
{
|
||||
"isDirty": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClose={[MockFunction props.onClose]}
|
||||
returnFunction={null}
|
||||
>
|
||||
<div
|
||||
className="editor-body h-75 overflow-auto"
|
||||
>
|
||||
<Toast
|
||||
onClose={[MockFunction hooks.nullMethod]}
|
||||
show={false}
|
||||
>
|
||||
Error: Could Not Load Text Content
|
||||
</Toast>
|
||||
<div
|
||||
className="text-center p-6"
|
||||
>
|
||||
<Spinner
|
||||
animation="border"
|
||||
className="m-3"
|
||||
screenreadertext="loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</EditorContainer>
|
||||
`;
|
||||
|
||||
exports[`TextEditor snapshots renders as expected with default behavior 1`] = `
|
||||
<EditorContainer
|
||||
getContent={
|
||||
{
|
||||
"getContent": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
isDirty={
|
||||
{
|
||||
"isDirty": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClose={[MockFunction props.onClose]}
|
||||
returnFunction={null}
|
||||
>
|
||||
<div
|
||||
className="editor-body h-75 overflow-auto"
|
||||
>
|
||||
<Toast
|
||||
onClose={[MockFunction hooks.nullMethod]}
|
||||
show={false}
|
||||
>
|
||||
Error: Could Not Load Text Content
|
||||
</Toast>
|
||||
<TinyMceWidget
|
||||
disabled={false}
|
||||
editorContentHtml="eDiTablE Text"
|
||||
editorRef={
|
||||
{
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
}
|
||||
}
|
||||
editorType="text"
|
||||
enableImageUpload={true}
|
||||
id={null}
|
||||
images={{}}
|
||||
initializeEditor={[MockFunction args.intializeEditor]}
|
||||
isLibrary={null}
|
||||
learningContextId="course+org+run"
|
||||
lmsEndpointUrl=""
|
||||
maxHeight={500}
|
||||
minHeight={500}
|
||||
onChange={[Function]}
|
||||
setEditorRef={[MockFunction hooks.prepareEditorRef.setEditorRef]}
|
||||
studioEndpointUrl=""
|
||||
/>
|
||||
</div>
|
||||
</EditorContainer>
|
||||
`;
|
||||
|
||||
exports[`TextEditor snapshots renders static images with relative paths 1`] = `
|
||||
<EditorContainer
|
||||
getContent={
|
||||
{
|
||||
"getContent": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
isDirty={
|
||||
{
|
||||
"isDirty": {
|
||||
"editorRef": {
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
},
|
||||
"showRawEditor": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
onClose={[MockFunction props.onClose]}
|
||||
returnFunction={null}
|
||||
>
|
||||
<div
|
||||
className="editor-body h-75 overflow-auto"
|
||||
>
|
||||
<Toast
|
||||
onClose={[MockFunction hooks.nullMethod]}
|
||||
show={false}
|
||||
>
|
||||
Error: Could Not Load Text Content
|
||||
</Toast>
|
||||
<TinyMceWidget
|
||||
disabled={false}
|
||||
editorContentHtml="eDiTablE Text with <img src="/asset+org+run+type@asset+block@img.jpg" />"
|
||||
editorRef={
|
||||
{
|
||||
"current": {
|
||||
"value": "something",
|
||||
},
|
||||
}
|
||||
}
|
||||
editorType="text"
|
||||
enableImageUpload={true}
|
||||
id={null}
|
||||
images={{}}
|
||||
initializeEditor={[MockFunction args.intializeEditor]}
|
||||
isLibrary={null}
|
||||
learningContextId="course+org+run"
|
||||
lmsEndpointUrl=""
|
||||
maxHeight={500}
|
||||
minHeight={500}
|
||||
onChange={[Function]}
|
||||
setEditorRef={[MockFunction hooks.prepareEditorRef.setEditorRef]}
|
||||
studioEndpointUrl=""
|
||||
/>
|
||||
</div>
|
||||
</EditorContainer>
|
||||
`;
|
||||
@@ -1,49 +1,14 @@
|
||||
import 'CourseAuthoring/editors/setupEditorTest';
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import { render, screen, initializeMocks } from '@src/testUtils';
|
||||
import { formatMessage } from '../../testUtils';
|
||||
import { actions, selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
import { TextEditorInternal as TextEditor, mapStateToProps, mapDispatchToProps } from '.';
|
||||
|
||||
// Per https://github.com/tinymce/tinymce-react/issues/91 React unit testing in JSDOM is not supported by tinymce.
|
||||
// Consequently, mock the Editor out.
|
||||
jest.mock('@tinymce/tinymce-react', () => {
|
||||
const originalModule = jest.requireActual('@tinymce/tinymce-react');
|
||||
return {
|
||||
__esModule: true,
|
||||
...originalModule,
|
||||
Editor: () => 'TiNYmCE EDitOR',
|
||||
};
|
||||
});
|
||||
jest.mock('../../sharedComponents/TinyMceWidget', () => 'TinyMceWidget');
|
||||
|
||||
jest.mock('../EditorContainer', () => 'EditorContainer');
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
getContent: jest.fn(args => ({ getContent: args })),
|
||||
isDirty: jest.fn(args => ({ isDirty: args })),
|
||||
nullMethod: jest.fn().mockName('hooks.nullMethod'),
|
||||
}));
|
||||
|
||||
jest.mock('../../sharedComponents/TinyMceWidget/hooks', () => ({
|
||||
...jest.requireActual('../../sharedComponents/TinyMceWidget/hooks'),
|
||||
prepareEditorRef: jest.fn(() => ({
|
||||
editorRef: { current: { value: 'something' } },
|
||||
refReady: true,
|
||||
setEditorRef: jest.fn().mockName('hooks.prepareEditorRef.setEditorRef'),
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('react', () => {
|
||||
const updateState = jest.fn();
|
||||
return {
|
||||
...jest.requireActual('react'),
|
||||
updateState,
|
||||
useState: jest.fn(val => ([{ state: val }, jest.fn().mockName('setState')])),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../../data/redux', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(),
|
||||
@@ -87,33 +52,52 @@ describe('TextEditor', () => {
|
||||
blockFinished: true,
|
||||
learningContextId: 'course+org+run',
|
||||
images: {},
|
||||
isLibrary: false,
|
||||
// inject
|
||||
intl: { formatMessage },
|
||||
};
|
||||
describe('snapshots', () => {
|
||||
test('renders as expected with default behavior', () => {
|
||||
expect(shallow(<TextEditor {...props} />).snapshot).toMatchSnapshot();
|
||||
|
||||
afterAll(() => jest.restoreAllMocks());
|
||||
describe('renders', () => {
|
||||
beforeEach(() => {
|
||||
initializeMocks();
|
||||
});
|
||||
|
||||
test('renders as expected with default behavior', () => {
|
||||
const { container } = render(<TextEditor {...props} />);
|
||||
const element = container.querySelector('tinymcewidget');
|
||||
expect(element).toBeInTheDocument();
|
||||
expect(element?.getAttribute('editorcontenthtml')).toBe('eDiTablE Text');
|
||||
});
|
||||
|
||||
test('renders static images with relative paths', () => {
|
||||
const updatedProps = {
|
||||
...props,
|
||||
blockValue: { data: { data: 'eDiTablE Text with <img src="/static/img.jpg" />' } },
|
||||
};
|
||||
expect(shallow(<TextEditor {...updatedProps} />).snapshot).toMatchSnapshot();
|
||||
const { container } = render(<TextEditor {...updatedProps} />);
|
||||
const element = container.querySelector('tinymcewidget');
|
||||
expect(element).toBeInTheDocument();
|
||||
expect(element?.getAttribute('editorcontenthtml')).toBe('eDiTablE Text with <img src="/asset+org+run+type@asset+block@img.jpg" />');
|
||||
});
|
||||
test('not yet loaded, Spinner appears', () => {
|
||||
expect(shallow(<TextEditor {...props} blockFinished={false} />).snapshot).toMatchSnapshot();
|
||||
const { container } = render(<TextEditor {...props} blockFinished={false} />);
|
||||
expect(container.querySelector('.pgn__spinner')).toBeInTheDocument();
|
||||
});
|
||||
test('loaded, raw editor', () => {
|
||||
expect(shallow(<TextEditor {...props} showRawEditor />).snapshot).toMatchSnapshot();
|
||||
render(<TextEditor {...props} showRawEditor />);
|
||||
expect(screen.getByText('You are using the raw html editor.')).toBeInTheDocument();
|
||||
});
|
||||
test('block failed to load, Toast is shown', () => {
|
||||
expect(shallow(<TextEditor {...props} blockFailed />).snapshot).toMatchSnapshot();
|
||||
render(<TextEditor {...props} blockFailed isLibrary />);
|
||||
expect(screen.getByRole('alert')).toBeInTheDocument();
|
||||
expect(screen.getByText('Error: Could Not Load Text Content')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapStateToProps', () => {
|
||||
const testState = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
// type set to any to prevent warning on not matchig expected type on the selectors
|
||||
const testState: any = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
test('blockValue from app.blockValue', () => {
|
||||
expect(
|
||||
mapStateToProps(testState).blockValue,
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'CourseAuthoring/editors/setupEditorTest';
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import {
|
||||
render, screen, initializeMocks, fireEvent,
|
||||
} from '@src/testUtils';
|
||||
import { thunkActions, selectors } from '../../../../../../data/redux';
|
||||
|
||||
import * as module from './TranscriptActionMenu';
|
||||
import * as componentModule from './TranscriptActionMenu';
|
||||
|
||||
const TranscriptActionMenu = module.TranscriptActionMenuInternal;
|
||||
const TranscriptActionMenu = componentModule.TranscriptActionMenuInternal;
|
||||
|
||||
jest.mock('react-redux', () => {
|
||||
const dispatchFn = jest.fn().mockName('mockUseDispatch');
|
||||
@@ -49,7 +49,7 @@ describe('TranscriptActionMenu', () => {
|
||||
const result = { newFile: { mockFile, name: mockFileName }, newFilename: mockFileName, language: lang1Code };
|
||||
|
||||
test('it dispatches the correct thunk', () => {
|
||||
const cb = module.hooks.replaceFileCallback({
|
||||
const cb = componentModule.hooks.replaceFileCallback({
|
||||
dispatch: mockDispatch, language: lang1Code,
|
||||
});
|
||||
cb(mockEvent);
|
||||
@@ -59,42 +59,51 @@ describe('TranscriptActionMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Snapshots', () => {
|
||||
describe('renders', () => {
|
||||
const props = {
|
||||
index: 'sOmenUmBer',
|
||||
index: 1,
|
||||
language: 'lAnG',
|
||||
launchDeleteConfirmation: jest.fn().mockName('launchDeleteConfirmation'),
|
||||
// redux
|
||||
getTranscriptDownloadUrl: jest.fn().mockName('selectors.video.getTranscriptDownloadUrl'),
|
||||
buildTranscriptUrl: jest.fn().mockName('selectors.video.buildTranscriptUrl'),
|
||||
buildTranscriptUrl: jest.fn().mockName('selectors.video.buildTranscriptUrl').mockImplementation((url) => url.transcriptUrl),
|
||||
};
|
||||
beforeEach(() => {
|
||||
initializeMocks();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
test('snapshots: renders as expected with default props: dont show confirm delete', () => {
|
||||
jest.spyOn(module.hooks, 'replaceFileCallback').mockImplementationOnce(() => jest.fn().mockName('module.hooks.replaceFileCallback'));
|
||||
expect(
|
||||
shallow(<TranscriptActionMenu {...props} />).snapshot,
|
||||
).toMatchSnapshot();
|
||||
|
||||
test('renders as expected with default props', () => {
|
||||
render(<TranscriptActionMenu {...props} />);
|
||||
expect(screen.getByRole('button', { name: 'Actions dropdown' })).toBeInTheDocument();
|
||||
});
|
||||
test('snapshots: renders as expected with transcriptUrl props: dont show confirm delete', () => {
|
||||
jest.spyOn(module.hooks, 'replaceFileCallback').mockImplementationOnce(() => jest.fn().mockName('module.hooks.replaceFileCallback'));
|
||||
expect(
|
||||
shallow(<TranscriptActionMenu {...props} transcriptUrl="url" />).snapshot,
|
||||
).toMatchSnapshot();
|
||||
|
||||
test('snapshots: renders as expected with transcriptUrl props', () => {
|
||||
render(<TranscriptActionMenu {...props} transcriptUrl="url" />);
|
||||
const actionsDropdown = screen.getByRole('button', { name: 'Actions dropdown' });
|
||||
expect(actionsDropdown).toBeInTheDocument();
|
||||
fireEvent.click(actionsDropdown);
|
||||
const downloadOption = screen.getByRole('link', { name: 'Download' });
|
||||
expect(downloadOption).toBeInTheDocument();
|
||||
expect(downloadOption).toHaveAttribute('href', 'url');
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapStateToProps', () => {
|
||||
const testState = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
// type set to any to prevent warning on not matchig expected type on the selectors
|
||||
const testState: any = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
test('getTranscriptDownloadUrl from video.getTranscriptDownloadUrl', () => {
|
||||
expect(
|
||||
module.mapStateToProps(testState).getTranscriptDownloadUrl,
|
||||
componentModule.mapStateToProps(testState).getTranscriptDownloadUrl,
|
||||
).toEqual(selectors.video.getTranscriptDownloadUrl(testState));
|
||||
});
|
||||
});
|
||||
describe('mapDispatchToProps', () => {
|
||||
test('deleteTranscript from thunkActions.video.deleteTranscript', () => {
|
||||
expect(module.mapDispatchToProps.downloadTranscript).toEqual(thunkActions.video.downloadTranscript);
|
||||
expect(componentModule.mapDispatchToProps.downloadTranscript).toEqual(thunkActions.video.downloadTranscript);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,109 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TranscriptActionMenu Snapshots snapshots: renders as expected with default props: dont show confirm delete 1`] = `
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle
|
||||
alt="Actions dropdown"
|
||||
as="IconButton"
|
||||
iconAs="Icon"
|
||||
id="dropdown-toggle-with-iconbutton-video-transcript-widget"
|
||||
variant="primary"
|
||||
/>
|
||||
<Dropdown.Menu
|
||||
className="video_transcript Action Menu"
|
||||
>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-replace"
|
||||
onClick={[MockFunction click input]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Replace"
|
||||
description="Message Presented To user for action to replace transcript"
|
||||
id="authoring.videoeditor.transcript.replaceTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-download"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Download"
|
||||
description="Message Presented To user for action to download transcript"
|
||||
id="authoring.videoeditor.transcript.downloadTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-delete"
|
||||
onClick={[MockFunction launchDeleteConfirmation]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete"
|
||||
description="Message Presented To user for action to delete transcript"
|
||||
id="authoring.videoeditor.transcript.deleteTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
<FileInput
|
||||
acceptedFiles=".srt"
|
||||
fileInput={
|
||||
{
|
||||
"click": [MockFunction click input],
|
||||
"onAddFile": [MockFunction module.hooks.replaceFileCallback],
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Dropdown>
|
||||
`;
|
||||
|
||||
exports[`TranscriptActionMenu Snapshots snapshots: renders as expected with transcriptUrl props: dont show confirm delete 1`] = `
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle
|
||||
alt="Actions dropdown"
|
||||
as="IconButton"
|
||||
iconAs="Icon"
|
||||
id="dropdown-toggle-with-iconbutton-video-transcript-widget"
|
||||
variant="primary"
|
||||
/>
|
||||
<Dropdown.Menu
|
||||
className="video_transcript Action Menu"
|
||||
>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-replace"
|
||||
onClick={[MockFunction click input]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Replace"
|
||||
description="Message Presented To user for action to replace transcript"
|
||||
id="authoring.videoeditor.transcript.replaceTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-download"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Download"
|
||||
description="Message Presented To user for action to download transcript"
|
||||
id="authoring.videoeditor.transcript.downloadTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
key="transcript-actions-sOmenUmBer-delete"
|
||||
onClick={[MockFunction launchDeleteConfirmation]}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete"
|
||||
description="Message Presented To user for action to delete transcript"
|
||||
id="authoring.videoeditor.transcript.deleteTranscript"
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
<FileInput
|
||||
acceptedFiles=".srt"
|
||||
fileInput={
|
||||
{
|
||||
"click": [MockFunction click input],
|
||||
"onAddFile": [MockFunction module.hooks.replaceFileCallback],
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Dropdown>
|
||||
`;
|
||||
Reference in New Issue
Block a user