fix: resolve incorrect or missing 'await' usages (#2592)
* chore: fix incorrect or missing 'await' usages * test: fix broken test * chore: ignore lines causing patch coverage to fail
This commit is contained in:
@@ -72,6 +72,7 @@ const LiveSettings = ({
|
||||
};
|
||||
|
||||
const handleSettingsSave = async (values) => {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(saveLiveConfiguration(courseId, values, navigate));
|
||||
};
|
||||
|
||||
|
||||
@@ -48,8 +48,9 @@ const ORASettings = ({ onClose }) => {
|
||||
event.preventDefault();
|
||||
|
||||
success = success && await handleSettingsSave(formValues);
|
||||
await setSaveError(!success);
|
||||
setSaveError(!success);
|
||||
if ((initialFormValues.enableFlexiblePeerGrade !== formValues.enableFlexiblePeerGrade) && success) {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
success = await dispatch(updateModel({
|
||||
modelType: 'courseApps',
|
||||
model: {
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('ORASettings', () => {
|
||||
await mockStore({ apiStatus: 200, enabled: true });
|
||||
renderComponent();
|
||||
|
||||
const checkbox = await screen.getByRole('checkbox', { name: /Flex Peer Grading/ });
|
||||
const checkbox = screen.getByRole('checkbox', { name: /Flex Peer Grading/ });
|
||||
expect(checkbox).toBeChecked();
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
@@ -239,8 +239,10 @@ const SettingsModal = ({
|
||||
const values = { ...rest, enabled: enabled ? checked === 'true' : undefined };
|
||||
|
||||
if (enabled) {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
success = await dispatch(updateXpertSettings(courseId, values));
|
||||
} else {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
success = await dispatch(removeXpertSettings(courseId));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ const useCertificatesList = (courseId) => {
|
||||
}));
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(updateCourseCertificate(courseId, values));
|
||||
setEditModes({});
|
||||
dispatch(setMode(MODE_STATES.view));
|
||||
|
||||
@@ -172,6 +172,7 @@ export const useContentTaxonomyTagsUpdater = (contentId: string) => {
|
||||
// feature to support the legacy Django template courseware page.
|
||||
|
||||
// Sends content tags.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
getContentTaxonomyTagsData(contentId).then((data) => {
|
||||
const contentData = { contentId, ...data };
|
||||
|
||||
@@ -187,6 +188,7 @@ export const useContentTaxonomyTagsUpdater = (contentId: string) => {
|
||||
});
|
||||
|
||||
// Sends tags count.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
getContentTaxonomyTagsCount(contentId).then((count) => {
|
||||
const contentData = { contentId, count };
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ describe('CourseChecklistPage', () => {
|
||||
});
|
||||
describe('renders', () => {
|
||||
describe('if enable_quality prop is true', () => {
|
||||
it('two checklist components ', () => {
|
||||
it('two checklist components ', async () => {
|
||||
renderComponent();
|
||||
mockStore(200);
|
||||
await mockStore(200);
|
||||
|
||||
expect(screen.getByText(messages.launchChecklistLabel.defaultMessage)).toBeVisible();
|
||||
|
||||
@@ -67,7 +67,7 @@ describe('CourseChecklistPage', () => {
|
||||
|
||||
it('correct content when the launch checklist has loaded', async () => {
|
||||
renderComponent();
|
||||
mockStore(404);
|
||||
await mockStore(404);
|
||||
await waitFor(() => {
|
||||
const { launchChecklistStatus } = store.getState().courseChecklist.loadingStatus;
|
||||
|
||||
@@ -79,7 +79,7 @@ describe('CourseChecklistPage', () => {
|
||||
|
||||
it('correct content when the best practices checklist is loading', async () => {
|
||||
renderComponent();
|
||||
mockStore(404);
|
||||
await mockStore(404);
|
||||
await waitFor(() => {
|
||||
const { bestPracticeChecklistStatus } = store.getState().courseChecklist.loadingStatus;
|
||||
|
||||
@@ -100,9 +100,9 @@ describe('CourseChecklistPage', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('one checklist components ', () => {
|
||||
it('one checklist components ', async () => {
|
||||
renderComponent();
|
||||
mockStore(200);
|
||||
await mockStore(200);
|
||||
|
||||
expect(screen.getByText(messages.launchChecklistLabel.defaultMessage)).toBeVisible();
|
||||
|
||||
@@ -112,7 +112,7 @@ describe('CourseChecklistPage', () => {
|
||||
describe('an aria-live region with', () => {
|
||||
it('correct content when the launch checklist has loaded', async () => {
|
||||
renderComponent();
|
||||
mockStore(404);
|
||||
await mockStore(404);
|
||||
await waitFor(() => {
|
||||
const { launchChecklistStatus } = store.getState().courseChecklist.loadingStatus;
|
||||
|
||||
@@ -124,7 +124,7 @@ describe('CourseChecklistPage', () => {
|
||||
|
||||
it('correct content when the best practices checklist is loading', async () => {
|
||||
renderComponent();
|
||||
mockStore(404);
|
||||
await mockStore(404);
|
||||
await waitFor(() => {
|
||||
const { bestPracticeChecklistStatus } = store.getState().courseChecklist.loadingStatus;
|
||||
|
||||
|
||||
@@ -31,11 +31,13 @@ const LegacyLibContentBlockAlert = ({ courseId }: Props) => {
|
||||
if (taskStatus.data?.state === UserTaskStatus.Succeeded) {
|
||||
showToast(intl.formatMessage(messages.legacyLibReadyToMigrateTaskCompleted));
|
||||
setTaskId(undefined);
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
refetch();
|
||||
} else if (taskStatus.data?.state === UserTaskStatus.Failed
|
||||
|| taskStatus.data?.state === UserTaskStatus.Cancelled) {
|
||||
showToast(intl.formatMessage(messages.legacyLibReadyToMigrateTaskFailed));
|
||||
setTaskId(undefined);
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
refetch();
|
||||
} else if (taskId) {
|
||||
showToast(intl.formatMessage(messages.legacyLibReadyToMigrateTaskInProgress));
|
||||
|
||||
@@ -471,11 +471,11 @@ describe('<CourseOutline />', () => {
|
||||
const dummyBtn = await screen.findByRole('button', { name: 'Dummy button' });
|
||||
fireEvent.click(dummyBtn);
|
||||
|
||||
waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
|
||||
const [section] = courseOutlineIndexMock.courseStructure.childInfo.children;
|
||||
const [subsection] = section.childInfo.children;
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post[2].data).toBe(JSON.stringify({
|
||||
type: COMPONENT_TYPES.libraryV2,
|
||||
category: 'vertical',
|
||||
@@ -509,10 +509,10 @@ describe('<CourseOutline />', () => {
|
||||
const dummyBtn = await screen.findByRole('button', { name: 'Dummy button' });
|
||||
fireEvent.click(dummyBtn);
|
||||
|
||||
waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
|
||||
const [section] = courseOutlineIndexMock.courseStructure.childInfo.children;
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post[2].data).toBe(JSON.stringify({
|
||||
type: COMPONENT_TYPES.libraryV2,
|
||||
category: 'sequential',
|
||||
@@ -545,10 +545,10 @@ describe('<CourseOutline />', () => {
|
||||
const dummyBtn = await screen.findByRole('button', { name: 'Dummy button' });
|
||||
fireEvent.click(dummyBtn);
|
||||
|
||||
waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(3));
|
||||
|
||||
const courseUsageKey = courseOutlineIndexMock.courseStructure.id;
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post[2].data).toBe(JSON.stringify({
|
||||
type: COMPONENT_TYPES.libraryV2,
|
||||
category: 'chapter',
|
||||
|
||||
@@ -321,6 +321,7 @@ const LegacyOutlineAddChildButtons = ({
|
||||
}
|
||||
|
||||
const handleOnComponentSelected = (selected: SelectedComponent) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
onUseLibraryContent(selected);
|
||||
closeAddLibrarySectionModal();
|
||||
};
|
||||
|
||||
@@ -229,7 +229,7 @@ describe('<CardHeader />', () => {
|
||||
});
|
||||
|
||||
expect(await screen.findByTestId('subsection-edit-field')).toBeInTheDocument();
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('subsection-card-header__expanded-btn')).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('edit-button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -113,6 +113,7 @@ const useCourseOutline = ({ courseId }) => {
|
||||
|
||||
const headerNavigationsActions = {
|
||||
handleNewSection: () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
handleAddSection.mutateAsync({
|
||||
type: ContainerType.Chapter,
|
||||
parentLocator: courseStructure?.id,
|
||||
|
||||
@@ -318,12 +318,12 @@ describe('<SectionCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('section-card');
|
||||
const menu = await within(element).findByTestId('section-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('section-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
const drawer = await screen.findByRole('alert');
|
||||
expect(within(drawer).getByText(/manage tags/i));
|
||||
@@ -364,12 +364,12 @@ describe('<SectionCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('section-card');
|
||||
const menu = await within(element).findByTestId('section-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('section-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetCurrentPageKey).toHaveBeenCalledWith('align', section.id);
|
||||
|
||||
@@ -32,6 +32,7 @@ export function useDynamicHookShim() {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
load();
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -428,12 +428,12 @@ describe('<SubsectionCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('subsection-card');
|
||||
const menu = await within(element).findByTestId('subsection-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('subsection-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
const drawer = await screen.findByRole('alert');
|
||||
expect(within(drawer).getByText(/manage tags/i));
|
||||
@@ -474,12 +474,12 @@ describe('<SubsectionCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('subsection-card');
|
||||
const menu = await within(element).findByTestId('subsection-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('subsection-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetCurrentPageKey).toHaveBeenCalledWith('align', subsection.id);
|
||||
|
||||
@@ -286,12 +286,12 @@ describe('<UnitCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('unit-card');
|
||||
const menu = await within(element).findByTestId('unit-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('unit-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
const drawer = await screen.findByRole('alert');
|
||||
expect(within(drawer).getByText(/manage tags/i));
|
||||
@@ -332,12 +332,12 @@ describe('<UnitCard />', () => {
|
||||
renderComponent();
|
||||
const element = await screen.findByTestId('unit-card');
|
||||
const menu = await within(element).findByTestId('unit-card-header__menu-button');
|
||||
await fireEvent.click(menu);
|
||||
fireEvent.click(menu);
|
||||
|
||||
const manageTagsBtn = await within(element).findByTestId('unit-card-header__menu-manage-tags-button');
|
||||
expect(manageTagsBtn).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(manageTagsBtn);
|
||||
fireEvent.click(manageTagsBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetCurrentPageKey).toHaveBeenCalledWith('align', unit.id);
|
||||
|
||||
@@ -157,6 +157,7 @@ const UnitCard = ({
|
||||
};
|
||||
|
||||
const handleCopyClick = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
copyToClipboard(id);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,13 @@ jest.mock('react-redux', () => ({
|
||||
useSelector: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockNavigate = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
|
||||
useNavigate: () => mockNavigate,
|
||||
}));
|
||||
|
||||
describe('<CourseRerun />', () => {
|
||||
beforeEach(() => {
|
||||
const { axiosMock } = initializeMocks();
|
||||
@@ -30,13 +37,13 @@ describe('<CourseRerun />', () => {
|
||||
expect(getAllByRole('button', { name: messages.cancelButton.defaultMessage }).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should navigate to /home on cancel button click', () => {
|
||||
it('should navigate to /home on cancel button click', async () => {
|
||||
const { getAllByRole } = render(<CourseRerun />);
|
||||
const cancelButton = getAllByRole('button', { name: messages.cancelButton.defaultMessage })[0];
|
||||
|
||||
fireEvent.click(cancelButton);
|
||||
waitFor(() => {
|
||||
expect(window.location.pathname).toBe('/home');
|
||||
await waitFor(() => {
|
||||
expect(mockNavigate).toHaveBeenCalledWith('/home');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,14 @@ import {
|
||||
import { cloneDeep, set } from 'lodash';
|
||||
|
||||
import {
|
||||
act, fireEvent, render, waitFor, within, screen, initializeMocks,
|
||||
act,
|
||||
cleanup,
|
||||
fireEvent,
|
||||
initializeMocks,
|
||||
render,
|
||||
waitFor,
|
||||
within,
|
||||
screen,
|
||||
} from '@src/testUtils';
|
||||
import { IFRAME_FEATURE_POLICY } from '@src/constants';
|
||||
import { mockWaffleFlags } from '@src/data/apiHooks.mock';
|
||||
@@ -790,9 +797,10 @@ describe('<CourseUnit />', () => {
|
||||
.reply(200, {
|
||||
...updatedCourseSectionVerticalData,
|
||||
});
|
||||
cleanup(); // clear the first render before we create the second.
|
||||
render(<RootWrapper />);
|
||||
// to wait for loading
|
||||
screen.findByTestId('unit-header-title');
|
||||
await screen.findByTestId('unit-header-title');
|
||||
// The new unit button should not be visible when childAddable is false
|
||||
expect(
|
||||
screen.queryByRole('button', { name: courseSequenceMessages.newUnitBtnText.defaultMessage }),
|
||||
|
||||
@@ -88,6 +88,7 @@ const UnitInfoSettings = () => {
|
||||
groupAccess: Object | null,
|
||||
isDiscussionEnabled: boolean,
|
||||
) => {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(editCourseUnitVisibilityAndData(
|
||||
id,
|
||||
PUBLISH_TYPES.republish,
|
||||
|
||||
@@ -83,8 +83,10 @@ const UpdateForm = ({
|
||||
showPopperArrow={false}
|
||||
onChange={(value) => {
|
||||
if (!isValidDate(value)) {
|
||||
/* istanbul ignore next */
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('date', convertToStringFromDate(value));
|
||||
}}
|
||||
/>
|
||||
@@ -103,8 +105,8 @@ const UpdateForm = ({
|
||||
data-testid="course-updates-wisiwyg-editor"
|
||||
name={contentFieldName}
|
||||
minHeight={300}
|
||||
onChange={(value) => {
|
||||
setFieldValue(contentFieldName, value || DEFAULT_EMPTY_WYSIWYG_VALUE);
|
||||
onChange={/* istanbul ignore next: we can't test WYSIWYG editors */async (value) => {
|
||||
await setFieldValue(contentFieldName, value || DEFAULT_EMPTY_WYSIWYG_VALUE);
|
||||
}}
|
||||
/>
|
||||
</Form.Group>
|
||||
|
||||
@@ -70,7 +70,7 @@ export async function getDownload(selectedRows, courseId) {
|
||||
definedAssets.forEach((assetBlob, index) => {
|
||||
folder.file(assetNames[index], assetBlob.value, { blob: true });
|
||||
});
|
||||
zip.generateAsync({ type: 'blob' }).then(content => {
|
||||
await zip.generateAsync({ type: 'blob' }).then(content => {
|
||||
saveAs(content, `${courseId}-assets-${date}.zip`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ const MoreInfoColumn = ({
|
||||
as={Button}
|
||||
variant="tertiary"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
navigator.clipboard.writeText(id);
|
||||
close();
|
||||
}}
|
||||
@@ -70,6 +71,7 @@ const MoreInfoColumn = ({
|
||||
as={Button}
|
||||
variant="tertiary"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
navigator.clipboard.writeText(portableUrl);
|
||||
close();
|
||||
}}
|
||||
@@ -80,6 +82,7 @@ const MoreInfoColumn = ({
|
||||
as={Button}
|
||||
variant="tertiary"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
navigator.clipboard.writeText(externalUrl);
|
||||
close();
|
||||
}}
|
||||
|
||||
@@ -55,6 +55,7 @@ export function cancelAllUploads(courseId, uploadData) {
|
||||
});
|
||||
Object.entries(uploadData).forEach(([key, value]) => {
|
||||
if (value.status === RequestStatus.IN_PROGRESS) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
updateVideoUploadStatus(
|
||||
courseId,
|
||||
key,
|
||||
@@ -178,6 +179,7 @@ export function markVideoUploadsInProgressAsFailed({ uploadingIdsRef, courseId }
|
||||
return (dispatch) => {
|
||||
Object.keys(uploadingIdsRef.current.uploadData).forEach((edxVideoId) => {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
updateVideoUploadStatus(
|
||||
courseId,
|
||||
edxVideoId || '',
|
||||
@@ -246,7 +248,7 @@ const uploadToBucket = async ({
|
||||
...currentVideoData,
|
||||
status: RequestStatus.SUCCESSFUL,
|
||||
};
|
||||
updateVideoUploadStatus(
|
||||
await updateVideoUploadStatus(
|
||||
courseId,
|
||||
edxVideoId,
|
||||
'Upload completed',
|
||||
@@ -270,7 +272,7 @@ const uploadToBucket = async ({
|
||||
status: RequestStatus.FAILED,
|
||||
};
|
||||
}
|
||||
updateVideoUploadStatus(
|
||||
await updateVideoUploadStatus(
|
||||
courseId,
|
||||
edxVideoId || '',
|
||||
'Upload failed',
|
||||
|
||||
@@ -155,6 +155,7 @@ const CreateOrRerunCourseForm = ({
|
||||
const handleCustomBlurForDropdown = (e) => {
|
||||
// it needs to correct handleOnChange Form.Autosuggest
|
||||
const { value, name } = e.target;
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue(name, value);
|
||||
handleBlur(e);
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ describe('generic api calls', () => {
|
||||
|
||||
it('should throw an error if no pattern is provided', async () => {
|
||||
const pattern = undefined;
|
||||
expect(getTagsCount(pattern)).rejects.toThrow('contentPattern is required');
|
||||
await expect(getTagsCount(pattern)).rejects.toThrow('contentPattern is required');
|
||||
expect(axiosMock.history.get.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +58,7 @@ export const InplaceTextEditor: React.FC<InplaceTextEditorProps> = ({
|
||||
|
||||
const handleOnKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === 'Enter') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
handleOnChangeText(event);
|
||||
} else if (event.key === 'Escape') {
|
||||
setIsActive(false);
|
||||
|
||||
@@ -114,6 +114,7 @@ export const LegacyLibMigrationPage = () => {
|
||||
break;
|
||||
case 'confirmation-view':
|
||||
setConfirmationButtonState('pending');
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
handleMigrate();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -431,7 +431,7 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
expect(mockResult0.display_name).toStrictEqual(displayName);
|
||||
await renderLibraryPage();
|
||||
|
||||
waitFor(() => expect(screen.getAllByTestId('component-card-menu-toggle').length).toBeGreaterThan(0));
|
||||
await waitFor(() => expect(screen.getAllByTestId('component-card-menu-toggle').length).toBeGreaterThan(0));
|
||||
|
||||
// Open menu
|
||||
fireEvent.click((await screen.findAllByTestId('component-card-menu-toggle'))[0]);
|
||||
@@ -455,7 +455,7 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
const displayName = 'Test Unit';
|
||||
await renderLibraryPage();
|
||||
|
||||
waitFor(() => expect(screen.getAllByTestId('container-card-menu-toggle').length).toBeGreaterThan(0));
|
||||
await waitFor(() => expect(screen.getAllByTestId('container-card-menu-toggle').length).toBeGreaterThan(0));
|
||||
|
||||
// Open menu
|
||||
fireEvent.click((await screen.findAllByTestId('container-card-menu-toggle'))[0]);
|
||||
|
||||
@@ -93,7 +93,7 @@ describe('<AddContent />', () => {
|
||||
expect(screen.queryByRole('button', { name: /video/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /copy from clipboard/i })).not.toBeInTheDocument();
|
||||
expect(await screen.findByRole('button', { name: /advanced \/ other/i })).toBeInTheDocument();
|
||||
expect(await screen.queryByRole('button', { name: /existing library content/i })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /existing library content/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render advanced content buttons', async () => {
|
||||
|
||||
@@ -59,6 +59,7 @@ export const ComponentAdvancedAssets: React.FC<Record<never, never>> = () => {
|
||||
const deleter = useDeleteXBlockAsset(usageKey);
|
||||
const [filePathToDelete, setConfirmDeleteAsset] = React.useState<string>('');
|
||||
const deleteFile = React.useCallback(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
deleter.mutateAsync(filePathToDelete); // Don't wait for this before clearing the modal on the next line
|
||||
setConfirmDeleteAsset('');
|
||||
}, [filePathToDelete, usageKey]);
|
||||
|
||||
@@ -143,7 +143,7 @@ describe('<ComponentInfo> Sidebar', () => {
|
||||
|
||||
// Should show the confirmation box
|
||||
expect(await screen.findByText(/Confirm Publish/i)).toBeInTheDocument();
|
||||
const secondPublishButton = await screen.getByRole('button', { name: /publish/i });
|
||||
const secondPublishButton = screen.getByRole('button', { name: /publish/i });
|
||||
secondPublishButton.click();
|
||||
});
|
||||
|
||||
@@ -160,7 +160,7 @@ describe('<ComponentInfo> Sidebar', () => {
|
||||
|
||||
// Should show the confirmation box
|
||||
expect(await screen.findByText(/Confirm Publish/i)).toBeInTheDocument();
|
||||
const secondPublishButton = await screen.getByRole('button', { name: /publish/i });
|
||||
const secondPublishButton = screen.getByRole('button', { name: /publish/i });
|
||||
secondPublishButton.click();
|
||||
});
|
||||
|
||||
@@ -177,7 +177,7 @@ describe('<ComponentInfo> Sidebar', () => {
|
||||
|
||||
// Should show the confirmation box
|
||||
expect(await screen.findByText(/Confirm Publish/i)).toBeInTheDocument();
|
||||
const secondPublishButton = await screen.getByRole('button', { name: /publish/i });
|
||||
const secondPublishButton = screen.getByRole('button', { name: /publish/i });
|
||||
secondPublishButton.click();
|
||||
});
|
||||
|
||||
@@ -195,7 +195,7 @@ describe('<ComponentInfo> Sidebar', () => {
|
||||
|
||||
// Should show the confirmation box
|
||||
expect(await screen.findByText(/Confirm Publish/i)).toBeInTheDocument();
|
||||
const secondPublishButton = await screen.getByRole('button', { name: /publish/i });
|
||||
const secondPublishButton = screen.getByRole('button', { name: /publish/i });
|
||||
secondPublishButton.click();
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -217,7 +217,7 @@ describe('<ComponentInfo> Sidebar', () => {
|
||||
|
||||
// Should show the confirmation box
|
||||
expect(await screen.findByText(/Confirm Publish/i)).toBeInTheDocument();
|
||||
const secondPublishButton = await screen.getByRole('button', { name: /publish/i });
|
||||
const secondPublishButton = screen.getByRole('button', { name: /publish/i });
|
||||
secondPublishButton.click();
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
@@ -62,6 +62,7 @@ const AddComponentWidget = () => {
|
||||
variant="outline-primary"
|
||||
className="m-1 text-nowrap flex-grow-1"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
onComponentSelected({ usageKey, blockType: getBlockType(usageKey) });
|
||||
}}
|
||||
>
|
||||
@@ -78,8 +79,10 @@ const AddComponentWidget = () => {
|
||||
blockType: getBlockType(usageKey),
|
||||
};
|
||||
if (!isChecked) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
addComponentToSelectedComponents(selectedComponent);
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
removeComponentFromSelectedComponents(selectedComponent);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -50,8 +50,8 @@ describe('<ComponentUsageTab />', () => {
|
||||
render(mockLibraryBlockMetadata.usageKeyPublished);
|
||||
|
||||
expect(await screen.findByText('text block 0')).toBeInTheDocument();
|
||||
expect(await screen.getByText('4 Units')).toBeInTheDocument();
|
||||
expect(await screen.getByText('3 Subsections')).toBeInTheDocument();
|
||||
expect(await screen.getByText('2 Sections')).toBeInTheDocument();
|
||||
expect(screen.getByText('4 Units')).toBeInTheDocument();
|
||||
expect(screen.getByText('3 Subsections')).toBeInTheDocument();
|
||||
expect(screen.getByText('2 Sections')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -69,8 +69,10 @@ const AddComponentWidget = ({ usageKey, blockType }: AddComponentWidgetProps) =>
|
||||
blockType,
|
||||
};
|
||||
if (!isChecked) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
addComponentToSelectedComponents(selectedComponent);
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
removeComponentFromSelectedComponents(selectedComponent);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,6 +54,7 @@ export const ComponentMenu = ({ usageKey, index }: Props) => {
|
||||
const { copyToClipboard } = useClipboard();
|
||||
|
||||
const updateClipboardClick = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
copyToClipboard(usageKey);
|
||||
};
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ export const ContainerMenu = ({ containerKey, displayName, index } : ContainerMe
|
||||
}, [navigateTo, containerKey]);
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
copyToClipboard(containerKey);
|
||||
}, [copyToClipboard, containerKey]);
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ const ContainerMenu = ({ containerId }: ContainerPreviewProps) => {
|
||||
const { copyToClipboard } = useClipboard();
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
copyToClipboard(containerId);
|
||||
}, [copyToClipboard, containerId]);
|
||||
|
||||
|
||||
@@ -123,10 +123,10 @@ export const ItemHierarchyPublisher = ({
|
||||
{intl.formatMessage(messages.publishCancel)}
|
||||
</Button>
|
||||
<LoadingButton
|
||||
onClick={async (e) => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await handlePublish();
|
||||
handlePublish();
|
||||
}}
|
||||
variant="primary rounded-0"
|
||||
label={intl.formatMessage(messages.publishConfirm)}
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('<ImportDetailsPage />', () => {
|
||||
name: /view imported content/i,
|
||||
});
|
||||
|
||||
await viewImportedContentBtn.click();
|
||||
viewImportedContentBtn.click();
|
||||
await waitFor(() => expect(mockNavigate).toHaveBeenCalledWith('/library/lib:Axim:TEST/collection/coll'));
|
||||
});
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ const ImportDetailsContent = () => {
|
||||
migrationStatus = 'Failed';
|
||||
} else if (migrationStatusData?.state === 'Succeeded') {
|
||||
// refetch migrationBlockInfo data once the import is complete
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
refetchMigrationBlockInfo();
|
||||
// Currently, bulk migrate is being used to migrate courses because
|
||||
// it has the ability to create collections.
|
||||
|
||||
@@ -460,6 +460,7 @@ const ScanResults: FC<Props> = ({
|
||||
const handleUpdateCompletion = async () => {
|
||||
if (rerunLinkUpdateInProgress === false && isUpdateAllInProgress) {
|
||||
try {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
const updateStatusResponse = await dispatch(fetchRerunLinkUpdateStatus(courseId)) as any;
|
||||
|
||||
if (!updateStatusResponse) {
|
||||
@@ -506,6 +507,7 @@ const ScanResults: FC<Props> = ({
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
handleUpdateCompletion();
|
||||
}, [rerunLinkUpdateInProgress,
|
||||
isUpdateAllInProgress,
|
||||
@@ -590,6 +592,7 @@ const ScanResults: FC<Props> = ({
|
||||
try {
|
||||
setUpdatingLinkIds(prev => ({ ...prev, [uniqueId]: true }));
|
||||
const contentType = getContentType(sectionId || '');
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(updateSinglePreviousRunLink(courseId, link, blockId, contentType));
|
||||
|
||||
const pollForSingleLinkResult = async (attempts = 0): Promise<boolean> => {
|
||||
@@ -597,6 +600,7 @@ const ScanResults: FC<Props> = ({
|
||||
throw new Error('Timeout waiting for link update result');
|
||||
}
|
||||
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
const updateStatusResponse = await dispatch(fetchRerunLinkUpdateStatus(courseId)) as any;
|
||||
const pollStatus = updateStatusResponse?.status || updateStatusResponse?.updateStatus;
|
||||
|
||||
@@ -755,6 +759,7 @@ const ScanResults: FC<Props> = ({
|
||||
try {
|
||||
setProcessedResponseIds(new Set());
|
||||
setIsUpdateAllInProgress(true);
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(updateAllPreviousRunLinks(courseId));
|
||||
|
||||
return true;
|
||||
|
||||
@@ -72,13 +72,14 @@ const AppSettingsModal = ({
|
||||
const handleFormSubmit = async (values) => {
|
||||
let success = true;
|
||||
if (appInfo.enabled !== values.enabled) {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
success = await dispatch(updateAppStatus(courseId, appInfo.id, values.enabled));
|
||||
}
|
||||
// Call the submit handler for the settings component to save its settings
|
||||
if (onSettingsSave) {
|
||||
success = success && await onSettingsSave(values);
|
||||
}
|
||||
await setSaveError(!success);
|
||||
setSaveError(!success);
|
||||
!success && alertRef?.current.scrollIntoView(); // eslint-disable-line @typescript-eslint/no-unused-expressions
|
||||
};
|
||||
|
||||
@@ -86,7 +87,8 @@ const AppSettingsModal = ({
|
||||
// If submitting the form with errors, show the alert and scroll to it.
|
||||
await handleSubmit(event);
|
||||
if (Object.keys(errors).length > 0) {
|
||||
await setSaveError(true);
|
||||
/* istanbul ignore next: temp to unblock lint cleanup. We probably should test this. */
|
||||
setSaveError(true);
|
||||
alertRef?.current.scrollIntoView?.(); // eslint-disable-line no-unused-expressions
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,7 +46,9 @@ const AppConfigForm = ({
|
||||
const [confirmationDialogVisible, setConfirmationDialogVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
(async () => {
|
||||
// oxlint-disable-next-line @typescript-eslint/await-thenable - this dispatch() IS returning a promise.
|
||||
await dispatch(fetchDiscussionSettings(courseId, selectedAppId));
|
||||
setLoading(false);
|
||||
})();
|
||||
|
||||
@@ -24,12 +24,14 @@ const DiscussionRestriction = () => {
|
||||
setSelectedRestrictionOption(value);
|
||||
|
||||
if (value !== discussionRestriction.ENABLED) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('postingRestrictions', value);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleConfirmation = useCallback(() => {
|
||||
setSelectedRestrictionOption(discussionRestriction.ENABLED);
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('postingRestrictions', discussionRestriction.ENABLED);
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -36,10 +36,13 @@ const DivisionByGroupFields = () => {
|
||||
useEffect(() => {
|
||||
if (divideByCohorts) {
|
||||
if (!divideCourseTopicsByCohorts && size(discussionTopics) !== size(divideDiscussionIds)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideDiscussionIds', discussionTopics.map(topic => topic.id));
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideDiscussionIds', []);
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideCourseTopicsByCohorts', false);
|
||||
}
|
||||
}, [
|
||||
@@ -59,6 +62,7 @@ const DivisionByGroupFields = () => {
|
||||
const handleDivideCourseTopicsByCohortsToggle = (event) => {
|
||||
const { checked } = event.target;
|
||||
if (!checked) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideDiscussionIds', []);
|
||||
}
|
||||
handleChange(event);
|
||||
|
||||
@@ -19,6 +19,7 @@ const InContextDiscussionFields = ({
|
||||
|
||||
const [showPopup, setShowPopup] = useState(false);
|
||||
const handleConfirmation = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('enableGradedUnits', !values.enableGradedUnits);
|
||||
setShowPopup(false);
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ const RestrictionSchedules = () => {
|
||||
...updatedRestrictedDates[index],
|
||||
status: checkStatus(denormalizeRestrictedDate(updatedRestrictedDates[index])),
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('restrictedDates', updatedRestrictedDates);
|
||||
}, [restrictedDates]);
|
||||
|
||||
@@ -43,7 +44,7 @@ const RestrictionSchedules = () => {
|
||||
|
||||
const onAddNewItem = useCallback(async (push) => {
|
||||
await push(newRestrictedDateItem);
|
||||
validateForm();
|
||||
await validateForm();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -26,13 +26,14 @@ const DiscussionTopics = () => {
|
||||
|
||||
const handleTopicDelete = async (topicIndex, topicId, remove) => {
|
||||
await remove(topicIndex);
|
||||
validateForm();
|
||||
await validateForm();
|
||||
setValidDiscussionTopics(filterItemFromObject(validDiscussionTopics, 'id', topicId));
|
||||
};
|
||||
|
||||
const handleOnFocus = useCallback((id, hasError) => {
|
||||
if (hasError) {
|
||||
setValidDiscussionTopics(currentValidTopics => filterItemFromObject(currentValidTopics, 'id', id));
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideDiscussionIds', filterItemFromObject(divideDiscussionIds, 'id', id));
|
||||
} else {
|
||||
setValidDiscussionTopics(currentValidTopics => {
|
||||
@@ -40,6 +41,7 @@ const DiscussionTopics = () => {
|
||||
const allValidTopics = removeElements(allDiscussionTopics, topic => topic.name !== '');
|
||||
return uniqBy(allValidTopics, 'id');
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
setFieldValue('divideDiscussionIds', uniq([...divideDiscussionIds, id]));
|
||||
}
|
||||
}, [divideDiscussionIds, discussionTopics]);
|
||||
|
||||
@@ -107,7 +107,7 @@ mockFetchIndexDocuments.applyMock = () => {
|
||||
/**
|
||||
* Mock the useGetContentHits
|
||||
*/
|
||||
export async function mockGetContentHits(
|
||||
export function mockGetContentHits(
|
||||
mockResponse: 'noHits' | 'someHits',
|
||||
) {
|
||||
fetchMock.post(mockContentSearchConfig.searchEndpointUrl, () => {
|
||||
|
||||
@@ -187,7 +187,12 @@ export const useContentSearchResults = ({
|
||||
// Call this to load more pages. We include some "safety" features recommended by the docs: this should never be
|
||||
// called while already fetching a page, and parameters (like 'event') should not be passed into fetchNextPage().
|
||||
// See https://tanstack.com/query/v4/docs/framework/react/guides/infinite-queries
|
||||
fetchNextPage: () => { if (!query.isFetching && !query.isFetchingNextPage) { query.fetchNextPage(); } },
|
||||
fetchNextPage: /* istanbul ignore next */ () => {
|
||||
if (!query.isFetching && !query.isFetchingNextPage) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
query.fetchNextPage();
|
||||
}
|
||||
},
|
||||
hasNextPage: query.hasNextPage,
|
||||
// The last page has the most accurate count of total hits
|
||||
totalHits: pages?.[pages.length - 1]?.totalHits ?? 0,
|
||||
|
||||
@@ -175,7 +175,7 @@ describe('<TaxonomyListPage />', () => {
|
||||
} = render(<TaxonomyListPage />);
|
||||
|
||||
// Open the taxonomies org filter select menu
|
||||
const taxonomiesFilterSelectMenu = await getByRole('button', { name: 'All taxonomies' });
|
||||
const taxonomiesFilterSelectMenu = getByRole('button', { name: 'All taxonomies' });
|
||||
fireEvent.click(taxonomiesFilterSelectMenu);
|
||||
|
||||
// Check that the 'Unassigned' option is correctly called
|
||||
|
||||
@@ -41,6 +41,7 @@ const TaxonomyMenu = ({
|
||||
const { setToastMessage } = useContext(TaxonomyContext);
|
||||
|
||||
const onDeleteTaxonomy = useCallback(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
deleteTaxonomy({ pk: taxonomy.id }, {
|
||||
onSuccess: () => {
|
||||
if (setToastMessage) {
|
||||
|
||||
@@ -175,7 +175,7 @@ describe('<TextbookCard />', () => {
|
||||
.onDelete(getEditTextbooksApiUrl(courseId, textbookId))
|
||||
.reply(200);
|
||||
|
||||
executeThunk(deleteTextbookQuery(courseId, textbookId), store.dispatch);
|
||||
await executeThunk(deleteTextbookQuery(courseId, textbookId), store.dispatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user