Compare commits

..

22 Commits

Author SHA1 Message Date
renovate[bot]
9285adaad2 fix(deps): update dependency core-js to v3.48.0 2026-02-13 22:15:43 +00:00
Brian Smith
e1383d1e65 fix(deps): regenerate package-lock.json
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-02-13 17:14:44 -05:00
bydawen
f7b5615660 fix: matching styles for report/delete post buttons (#794)
* fix: matching styles for report/delete post buttons

* feat: add tests for the Post.jsx
2026-02-10 09:17:20 -06:00
bydawen
0d5e3b8a1c fix: add space gap between modals buttons + fixed reply/post/comment sections text colors (#805) 2026-01-28 12:43:40 -06:00
Feanil Patel
4e90bbc756 Merge pull request #793 from raccoongang/buhaienko/fix/remove-primary-color-from-discussion-post-and-messages-text
fix: remove primary color from discussion post and messages text
2026-01-16 13:51:16 -05:00
oleksandr.buhaienko
b4dcaca660 fix: remove primary color from discussion post and messages text 2026-01-16 19:22:25 +02:00
Awais Ansari
5defe5cbd4 fix: profile picture is not showing in forum responses (#849) 2026-01-02 14:57:49 +05:00
Awais Ansari
911b8b3fc5 fix: cohort name difference in filter and post view (#841)
* fix: cohort name difference in filter and post view

* test: fix cohort test cases

---------

Co-authored-by: Awais  Ansari <awais.ansari@A006-01824.local>
2025-12-16 20:07:40 +05:00
Awais Ansari
4917da3245 fix: fetch topics on MFE load (#840)
* fix: added fetch topic API call in learners tab

* refactor: fetch topics on MFE load

* test: added legacy param in legacy topic test cases

---------

Co-authored-by: Awais  Ansari <awais.ansari@A006-01824.local>
2025-12-16 19:39:36 +05:00
renovate[bot]
e5388690b2 fix(deps): update dependency core-js to v3.47.0 2025-12-10 12:05:24 +05:00
edX requirements bot
cefc8d9d35 chore: enable github action auto update in dependabot.yml (#737) 2025-12-10 10:40:23 +05:00
renovate[bot]
f5c5913d3f chore(deps): update dependency glob to v7.2.3 2025-12-09 20:50:15 +00:00
renovate[bot]
687dae6b21 fix(deps): update dependency tinymce to v5.10.9 (#587)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 15:26:31 +00:00
renovate[bot]
b812b96d77 fix(deps): update dependency formik to v2.4.9 2025-12-09 14:59:27 +00:00
renovate[bot]
142abd8dd4 fix(deps): update dependency @edx/openedx-atlas to ^0.7.0 (#815)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 14:47:28 +00:00
renovate[bot]
ece4432f58 chore(deps): update dependency @edx/browserslist-config to v1.5.0 (#747)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 14:17:40 +00:00
renovate[bot]
c599046813 chore(deps): update dependency axios to ^0.30.0 (#780)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 14:13:55 +00:00
renovate[bot]
c323c80bc8 chore(deps): update actions/checkout action to v6 (#833)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 19:02:49 +05:00
renovate[bot]
37cec76dcb chore(deps): update dependency @openedx/paragon to v23.18.1 (#814)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 18:50:31 +05:00
Awais Ansari
00440fc15a chore: update header version to 8 (#829) 2025-11-14 15:31:25 +05:00
Tobias Macey
a4826ae62d fix: prevent generatePath error when author is invalid in AuthorLabel (#821)
Wrap learnerPostsLink creation in useMemo with guard to prevent
'Missing :learnerUsername param' error. The generatePath function
was being called unconditionally during render even when the link
wouldn't be displayed, causing errors when author was null, undefined,
or the 'anonymous' string.

The fix ensures generatePath is only called when showUserNameAsLink
is true, which validates that author is a valid username.
2025-11-13 16:08:51 -05:00
renovate[bot]
16c49b2404 chore(deps): update dependency @edx/frontend-platform to v8.5.2 (#775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-13 14:36:31 -05:00
10 changed files with 1949 additions and 6427 deletions

7
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: 2
updates:
# Adding new check for github-actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -12,7 +12,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Nodejs

8182
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,17 +31,17 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/frontend-component-footer": "^14.6.0",
"@edx/frontend-component-header": "^6.2.0",
"@edx/frontend-component-header": "^8.1.0",
"@edx/frontend-platform": "^8.3.3",
"@edx/openedx-atlas": "^0.6.0",
"@edx/openedx-atlas": "^0.7.0",
"@openedx/paragon": "^23.4.5",
"@reduxjs/toolkit": "1.9.7",
"@tinymce/tinymce-react": "5.1.1",
"babel-polyfill": "6.26.0",
"classnames": "2.5.1",
"core-js": "3.21.1",
"core-js": "3.48.0",
"dompurify": "^2.4.3",
"formik": "2.4.5",
"formik": "2.4.9",
"lodash.snakecase": "4.1.1",
"prop-types": "15.8.1",
"raw-loader": "4.0.2",
@@ -56,20 +56,20 @@
"redux": "4.2.1",
"regenerator-runtime": "0.14.1",
"timeago.js": "4.0.2",
"tinymce": "5.10.7",
"tinymce": "5.10.9",
"yup": "0.32.11"
},
"devDependencies": {
"@edx/browserslist-config": "1.2.0",
"@edx/browserslist-config": "1.5.0",
"@openedx/frontend-build": "^14.6.2",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "14.3.1",
"@testing-library/user-event": "13.5.0",
"axios": "^0.28.0",
"axios": "^0.30.0",
"axios-mock-adapter": "1.22.0",
"babel-plugin-react-intl": "8.2.25",
"eslint-plugin-simple-import-sort": "7.0.0",
"glob": "7.2.0",
"glob": "7.2.3",
"jest": "29.7.0",
"rosie": "2.1.1"
}

View File

@@ -75,7 +75,7 @@ const HoverCard = ({
const actionFunction = actionHandlers[endorseIcons.action];
actionFunction();
}}
className={['endorse', 'unendorse'].includes(endorseIcons.id) ? 'text-dark-500' : 'text-success-500'}
className="text-primary"
size="sm"
alt="Endorse"
/>

View File

@@ -226,7 +226,7 @@ const Comment = ({
/>
) : (
<HTMLLoader
cssClassName="comment-body html-loader text-break mt-14px font-style text-primary-500"
cssClassName="comment-body html-loader text-break mt-14px font-style text-gray-700"
componentId="comment"
htmlNode={renderedBody}
testId={id}

View File

@@ -173,7 +173,7 @@ const Reply = ({ responseId }) => {
<HTMLLoader
componentId="reply"
htmlNode={renderedBody}
cssClassName="html-loader text-break font-style text-primary-500"
cssClassName="html-loader text-break font-style text-gray-700"
testId={id}
/>
)}

View File

@@ -143,6 +143,7 @@ const Post = ({ handleAddResponseButton, openRestrictionDialogue }) => {
onClose={hideDeleteConfirmation}
confirmAction={handleDeleteConfirmation}
closeButtonVariant="tertiary"
confirmButtonVariant="danger"
confirmButtonText={intl.formatMessage(messages.deleteConfirmationDelete)}
/>
{!abuseFlagged && (
@@ -152,7 +153,6 @@ const Post = ({ handleAddResponseButton, openRestrictionDialogue }) => {
description={intl.formatMessage(messages.reportPostDescription)}
onClose={hideReportConfirmation}
confirmAction={handleReportConfirmation}
confirmButtonVariant="danger"
/>
)}
<HoverCard
@@ -189,7 +189,7 @@ const Post = ({ handleAddResponseButton, openRestrictionDialogue }) => {
title={title}
postUsers={postUsers}
/>
<div className="d-flex mt-14px text-break font-style text-primary-500">
<div className="d-flex mt-14px text-break font-style text-gray-700">
<HTMLLoader htmlNode={renderedBody} componentId="post" cssClassName="html-loader w-100" testId={postId} />
</div>
{(topicContext || topic) && (

View File

@@ -0,0 +1,157 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { useSelector } from 'react-redux';
import Post from './Post';
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: () => jest.fn(),
useSelector: jest.fn(),
}));
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/test' }),
useNavigate: () => jest.fn(),
}));
jest.mock('@edx/frontend-platform/i18n', () => ({
useIntl: () => ({
formatMessage: (msg) => ((msg && msg.defaultMessage) ? msg.defaultMessage : 'test-message'),
}),
defineMessages: (msgs) => msgs,
}));
jest.mock('@openedx/paragon', () => {
const actual = jest.requireActual('@openedx/paragon');
// eslint-disable-next-line global-require
const PropTypes = require('prop-types');
const MockHyperlink = ({ children }) => <div>{children}</div>;
MockHyperlink.propTypes = { children: PropTypes.node.isRequired };
return {
...actual,
Hyperlink: MockHyperlink,
useToggle: actual.useToggle,
};
});
jest.mock('../../common', () => {
// eslint-disable-next-line global-require
const PropTypes = require('prop-types');
const MockConfirmation = ({ confirmButtonVariant, isOpen }) => {
if (!isOpen) { return null; }
return (
<div data-testid="mock-confirmation" data-variant={confirmButtonVariant}>
Mock Confirmation
</div>
);
};
MockConfirmation.propTypes = {
confirmButtonVariant: PropTypes.string,
isOpen: PropTypes.bool.isRequired,
};
// eslint-disable-next-line react/prop-types
const MockAlertBanner = () => <div />;
return {
Confirmation: MockConfirmation,
AlertBanner: MockAlertBanner,
};
});
jest.mock('./PostHeader', () => function MockPostHeader() { return <div>PostHeader</div>; });
jest.mock('./PostFooter', () => function MockPostFooter() { return <div>PostFooter</div>; });
jest.mock('./ClosePostReasonModal', () => function MockCloseModal() { return <div />; });
jest.mock('../../../components/HTMLLoader', () => function MockLoader() { return <div>Body Content</div>; });
jest.mock('../../common/HoverCard', () => {
// eslint-disable-next-line global-require
const { ContentActions } = require('../../../data/constants');
// eslint-disable-next-line global-require
const PropTypes = require('prop-types');
const MockHoverCard = ({ actionHandlers }) => (
<div>
<button
type="button"
data-testid="trigger-delete"
onClick={() => actionHandlers[ContentActions.DELETE] && actionHandlers[ContentActions.DELETE]()}
>
Delete Post
</button>
<button
type="button"
data-testid="trigger-report"
onClick={() => actionHandlers[ContentActions.REPORT] && actionHandlers[ContentActions.REPORT]()}
>
Report Post
</button>
</div>
);
MockHoverCard.propTypes = {
actionHandlers: PropTypes.shape({}).isRequired,
};
return MockHoverCard;
});
describe('Post Component - Delete/Report Confirmation', () => {
const mockPostId = '123';
beforeEach(() => {
useSelector.mockReturnValue({
topicId: 'topic-1',
abuseFlagged: false,
closed: false,
pinned: false,
voted: false,
following: false,
author: {},
title: 'Test Post',
renderedBody: '<div>Hello</div>',
users: {},
});
});
const renderPost = () => {
// eslint-disable-next-line global-require
const DiscussionContext = require('../../common/context').default;
return render(
<DiscussionContext.Provider value={{ postId: mockPostId, enableInContextSidebar: false, courseId: 'course-1' }}>
<Post
handleAddResponseButton={jest.fn()}
openRestrictionDialogue={jest.fn()}
/>
</DiscussionContext.Provider>,
);
};
it('passes "danger" variant to Confirmation modal when deleting a post', () => {
renderPost();
const deleteBtn = screen.getByTestId('trigger-delete');
fireEvent.click(deleteBtn);
const confirmation = screen.getByTestId('mock-confirmation');
expect(confirmation).toHaveAttribute('data-variant', 'danger');
});
it('does NOT pass "danger" variant to Confirmation modal when reporting a post', () => {
renderPost();
const reportBtn = screen.getByTestId('trigger-report');
fireEvent.click(reportBtn);
const confirmation = screen.getByTestId('mock-confirmation');
expect(confirmation).not.toHaveAttribute('data-variant', 'danger');
});
});

View File

@@ -126,7 +126,7 @@ const PostHeader = ({
</div>
) : (
<h5
className="mb-0 font-style text-primary-500"
className="mb-0 font-style"
style={{ lineHeight: '21px' }}
aria-level="1"
tabIndex="-1"