This reverts commit ad640611a1.
This commit is contained in:
@@ -1,9 +1,31 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
const baseConfig = {
|
||||
showMathMenu: true,
|
||||
tex2jax: {
|
||||
inlineMath: [
|
||||
['$', '$'],
|
||||
['\\\\(', '\\\\)'],
|
||||
['\\(', '\\)'],
|
||||
['[mathjaxinline]', '[/mathjaxinline]'],
|
||||
['\\begin{math}', '\\end{math}'],
|
||||
],
|
||||
displayMath: [
|
||||
['[mathjax]', '[/mathjax]'],
|
||||
['$$', '$$'],
|
||||
['\\\\[', '\\\\]'],
|
||||
['\\[', '\\]'],
|
||||
['\\begin{displaymath}', '\\end{displaymath}'],
|
||||
['\\begin{equation}', '\\end{equation}'],
|
||||
],
|
||||
processEscapes: true,
|
||||
processEnvironments: true,
|
||||
},
|
||||
skipStartupTypeset: false,
|
||||
};
|
||||
|
||||
const defaultSanitizeOptions = {
|
||||
USE_PROFILES: { html: true },
|
||||
@@ -11,28 +33,50 @@ const defaultSanitizeOptions = {
|
||||
};
|
||||
|
||||
function HTMLLoader({ htmlNode, componentId, cssClassName }) {
|
||||
const [loadingState, setLoadingState] = useState(window.MathJax ? 'loaded' : 'loading');
|
||||
const sanitizedMath = DOMPurify.sanitize(htmlNode, { ...defaultSanitizeOptions });
|
||||
const mathjaxScript = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_SVG';
|
||||
|
||||
useEffect(() => {
|
||||
let promise = Promise.resolve(); // Used to hold chain of typesetting calls
|
||||
function typeset(code) {
|
||||
promise = promise.then(() => window.MathJax.typesetPromise(code()))
|
||||
.catch((err) => logError(`Typeset failed: ${err.message}`));
|
||||
return promise;
|
||||
}
|
||||
let mathjaxScriptTag = document.querySelector(`script[src="${mathjaxScript}"]`);
|
||||
if (!mathjaxScriptTag) {
|
||||
mathjaxScriptTag = document.createElement('script');
|
||||
mathjaxScriptTag.async = true;
|
||||
mathjaxScriptTag.src = mathjaxScript;
|
||||
|
||||
typeset(() => {
|
||||
const math = document.querySelector('#tex2jax_process');
|
||||
math.innerHTML = sanitizedMath;
|
||||
return [math];
|
||||
});
|
||||
}, [sanitizedMath]);
|
||||
const node = document.head || document.getElementsByTagName('head')[0];
|
||||
node.appendChild(mathjaxScriptTag);
|
||||
}
|
||||
const onloadHandler = () => {
|
||||
setLoadingState('loaded');
|
||||
window.MathJax.Hub.Config({ ...baseConfig });
|
||||
};
|
||||
const onerrorHandler = () => {
|
||||
setLoadingState('failed');
|
||||
};
|
||||
|
||||
return () => {
|
||||
mathjaxScriptTag.removeEventListener('load', onloadHandler);
|
||||
mathjaxScriptTag.removeEventListener('error', onerrorHandler);
|
||||
};
|
||||
}, [setLoadingState, baseConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingState !== 'loaded') {
|
||||
return;
|
||||
}
|
||||
window.MathJax.Hub.Queue([
|
||||
'Typeset',
|
||||
window.MathJax.Hub,
|
||||
'mathjax-code',
|
||||
]);
|
||||
}, [sanitizedMath, loadingState]);
|
||||
|
||||
return (
|
||||
<div className={cssClassName} id={componentId}>
|
||||
<div id="tex2jax_process" />
|
||||
<div id="mathjax-code">
|
||||
{/* eslint-disable-next-line react/no-danger */}
|
||||
<div className={cssClassName} id={componentId} dangerouslySetInnerHTML={{ __html: sanitizedMath }} />
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
act, fireEvent, render, screen, waitFor, /* within, */
|
||||
act, fireEvent, render, screen, waitFor, within,
|
||||
} from '@testing-library/react';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
@@ -32,7 +32,7 @@ const closedPostId = 'thread-2';
|
||||
const courseId = 'course-v1:edX+TestX+Test_Course';
|
||||
let store;
|
||||
let axiosMock;
|
||||
// let testLocation;
|
||||
let testLocation;
|
||||
|
||||
function mockAxiosReturnPagedComments() {
|
||||
[null, false, true].forEach(endorsed => {
|
||||
@@ -92,7 +92,10 @@ function renderComponent(postId) {
|
||||
<DiscussionContent />
|
||||
<Route
|
||||
path="*"
|
||||
render={() => null}
|
||||
render={({ location }) => {
|
||||
testLocation = location;
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
</DiscussionContext.Provider>
|
||||
@@ -157,43 +160,43 @@ describe('CommentsView', () => {
|
||||
expect(JSON.parse(axiosMock.history.patch[axiosMock.history.patch.length - 1].data)).toMatchObject(data);
|
||||
}
|
||||
|
||||
// it('should show and hide the editor', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
// const addResponseButtons = screen.getAllByRole('button', { name: /add a response/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// addResponseButtons[0],
|
||||
// );
|
||||
// });
|
||||
// expect(screen.queryByTestId('tinymce-editor')).toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
||||
// });
|
||||
// expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
// });
|
||||
it('should show and hide the editor', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
const addResponseButtons = screen.getAllByRole('button', { name: /add a response/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
addResponseButtons[0],
|
||||
);
|
||||
});
|
||||
expect(screen.queryByTestId('tinymce-editor')).toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
||||
});
|
||||
expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
// it('should allow posting a response', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
// const responseButtons = screen.getAllByRole('button', { name: /add a response/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// responseButtons[0],
|
||||
// );
|
||||
// });
|
||||
// await act(() => {
|
||||
// fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// screen.getByText(/submit/i),
|
||||
// );
|
||||
// });
|
||||
// expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
// await waitFor(async () => expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument());
|
||||
// });
|
||||
it('should allow posting a response', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
const responseButtons = screen.getAllByRole('button', { name: /add a response/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
responseButtons[0],
|
||||
);
|
||||
});
|
||||
await act(() => {
|
||||
fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
screen.getByText(/submit/i),
|
||||
);
|
||||
});
|
||||
expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
await waitFor(async () => expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it('should not allow posting a response on a closed post', async () => {
|
||||
renderComponent(closedPostId);
|
||||
@@ -201,26 +204,26 @@ describe('CommentsView', () => {
|
||||
expect(screen.queryByRole('button', { name: /add a response/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
// it('should allow posting a comment', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// screen.getAllByRole('button', { name: /add a comment/i })[0],
|
||||
// );
|
||||
// });
|
||||
// act(() => {
|
||||
// fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// screen.getByText(/submit/i),
|
||||
// );
|
||||
// });
|
||||
// expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
// await waitFor(async () => expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument());
|
||||
// });
|
||||
it('should allow posting a comment', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
screen.getAllByRole('button', { name: /add a comment/i })[0],
|
||||
);
|
||||
});
|
||||
act(() => {
|
||||
fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
screen.getByText(/submit/i),
|
||||
);
|
||||
});
|
||||
expect(screen.queryByTestId('tinymce-editor')).not.toBeInTheDocument();
|
||||
await waitFor(async () => expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it('should not allow posting a comment on a closed post', async () => {
|
||||
renderComponent(closedPostId);
|
||||
@@ -232,29 +235,29 @@ describe('CommentsView', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// it('should allow editing an existing comment', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// // The first edit menu is for the post, the second will be for the first comment.
|
||||
// screen.getAllByRole('button', { name: /actions menu/i })[1],
|
||||
// );
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
// });
|
||||
// act(() => {
|
||||
// fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
||||
// });
|
||||
// await waitFor(async () => {
|
||||
// expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument();
|
||||
// });
|
||||
// });
|
||||
//
|
||||
it('should allow editing an existing comment', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
// The first edit menu is for the post, the second will be for the first comment.
|
||||
screen.getAllByRole('button', { name: /actions menu/i })[1],
|
||||
);
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
});
|
||||
act(() => {
|
||||
fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
||||
});
|
||||
await waitFor(async () => {
|
||||
expect(await screen.findByText('testing123', { exact: false })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
async function setupCourseConfig(reasonCodesEnabled = true) {
|
||||
axiosMock.onGet(`${courseConfigApiUrl}${courseId}/`).reply(200, {
|
||||
has_moderation_privileges: true,
|
||||
@@ -271,83 +274,81 @@ describe('CommentsView', () => {
|
||||
axiosMock.onGet(`${courseConfigApiUrl}${courseId}/settings`).reply(200, {});
|
||||
await executeThunk(fetchCourseConfig(courseId), store.dispatch, store.getState);
|
||||
}
|
||||
//
|
||||
// it('should show reason codes when editing an existing comment', async () => {
|
||||
// setupCourseConfig();
|
||||
// renderComponent(discussionPostId);
|
||||
// await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// // The first edit menu is for the post, the second will be for the first comment.
|
||||
// screen.getAllByRole('button', { name: /actions menu/i })[1],
|
||||
// );
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('combobox', { name: /reason for editing/i })).toBeInTheDocument();
|
||||
// expect(screen.getAllByRole('option', { name: /reason \d/i })).toHaveLength(2);
|
||||
// await act(async () => {
|
||||
// fireEvent.change(screen.queryByRole('combobox', { name: /reason for editing/i }),
|
||||
// { target: { value: null } });
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.change(screen.queryByRole('combobox',
|
||||
// { name: /reason for editing/i }), { target: { value: 'reason-1' } });
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
||||
// });
|
||||
// assertLastUpdateData({ edit_reason_code: 'reason-1' });
|
||||
// });
|
||||
//
|
||||
// it('should show reason codes when closing a post', async () => {
|
||||
// setupCourseConfig();
|
||||
// renderComponent(discussionPostId);
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// // The first edit menu is for the post
|
||||
// screen.getAllByRole('button', {
|
||||
// name: /actions menu/i,
|
||||
// })[0],
|
||||
// );
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /close post/i })).toBeInTheDocument();
|
||||
// expect(screen.queryByRole('combobox', { name: /reason/i })).toBeInTheDocument();
|
||||
// expect(screen.getAllByRole('option', { name: /reason \d/i })).toHaveLength(2);
|
||||
// await act(async () => {
|
||||
// fireEvent.change(screen.queryByRole('combobox', { name: /reason/i }), { target: { value: 'reason-1' } });
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /close post/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
// assertLastUpdateData({ closed: true, close_reason_code: 'reason-1' });
|
||||
// });
|
||||
|
||||
// it('should close the post directly if reason codes are not enabled', async () => {
|
||||
// setupCourseConfig(false);
|
||||
// renderComponent(discussionPostId);
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// // The first edit menu is for the post
|
||||
// screen.getAllByRole('button', { name: /actions menu/i })[0],
|
||||
// );
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
// assertLastUpdateData({ closed: true });
|
||||
// });
|
||||
it('should show reason codes when editing an existing comment', async () => {
|
||||
setupCourseConfig();
|
||||
renderComponent(discussionPostId);
|
||||
await waitFor(() => screen.findByText('comment number 1', { exact: false }));
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
// The first edit menu is for the post, the second will be for the first comment.
|
||||
screen.getAllByRole('button', { name: /actions menu/i })[1],
|
||||
);
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
});
|
||||
expect(screen.queryByRole('combobox', { name: /reason for editing/i })).toBeInTheDocument();
|
||||
expect(screen.getAllByRole('option', { name: /reason \d/i })).toHaveLength(2);
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.queryByRole('combobox', { name: /reason for editing/i }), { target: { value: null } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.queryByRole('combobox', { name: /reason for editing/i }), { target: { value: 'reason-1' } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.getByTestId('tinymce-editor'), { target: { value: 'testing123' } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
||||
});
|
||||
assertLastUpdateData({ edit_reason_code: 'reason-1' });
|
||||
});
|
||||
|
||||
it('should show reason codes when closing a post', async () => {
|
||||
setupCourseConfig();
|
||||
renderComponent(discussionPostId);
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
// The first edit menu is for the post
|
||||
screen.getAllByRole('button', {
|
||||
name: /actions menu/i,
|
||||
})[0],
|
||||
);
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /close post/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('combobox', { name: /reason/i })).toBeInTheDocument();
|
||||
expect(screen.getAllByRole('option', { name: /reason \d/i })).toHaveLength(2);
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.queryByRole('combobox', { name: /reason/i }), { target: { value: 'reason-1' } });
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /close post/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
assertLastUpdateData({ closed: true, close_reason_code: 'reason-1' });
|
||||
});
|
||||
|
||||
it('should close the post directly if reason codes are not enabled', async () => {
|
||||
setupCourseConfig(false);
|
||||
renderComponent(discussionPostId);
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
// The first edit menu is for the post
|
||||
screen.getAllByRole('button', { name: /actions menu/i })[0],
|
||||
);
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /close post/i })).not.toBeInTheDocument();
|
||||
assertLastUpdateData({ closed: true });
|
||||
});
|
||||
|
||||
it.each([true, false])(
|
||||
'should reopen the post directly when reason codes enabled=%s',
|
||||
@@ -369,20 +370,20 @@ describe('CommentsView', () => {
|
||||
},
|
||||
);
|
||||
|
||||
// it('should show the editor if the post is edited', async () => {
|
||||
// setupCourseConfig(false);
|
||||
// renderComponent(discussionPostId);
|
||||
// await act(async () => {
|
||||
// fireEvent.click(
|
||||
// // The first edit menu is for the post
|
||||
// screen.getAllByRole('button', { name: /actions menu/i })[0],
|
||||
// );
|
||||
// });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
// });
|
||||
// expect(testLocation.pathname).toBe(`/${courseId}/posts/${discussionPostId}/edit`);
|
||||
// });
|
||||
it('should show the editor if the post is edited', async () => {
|
||||
setupCourseConfig(false);
|
||||
renderComponent(discussionPostId);
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
// The first edit menu is for the post
|
||||
screen.getAllByRole('button', { name: /actions menu/i })[0],
|
||||
);
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
});
|
||||
expect(testLocation.pathname).toBe(`/${courseId}/posts/${discussionPostId}/edit`);
|
||||
});
|
||||
|
||||
it('should allow pinning the post', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
@@ -417,314 +418,314 @@ describe('CommentsView', () => {
|
||||
assertLastUpdateData({ abuse_flagged: true });
|
||||
});
|
||||
|
||||
// it('handles liking a comment', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
// const view = screen.getByTestId('comment-comment-1');
|
||||
//
|
||||
// const likeButton = within(view).getByRole('button', { name: /like/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(likeButton);
|
||||
// });
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ voted: true });
|
||||
// });
|
||||
//
|
||||
// it('handles endorsing comments', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
//
|
||||
// // There should be three buttons, one for the post, the second for the
|
||||
// // comment and the third for a response to that comment
|
||||
// const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(actionButtons[1]);
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /Endorse/i }));
|
||||
// });
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ endorsed: true });
|
||||
// });
|
||||
//
|
||||
// it('handles reporting comments', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
//
|
||||
// // There should be three buttons, one for the post, the second for the
|
||||
// // comment and the third for a response to that comment
|
||||
// const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(actionButtons[1]);
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /Report/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.queryByRole('button', { name: /Confirm/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ abuse_flagged: true });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('for discussion thread', () => {
|
||||
// const findLoadMoreCommentsButton = () => screen.findByTestId('load-more-comments');
|
||||
//
|
||||
// it('shown post not found when post id does not belong to course', async () => {
|
||||
// renderComponent('unloaded-id');
|
||||
// expect(await screen.findByText('Thread not found', { exact: true }))
|
||||
// .toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('initially loads only the first page', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// expect(await screen.findByText('comment number 1', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// expect(screen.queryByText('comment number 2', { exact: false }))
|
||||
// .not
|
||||
// .toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('pressing load more button will load next page of comments', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
// fireEvent.click(loadMoreButton);
|
||||
//
|
||||
// await screen.findByText('comment number 1', { exact: false });
|
||||
// await screen.findByText('comment number 2', { exact: false });
|
||||
// });
|
||||
//
|
||||
// it('newly loaded comments are appended to the old ones', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
// fireEvent.click(loadMoreButton);
|
||||
//
|
||||
// await screen.findByText('comment number 1', { exact: false });
|
||||
// // check that comments from the first page are also displayed
|
||||
// expect(screen.queryByText('comment number 2', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('load more button is hidden when no more comments pages to load', async () => {
|
||||
// const totalPages = 2;
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
// for (let page = 1; page < totalPages; page++) {
|
||||
// fireEvent.click(loadMoreButton);
|
||||
// }
|
||||
//
|
||||
// await screen.findByText('comment number 2', { exact: false });
|
||||
// await expect(findLoadMoreCommentsButton())
|
||||
// .rejects
|
||||
// .toThrow();
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('for question thread', () => {
|
||||
// const findLoadMoreCommentsButtons = () => screen.findAllByTestId('load-more-comments');
|
||||
//
|
||||
// it('initially loads only the first page', async () => {
|
||||
// act(() => renderComponent(questionPostId));
|
||||
// expect(await screen.findByText('comment number 3', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// expect(await screen.findByText('endorsed comment number 5', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// expect(screen.queryByText('comment number 4', { exact: false }))
|
||||
// .not
|
||||
// .toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('pressing load more button will load next page of comments', async () => {
|
||||
// act(() => {
|
||||
// renderComponent(questionPostId);
|
||||
// });
|
||||
//
|
||||
// const [loadMoreButtonEndorsed, loadMoreButtonUnendorsed] = await findLoadMoreCommentsButtons();
|
||||
// // Both load more buttons should show
|
||||
// expect(await findLoadMoreCommentsButtons()).toHaveLength(2);
|
||||
// expect(await screen.findByText('unendorsed comment number 3', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// expect(await screen.findByText('endorsed comment number 5', { exact: false }))
|
||||
// .toBeInTheDocument();
|
||||
// // Comments from next page should not be loaded yet.
|
||||
// expect(await screen.queryByText('endorsed comment number 6', { exact: false }))
|
||||
// .not
|
||||
// .toBeInTheDocument();
|
||||
// expect(await screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
// .not
|
||||
// .toBeInTheDocument();
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(loadMoreButtonEndorsed);
|
||||
// });
|
||||
// // Endorsed comment from next page should be loaded now.
|
||||
// await waitFor(() => expect(screen.queryByText('endorsed comment number 6', { exact: false }))
|
||||
// .toBeInTheDocument());
|
||||
// // Unendorsed comment from next page should not be loaded yet.
|
||||
// expect(await screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
// .not
|
||||
// .toBeInTheDocument();
|
||||
// // Now only one load more buttons should show, for unendorsed comments
|
||||
// expect(await findLoadMoreCommentsButtons()).toHaveLength(1);
|
||||
// await act(async () => {
|
||||
// fireEvent.click(loadMoreButtonUnendorsed);
|
||||
// });
|
||||
// // Unendorsed comment from next page should be loaded now.
|
||||
// await waitFor(() => expect(screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
// .toBeInTheDocument());
|
||||
// await expect(findLoadMoreCommentsButtons()).rejects.toThrow();
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('comments responses', () => {
|
||||
// const findLoadMoreCommentsResponsesButton = () => screen.findByTestId('load-more-comments-responses');
|
||||
//
|
||||
// it('initially loads only the first page', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// await waitFor(() => screen.findByText('comment number 7', { exact: false }));
|
||||
// expect(screen.queryByText('comment number 8', { exact: false })).not.toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('pressing load more button will load next page of responses', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(loadMoreButton);
|
||||
// });
|
||||
//
|
||||
// await screen.findByText('comment number 8', { exact: false });
|
||||
// });
|
||||
//
|
||||
// it('newly loaded responses are appended to the old ones', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(loadMoreButton);
|
||||
// });
|
||||
//
|
||||
// await screen.findByText('comment number 8', { exact: false });
|
||||
// // check that comments from the first page are also displayed
|
||||
// expect(screen.queryByText('comment number 7', { exact: false })).toBeInTheDocument();
|
||||
// });
|
||||
//
|
||||
// it('load more button is hidden when no more responses pages to load', async () => {
|
||||
// const totalPages = 2;
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
// for (let page = 1; page < totalPages; page++) {
|
||||
// act(() => {
|
||||
// fireEvent.click(loadMoreButton);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// await screen.findByText('comment number 8', { exact: false });
|
||||
// await expect(findLoadMoreCommentsResponsesButton())
|
||||
// .rejects
|
||||
// .toThrow();
|
||||
// });
|
||||
//
|
||||
// it('handles liking a comment', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
//
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
// const view = screen.getByTestId('comment-comment-1');
|
||||
//
|
||||
// const likeButton = within(view).getByRole('button', { name: /like/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(likeButton);
|
||||
// });
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ voted: true });
|
||||
// });
|
||||
//
|
||||
// it('handles endorsing comments', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
//
|
||||
// // There should be three buttons, one for the post, the second for the
|
||||
// // comment and the third for a response to that comment
|
||||
// const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(actionButtons[1]);
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /Endorse/i }));
|
||||
// });
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ endorsed: true });
|
||||
// });
|
||||
//
|
||||
// it('handles reporting comments', async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// // Wait for the content to load
|
||||
// await screen.findByText('comment number 7', { exact: false });
|
||||
//
|
||||
// // There should be three buttons, one for the post, the second for the
|
||||
// // comment and the third for a response to that comment
|
||||
// const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(actionButtons[1]);
|
||||
// });
|
||||
//
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.getByRole('button', { name: /Report/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.queryByRole('button', { name: /Confirm/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
// expect(axiosMock.history.patch).toHaveLength(2);
|
||||
// expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ abuse_flagged: true });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe.each([
|
||||
// { component: 'post', testId: 'post-thread-1' },
|
||||
// { component: 'comment', testId: 'comment-comment-1' },
|
||||
// { component: 'reply', testId: 'reply-comment-7' },
|
||||
// ])('delete confirmation modal', ({
|
||||
// component,
|
||||
// testId,
|
||||
// }) => {
|
||||
// test(`for ${component}`, async () => {
|
||||
// renderComponent(discussionPostId);
|
||||
// // Wait for the content to load
|
||||
// await waitFor(() => expect(screen.queryByText('comment number 7', { exact: false })).toBeInTheDocument());
|
||||
// const content = screen.getByTestId(testId);
|
||||
// const actionsButton = within(content).getAllByRole('button', { name: /actions menu/i })[0];
|
||||
// await act(async () => {
|
||||
// fireEvent.click(actionsButton);
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
// const deleteButton = within(content).queryByRole('button', { name: /delete/i });
|
||||
// await act(async () => {
|
||||
// fireEvent.click(deleteButton);
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).toBeInTheDocument();
|
||||
// await act(async () => {
|
||||
// fireEvent.click(screen.queryByRole('button', { name: /delete/i }));
|
||||
// });
|
||||
// expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
// });
|
||||
it('handles liking a comment', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
const view = screen.getByTestId('comment-comment-1');
|
||||
|
||||
const likeButton = within(view).getByRole('button', { name: /like/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(likeButton);
|
||||
});
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ voted: true });
|
||||
});
|
||||
|
||||
it('handles endorsing comments', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
|
||||
// There should be three buttons, one for the post, the second for the
|
||||
// comment and the third for a response to that comment
|
||||
const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(actionButtons[1]);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /Endorse/i }));
|
||||
});
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ endorsed: true });
|
||||
});
|
||||
|
||||
it('handles reporting comments', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
|
||||
// There should be three buttons, one for the post, the second for the
|
||||
// comment and the third for a response to that comment
|
||||
const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(actionButtons[1]);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /Report/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.queryByRole('button', { name: /Confirm/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ abuse_flagged: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('for discussion thread', () => {
|
||||
const findLoadMoreCommentsButton = () => screen.findByTestId('load-more-comments');
|
||||
|
||||
it('shown post not found when post id does not belong to course', async () => {
|
||||
renderComponent('unloaded-id');
|
||||
expect(await screen.findByText('Thread not found', { exact: true }))
|
||||
.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('initially loads only the first page', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
expect(await screen.findByText('comment number 1', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
expect(screen.queryByText('comment number 2', { exact: false }))
|
||||
.not
|
||||
.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('pressing load more button will load next page of comments', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
fireEvent.click(loadMoreButton);
|
||||
|
||||
await screen.findByText('comment number 1', { exact: false });
|
||||
await screen.findByText('comment number 2', { exact: false });
|
||||
});
|
||||
|
||||
it('newly loaded comments are appended to the old ones', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
fireEvent.click(loadMoreButton);
|
||||
|
||||
await screen.findByText('comment number 1', { exact: false });
|
||||
// check that comments from the first page are also displayed
|
||||
expect(screen.queryByText('comment number 2', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('load more button is hidden when no more comments pages to load', async () => {
|
||||
const totalPages = 2;
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsButton();
|
||||
for (let page = 1; page < totalPages; page++) {
|
||||
fireEvent.click(loadMoreButton);
|
||||
}
|
||||
|
||||
await screen.findByText('comment number 2', { exact: false });
|
||||
await expect(findLoadMoreCommentsButton())
|
||||
.rejects
|
||||
.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('for question thread', () => {
|
||||
const findLoadMoreCommentsButtons = () => screen.findAllByTestId('load-more-comments');
|
||||
|
||||
it('initially loads only the first page', async () => {
|
||||
act(() => renderComponent(questionPostId));
|
||||
expect(await screen.findByText('comment number 3', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
expect(await screen.findByText('endorsed comment number 5', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
expect(screen.queryByText('comment number 4', { exact: false }))
|
||||
.not
|
||||
.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('pressing load more button will load next page of comments', async () => {
|
||||
act(() => {
|
||||
renderComponent(questionPostId);
|
||||
});
|
||||
|
||||
const [loadMoreButtonEndorsed, loadMoreButtonUnendorsed] = await findLoadMoreCommentsButtons();
|
||||
// Both load more buttons should show
|
||||
expect(await findLoadMoreCommentsButtons()).toHaveLength(2);
|
||||
expect(await screen.findByText('unendorsed comment number 3', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
expect(await screen.findByText('endorsed comment number 5', { exact: false }))
|
||||
.toBeInTheDocument();
|
||||
// Comments from next page should not be loaded yet.
|
||||
expect(await screen.queryByText('endorsed comment number 6', { exact: false }))
|
||||
.not
|
||||
.toBeInTheDocument();
|
||||
expect(await screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
.not
|
||||
.toBeInTheDocument();
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(loadMoreButtonEndorsed);
|
||||
});
|
||||
// Endorsed comment from next page should be loaded now.
|
||||
await waitFor(() => expect(screen.queryByText('endorsed comment number 6', { exact: false }))
|
||||
.toBeInTheDocument());
|
||||
// Unendorsed comment from next page should not be loaded yet.
|
||||
expect(await screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
.not
|
||||
.toBeInTheDocument();
|
||||
// Now only one load more buttons should show, for unendorsed comments
|
||||
expect(await findLoadMoreCommentsButtons()).toHaveLength(1);
|
||||
await act(async () => {
|
||||
fireEvent.click(loadMoreButtonUnendorsed);
|
||||
});
|
||||
// Unendorsed comment from next page should be loaded now.
|
||||
await waitFor(() => expect(screen.queryByText('unendorsed comment number 4', { exact: false }))
|
||||
.toBeInTheDocument());
|
||||
await expect(findLoadMoreCommentsButtons()).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('comments responses', () => {
|
||||
const findLoadMoreCommentsResponsesButton = () => screen.findByTestId('load-more-comments-responses');
|
||||
|
||||
it('initially loads only the first page', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
await waitFor(() => screen.findByText('comment number 7', { exact: false }));
|
||||
expect(screen.queryByText('comment number 8', { exact: false })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('pressing load more button will load next page of responses', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
await act(async () => {
|
||||
fireEvent.click(loadMoreButton);
|
||||
});
|
||||
|
||||
await screen.findByText('comment number 8', { exact: false });
|
||||
});
|
||||
|
||||
it('newly loaded responses are appended to the old ones', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
await act(async () => {
|
||||
fireEvent.click(loadMoreButton);
|
||||
});
|
||||
|
||||
await screen.findByText('comment number 8', { exact: false });
|
||||
// check that comments from the first page are also displayed
|
||||
expect(screen.queryByText('comment number 7', { exact: false })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('load more button is hidden when no more responses pages to load', async () => {
|
||||
const totalPages = 2;
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
const loadMoreButton = await findLoadMoreCommentsResponsesButton();
|
||||
for (let page = 1; page < totalPages; page++) {
|
||||
act(() => {
|
||||
fireEvent.click(loadMoreButton);
|
||||
});
|
||||
}
|
||||
|
||||
await screen.findByText('comment number 8', { exact: false });
|
||||
await expect(findLoadMoreCommentsResponsesButton())
|
||||
.rejects
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('handles liking a comment', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
const view = screen.getByTestId('comment-comment-1');
|
||||
|
||||
const likeButton = within(view).getByRole('button', { name: /like/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(likeButton);
|
||||
});
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ voted: true });
|
||||
});
|
||||
|
||||
it('handles endorsing comments', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
|
||||
// There should be three buttons, one for the post, the second for the
|
||||
// comment and the third for a response to that comment
|
||||
const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(actionButtons[1]);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /Endorse/i }));
|
||||
});
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ endorsed: true });
|
||||
});
|
||||
|
||||
it('handles reporting comments', async () => {
|
||||
renderComponent(discussionPostId);
|
||||
// Wait for the content to load
|
||||
await screen.findByText('comment number 7', { exact: false });
|
||||
|
||||
// There should be three buttons, one for the post, the second for the
|
||||
// comment and the third for a response to that comment
|
||||
const actionButtons = screen.queryAllByRole('button', { name: /actions menu/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(actionButtons[1]);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /Report/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.queryByRole('button', { name: /Confirm/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /Report \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
expect(axiosMock.history.patch).toHaveLength(2);
|
||||
expect(JSON.parse(axiosMock.history.patch[1].data)).toMatchObject({ abuse_flagged: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe.each([
|
||||
{ component: 'post', testId: 'post-thread-1' },
|
||||
{ component: 'comment', testId: 'comment-comment-1' },
|
||||
{ component: 'reply', testId: 'reply-comment-7' },
|
||||
])('delete confirmation modal', ({
|
||||
component,
|
||||
testId,
|
||||
}) => {
|
||||
test(`for ${component}`, async () => {
|
||||
renderComponent(discussionPostId);
|
||||
// Wait for the content to load
|
||||
await waitFor(() => expect(screen.queryByText('comment number 7', { exact: false })).toBeInTheDocument());
|
||||
const content = screen.getByTestId(testId);
|
||||
const actionsButton = within(content).getAllByRole('button', { name: /actions menu/i })[0];
|
||||
await act(async () => {
|
||||
fireEvent.click(actionsButton);
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
const deleteButton = within(content).queryByRole('button', { name: /delete/i });
|
||||
await act(async () => {
|
||||
fireEvent.click(deleteButton);
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).toBeInTheDocument();
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.queryByRole('button', { name: /delete/i }));
|
||||
});
|
||||
expect(screen.queryByRole('dialog', { name: /delete \w+/i, exact: false })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user