From 42e3f413e30918a4c3269db4f57b1260fb1cc712 Mon Sep 17 00:00:00 2001 From: Kyrylo Hudym-Levkovych Date: Fri, 15 Mar 2024 17:21:02 +0200 Subject: [PATCH] refactor: add changes after review --- src/certificates/Certificates.jsx | 2 +- src/certificates/Certificates.test.jsx | 25 +++++++++++++++++++ .../CertificateEditForm.test.jsx | 20 +++++++++++++++ .../header-buttons/hooks/useHeaderButtons.jsx | 3 ++- 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/certificates/Certificates.jsx b/src/certificates/Certificates.jsx index de88d576f8..fd67f74542 100644 --- a/src/certificates/Certificates.jsx +++ b/src/certificates/Certificates.jsx @@ -32,7 +32,7 @@ const Certificates = ({ courseId }) => { if (loadingStatus === RequestStatus.DENIED) { return ( -
+
); diff --git a/src/certificates/Certificates.test.jsx b/src/certificates/Certificates.test.jsx index 447abbe4a0..e04d50a21c 100644 --- a/src/certificates/Certificates.test.jsx +++ b/src/certificates/Certificates.test.jsx @@ -6,6 +6,7 @@ import { AppProvider } from '@edx/frontend-platform/react'; import MockAdapter from 'axios-mock-adapter'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import { RequestStatus } from '../data/constants'; import { executeThunk } from '../utils'; import initializeStore from '../store'; import { getCertificatesApiUrl } from './data/api'; @@ -161,4 +162,28 @@ describe('Certificates', () => { expect(queryByTestId('certificate-details')).not.toBeInTheDocument(); expect(queryByTestId('signatory')).not.toBeInTheDocument(); }); + + it('renders placeholder if request fails', async () => { + axiosMock + .onGet(getCertificatesApiUrl(courseId)) + .reply(403, certificatesDataMock); + + const { getByTestId } = renderComponent(); + + await executeThunk(fetchCertificates(courseId), store.dispatch); + + expect(getByTestId('request-denied-placeholder')).toBeInTheDocument(); + }); + + it('updates loading status if request fails', async () => { + axiosMock + .onGet(getCertificatesApiUrl(courseId)) + .reply(404, certificatesDataMock); + + renderComponent(); + + await executeThunk(fetchCertificates(courseId), store.dispatch); + + expect(store.getState().certificates.loadingStatus).toBe(RequestStatus.FAILED); + }); }); diff --git a/src/certificates/certificate-edit-form/CertificateEditForm.test.jsx b/src/certificates/certificate-edit-form/CertificateEditForm.test.jsx index 4c03912bda..38757b3272 100644 --- a/src/certificates/certificate-edit-form/CertificateEditForm.test.jsx +++ b/src/certificates/certificate-edit-form/CertificateEditForm.test.jsx @@ -6,6 +6,7 @@ import { IntlProvider } from '@edx/frontend-platform/i18n'; import MockAdapter from 'axios-mock-adapter'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import { RequestStatus } from '../../data/constants'; import { executeThunk } from '../../utils'; import initializeStore from '../../store'; import { getCertificatesApiUrl, getUpdateCertificateApiUrl } from '../data/api'; @@ -108,6 +109,25 @@ describe('CertificateEditForm Component', () => { }); }); + it('updates loading status if delete fails', async () => { + axiosMock.onDelete( + getUpdateCertificateApiUrl(courseId, certificatesDataMock.certificates[0].id), + ).reply(404); + + const { getByRole } = renderComponent(); + + userEvent.click(getByRole('button', { name: messages.deleteTooltip.defaultMessage })); + + const confirmDeleteModal = getByRole('dialog'); + userEvent.click(within(confirmDeleteModal).getByRole('button', { name: messages.deleteTooltip.defaultMessage })); + + await executeThunk(deleteCourseCertificate(courseId, certificatesDataMock.certificates[0].id), store.dispatch); + + await waitFor(() => { + expect(store.getState().certificates.savingStatus).toBe(RequestStatus.FAILED); + }); + }); + it('cancel edit form', async () => { const { getByRole } = renderComponent(); diff --git a/src/certificates/layout/header-buttons/hooks/useHeaderButtons.jsx b/src/certificates/layout/header-buttons/hooks/useHeaderButtons.jsx index fcd0965927..b7eb623990 100644 --- a/src/certificates/layout/header-buttons/hooks/useHeaderButtons.jsx +++ b/src/certificates/layout/header-buttons/hooks/useHeaderButtons.jsx @@ -26,7 +26,8 @@ const useHeaderButtons = () => { const previewUrl = useMemo(() => { if (!certificateWebViewUrl) { return ''; } - const url = new URL(certificateWebViewUrl, window.location.origin); + const getUrl = () => new URL(certificateWebViewUrl, window.location.origin); + const url = getUrl(); const searchParams = new URLSearchParams(url.search); searchParams.set('preview', dropdowmItem);