fix: null error at useRouteMatch when running on tutor (#613)

tutor sets the PUBLIC_PATH to '/discussions' which causes frontend-platform to
treat all URLs for matching etc to be relative to this path. Since many places
include '/discussions' in the match it causes those matches to break.

This change makes the default PUBLIC_PATH in .env.development to match the one
set by tutor and removes it from the base path of the router letting frontend
platform handle the prefix.

This also allows for deployments to customise this path to be something other
than 'discussions'.
This commit is contained in:
Kshitij Sobti
2023-12-06 17:50:28 +05:30
committed by GitHub
parent 0d5df18ab2
commit b36c0266fd
4 changed files with 22 additions and 5 deletions

View File

@@ -1,6 +1,9 @@
import { getConfig } from '@edx/frontend-platform';
export const getApiBaseUrl = () => getConfig().LMS_BASE_URL;
export const getFullUrl = (path) => (
new URL(`${getConfig().PUBLIC_PATH.replace(/\/$/, '')}/${path}`, window.location.origin).href
);
/**
* Enum for thread types.
@@ -137,7 +140,7 @@ export const DiscussionProvider = {
OPEN_EDX: 'openedx',
};
const BASE_PATH = `${getConfig().PUBLIC_PATH}:courseId`;
const BASE_PATH = '/:courseId';
export const Routes = {
DISCUSSIONS: {

View File

@@ -442,6 +442,20 @@ describe('ThreadView', () => {
assertLastUpdateData({ pinned: false });
});
it('should allow copying a link to the post', async () => {
await waitFor(() => renderComponent(discussionPostId));
const post = await screen.findByTestId('post-thread-1');
const hoverCard = within(post).getByTestId('hover-card-thread-1');
Object.assign(navigator, { clipboard: { writeText: jest.fn() } });
await act(async () => {
fireEvent.click(within(hoverCard).getByRole('button', { name: /actions menu/i }));
});
await act(async () => {
fireEvent.click(within(hoverCard).getByRole('button', { name: /copy link/i }));
});
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(`http://localhost/${courseId}/posts/${discussionPostId}`);
});
it('should allow reporting the post', async () => {
await waitFor(() => renderComponent(discussionPostId));
const post = await screen.findByTestId('post-thread-1');

View File

@@ -26,6 +26,7 @@ Factory.define('thread')
'type',
'voted',
'pinned',
'copy_link',
],
author: 'test_user',
author_label: 'Staff',

View File

@@ -11,7 +11,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, useToggle } from '@edx/paragon';
import HTMLLoader from '../../../components/HTMLLoader';
import { ContentActions } from '../../../data/constants';
import { ContentActions, getFullUrl } from '../../../data/constants';
import { selectorForUnitSubsection, selectTopicContext } from '../../../data/selectors';
import { AlertBanner, Confirmation } from '../../common';
import { DiscussionContext } from '../../common/context';
@@ -37,7 +37,7 @@ const Post = ({ handleAddResponseButton }) => {
const location = useLocation();
const history = useHistory();
const dispatch = useDispatch();
const courseId = useSelector((state) => state.config.id);
const { courseId } = useContext(DiscussionContext);
const topic = useSelector(selectTopic(topicId));
const getTopicSubsection = useSelector(selectorForUnitSubsection);
const topicContext = useSelector(selectTopicContext(topicId));
@@ -75,8 +75,7 @@ const Post = ({ handleAddResponseButton }) => {
}, [closed, postId, showClosePostModal]);
const handlePostCopyLink = useCallback(() => {
const postURL = new URL(`${getConfig().PUBLIC_PATH}${courseId}/posts/${postId}`, window.location.origin);
navigator.clipboard.writeText(postURL.href);
navigator.clipboard.writeText(getFullUrl(`${courseId}/posts/${postId}`));
}, [window.location.origin, postId, courseId]);
const handlePostPin = useCallback(() => dispatch(