Skip to content

Commit f7b5615

Browse files
authored
fix: matching styles for report/delete post buttons (#794)
* fix: matching styles for report/delete post buttons * feat: add tests for the Post.jsx
1 parent 0d5e3b8 commit f7b5615

File tree

2 files changed

+158
-1
lines changed

2 files changed

+158
-1
lines changed

src/discussions/posts/post/Post.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ const Post = ({ handleAddResponseButton, openRestrictionDialogue }) => {
143143
onClose={hideDeleteConfirmation}
144144
confirmAction={handleDeleteConfirmation}
145145
closeButtonVariant="tertiary"
146+
confirmButtonVariant="danger"
146147
confirmButtonText={intl.formatMessage(messages.deleteConfirmationDelete)}
147148
/>
148149
{!abuseFlagged && (
@@ -152,7 +153,6 @@ const Post = ({ handleAddResponseButton, openRestrictionDialogue }) => {
152153
description={intl.formatMessage(messages.reportPostDescription)}
153154
onClose={hideReportConfirmation}
154155
confirmAction={handleReportConfirmation}
155-
confirmButtonVariant="danger"
156156
/>
157157
)}
158158
<HoverCard
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import React from 'react';
2+
3+
import { fireEvent, render, screen } from '@testing-library/react';
4+
import { useSelector } from 'react-redux';
5+
6+
import Post from './Post';
7+
8+
jest.mock('react-redux', () => ({
9+
...jest.requireActual('react-redux'),
10+
useDispatch: () => jest.fn(),
11+
useSelector: jest.fn(),
12+
}));
13+
14+
jest.mock('react-router-dom', () => ({
15+
...jest.requireActual('react-router-dom'),
16+
useLocation: () => ({ pathname: '/test' }),
17+
useNavigate: () => jest.fn(),
18+
}));
19+
20+
jest.mock('@edx/frontend-platform/i18n', () => ({
21+
useIntl: () => ({
22+
formatMessage: (msg) => ((msg && msg.defaultMessage) ? msg.defaultMessage : 'test-message'),
23+
}),
24+
defineMessages: (msgs) => msgs,
25+
}));
26+
27+
jest.mock('@openedx/paragon', () => {
28+
const actual = jest.requireActual('@openedx/paragon');
29+
// eslint-disable-next-line global-require
30+
const PropTypes = require('prop-types');
31+
32+
const MockHyperlink = ({ children }) => <div>{children}</div>;
33+
MockHyperlink.propTypes = { children: PropTypes.node.isRequired };
34+
35+
return {
36+
...actual,
37+
Hyperlink: MockHyperlink,
38+
useToggle: actual.useToggle,
39+
};
40+
});
41+
42+
jest.mock('../../common', () => {
43+
// eslint-disable-next-line global-require
44+
const PropTypes = require('prop-types');
45+
46+
const MockConfirmation = ({ confirmButtonVariant, isOpen }) => {
47+
if (!isOpen) { return null; }
48+
return (
49+
<div data-testid="mock-confirmation" data-variant={confirmButtonVariant}>
50+
Mock Confirmation
51+
</div>
52+
);
53+
};
54+
55+
MockConfirmation.propTypes = {
56+
confirmButtonVariant: PropTypes.string,
57+
isOpen: PropTypes.bool.isRequired,
58+
};
59+
60+
// eslint-disable-next-line react/prop-types
61+
const MockAlertBanner = () => <div />;
62+
63+
return {
64+
Confirmation: MockConfirmation,
65+
AlertBanner: MockAlertBanner,
66+
};
67+
});
68+
69+
jest.mock('./PostHeader', () => function MockPostHeader() { return <div>PostHeader</div>; });
70+
jest.mock('./PostFooter', () => function MockPostFooter() { return <div>PostFooter</div>; });
71+
jest.mock('./ClosePostReasonModal', () => function MockCloseModal() { return <div />; });
72+
jest.mock('../../../components/HTMLLoader', () => function MockLoader() { return <div>Body Content</div>; });
73+
74+
jest.mock('../../common/HoverCard', () => {
75+
// eslint-disable-next-line global-require
76+
const { ContentActions } = require('../../../data/constants');
77+
// eslint-disable-next-line global-require
78+
const PropTypes = require('prop-types');
79+
80+
const MockHoverCard = ({ actionHandlers }) => (
81+
<div>
82+
<button
83+
type="button"
84+
data-testid="trigger-delete"
85+
onClick={() => actionHandlers[ContentActions.DELETE] && actionHandlers[ContentActions.DELETE]()}
86+
>
87+
Delete Post
88+
</button>
89+
<button
90+
type="button"
91+
data-testid="trigger-report"
92+
onClick={() => actionHandlers[ContentActions.REPORT] && actionHandlers[ContentActions.REPORT]()}
93+
>
94+
Report Post
95+
</button>
96+
</div>
97+
);
98+
99+
MockHoverCard.propTypes = {
100+
actionHandlers: PropTypes.shape({}).isRequired,
101+
};
102+
103+
return MockHoverCard;
104+
});
105+
106+
describe('Post Component - Delete/Report Confirmation', () => {
107+
const mockPostId = '123';
108+
109+
beforeEach(() => {
110+
useSelector.mockReturnValue({
111+
topicId: 'topic-1',
112+
abuseFlagged: false,
113+
closed: false,
114+
pinned: false,
115+
voted: false,
116+
following: false,
117+
author: {},
118+
title: 'Test Post',
119+
renderedBody: '<div>Hello</div>',
120+
users: {},
121+
});
122+
});
123+
124+
const renderPost = () => {
125+
// eslint-disable-next-line global-require
126+
const DiscussionContext = require('../../common/context').default;
127+
128+
return render(
129+
<DiscussionContext.Provider value={{ postId: mockPostId, enableInContextSidebar: false, courseId: 'course-1' }}>
130+
<Post
131+
handleAddResponseButton={jest.fn()}
132+
openRestrictionDialogue={jest.fn()}
133+
/>
134+
</DiscussionContext.Provider>,
135+
);
136+
};
137+
138+
it('passes "danger" variant to Confirmation modal when deleting a post', () => {
139+
renderPost();
140+
141+
const deleteBtn = screen.getByTestId('trigger-delete');
142+
fireEvent.click(deleteBtn);
143+
144+
const confirmation = screen.getByTestId('mock-confirmation');
145+
expect(confirmation).toHaveAttribute('data-variant', 'danger');
146+
});
147+
148+
it('does NOT pass "danger" variant to Confirmation modal when reporting a post', () => {
149+
renderPost();
150+
151+
const reportBtn = screen.getByTestId('trigger-report');
152+
fireEvent.click(reportBtn);
153+
154+
const confirmation = screen.getByTestId('mock-confirmation');
155+
expect(confirmation).not.toHaveAttribute('data-variant', 'danger');
156+
});
157+
});

0 commit comments

Comments
 (0)