Fix some test warnings (#1062)
* fix: paragon's Hyperlink no longer accepts a 'content' attribute * test: ensure all act() calls are async * test: Removed "async" from "describe" Returning a Promise from "describe" is not supported. * fix: DiscussionsSettings tests Previous commit revealed several issues with these tests * Don't nest userAction.click in act() -- nested act() statements have indeterminent behaviour. * Use getBy* instead of findBy* with userAction to avoid nested act() statements * Use fireEvent.click when the onClick handlers need to be called * Use queryBy* instead of getBy* when using .toBeInTheDocument or waitForElementToBeRemoved queryBy* return null when the element is not found. * fix: typo in data-testid Warning: React does not recognize the `data-testId` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `data-testid` instead. * test: Use useLocation to test route changes --------- Co-authored-by: Yusuf Musleh <yusuf@opencraft.com>
This commit is contained in:
@@ -103,9 +103,7 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsNo');
|
||||
expect(zendeskTicketInput.checked).toEqual(true);
|
||||
});
|
||||
@@ -115,9 +113,7 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'software_secure' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'software_secure' } });
|
||||
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsYes');
|
||||
expect(zendeskTicketInput.checked).toEqual(true);
|
||||
});
|
||||
@@ -127,9 +123,7 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'mockproc' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'mockproc' } });
|
||||
const zendeskTicketInput = screen.getByTestId('createZendeskTicketsYes');
|
||||
expect(zendeskTicketInput.checked).toEqual(true);
|
||||
});
|
||||
@@ -176,9 +170,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
let enabledProctoredExamCheck = screen.getAllByLabelText('Proctored exams', { exact: false })[0];
|
||||
expect(enabledProctoredExamCheck.checked).toEqual(true);
|
||||
await act(async () => {
|
||||
fireEvent.click(enabledProctoredExamCheck, { target: { value: false } });
|
||||
});
|
||||
fireEvent.click(enabledProctoredExamCheck, { target: { value: false } });
|
||||
enabledProctoredExamCheck = screen.getByLabelText('Proctored exams');
|
||||
expect(enabledProctoredExamCheck.checked).toEqual(false);
|
||||
expect(screen.queryByText('Allow opting out of proctored exams')).toBeNull();
|
||||
@@ -193,9 +185,7 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('mockproc');
|
||||
});
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
|
||||
expect(screen.queryByTestId('allowOptingOutRadio')).toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull();
|
||||
expect(screen.queryByTestId('createZendeskTicketsNo')).toBeNull();
|
||||
@@ -237,13 +227,9 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('proctortrack');
|
||||
});
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
const selectButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(selectButton);
|
||||
});
|
||||
fireEvent.click(selectButton);
|
||||
|
||||
// verify alert content and focus management
|
||||
const escalationEmailError = screen.getByTestId('escalationEmailError');
|
||||
@@ -252,9 +238,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
// verify alert link links to offending input
|
||||
const errorLink = screen.getByTestId('escalationEmailErrorLink');
|
||||
await act(async () => {
|
||||
fireEvent.click(errorLink);
|
||||
});
|
||||
fireEvent.click(errorLink);
|
||||
const escalationEmailInput = screen.getByTestId('escalationEmail');
|
||||
expect(document.activeElement).toEqual(escalationEmailInput);
|
||||
});
|
||||
@@ -265,18 +249,12 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
|
||||
const selectElement = screen.getByDisplayValue('proctortrack');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: provider } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: provider } });
|
||||
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
|
||||
});
|
||||
const selectButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(selectButton);
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
|
||||
const proctoringForm = screen.getByTestId('proctoringForm');
|
||||
fireEvent.submit(proctoringForm);
|
||||
|
||||
// verify alert content and focus management
|
||||
const escalationEmailError = screen.getByTestId('escalationEmailError');
|
||||
@@ -286,9 +264,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
// verify alert link links to offending input
|
||||
const errorLink = screen.getByTestId('escalationEmailErrorLink');
|
||||
await act(async () => {
|
||||
fireEvent.click(errorLink);
|
||||
});
|
||||
fireEvent.click(errorLink);
|
||||
const escalationEmailInput = screen.getByTestId('escalationEmail');
|
||||
expect(document.activeElement).toEqual(escalationEmailInput);
|
||||
});
|
||||
@@ -298,15 +274,11 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('proctortrack');
|
||||
});
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo.bar' } });
|
||||
const enableProctoringElement = screen.getByText('Proctored exams');
|
||||
await act(async () => fireEvent.click(enableProctoringElement));
|
||||
fireEvent.click(enableProctoringElement);
|
||||
const selectButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(selectButton);
|
||||
});
|
||||
fireEvent.click(selectButton);
|
||||
|
||||
// verify alert content and focus management
|
||||
const escalationEmailError = screen.getByTestId('escalationEmailError');
|
||||
@@ -320,24 +292,22 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('proctortrack');
|
||||
});
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
const enableProctoringElement = screen.getByText('Proctored exams');
|
||||
await act(async () => fireEvent.click(enableProctoringElement));
|
||||
fireEvent.click(enableProctoringElement);
|
||||
const selectButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(selectButton);
|
||||
});
|
||||
fireEvent.click(selectButton);
|
||||
|
||||
// verify there is no escalation email alert, and focus has been set on save success alert
|
||||
expect(screen.queryByTestId('escalationEmailError')).toBeNull();
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it(`Has no error when valid proctoring escalation email is provided with ${provider} selected`, async () => {
|
||||
@@ -345,22 +315,20 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('proctortrack');
|
||||
});
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo@bar.com' } });
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: 'foo@bar.com' } });
|
||||
const selectButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(selectButton);
|
||||
});
|
||||
fireEvent.click(selectButton);
|
||||
|
||||
// verify there is no escalation email alert, and focus has been set on save success alert
|
||||
expect(screen.queryByTestId('escalationEmailError')).toBeNull();
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it(`Escalation email field hidden when proctoring backend is not ${provider}`, async () => {
|
||||
@@ -370,9 +338,7 @@ describe('ProctoredExamSettings', () => {
|
||||
const proctoringBackendSelect = screen.getByDisplayValue('proctortrack');
|
||||
const selectEscalationEmailElement = screen.getByTestId('escalationEmail');
|
||||
expect(selectEscalationEmailElement.value).toEqual('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
|
||||
});
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
|
||||
expect(screen.queryByTestId('escalationEmail')).toBeNull();
|
||||
});
|
||||
|
||||
@@ -382,13 +348,9 @@ describe('ProctoredExamSettings', () => {
|
||||
});
|
||||
const proctoringBackendSelect = screen.getByDisplayValue('proctortrack');
|
||||
let selectEscalationEmailElement = screen.getByTestId('escalationEmail');
|
||||
await act(async () => {
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
|
||||
});
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'software_secure' } });
|
||||
expect(screen.queryByTestId('escalationEmail')).toBeNull();
|
||||
await act(async () => {
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'proctortrack' } });
|
||||
});
|
||||
fireEvent.change(proctoringBackendSelect, { target: { value: 'proctortrack' } });
|
||||
expect(screen.queryByTestId('escalationEmail')).toBeDefined();
|
||||
selectEscalationEmailElement = screen.getByTestId('escalationEmail');
|
||||
expect(selectEscalationEmailElement.value).toEqual('test@example.com');
|
||||
@@ -399,12 +361,8 @@ describe('ProctoredExamSettings', () => {
|
||||
screen.getByDisplayValue('proctortrack');
|
||||
});
|
||||
const selectEscalationEmailElement = screen.getByDisplayValue('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.submit(selectEscalationEmailElement);
|
||||
});
|
||||
fireEvent.change(selectEscalationEmailElement, { target: { value: '' } });
|
||||
fireEvent.submit(selectEscalationEmailElement);
|
||||
// if the error appears, the form has been submitted
|
||||
expect(screen.getByTestId('escalationEmailError')).toBeDefined();
|
||||
});
|
||||
@@ -628,9 +586,7 @@ describe('ProctoredExamSettings', () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
let submitButton = screen.getByTestId('submissionButton');
|
||||
expect(screen.queryByTestId('saveInProgress')).toBeFalsy();
|
||||
act(() => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
submitButton = screen.getByTestId('submissionButton');
|
||||
expect(submitButton).toHaveAttribute('disabled');
|
||||
@@ -640,19 +596,13 @@ describe('ProctoredExamSettings', () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the provider to proctortrack and set the email
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
const escalationEmail = screen.getByTestId('escalationEmail');
|
||||
expect(escalationEmail.value).toEqual('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(escalationEmail, { target: { value: 'proctortrack@example.com' } });
|
||||
});
|
||||
fireEvent.change(escalationEmail, { target: { value: 'proctortrack@example.com' } });
|
||||
expect(escalationEmail.value).toEqual('proctortrack@example.com');
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
|
||||
proctored_exam_settings: {
|
||||
@@ -664,11 +614,13 @@ describe('ProctoredExamSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Makes API call successfully without proctoring_escalation_email if not proctortrack', async () => {
|
||||
@@ -678,9 +630,7 @@ describe('ProctoredExamSettings', () => {
|
||||
expect(screen.getByDisplayValue('mockproc')).toBeDefined();
|
||||
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
|
||||
proctored_exam_settings: {
|
||||
@@ -691,32 +641,28 @@ describe('ProctoredExamSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Successfully updates exam configuration and studio provider is set to "lti_external" for lti providers', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the provider to test_lti and set the email
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'test_lti' } });
|
||||
|
||||
const escalationEmail = screen.getByTestId('escalationEmail');
|
||||
expect(escalationEmail.value).toEqual('test@example.com');
|
||||
await act(async () => {
|
||||
fireEvent.change(escalationEmail, { target: { value: 'test_lti@example.com' } });
|
||||
});
|
||||
fireEvent.change(escalationEmail, { target: { value: 'test_lti@example.com' } });
|
||||
expect(escalationEmail.value).toEqual('test_lti@example.com');
|
||||
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
// update exam service config
|
||||
expect(axiosMock.history.patch.length).toBe(1);
|
||||
@@ -736,19 +682,19 @@ describe('ProctoredExamSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Sets exam service provider to null if a non-lti provider is selected', async () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
// update exam service config
|
||||
expect(axiosMock.history.patch.length).toBe(1);
|
||||
expect(JSON.parse(axiosMock.history.patch[0].data)).toEqual({
|
||||
@@ -766,11 +712,13 @@ describe('ProctoredExamSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Does not update exam service if lti is not enabled in studio', async () => {
|
||||
@@ -790,9 +738,7 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
// does not update exam service config
|
||||
expect(axiosMock.history.patch.length).toBe(0);
|
||||
// does update studio
|
||||
@@ -806,11 +752,13 @@ describe('ProctoredExamSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveSuccess');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Makes studio API call generated error', async () => {
|
||||
@@ -820,15 +768,15 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Makes exams API call generated error', async () => {
|
||||
@@ -838,15 +786,15 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Manages focus correctly after different save statuses', async () => {
|
||||
@@ -857,30 +805,30 @@ describe('ProctoredExamSettings', () => {
|
||||
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
await waitFor(() => {
|
||||
const errorAlert = screen.getByTestId('saveError');
|
||||
expect(errorAlert.textContent).toEqual(
|
||||
expect.stringContaining('We encountered a technical error while trying to save proctored exam settings'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(errorAlert);
|
||||
});
|
||||
|
||||
// now make a call that will allow for a successful save
|
||||
axiosMock.onPost(
|
||||
StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId),
|
||||
).reply(200, 'success');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
expect(axiosMock.history.post.length).toBe(2);
|
||||
const successAlert = screen.getByTestId('saveSuccess');
|
||||
expect(successAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(successAlert);
|
||||
await waitFor(() => {
|
||||
const successAlert = screen.getByTestId('saveSuccess');
|
||||
expect(successAlert.textContent).toEqual(
|
||||
expect.stringContaining('Proctored exam settings saved successfully.'),
|
||||
);
|
||||
expect(document.activeElement).toEqual(successAlert);
|
||||
});
|
||||
});
|
||||
|
||||
it('Include Zendesk ticket in post request if user is not an admin', async () => {
|
||||
@@ -891,13 +839,9 @@ describe('ProctoredExamSettings', () => {
|
||||
await act(async () => render(intlWrapper(<IntlProctoredExamSettings {...defaultProps} />)));
|
||||
// Make a change to the proctoring provider
|
||||
const selectElement = screen.getByDisplayValue('mockproc');
|
||||
await act(async () => {
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
});
|
||||
fireEvent.change(selectElement, { target: { value: 'proctortrack' } });
|
||||
const submitButton = screen.getByTestId('submissionButton');
|
||||
await act(async () => {
|
||||
fireEvent.click(submitButton);
|
||||
});
|
||||
fireEvent.click(submitButton);
|
||||
expect(axiosMock.history.post.length).toBe(1);
|
||||
expect(JSON.parse(axiosMock.history.post[0].data)).toEqual({
|
||||
proctored_exam_settings: {
|
||||
|
||||
@@ -59,10 +59,10 @@ describe('HeaderButtons Component', () => {
|
||||
expect(previewLink).toHaveAttribute('href', expect.stringContaining(certificatesDataMock.courseModes[0]));
|
||||
|
||||
const dropdownButton = getByRole('button', { name: certificatesDataMock.courseModes[0] });
|
||||
await userEvent.click(dropdownButton);
|
||||
userEvent.click(dropdownButton);
|
||||
|
||||
const verifiedMode = await getByRole('button', { name: certificatesDataMock.courseModes[1] });
|
||||
await userEvent.click(verifiedMode);
|
||||
userEvent.click(verifiedMode);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(previewLink).toHaveAttribute('href', expect.stringContaining(certificatesDataMock.courseModes[1]));
|
||||
@@ -78,7 +78,7 @@ describe('HeaderButtons Component', () => {
|
||||
const { getByRole, queryByRole } = renderComponent();
|
||||
|
||||
const activationButton = getByRole('button', { name: messages.headingActionsActivate.defaultMessage });
|
||||
await userEvent.click(activationButton);
|
||||
userEvent.click(activationButton);
|
||||
|
||||
axiosMock.onPost(
|
||||
getUpdateCertificateApiUrl(courseId, certificatesDataMock.certificates[0].id),
|
||||
@@ -110,7 +110,7 @@ describe('HeaderButtons Component', () => {
|
||||
const { getByRole, queryByRole } = renderComponent();
|
||||
|
||||
const deactivateButton = getByRole('button', { name: messages.headingActionsDeactivate.defaultMessage });
|
||||
await userEvent.click(deactivateButton);
|
||||
userEvent.click(deactivateButton);
|
||||
|
||||
axiosMock.onPost(
|
||||
getUpdateCertificateApiUrl(courseId, certificatesDataMock.certificates[0].id),
|
||||
|
||||
@@ -79,10 +79,9 @@ const ChecklistItemComment = ({
|
||||
<ul className="assignment-list">
|
||||
{gradedAssignmentsOutsideDateRange.map(assignment => (
|
||||
<li className="assignment-list-item" key={assignment.id}>
|
||||
<Hyperlink
|
||||
content={assignment.displayName}
|
||||
destination={`${outlineUrl}#${assignment.id}`}
|
||||
/>
|
||||
<Hyperlink destination={`${outlineUrl}#${assignment.id}`}>
|
||||
{assignment.displayName}
|
||||
</Hyperlink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
render,
|
||||
act,
|
||||
fireEvent,
|
||||
screen,
|
||||
waitFor,
|
||||
@@ -71,6 +70,15 @@ const mockStore = async (
|
||||
}
|
||||
renderComponent();
|
||||
await executeThunk(fetchAssets(courseId), store.dispatch);
|
||||
|
||||
// Finish loading the expected files into the data table before returning,
|
||||
// because loading new files can disrupt things like accessing file menus.
|
||||
if (status === RequestStatus.SUCCESSFUL) {
|
||||
const numFiles = skipNextPageFetch ? 13 : 15;
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(`Showing ${numFiles} of ${numFiles}`)).toBeInTheDocument();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const emptyMockStore = async (status) => {
|
||||
@@ -126,15 +134,13 @@ describe('FilesAndUploads', () => {
|
||||
it('should upload a single file', async () => {
|
||||
await emptyMockStore(RequestStatus.SUCCESSFUL);
|
||||
const dropzone = screen.getByTestId('files-dropzone');
|
||||
await act(async () => {
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(200, { assets: [] });
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(204, generateNewAssetApiResponse());
|
||||
Object.defineProperty(dropzone, 'files', {
|
||||
value: [file],
|
||||
});
|
||||
fireEvent.drop(dropzone);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(200, { assets: [] });
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(204, generateNewAssetApiResponse());
|
||||
Object.defineProperty(dropzone, 'files', {
|
||||
value: [file],
|
||||
});
|
||||
fireEvent.drop(dropzone);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
@@ -185,9 +191,7 @@ describe('FilesAndUploads', () => {
|
||||
expect(screen.queryByRole('table')).toBeNull();
|
||||
|
||||
const listButton = screen.getByLabelText('List');
|
||||
await act(async () => {
|
||||
fireEvent.click(listButton);
|
||||
});
|
||||
fireEvent.click(listButton);
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
|
||||
expect(screen.getByRole('table')).toBeVisible();
|
||||
@@ -200,16 +204,13 @@ describe('FilesAndUploads', () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(200, { assets: [] });
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(200, generateNewAssetApiResponse());
|
||||
let addFilesButton;
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
await waitFor(() => {
|
||||
addFilesButton = screen.getByLabelText('file-input');
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
});
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
it('should show duplicate file modal', async () => {
|
||||
@@ -219,14 +220,9 @@ describe('FilesAndUploads', () => {
|
||||
axiosMock.onGet(
|
||||
`${getAssetsUrl(courseId)}?display_name=mOckID6&page_size=1`,
|
||||
).reply(200, { assets: [{ display_name: 'mOckID6' }] });
|
||||
let addFilesButton;
|
||||
await waitFor(() => {
|
||||
addFilesButton = screen.getByLabelText('file-input');
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
});
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
expect(screen.getByText(filesPageMessages.overwriteConfirmMessage.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -245,26 +241,21 @@ describe('FilesAndUploads', () => {
|
||||
};
|
||||
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(200, responseData);
|
||||
let addFilesButton;
|
||||
await waitFor(() => {
|
||||
addFilesButton = screen.getByLabelText('file-input');
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
});
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
|
||||
const overwriteButton = screen.getByText(filesPageMessages.confirmOverwriteButtonLabel.defaultMessage);
|
||||
await act(async () => {
|
||||
fireEvent.click(overwriteButton);
|
||||
});
|
||||
|
||||
const assetData = store.getState().models.assets.mOckID6;
|
||||
const { asset: responseAssetData } = responseData;
|
||||
const [defaultData] = updateFileValues([camelCaseObject(responseAssetData)]);
|
||||
fireEvent.click(overwriteButton);
|
||||
|
||||
expect(screen.queryByText(filesPageMessages.overwriteConfirmMessage.defaultMessage)).toBeNull();
|
||||
expect(assetData).toEqual(defaultData);
|
||||
await waitFor(() => {
|
||||
const assetData = store.getState().models.assets.mOckID6;
|
||||
const { asset: responseAssetData } = responseData;
|
||||
const [defaultData] = updateFileValues([camelCaseObject(responseAssetData)]);
|
||||
|
||||
expect(assetData).toEqual(defaultData);
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep original file', async () => {
|
||||
@@ -274,19 +265,12 @@ describe('FilesAndUploads', () => {
|
||||
axiosMock.onGet(
|
||||
`${getAssetsUrl(courseId)}?display_name=mOckID6&page_size=1`,
|
||||
).reply(200, { assets: [{ display_name: 'mOckID6' }] });
|
||||
let addFilesButton;
|
||||
await waitFor(() => {
|
||||
addFilesButton = screen.getByLabelText('file-input');
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
});
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(validateAssetFiles(courseId, [file]), store.dispatch);
|
||||
|
||||
const cancelButton = screen.getByText(filesPageMessages.cancelOverwriteButtonLabel.defaultMessage);
|
||||
await act(async () => {
|
||||
fireEvent.click(cancelButton);
|
||||
});
|
||||
fireEvent.click(cancelButton);
|
||||
|
||||
const assetData = store.getState().models.assets.mOckID6;
|
||||
const defaultAssets = generateFetchAssetApiResponse().assets;
|
||||
@@ -299,12 +283,9 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
it('should have disabled action buttons', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
let actionsButton;
|
||||
|
||||
await waitFor(() => {
|
||||
actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
const actionsButton = await screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
fireEvent.click(actionsButton);
|
||||
expect(screen.getByText(messages.downloadTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
|
||||
expect(screen.getByText(messages.deleteTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
@@ -312,19 +293,14 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
it('delete button should be enabled and delete selected file', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
let selectCardButton;
|
||||
|
||||
await waitFor(() => {
|
||||
[selectCardButton] = screen.getAllByTestId('datatable-select-column-checkbox-cell');
|
||||
fireEvent.click(selectCardButton);
|
||||
});
|
||||
const [selectCardButton] = await screen.findAllByTestId('datatable-select-column-checkbox-cell');
|
||||
fireEvent.click(selectCardButton);
|
||||
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
fireEvent.click(actionsButton);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
const deleteButton = screen.getByText(messages.deleteTitle.defaultMessage).closest('a');
|
||||
expect(deleteButton).not.toHaveClass('disabled');
|
||||
|
||||
@@ -332,24 +308,21 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
fireEvent.click(deleteButton);
|
||||
expect(screen.getByText('Delete mOckID1')).toBeVisible();
|
||||
await act(async () => {
|
||||
userEvent.click(deleteButton);
|
||||
});
|
||||
fireEvent.click(deleteButton);
|
||||
|
||||
// Wait for the delete confirmation button to appear
|
||||
const confirmDeleteButton = await screen.findByRole('button', {
|
||||
name: messages.deleteFileButtonLabel.defaultMessage,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
userEvent.click(confirmDeleteButton);
|
||||
});
|
||||
fireEvent.click(confirmDeleteButton);
|
||||
|
||||
expect(screen.queryByText('Delete mOckID1')).toBeNull();
|
||||
|
||||
// Check if the asset is deleted in the store and UI
|
||||
const deleteStatus = store.getState().assets.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
await waitFor(() => {
|
||||
const deleteStatus = store.getState().assets.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
});
|
||||
|
||||
@@ -360,9 +333,7 @@ describe('FilesAndUploads', () => {
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
fireEvent.click(actionsButton);
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
expect(downloadButton).not.toHaveClass('disabled');
|
||||
|
||||
@@ -378,9 +349,7 @@ describe('FilesAndUploads', () => {
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
fireEvent.click(actionsButton);
|
||||
const mockResponseData = { ok: true, blob: () => 'Data' };
|
||||
const mockFetchResponse = Promise.resolve(mockResponseData);
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
@@ -396,19 +365,18 @@ describe('FilesAndUploads', () => {
|
||||
const sortsButton = screen.getByText(messages.sortButtonLabel.defaultMessage);
|
||||
expect(sortsButton).toBeVisible();
|
||||
|
||||
fireEvent.click(sortsButton);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(sortsButton);
|
||||
expect(screen.getByText(messages.sortModalTitleLabel.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
const sortNameAscendingButton = screen.getByText(messages.sortByNameAscending.defaultMessage);
|
||||
fireEvent.click(sortNameAscendingButton);
|
||||
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
|
||||
it('sort button should be enabled and sort files by file size', async () => {
|
||||
@@ -416,30 +384,26 @@ describe('FilesAndUploads', () => {
|
||||
const sortsButton = screen.getByText(messages.sortButtonLabel.defaultMessage);
|
||||
expect(sortsButton).toBeVisible();
|
||||
|
||||
fireEvent.click(sortsButton);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(sortsButton);
|
||||
expect(screen.getByText(messages.sortModalTitleLabel.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
const sortBySizeDescendingButton = screen.getByText(messages.sortBySizeDescending.defaultMessage);
|
||||
fireEvent.click(sortBySizeDescendingButton);
|
||||
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('card menu actions', () => {
|
||||
it('should open asset info', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
let assetMenuButton;
|
||||
|
||||
await waitFor(() => {
|
||||
[assetMenuButton] = screen.getAllByTestId('file-menu-dropdown-mOckID1');
|
||||
});
|
||||
const [assetMenuButton] = await screen.getAllByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}mOckID1/usage`)
|
||||
.reply(201, {
|
||||
@@ -450,14 +414,15 @@ describe('FilesAndUploads', () => {
|
||||
}],
|
||||
},
|
||||
});
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
|
||||
await executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID1', displayName: 'mOckID1' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID1', displayName: 'mOckID1' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
expect(screen.getAllByLabelText('mOckID1')[0]).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -472,23 +437,23 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID1`).reply(201, { locked: false });
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}mOckID1/usage`).reply(201, { usage_locations: { mOckID1: [] } });
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
await executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID1', displayName: 'mOckID1' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID1', displayName: 'mOckID1' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
expect(screen.getAllByLabelText('mOckID1')[0]).toBeVisible();
|
||||
|
||||
fireEvent.click(screen.getByLabelText('Checkbox'));
|
||||
executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID1',
|
||||
locked: false,
|
||||
}), store.dispatch);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByLabelText('Checkbox'));
|
||||
await executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID1',
|
||||
locked: false,
|
||||
}), store.dispatch);
|
||||
expect(screen.getByText(messages.usageNotInUseMessage.defaultMessage)).toBeVisible();
|
||||
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
@@ -500,18 +465,18 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID1')[0];
|
||||
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID1`).reply(201, { locked: false });
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Unlock'));
|
||||
await executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID1',
|
||||
locked: false,
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID1`).reply(201, { locked: false });
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Unlock'));
|
||||
executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID1',
|
||||
locked: false,
|
||||
}), store.dispatch);
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
it('should lock asset', async () => {
|
||||
@@ -519,18 +484,18 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID3')[0];
|
||||
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID3`).reply(201, { locked: true });
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Lock'));
|
||||
await executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID3',
|
||||
locked: true,
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID3`).reply(201, { locked: true });
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Lock'));
|
||||
executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID3',
|
||||
locked: true,
|
||||
}), store.dispatch);
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
it('download button should download file', async () => {
|
||||
@@ -538,10 +503,8 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID1')[0];
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Download'));
|
||||
});
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Download'));
|
||||
expect(saveAs).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -550,17 +513,18 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID1')[0];
|
||||
|
||||
axiosMock.onDelete(`${getAssetsUrl(courseId)}mOckID1`).reply(204);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
await waitFor(() => {
|
||||
axiosMock.onDelete(`${getAssetsUrl(courseId)}mOckID1`).reply(204);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
expect(screen.getByText('Delete mOckID1')).toBeVisible();
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
expect(screen.queryByText('Delete mOckID1')).toBeNull();
|
||||
|
||||
executeThunk(deleteAssetFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Delete mOckID1')).toBeNull();
|
||||
});
|
||||
await executeThunk(deleteAssetFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
const deleteStatus = store.getState().assets.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
@@ -572,9 +536,7 @@ describe('FilesAndUploads', () => {
|
||||
it('404 intitial fetch should show error', async () => {
|
||||
await mockStore(RequestStatus.FAILED);
|
||||
const { loadingStatus } = store.getState().assets;
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
});
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
|
||||
expect(loadingStatus).toEqual(RequestStatus.FAILED);
|
||||
expect(screen.getByText('Failed to load all files.')).toBeVisible();
|
||||
@@ -583,9 +545,7 @@ describe('FilesAndUploads', () => {
|
||||
it('404 intitial fetch should show error', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL, true);
|
||||
const { loadingStatus } = store.getState().assets;
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
});
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
|
||||
expect(loadingStatus).toEqual(RequestStatus.PARTIAL_FAILURE);
|
||||
expect(screen.getByText('Failed to load remaining files.')).toBeVisible();
|
||||
@@ -597,12 +557,11 @@ describe('FilesAndUploads', () => {
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(200, { assets: [] });
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(413, { error: errorMessage });
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await waitFor(() => {
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -610,10 +569,8 @@ describe('FilesAndUploads', () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(404);
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addAssetFile(courseId, file, 1), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addAssetFile(courseId, file, 1), store.dispatch);
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -625,10 +582,8 @@ describe('FilesAndUploads', () => {
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}?display_name=download.png&page_size=1`).reply(200, { assets: [] });
|
||||
axiosMock.onPost(getAssetsUrl(courseId)).reply(404);
|
||||
const addFilesButton = screen.getByLabelText('file-input');
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addAssetFile(courseId, file, 1), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addAssetFile(courseId, file, 1), store.dispatch);
|
||||
const addStatus = store.getState().assets.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -640,17 +595,18 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID3')[0];
|
||||
|
||||
axiosMock.onDelete(`${getAssetsUrl(courseId)}mOckID3`).reply(404);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
await waitFor(() => {
|
||||
axiosMock.onDelete(`${getAssetsUrl(courseId)}mOckID3`).reply(404);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
expect(screen.getByText('Delete mOckID3')).toBeVisible();
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
expect(screen.queryByText('Delete mOckID3')).toBeNull();
|
||||
|
||||
executeThunk(deleteAssetFile(courseId, 'mOckID3', 5), store.dispatch);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Delete mOckID3')).toBeNull();
|
||||
});
|
||||
await executeThunk(deleteAssetFile(courseId, 'mOckID3', 5), store.dispatch);
|
||||
const deleteStatus = store.getState().assets.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -665,17 +621,17 @@ describe('FilesAndUploads', () => {
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID3')[0];
|
||||
|
||||
axiosMock.onGet(`${getAssetsUrl(courseId)}mOckID3/usage`).reply(404);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
await executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID3', displayName: 'mOckID3' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
asset: { id: 'mOckID3', displayName: 'mOckID3' },
|
||||
setSelectedRows: jest.fn(),
|
||||
}), store.dispatch);
|
||||
const { usageStatus } = store.getState().assets;
|
||||
expect(usageStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
const { usageStatus } = store.getState().assets;
|
||||
expect(usageStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
it('404 lock update should show error', async () => {
|
||||
@@ -683,19 +639,18 @@ describe('FilesAndUploads', () => {
|
||||
|
||||
const assetMenuButton = screen.getAllByTestId('file-menu-dropdown-mOckID3')[0];
|
||||
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID3`).reply(404);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Lock'));
|
||||
await executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID3',
|
||||
locked: true,
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
axiosMock.onPut(`${getAssetsUrl(courseId)}mOckID3`).reply(404);
|
||||
fireEvent.click(within(assetMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Lock'));
|
||||
executeThunk(updateAssetLock({
|
||||
courseId,
|
||||
assetId: 'mOckID3',
|
||||
locked: true,
|
||||
}), store.dispatch);
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
const updateStatus = store.getState().assets.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
expect(screen.getByText('Error')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -707,17 +662,15 @@ describe('FilesAndUploads', () => {
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
fireEvent.click(actionsButton);
|
||||
const mockResponseData = { ok: false };
|
||||
const mockFetchResponse = Promise.resolve(mockResponseData);
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
expect(downloadButton).not.toHaveClass('disabled');
|
||||
|
||||
global.fetch = jest.fn().mockImplementation(() => mockFetchResponse);
|
||||
fireEvent.click(downloadButton);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(downloadButton);
|
||||
expect(fetch).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ GalleryCard.propTypes = {
|
||||
handleOpenDeleteConfirmation: PropTypes.func.isRequired,
|
||||
handleOpenFileInfo: PropTypes.func.isRequired,
|
||||
thumbnailPreview: PropTypes.func.isRequired,
|
||||
fileType: PropTypes.func.isRequired,
|
||||
fileType: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default GalleryCard;
|
||||
|
||||
@@ -70,6 +70,15 @@ const mockStore = async (
|
||||
|
||||
renderComponent();
|
||||
await executeThunk(fetchVideos(courseId), store.dispatch);
|
||||
|
||||
// Finish loading the expected files into the data table before returning,
|
||||
// because loading new files can disrupt things like accessing file menus.
|
||||
if (status === RequestStatus.SUCCESSFUL) {
|
||||
const numFiles = 3;
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(`Showing ${numFiles} of ${numFiles}`)).toBeInTheDocument();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const emptyMockStore = async (status) => {
|
||||
@@ -127,24 +136,24 @@ describe('Videos page', () => {
|
||||
it('should upload a single file', async () => {
|
||||
await emptyMockStore(RequestStatus.SUCCESSFUL);
|
||||
const dropzone = screen.getByTestId('files-dropzone');
|
||||
await act(async () => {
|
||||
const mockResponseData = { status: '200', ok: true, blob: () => 'Data' };
|
||||
const mockFetchResponse = Promise.resolve(mockResponseData);
|
||||
global.fetch = jest.fn().mockImplementation(() => mockFetchResponse);
|
||||
const mockResponseData = { status: '200', ok: true, blob: () => 'Data' };
|
||||
const mockFetchResponse = Promise.resolve(mockResponseData);
|
||||
global.fetch = jest.fn().mockImplementation(() => mockFetchResponse);
|
||||
|
||||
axiosMock.onPost(getCourseVideosApiUrl(courseId)).reply(204, generateNewVideoApiResponse());
|
||||
axiosMock.onGet(getCourseVideosApiUrl(courseId)).reply(200, generateAddVideoApiResponse());
|
||||
Object.defineProperty(dropzone, 'files', {
|
||||
value: [file],
|
||||
});
|
||||
fireEvent.drop(dropzone);
|
||||
await executeThunk(addVideoFile(courseId, file, [], { current: [] }), store.dispatch);
|
||||
axiosMock.onPost(getCourseVideosApiUrl(courseId)).reply(204, generateNewVideoApiResponse());
|
||||
axiosMock.onGet(getCourseVideosApiUrl(courseId)).reply(200, generateAddVideoApiResponse());
|
||||
Object.defineProperty(dropzone, 'files', {
|
||||
value: [file],
|
||||
});
|
||||
fireEvent.drop(dropzone);
|
||||
await executeThunk(addVideoFile(courseId, file, [], { current: [] }), store.dispatch);
|
||||
|
||||
await waitFor(() => {
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
expect(screen.queryByTestId('files-dropzone')).toBeNull();
|
||||
|
||||
expect(screen.getByTestId('files-data-table')).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -170,9 +179,7 @@ describe('Videos page', () => {
|
||||
const transcriptSettingsButton = screen.getByText(videoMessages.transcriptSettingsButtonLabel.defaultMessage);
|
||||
expect(transcriptSettingsButton).toBeVisible();
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(transcriptSettingsButton);
|
||||
});
|
||||
fireEvent.click(transcriptSettingsButton);
|
||||
|
||||
expect(screen.getByLabelText('close settings')).toBeVisible();
|
||||
});
|
||||
@@ -200,9 +207,7 @@ describe('Videos page', () => {
|
||||
expect(screen.queryByRole('table')).toBeNull();
|
||||
|
||||
const listButton = screen.getByLabelText('List');
|
||||
await act(async () => {
|
||||
fireEvent.click(listButton);
|
||||
});
|
||||
fireEvent.click(listButton);
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
|
||||
expect(screen.getByRole('table')).toBeVisible();
|
||||
@@ -213,10 +218,8 @@ describe('Videos page', () => {
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/video_images/${courseId}/mOckID1`).reply(200, { image_url: 'url' });
|
||||
const addThumbnailButton = screen.getByTestId('video-thumbnail-mOckID1');
|
||||
const thumbnail = new File(['test'], 'sOMEUrl.jpg', { type: 'image/jpg' });
|
||||
await act(async () => {
|
||||
fireEvent.click(addThumbnailButton);
|
||||
await executeThunk(addVideoThumbnail({ file: thumbnail, videoId: 'mOckID1', courseId }), store.dispatch);
|
||||
});
|
||||
fireEvent.click(addThumbnailButton);
|
||||
await executeThunk(addVideoThumbnail({ file: thumbnail, videoId: 'mOckID1', courseId }), store.dispatch);
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
@@ -247,10 +250,8 @@ describe('Videos page', () => {
|
||||
|
||||
const addFilesButton = screen.getAllByLabelText('file-input')[3];
|
||||
const { videoIds } = store.getState().videos;
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, videoIds, { current: [] }), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, videoIds, { current: [] }), store.dispatch);
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
@@ -270,9 +271,7 @@ describe('Videos page', () => {
|
||||
uploadSpy.mockResolvedValue(new Promise(() => {}));
|
||||
|
||||
const addFilesButton = screen.getAllByLabelText('file-input')[3];
|
||||
act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await waitFor(() => {
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.IN_PROGRESS);
|
||||
@@ -293,23 +292,24 @@ describe('Videos page', () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
|
||||
fireEvent.click(actionsButton);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
expect(screen.getByText(messages.downloadTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
expect(screen.getByText(messages.downloadTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
|
||||
expect(screen.getByText(messages.deleteTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
expect(screen.getByText(messages.deleteTitle.defaultMessage).closest('a')).toHaveClass('disabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('delete button should be enabled and delete selected file', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
const selectCardButton = screen.getAllByTestId('datatable-select-column-checkbox-cell')[0];
|
||||
fireEvent.click(selectCardButton);
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
const [selectCardButton] = await screen.findAllByTestId('datatable-select-column-checkbox-cell');
|
||||
fireEvent.click(selectCardButton);
|
||||
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
fireEvent.click(actionsButton);
|
||||
|
||||
const deleteButton = screen.getByText(messages.deleteTitle.defaultMessage).closest('a');
|
||||
expect(deleteButton).not.toHaveClass('disabled');
|
||||
|
||||
@@ -317,45 +317,22 @@ describe('Videos page', () => {
|
||||
|
||||
fireEvent.click(deleteButton);
|
||||
expect(screen.getByText('Delete mOckID1.mp4')).toBeVisible();
|
||||
await act(async () => {
|
||||
userEvent.click(deleteButton);
|
||||
});
|
||||
fireEvent.click(deleteButton);
|
||||
|
||||
// Wait for the delete confirmation button to appear
|
||||
const confirmDeleteButton = await screen.findByRole('button', {
|
||||
name: messages.deleteFileButtonLabel.defaultMessage,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
userEvent.click(confirmDeleteButton);
|
||||
});
|
||||
fireEvent.click(confirmDeleteButton);
|
||||
|
||||
expect(screen.queryByText('Delete mOckID1.mp4')).toBeNull();
|
||||
|
||||
// Check if the video is deleted in the store and UI
|
||||
const deleteStatus = store.getState().videos.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
});
|
||||
|
||||
it('download button should be enabled and download single selected file', async () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
const selectCardButton = screen.getAllByTestId('datatable-select-column-checkbox-cell')[0];
|
||||
fireEvent.click(selectCardButton);
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
const deleteStatus = store.getState().videos.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
expect(downloadButton).not.toHaveClass('disabled');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(downloadButton);
|
||||
});
|
||||
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
expect(screen.queryByTestId('grid-card-mOckID1')).toBeNull();
|
||||
});
|
||||
|
||||
it('download button should be enabled and download multiple selected files', async () => {
|
||||
@@ -365,20 +342,18 @@ describe('Videos page', () => {
|
||||
fireEvent.click(selectCardButtons[1]);
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
fireEvent.click(actionsButton);
|
||||
axiosMock.onPut(`${getVideosUrl(courseId)}/download`).reply(200, null);
|
||||
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
expect(downloadButton).not.toHaveClass('disabled');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(downloadButton);
|
||||
});
|
||||
fireEvent.click(downloadButton);
|
||||
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
await waitFor(() => {
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sort and filter button', () => {
|
||||
@@ -386,9 +361,7 @@ describe('Videos page', () => {
|
||||
await mockStore(RequestStatus.SUCCESSFUL);
|
||||
const sortAndFilterButton = screen.getByText(messages.sortButtonLabel.defaultMessage);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(sortAndFilterButton);
|
||||
});
|
||||
fireEvent.click(sortAndFilterButton);
|
||||
});
|
||||
|
||||
describe('sort function', () => {
|
||||
@@ -396,22 +369,22 @@ describe('Videos page', () => {
|
||||
const sortNameAscendingButton = screen.getByText(messages.sortByNameAscending.defaultMessage);
|
||||
fireEvent.click(sortNameAscendingButton);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
});
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it('sort button should be enabled and sort files by file size', async () => {
|
||||
const sortBySizeDescendingButton = screen.getByText(messages.sortBySizeDescending.defaultMessage);
|
||||
fireEvent.click(sortBySizeDescendingButton);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
});
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(messages.sortModalTitleLabel.defaultMessage)).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -425,13 +398,12 @@ describe('Videos page', () => {
|
||||
fireEvent.click(notTranscribedCheckboxFilter);
|
||||
fireEvent.click(transcribedCheckboxFilter);
|
||||
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
const galleryCards = screen.getAllByTestId('grid-card', { exact: false });
|
||||
expect(galleryCards).toHaveLength(1);
|
||||
});
|
||||
|
||||
const galleryCards = screen.getAllByTestId('grid-card', { exact: false });
|
||||
|
||||
expect(galleryCards).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should clearAll selections', async () => {
|
||||
@@ -445,7 +417,7 @@ describe('Videos page', () => {
|
||||
fireEvent.click(transcribedCheckboxFilter);
|
||||
|
||||
const clearAllButton = screen.getByText('Clear all');
|
||||
await waitFor(() => fireEvent.click(clearAllButton));
|
||||
fireEvent.click(clearAllButton);
|
||||
|
||||
expect(transcribedCheckboxFilter).toHaveProperty('checked', false);
|
||||
|
||||
@@ -460,11 +432,9 @@ describe('Videos page', () => {
|
||||
const transcribedCheckboxFilter = screen.getByText(videoMessages.transcribedCheckboxLabel.defaultMessage);
|
||||
fireEvent.click(transcribedCheckboxFilter);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
});
|
||||
fireEvent.click(screen.getByText(messages.applySortButton.defaultMessage));
|
||||
|
||||
const imageFilterChip = screen.getByRole('button', { name: 'Remove this filter' });
|
||||
const imageFilterChip = await screen.findByRole('button', { name: 'Remove this filter' });
|
||||
fireEvent.click(imageFilterChip);
|
||||
|
||||
expect(screen.queryByText(videoMessages.transcribedCheckboxLabel.defaultMessage)).toBeNull();
|
||||
@@ -488,12 +458,12 @@ describe('Videos page', () => {
|
||||
}],
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
});
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
|
||||
expect(screen.getByText(messages.infoTitle.defaultMessage)).toBeVisible();
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(messages.infoTitle.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
const { usageStatus } = store.getState().videos;
|
||||
|
||||
@@ -507,13 +477,12 @@ describe('Videos page', () => {
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
axiosMock.onGet(`${getVideosUrl(courseId)}/mOckID1/usage`).reply(201, { usageLocations: [] });
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
expect(screen.getByText(messages.usageNotInUseMessage.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
expect(screen.getByText(messages.usageNotInUseMessage.defaultMessage)).toBeVisible();
|
||||
|
||||
const infoTab = screen.getAllByRole('tab')[0];
|
||||
expect(infoTab).toBeVisible();
|
||||
|
||||
@@ -525,17 +494,14 @@ describe('Videos page', () => {
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
axiosMock.onGet(`${getVideosUrl(courseId)}/mOckID1/usage`).reply(201, { usageLocations: [] });
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
expect(screen.getByText(messages.usageNotInUseMessage.defaultMessage)).toBeVisible();
|
||||
});
|
||||
|
||||
expect(screen.getByText(messages.usageNotInUseMessage.defaultMessage)).toBeVisible();
|
||||
|
||||
const transcriptTab = screen.getAllByRole('tab')[1];
|
||||
await act(async () => {
|
||||
fireEvent.click(transcriptTab);
|
||||
});
|
||||
fireEvent.click(transcriptTab);
|
||||
expect(transcriptTab).toBeVisible();
|
||||
|
||||
expect(transcriptTab).toHaveClass('active');
|
||||
@@ -546,15 +512,11 @@ describe('Videos page', () => {
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID3');
|
||||
|
||||
axiosMock.onGet(`${getVideosUrl(courseId)}/mOckID3/usage`).reply(201, { usageLocations: [] });
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
});
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
|
||||
const transcriptTab = screen.getAllByRole('tab')[1];
|
||||
await act(async () => {
|
||||
fireEvent.click(transcriptTab);
|
||||
});
|
||||
const transcriptTab = await screen.getAllByRole('tab')[1];
|
||||
fireEvent.click(transcriptTab);
|
||||
|
||||
expect(screen.getByText('Transcript (1)')).toBeVisible();
|
||||
});
|
||||
@@ -565,14 +527,13 @@ describe('Videos page', () => {
|
||||
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Download'));
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Download'));
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
|
||||
expect(updateStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
it('delete button should delete file', async () => {
|
||||
@@ -580,17 +541,18 @@ describe('Videos page', () => {
|
||||
|
||||
const fileMenuButton = screen.getByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
axiosMock.onDelete(`${getCourseVideosApiUrl(courseId)}/mOckID1`).reply(204);
|
||||
fireEvent.click(within(fileMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
await waitFor(() => {
|
||||
axiosMock.onDelete(`${getCourseVideosApiUrl(courseId)}/mOckID1`).reply(204);
|
||||
fireEvent.click(within(fileMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
expect(screen.getByText('Delete mOckID1.mp4')).toBeVisible();
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
expect(screen.queryByText('Delete mOckID1.mp4')).toBeNull();
|
||||
|
||||
executeThunk(deleteVideoFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Delete mOckID1.mp4')).toBeNull();
|
||||
});
|
||||
await executeThunk(deleteVideoFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
const deleteStatus = store.getState().videos.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
@@ -614,10 +576,8 @@ describe('Videos page', () => {
|
||||
axiosMock.onPost(getCourseVideosApiUrl(courseId)).reply(413, { error: errorMessage });
|
||||
|
||||
const addFilesButton = screen.getAllByLabelText('file-input')[3];
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -629,10 +589,8 @@ describe('Videos page', () => {
|
||||
axiosMock.onPost(getCourseVideosApiUrl(courseId)).reply(404);
|
||||
|
||||
const addFilesButton = screen.getAllByLabelText('file-input')[3];
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -645,10 +603,8 @@ describe('Videos page', () => {
|
||||
|
||||
const addThumbnailButton = screen.getByTestId('video-thumbnail-mOckID1');
|
||||
const thumbnail = new File(['test'], 'sOMEUrl.jpg', { type: 'image/jpg' });
|
||||
await act(async () => {
|
||||
fireEvent.click(addThumbnailButton);
|
||||
await executeThunk(addVideoThumbnail({ file: thumbnail, videoId: 'mOckID1', courseId }), store.dispatch);
|
||||
});
|
||||
fireEvent.click(addThumbnailButton);
|
||||
await executeThunk(addVideoThumbnail({ file: thumbnail, videoId: 'mOckID1', courseId }), store.dispatch);
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -664,10 +620,8 @@ describe('Videos page', () => {
|
||||
axiosMock.onPost(getCourseVideosApiUrl(courseId)).reply(204, generateNewVideoApiResponse());
|
||||
axiosMock.onGet(getCourseVideosApiUrl(courseId)).reply(200, generateAddVideoApiResponse());
|
||||
const addFilesButton = screen.getAllByLabelText('file-input')[3];
|
||||
await act(async () => {
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
});
|
||||
userEvent.upload(addFilesButton, file);
|
||||
await executeThunk(addVideoFile(courseId, file, undefined, { current: [] }), store.dispatch);
|
||||
const addStatus = store.getState().videos.addingStatus;
|
||||
expect(addStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -679,16 +633,19 @@ describe('Videos page', () => {
|
||||
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID1');
|
||||
|
||||
axiosMock.onDelete(`${getCourseVideosApiUrl(courseId)}/mOckID1`).reply(404);
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
await waitFor(async () => {
|
||||
axiosMock.onDelete(`${getCourseVideosApiUrl(courseId)}/mOckID1`).reply(404);
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByTestId('open-delete-confirmation-button'));
|
||||
expect(screen.getByText('Delete mOckID1.mp4')).toBeVisible();
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
fireEvent.click(screen.getByText(messages.deleteFileButtonLabel.defaultMessage));
|
||||
await waitFor(async () => {
|
||||
expect(screen.queryByText('Delete mOckID1.mp4')).toBeNull();
|
||||
});
|
||||
executeThunk(deleteVideoFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
|
||||
await executeThunk(deleteVideoFile(courseId, 'mOckID1', 5), store.dispatch);
|
||||
await waitFor(() => {
|
||||
const deleteStatus = store.getState().videos.deletingStatus;
|
||||
expect(deleteStatus).toEqual(RequestStatus.FAILED);
|
||||
@@ -705,14 +662,12 @@ describe('Videos page', () => {
|
||||
const videoMenuButton = screen.getByTestId('file-menu-dropdown-mOckID3');
|
||||
|
||||
axiosMock.onGet(`${getVideosUrl(courseId)}/mOckID3/usage`).reply(404);
|
||||
await waitFor(() => {
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
video: { id: 'mOckID3', displayName: 'mOckID3' },
|
||||
}), store.dispatch);
|
||||
});
|
||||
fireEvent.click(within(videoMenuButton).getByLabelText('file-menu-toggle'));
|
||||
fireEvent.click(screen.getByText('Info'));
|
||||
await executeThunk(getUsagePaths({
|
||||
courseId,
|
||||
video: { id: 'mOckID3', displayName: 'mOckID3' },
|
||||
}), store.dispatch);
|
||||
await waitFor(() => {
|
||||
const { usageStatus } = store.getState().videos;
|
||||
expect(usageStatus).toEqual(RequestStatus.FAILED);
|
||||
@@ -728,18 +683,13 @@ describe('Videos page', () => {
|
||||
const actionsButton = screen.getByText(messages.actionsButtonLabel.defaultMessage);
|
||||
expect(actionsButton).toBeVisible();
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
const downloadButton = screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
fireEvent.click(actionsButton);
|
||||
const downloadButton = await screen.getByText(messages.downloadTitle.defaultMessage).closest('a');
|
||||
expect(downloadButton).not.toHaveClass('disabled');
|
||||
|
||||
axiosMock.onPut(`${getVideosUrl(courseId)}/download`).reply(404);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.click(downloadButton);
|
||||
executeThunk(fetchVideoDownload([{ original: { displayName: 'mOckID1', id: '2', downloadLink: 'test' } }]), store.dispatch);
|
||||
});
|
||||
fireEvent.click(downloadButton);
|
||||
await executeThunk(fetchVideoDownload([{ original: { displayName: 'mOckID1', id: '2', downloadLink: 'test' } }]), store.dispatch);
|
||||
|
||||
const updateStatus = store.getState().videos.updatingStatus;
|
||||
expect(updateStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
render,
|
||||
act,
|
||||
fireEvent,
|
||||
screen,
|
||||
waitFor,
|
||||
within,
|
||||
@@ -70,9 +70,7 @@ describe('TranscriptSettings', () => {
|
||||
it('should change view to order form', async () => {
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
const selectableButtons = screen.getAllByLabelText('none radio')[0];
|
||||
|
||||
expect(selectableButtons).toBeVisible();
|
||||
@@ -81,17 +79,14 @@ describe('TranscriptSettings', () => {
|
||||
it('should return to order transcript collapsible', async () => {
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
const selectableButtons = screen.getAllByLabelText('none radio')[0];
|
||||
|
||||
expect(selectableButtons).toBeVisible();
|
||||
|
||||
const backButton = screen.getByLabelText('back button to main transcript settings view');
|
||||
userEvent.click(backButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(backButton);
|
||||
|
||||
expect(screen.queryByLabelText('back button to main transcript settings view')).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -99,13 +94,9 @@ describe('TranscriptSettings', () => {
|
||||
it('discard changes should call closeTranscriptSettings', async () => {
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
const discardButton = screen.getByText(messages.discardSettingsLabel.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(discardButton);
|
||||
});
|
||||
userEvent.click(discardButton);
|
||||
|
||||
expect(defaultProps.closeTranscriptSettings).toHaveBeenCalled();
|
||||
});
|
||||
@@ -145,9 +136,7 @@ describe('TranscriptSettings', () => {
|
||||
|
||||
it('should load page with Cielo24 selected', async () => {
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
const cielo24Button = screen.getByText(messages.cieloLabel.defaultMessage);
|
||||
|
||||
expect(within(cielo24Button).getByLabelText('Cielo24 radio')).toHaveProperty('checked', true);
|
||||
@@ -185,38 +174,32 @@ describe('TranscriptSettings', () => {
|
||||
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
const noneButton = screen.getAllByLabelText('none radio')[0];
|
||||
|
||||
await act(async () => {
|
||||
userEvent.click(noneButton);
|
||||
});
|
||||
userEvent.click(noneButton);
|
||||
});
|
||||
|
||||
it('api should succeed', async () => {
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
|
||||
axiosMock.onDelete(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(204);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
it('should show error alert', async () => {
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
|
||||
axiosMock.onDelete(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(404);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
|
||||
expect(screen.getByText('Failed to update order transcripts settings.')).toBeVisible();
|
||||
});
|
||||
@@ -237,24 +220,18 @@ describe('TranscriptSettings', () => {
|
||||
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
|
||||
it('should ask for Cielo24 or 3Play Media credentials', async () => {
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
const cieloCredentialMessage = screen.getByTestId('cieloCredentialMessage');
|
||||
|
||||
expect(cieloCredentialMessage).toBeVisible();
|
||||
|
||||
const threePlayMediaButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayMediaButton);
|
||||
});
|
||||
userEvent.click(threePlayMediaButton);
|
||||
const threePlayMediaCredentialMessage = screen.getByTestId('threePlayMediaCredentialMessage');
|
||||
|
||||
expect(threePlayMediaCredentialMessage).toBeVisible();
|
||||
@@ -263,9 +240,7 @@ describe('TranscriptSettings', () => {
|
||||
describe('api succeeds', () => {
|
||||
it('should update cielo24 credentials ', async () => {
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
|
||||
const firstInput = screen.getByLabelText(messages.cieloApiKeyLabel.defaultMessage);
|
||||
const secondInput = screen.getByLabelText(messages.cieloUsernameLabel.defaultMessage);
|
||||
@@ -279,14 +254,12 @@ describe('TranscriptSettings', () => {
|
||||
});
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_credentials/${courseId}`).reply(200);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
|
||||
expect(screen.queryByTestId('cieloCredentialMessage')).toBeNull();
|
||||
|
||||
expect(screen.getByText(messages.cieloFidelityLabel.defaultMessage)).toBeVisible();
|
||||
@@ -294,9 +267,7 @@ describe('TranscriptSettings', () => {
|
||||
|
||||
it('should update 3Play Media credentials', async () => {
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const firstInput = screen.getByLabelText(messages.threePlayMediaApiKeyLabel.defaultMessage);
|
||||
@@ -310,12 +281,12 @@ describe('TranscriptSettings', () => {
|
||||
});
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_credentials/${courseId}`).reply(200);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
fireEvent.click(updateButton);
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
await waitFor(() => {
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
expect(screen.queryByTestId('threePlayCredentialMessage')).toBeNull();
|
||||
|
||||
@@ -326,9 +297,7 @@ describe('TranscriptSettings', () => {
|
||||
describe('api fails', () => {
|
||||
it('should show error alert on Cielo24 credentials update', async () => {
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
|
||||
const firstInput = screen.getByLabelText(messages.cieloApiKeyLabel.defaultMessage);
|
||||
const secondInput = screen.getByLabelText(messages.cieloUsernameLabel.defaultMessage);
|
||||
@@ -342,21 +311,19 @@ describe('TranscriptSettings', () => {
|
||||
});
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(503);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
fireEvent.click(updateButton);
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
await waitFor(() => {
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Failed to update Cielo24 credentials.')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should show error alert on 3PlayMedia credentials update', async () => {
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const firstInput = screen.getByLabelText(messages.threePlayMediaApiKeyLabel.defaultMessage);
|
||||
@@ -370,12 +337,12 @@ describe('TranscriptSettings', () => {
|
||||
});
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(404);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
fireEvent.click(updateButton);
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
await waitFor(() => {
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Failed to update 3PlayMedia credentials.')).toBeVisible();
|
||||
});
|
||||
@@ -408,24 +375,18 @@ describe('TranscriptSettings', () => {
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
renderComponent(defaultProps);
|
||||
const orderButton = screen.getByText(messages.orderTranscriptsTitle.defaultMessage);
|
||||
await act(async () => {
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
userEvent.click(orderButton);
|
||||
});
|
||||
|
||||
it('should not show credentials request for Cielo24 and 3Play Media', async () => {
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
const cieloCredentialMessage = screen.queryByTestId('cieloCredentialMessage');
|
||||
|
||||
expect(cieloCredentialMessage).toBeNull();
|
||||
|
||||
const threePlayMediaButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayMediaButton);
|
||||
});
|
||||
userEvent.click(threePlayMediaButton);
|
||||
const threePlayMediaCredentialMessage = screen.queryByTestId('threePlayMediaCredentialMessage');
|
||||
|
||||
expect(threePlayMediaCredentialMessage).toBeNull();
|
||||
@@ -443,9 +404,7 @@ describe('TranscriptSettings', () => {
|
||||
};
|
||||
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.cieloTurnaroundPlaceholder.defaultMessage);
|
||||
const fidelity = screen.getByText(messages.cieloFidelityPlaceholder.defaultMessage);
|
||||
@@ -469,12 +428,13 @@ describe('TranscriptSettings', () => {
|
||||
expect(updateButton).not.toHaveAttribute('disabled');
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(200, apiResponse);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
fireEvent.click(updateButton);
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
await waitFor(() => {
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
|
||||
expect(screen.getByText(messages.cieloFidelityLabel.defaultMessage)).toBeVisible();
|
||||
});
|
||||
@@ -488,9 +448,7 @@ describe('TranscriptSettings', () => {
|
||||
global: false,
|
||||
};
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.threePlayMediaTurnaroundPlaceholder.defaultMessage);
|
||||
const source = screen.getByText(messages.threePlayMediaSourceLanguagePlaceholder.defaultMessage);
|
||||
@@ -512,12 +470,12 @@ describe('TranscriptSettings', () => {
|
||||
});
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(200, apiResponse);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
});
|
||||
|
||||
it('should update 3Play Media preferences with spanish as source language', async () => {
|
||||
@@ -529,9 +487,7 @@ describe('TranscriptSettings', () => {
|
||||
global: false,
|
||||
};
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.threePlayMediaTurnaroundPlaceholder.defaultMessage);
|
||||
const source = screen.getByText(messages.threePlayMediaSourceLanguagePlaceholder.defaultMessage);
|
||||
@@ -550,21 +506,19 @@ describe('TranscriptSettings', () => {
|
||||
expect(updateButton).not.toHaveAttribute('disabled');
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(200, apiResponse);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
expect(transcriptStatus).toEqual(RequestStatus.SUCCESSFUL);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('api fails', () => {
|
||||
it('should show error alert on Cielo24 preferences update', async () => {
|
||||
const cielo24Button = screen.getAllByLabelText('Cielo24 radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(cielo24Button);
|
||||
});
|
||||
userEvent.click(cielo24Button);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.cieloTurnaroundPlaceholder.defaultMessage);
|
||||
const fidelity = screen.getByText(messages.cieloFidelityPlaceholder.defaultMessage);
|
||||
@@ -588,21 +542,19 @@ describe('TranscriptSettings', () => {
|
||||
expect(updateButton).not.toHaveAttribute('disabled');
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(503);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Failed to update Cielo24 transcripts settings.')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should show error alert with default message on 3PlayMedia preferences update', async () => {
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.threePlayMediaTurnaroundPlaceholder.defaultMessage);
|
||||
const source = screen.getByText(messages.threePlayMediaSourceLanguagePlaceholder.defaultMessage);
|
||||
@@ -621,21 +573,19 @@ describe('TranscriptSettings', () => {
|
||||
expect(updateButton).not.toHaveAttribute('disabled');
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(404);
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Failed to update 3PlayMedia transcripts settings.')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should show error alert with default message on 3PlayMedia preferences update', async () => {
|
||||
const threePlayButton = screen.getAllByLabelText('3PlayMedia radio')[0];
|
||||
await act(async () => {
|
||||
userEvent.click(threePlayButton);
|
||||
});
|
||||
userEvent.click(threePlayButton);
|
||||
const updateButton = screen.getByText(messages.updateSettingsLabel.defaultMessage);
|
||||
const turnaround = screen.getByText(messages.threePlayMediaTurnaroundPlaceholder.defaultMessage);
|
||||
const source = screen.getByText(messages.threePlayMediaSourceLanguagePlaceholder.defaultMessage);
|
||||
@@ -654,12 +604,12 @@ describe('TranscriptSettings', () => {
|
||||
expect(updateButton).not.toHaveAttribute('disabled');
|
||||
|
||||
axiosMock.onPost(`${getApiBaseUrl()}/transcript_preferences/${courseId}`).reply(404, { error: 'Invalid turnaround.' });
|
||||
fireEvent.click(updateButton);
|
||||
await waitFor(() => {
|
||||
userEvent.click(updateButton);
|
||||
});
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
const { transcriptStatus } = store.getState().videos;
|
||||
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
expect(transcriptStatus).toEqual(RequestStatus.FAILED);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Invalid turnaround.')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
screen,
|
||||
render,
|
||||
@@ -129,9 +128,7 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
render(<RootWrapper {...props} />);
|
||||
await mockStore();
|
||||
const cancelBtn = screen.getByRole('button', { name: messages.cancelButton.defaultMessage });
|
||||
await act(async () => {
|
||||
fireEvent.click(cancelBtn);
|
||||
});
|
||||
fireEvent.click(cancelBtn);
|
||||
|
||||
expect(onClickCancelMock).toHaveBeenCalled();
|
||||
});
|
||||
@@ -147,13 +144,11 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
const runInput = screen.getByPlaceholderText(messages.courseRunPlaceholder.defaultMessage);
|
||||
const createBtn = screen.getByRole('button', { name: messages.createButton.defaultMessage });
|
||||
|
||||
await act(async () => {
|
||||
userEvent.type(displayNameInput, 'foo course name');
|
||||
fireEvent.click(orgInput);
|
||||
userEvent.type(numberInput, '777');
|
||||
userEvent.type(runInput, '1');
|
||||
userEvent.click(createBtn);
|
||||
});
|
||||
userEvent.type(displayNameInput, 'foo course name');
|
||||
fireEvent.click(orgInput);
|
||||
userEvent.type(numberInput, '777');
|
||||
userEvent.type(runInput, '1');
|
||||
userEvent.click(createBtn);
|
||||
await axiosMock.onPost(getCreateOrRerunCourseUrl()).reply(200, { url });
|
||||
await executeThunk(updateCreateOrRerunCourseQuery({ org: 'testX', run: 'some' }), store.dispatch);
|
||||
|
||||
@@ -171,13 +166,11 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
const createBtn = screen.getByRole('button', { name: messages.createButton.defaultMessage });
|
||||
await axiosMock.onPost(getCreateOrRerunCourseUrl()).reply(200, { url, destinationCourseKey });
|
||||
|
||||
await act(async () => {
|
||||
userEvent.type(displayNameInput, 'foo course name');
|
||||
fireEvent.click(orgInput);
|
||||
userEvent.type(numberInput, '777');
|
||||
userEvent.type(runInput, '1');
|
||||
userEvent.click(createBtn);
|
||||
});
|
||||
userEvent.type(displayNameInput, 'foo course name');
|
||||
fireEvent.click(orgInput);
|
||||
userEvent.type(numberInput, '777');
|
||||
userEvent.type(runInput, '1');
|
||||
userEvent.click(createBtn);
|
||||
await executeThunk(updateCreateOrRerunCourseQuery({ org: 'testX', run: 'some' }), store.dispatch);
|
||||
|
||||
expect(mockedUsedNavigate).toHaveBeenCalledWith(`${url}${destinationCourseKey}`);
|
||||
@@ -208,12 +201,10 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
const numberInput = screen.getByPlaceholderText(messages.courseNumberPlaceholder.defaultMessage);
|
||||
const runInput = screen.getByPlaceholderText(messages.courseRunPlaceholder.defaultMessage);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(displayNameInput, { target: { value: 'foo course name' } });
|
||||
fireEvent.click(orgInput);
|
||||
fireEvent.change(numberInput, { target: { value: 'number with invalid (+) symbol' } });
|
||||
fireEvent.change(runInput, { target: { value: 'number with invalid (=) symbol' } });
|
||||
});
|
||||
fireEvent.change(displayNameInput, { target: { value: 'foo course name' } });
|
||||
fireEvent.click(orgInput);
|
||||
fireEvent.change(numberInput, { target: { value: 'number with invalid (+) symbol' } });
|
||||
fireEvent.change(runInput, { target: { value: 'number with invalid (=) symbol' } });
|
||||
|
||||
waitFor(() => {
|
||||
expect(createBtn).toBeDisabled();
|
||||
@@ -262,9 +253,7 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
await mockStore();
|
||||
const numberInput = screen.getByPlaceholderText(messages.courseNumberPlaceholder.defaultMessage);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(numberInput, { target: { value: 'number with invalid (+) symbol' } });
|
||||
});
|
||||
fireEvent.change(numberInput, { target: { value: 'number with invalid (+) symbol' } });
|
||||
|
||||
waitFor(() => {
|
||||
expect(screen.getByText(messages.noSpaceError)).toBeInTheDocument();
|
||||
|
||||
@@ -116,7 +116,7 @@ describe('<ModalDropzone />', () => {
|
||||
const dropzoneInput = getByRole('presentation', { hidden: true }).firstChild;
|
||||
const uploadButton = getByRole('button', { name: messages.uploadModal.defaultMessage });
|
||||
|
||||
await userEvent.upload(dropzoneInput, file);
|
||||
userEvent.upload(dropzoneInput, file);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(uploadButton).not.toBeDisabled();
|
||||
|
||||
@@ -5,13 +5,18 @@ import {
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { AppProvider, PageWrap } from '@edx/frontend-platform/react';
|
||||
import {
|
||||
act, findByRole, getByRole, queryByLabelText, queryByRole, queryByTestId, queryByText, render,
|
||||
screen, waitFor, waitForElementToBeRemoved,
|
||||
act, findByRole, fireEvent, getByRole, queryByLabelText, queryByRole, queryByTestId, queryByText,
|
||||
render, screen, waitFor, waitForElementToBeRemoved,
|
||||
} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import React from 'react';
|
||||
import { Routes, Route, MemoryRouter } from 'react-router-dom';
|
||||
import {
|
||||
Routes,
|
||||
Route,
|
||||
MemoryRouter,
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
import { fetchCourseDetail } from '../../data/thunks';
|
||||
import initializeStore from '../../store';
|
||||
import { executeThunk } from '../../utils';
|
||||
@@ -37,6 +42,11 @@ let container;
|
||||
// Modal creates a portal. Overriding ReactDOM.createPortal allows portals to be tested in jest.
|
||||
ReactDOM.createPortal = jest.fn(node => node);
|
||||
|
||||
const LocationDisplay = () => {
|
||||
const location = useLocation();
|
||||
return <div data-testid="location-display">{location.pathname}</div>;
|
||||
};
|
||||
|
||||
function renderComponent(route) {
|
||||
const wrapper = render(
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
@@ -52,6 +62,7 @@ function renderComponent(route) {
|
||||
element={<PageWrap><DiscussionsSettings courseId={courseId} /></PageWrap>}
|
||||
/>
|
||||
</Routes>
|
||||
<LocationDisplay />
|
||||
</MemoryRouter>
|
||||
</PagesAndResourcesProvider>
|
||||
</AppProvider>,
|
||||
@@ -94,7 +105,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
|
||||
@@ -104,7 +115,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
@@ -114,7 +125,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
@@ -134,7 +145,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(queryByLabelText(container, 'Select edX'));
|
||||
@@ -151,11 +162,11 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
|
||||
await act(() => userEvent.click(queryByText(container, appMessages.backButton.defaultMessage)));
|
||||
await waitFor(() => userEvent.click(queryByText(container, appMessages.backButton.defaultMessage)));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
|
||||
@@ -167,7 +178,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
expect(queryByTestId(container, 'appList')).toBeInTheDocument();
|
||||
|
||||
@@ -183,22 +194,27 @@ describe('DiscussionsSettings', () => {
|
||||
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
act(async () => {
|
||||
userEvent.click(queryByLabelText(container, 'Select Piazza'));
|
||||
userEvent.click(screen.getByLabelText('Select Piazza'));
|
||||
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
|
||||
userEvent.click(await findByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
// This is an important line that ensures the Close button has been removed, which implies that
|
||||
// the full screen modal has been closed following our click of Apply. Once this has happened,
|
||||
// then it's safe to proceed with our expectations.
|
||||
await waitFor(() => expect(screen.queryByRole(container, 'button', { name: 'Close' })).toBeNull());
|
||||
|
||||
await waitFor(() => expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources`));
|
||||
// Have to use fireEvent.click with these Stepper buttons so that the
|
||||
// onClick handler is triggered. (userEvent.click doesn't trigger onClick).
|
||||
await act(async () => {
|
||||
fireEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
});
|
||||
|
||||
// This is an important line that ensures the Close button has been removed, which implies that
|
||||
// the full screen modal has been closed following our click of Apply. Once this has happened,
|
||||
// then it's safe to proceed with our expectations.
|
||||
await waitFor(() => expect(screen.queryByRole(container, 'button', { name: 'Close' })).toBeNull());
|
||||
|
||||
// Confirm route is correct
|
||||
const locationDisplay = await screen.findByTestId('location-display');
|
||||
await waitFor(() => expect(locationDisplay.textContent).toEqual(`/course/${courseId}/pages-and-resources`));
|
||||
});
|
||||
|
||||
test('requires confirmation if changing provider', async () => {
|
||||
@@ -208,20 +224,18 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
act(async () => {
|
||||
userEvent.click(getByRole(container, 'checkbox', { name: 'Select Discourse' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
userEvent.click(getByRole(container, 'checkbox', { name: 'Select Discourse' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Next' }));
|
||||
|
||||
await findByRole(container, 'button', { name: 'Save' });
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'key');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
await findByRole(container, 'button', { name: 'Save' });
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'key');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
await waitFor(() => expect(queryByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
});
|
||||
await waitFor(() => expect(queryByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
});
|
||||
|
||||
test('can cancel confirmation', async () => {
|
||||
@@ -231,7 +245,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
const discourseBox = getByRole(container, 'checkbox', { name: 'Select Discourse' });
|
||||
expect(discourseBox).not.toBeDisabled();
|
||||
@@ -241,20 +255,18 @@ describe('DiscussionsSettings', () => {
|
||||
|
||||
await waitFor(() => expect(screen.queryByRole('status')).toBeNull());
|
||||
|
||||
act(async () => {
|
||||
expect(await findByRole(container, 'heading', { name: 'Discourse' })).toBeInTheDocument();
|
||||
expect(await findByRole(container, 'heading', { name: 'Discourse' })).toBeInTheDocument();
|
||||
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'a');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Key' }), 'a');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Consumer Secret' }), 'secret');
|
||||
userEvent.type(getByRole(container, 'textbox', { name: 'Launch URL' }), 'http://example.test');
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Cancel' }));
|
||||
await waitFor(() => expect(getByRole(container, 'dialog', { name: 'OK' })).toBeInTheDocument());
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Cancel' }));
|
||||
|
||||
expect(queryByRole(container, 'dialog', { name: 'Confirm' })).not.toBeInTheDocument();
|
||||
expect(queryByRole(container, 'dialog', { name: 'Configure discussion' }));
|
||||
});
|
||||
expect(queryByRole(container, 'dialog', { name: 'Confirm' })).not.toBeInTheDocument();
|
||||
expect(queryByRole(container, 'dialog', { name: 'Configure discussion' }));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -274,7 +286,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
const alert = queryByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
@@ -302,19 +314,17 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
// Apply causes an async action to take place
|
||||
act(async () => {
|
||||
userEvent.click(queryByText(container, appMessages.saveButton.defaultMessage));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
userEvent.click(queryByText(container, appMessages.saveButton.defaultMessage));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when applying changes.'));
|
||||
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
|
||||
});
|
||||
expect(queryByTestId(container, 'appConfigForm')).toBeInTheDocument();
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('We encountered a technical error when applying changes.'));
|
||||
expect(alert.innerHTML).toEqual(expect.stringContaining(getConfig().SUPPORT_URL));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -328,7 +338,7 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
const alert = queryByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
@@ -348,23 +358,23 @@ describe('DiscussionsSettings', () => {
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
await waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
act(async () => {
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
userEvent.click(getByRole(container, 'button', { name: 'Save' }));
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
await waitFor(() => expect(axiosMock.history.post.length).toBe(1));
|
||||
|
||||
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appList')).not.toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'appConfigForm')).not.toBeInTheDocument();
|
||||
|
||||
// We don't technically leave the route in this case, though the modal is hidden.
|
||||
expect(window.location.pathname).toEqual(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`);
|
||||
// Confirm route is correct
|
||||
// We don't technically leave the route in this case, though the modal is hidden.
|
||||
const locationDisplay = await screen.findByTestId('location-display');
|
||||
await waitFor(() => expect(locationDisplay.textContent).toEqual(`/course/${courseId}/pages-and-resources/discussion/configure/piazza`));
|
||||
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
|
||||
});
|
||||
const alert = await findByRole(container, 'alert');
|
||||
expect(alert).toBeInTheDocument();
|
||||
expect(alert.textContent).toEqual(expect.stringContaining('You are not authorized to view this page.'));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -406,13 +416,13 @@ describe.each([
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
act(async () => {
|
||||
userEvent.click(await screen.findByLabelText('Select Piazza'));
|
||||
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
userEvent.click(screen.getByLabelText('Select Piazza'));
|
||||
userEvent.click(queryByText(container, messages.nextButton.defaultMessage));
|
||||
expect(screen.queryByRole('status')).not.toBeInTheDocument();
|
||||
|
||||
await waitFor(() => {
|
||||
if (showLTIConfig) {
|
||||
expect(queryByText(container, ltiMessages.formInstructions.defaultMessage)).toBeInTheDocument();
|
||||
expect(queryByTestId(container, 'ltiConfigFields')).toBeInTheDocument();
|
||||
@@ -460,18 +470,16 @@ describe.each([
|
||||
renderComponent(`/course/${courseId}/pages-and-resources/discussion`);
|
||||
// This is an important line that ensures the spinner has been removed - and thus our main
|
||||
// content has been loaded - prior to proceeding with our expectations.
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
await waitForElementToBeRemoved(screen.queryByRole('status'));
|
||||
|
||||
act(async () => {
|
||||
userEvent.click(await screen.findByLabelText('Select Piazza'));
|
||||
userEvent.click(await screen.findByText(messages.nextButton.defaultMessage));
|
||||
userEvent.click(screen.getByLabelText('Select Piazza'));
|
||||
userEvent.click(screen.getByText(messages.nextButton.defaultMessage));
|
||||
|
||||
waitForElementToBeRemoved(screen.getByRole('status'));
|
||||
if (enablePIISharing) {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).not.toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
expect(screen.queryByRole('status')).not.toBeInTheDocument();
|
||||
if (enablePIISharing) {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).toBeInTheDocument();
|
||||
} else {
|
||||
expect(queryByTestId(container, 'piiSharingFields')).not.toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ const DiscussionRestriction = () => {
|
||||
const discussionRestrictionButtons = useMemo(() => discussionRestrictionOptions.map((restriction) => (
|
||||
<Button
|
||||
key={`restriction-${restriction.value}`}
|
||||
data-testId={restriction.value}
|
||||
data-testid={restriction.value}
|
||||
variant="plain"
|
||||
className={classNames('w-100 font-size-14 font-weight-500 line-height-20 py-7px border-light-400 unselected-button', {
|
||||
'text-white bg-primary-500 selected-button': selectedRestrictionOption === restriction.value,
|
||||
|
||||
@@ -50,7 +50,7 @@ const RestrictDatesInput = ({
|
||||
className={fieldClasses}
|
||||
onBlur={handleFocusOut}
|
||||
onFocus={handleSetFocus}
|
||||
data-testId={dataTestId}
|
||||
data-testid={dataTestId}
|
||||
/>
|
||||
<FieldFeedback
|
||||
feedbackCondition={inFocus}
|
||||
|
||||
@@ -47,7 +47,7 @@ const RestrictionSchedules = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div data-testId="restriction-schedules">
|
||||
<div data-testid="restriction-schedules">
|
||||
<FieldArray
|
||||
name="restrictedDates"
|
||||
render={({ push, remove }) => (
|
||||
|
||||
@@ -132,7 +132,7 @@ const AppList = ({ intl }) => {
|
||||
labelClassName="line-height-24"
|
||||
onChange={handleChange}
|
||||
checked={!enabled}
|
||||
data-testId="hide-discussion"
|
||||
data-testid="hide-discussion"
|
||||
>
|
||||
{intl.formatMessage(messages.hideDiscussionTab)}
|
||||
</Form.Switch>
|
||||
|
||||
@@ -133,21 +133,22 @@ describe('<ScheduleAndDetails />', () => {
|
||||
const { getAllByPlaceholderText, getByText } = render(
|
||||
<RootWrapper />,
|
||||
);
|
||||
let inputs;
|
||||
await waitFor(() => {
|
||||
const inputs = getAllByPlaceholderText(DATE_FORMAT.toLocaleUpperCase());
|
||||
act(() => {
|
||||
fireEvent.change(inputs[0], { target: { value: '06/16/2023' } });
|
||||
});
|
||||
|
||||
expect(
|
||||
getByText(messages.alertWarning.defaultMessage),
|
||||
).toBeInTheDocument();
|
||||
inputs = getAllByPlaceholderText(DATE_FORMAT.toLocaleUpperCase());
|
||||
});
|
||||
fireEvent.change(inputs[0], { target: { value: '06/16/2023' } });
|
||||
|
||||
expect(
|
||||
getByText(messages.alertWarning.defaultMessage),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display a success message when course details saves', async () => {
|
||||
const { getByText } = render(<RootWrapper />);
|
||||
await executeThunk(updateCourseDetailsQuery(courseId, 'DaTa'), store.dispatch);
|
||||
await waitFor(() => {
|
||||
executeThunk(updateCourseDetailsQuery(courseId, 'DaTa'), store.dispatch);
|
||||
});
|
||||
expect(getByText(messages.alertSuccess.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -176,7 +177,9 @@ describe('<ScheduleAndDetails />', () => {
|
||||
.onPut(getCourseDetailsApiUrl(courseId))
|
||||
.reply(404, 'error');
|
||||
const { getByText } = render(<RootWrapper />);
|
||||
await executeThunk(updateCourseDetailsQuery(courseId, 'DaTa'), store.dispatch);
|
||||
await act(async () => {
|
||||
await executeThunk(updateCourseDetailsQuery(courseId, 'DaTa'), store.dispatch);
|
||||
});
|
||||
expect(getByText(messages.alertFail.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,7 +49,7 @@ const RootWrapper = () => (
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
describe('<StudioHome />', async () => {
|
||||
describe('<StudioHome />', () => {
|
||||
describe('api fetch fails', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
|
||||
@@ -43,7 +43,7 @@ const props = {
|
||||
state: COURSE_CREATOR_STATES.unrequested,
|
||||
};
|
||||
|
||||
describe('<CollapsibleStateWithAction />', async () => {
|
||||
describe('<CollapsibleStateWithAction />', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
@@ -30,7 +30,7 @@ const RootWrapper = () => (
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
describe('<OrganizationSection />', async () => {
|
||||
describe('<OrganizationSection />', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
@@ -37,7 +37,7 @@ const course = {
|
||||
|
||||
const props = { course };
|
||||
|
||||
describe('<CourseItem />', async () => {
|
||||
describe('<CourseItem />', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
@@ -54,7 +54,7 @@ const RootWrapper = () => (
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
describe('<TaxonomyLayout />', async () => {
|
||||
describe('<TaxonomyLayout />', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
@@ -37,7 +37,7 @@ const TaxonomyCardComponent = ({ original }) => (
|
||||
|
||||
TaxonomyCardComponent.propTypes = TaxonomyCard.propTypes;
|
||||
|
||||
describe('<TaxonomyCard />', async () => {
|
||||
describe('<TaxonomyCard />', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
@@ -26,7 +26,7 @@ const TaxonomyCardComponent = ({ taxonomy }) => (
|
||||
|
||||
TaxonomyCardComponent.propTypes = TaxonomyDetailSideCard.propTypes;
|
||||
|
||||
describe('<TaxonomyDetailSideCard/>', async () => {
|
||||
describe('<TaxonomyDetailSideCard/>', () => {
|
||||
beforeEach(async () => {
|
||||
initializeMockApp({
|
||||
authenticatedUser: {
|
||||
|
||||
Reference in New Issue
Block a user