Files
frontend-app-authoring/src/certificates/layout/header-buttons/HeaderButtons.test.jsx
Jillian f20e5311a9 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>
2024-06-13 10:37:26 +05:30

131 lines
4.8 KiB
JavaScript

import { Provider } from 'react-redux';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { initializeMockApp } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { executeThunk } from '../../../utils';
import initializeStore from '../../../store';
import { MODE_STATES } from '../../data/constants';
import { getCertificatesApiUrl, getUpdateCertificateApiUrl } from '../../data/api';
import { fetchCertificates, updateCertificateActiveStatus } from '../../data/thunks';
import { certificatesDataMock } from '../../__mocks__';
import messages from '../../messages';
import HeaderButtons from './HeaderButtons';
let axiosMock;
let store;
const courseId = 'course-123';
const renderComponent = (props) => render(
<Provider store={store} messages={{}}>
<IntlProvider locale="en">
<HeaderButtons {...props} />
</IntlProvider>
</Provider>,
);
const initialState = {
certificates: {
certificatesData: {},
componentMode: MODE_STATES.editAll,
},
};
describe('HeaderButtons Component', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
axiosMock
.onGet(getCertificatesApiUrl(courseId))
.reply(200, certificatesDataMock);
await executeThunk(fetchCertificates(courseId), store.dispatch);
});
it('updates preview URL param based on selected dropdown item', async () => {
const { getByRole } = renderComponent();
const previewLink = getByRole('link', { name: messages.headingActionsPreview.defaultMessage });
expect(previewLink).toHaveAttribute('href', expect.stringContaining(certificatesDataMock.courseModes[0]));
const dropdownButton = getByRole('button', { name: certificatesDataMock.courseModes[0] });
userEvent.click(dropdownButton);
const verifiedMode = await getByRole('button', { name: certificatesDataMock.courseModes[1] });
userEvent.click(verifiedMode);
await waitFor(() => {
expect(previewLink).toHaveAttribute('href', expect.stringContaining(certificatesDataMock.courseModes[1]));
});
});
it('activates certificate when button is clicked', async () => {
const newCertificateData = {
...certificatesDataMock,
isActive: true,
};
const { getByRole, queryByRole } = renderComponent();
const activationButton = getByRole('button', { name: messages.headingActionsActivate.defaultMessage });
userEvent.click(activationButton);
axiosMock.onPost(
getUpdateCertificateApiUrl(courseId, certificatesDataMock.certificates[0].id),
).reply(200);
await executeThunk(updateCertificateActiveStatus(courseId), store.dispatch);
axiosMock
.onGet(getCertificatesApiUrl(courseId))
.reply(200, newCertificateData);
await executeThunk(fetchCertificates(courseId), store.dispatch);
await waitFor(() => {
expect(store.getState().certificates.certificatesData.isActive).toBe(true);
expect(getByRole('button', { name: messages.headingActionsDeactivate.defaultMessage })).toBeInTheDocument();
expect(queryByRole('button', { name: messages.headingActionsActivate.defaultMessage })).not.toBeInTheDocument();
});
});
it('deactivates certificate when button is clicked', async () => {
axiosMock
.onGet(getCertificatesApiUrl(courseId))
.reply(200, { ...certificatesDataMock, isActive: true });
await executeThunk(fetchCertificates(courseId), store.dispatch);
const newCertificateData = {
...certificatesDataMock,
isActive: false,
};
const { getByRole, queryByRole } = renderComponent();
const deactivateButton = getByRole('button', { name: messages.headingActionsDeactivate.defaultMessage });
userEvent.click(deactivateButton);
axiosMock.onPost(
getUpdateCertificateApiUrl(courseId, certificatesDataMock.certificates[0].id),
).reply(200);
await executeThunk(updateCertificateActiveStatus(courseId), store.dispatch);
axiosMock
.onGet(getCertificatesApiUrl(courseId))
.reply(200, newCertificateData);
await executeThunk(fetchCertificates(courseId), store.dispatch);
await waitFor(() => {
expect(store.getState().certificates.certificatesData.isActive).toBe(false);
expect(getByRole('button', { name: messages.headingActionsActivate.defaultMessage })).toBeInTheDocument();
expect(queryByRole('button', { name: messages.headingActionsDeactivate.defaultMessage })).not.toBeInTheDocument();
});
});
});