feat: upgrade react router to v6 (#716)
* feat: upgrade react router to v6 * refactor: add hoc to use params * fix: lint issue
This commit is contained in:
committed by
GitHub
parent
e1d4e9b474
commit
fe800f2ee9
@@ -41,6 +41,8 @@ import { profilePageSelector } from './data/selectors';
|
||||
// i18n
|
||||
import messages from './ProfilePage.messages';
|
||||
|
||||
import withParams from '../utils/hoc';
|
||||
|
||||
ensureConfig(['CREDENTIALS_BASE_URL', 'LMS_BASE_URL'], 'ProfilePage');
|
||||
|
||||
class ProfilePage extends React.Component {
|
||||
@@ -63,9 +65,9 @@ class ProfilePage extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchProfile(this.props.match.params.username);
|
||||
this.props.fetchProfile(this.props.params.username);
|
||||
sendTrackingLogEvent('edx.profile.viewed', {
|
||||
username: this.props.match.params.username,
|
||||
username: this.props.params.username,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ class ProfilePage extends React.Component {
|
||||
}
|
||||
|
||||
isAuthenticatedUserProfile() {
|
||||
return this.props.match.params.username === this.context.authenticatedUser.username;
|
||||
return this.props.params.username === this.context.authenticatedUser.username;
|
||||
}
|
||||
|
||||
// Inserted into the DOM in two places (for responsive layout)
|
||||
@@ -124,7 +126,7 @@ class ProfilePage extends React.Component {
|
||||
|
||||
return (
|
||||
<span data-hj-suppress>
|
||||
<h1 className="h2 mb-0 font-weight-bold">{this.props.match.params.username}</h1>
|
||||
<h1 className="h2 mb-0 font-weight-bold">{this.props.params.username}</h1>
|
||||
<DateJoined date={dateJoined} />
|
||||
{this.isYOBDisabled() && <UsernameDescription />}
|
||||
<hr className="d-none d-md-block" />
|
||||
@@ -370,10 +372,8 @@ ProfilePage.propTypes = {
|
||||
updateDraft: PropTypes.func.isRequired,
|
||||
|
||||
// Router
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
username: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
params: PropTypes.shape({
|
||||
username: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
// i18n
|
||||
@@ -410,4 +410,4 @@ export default connect(
|
||||
closeForm,
|
||||
updateDraft,
|
||||
},
|
||||
)(injectIntl(ProfilePage));
|
||||
)(injectIntl(withParams(ProfilePage)));
|
||||
|
||||
@@ -29,7 +29,7 @@ const requiredProfilePageProps = {
|
||||
deleteProfilePhoto: () => {},
|
||||
openField: () => {},
|
||||
closeField: () => {},
|
||||
match: { params: { username: 'staff' } },
|
||||
params: { username: 'staff' },
|
||||
};
|
||||
|
||||
// Mock language cookie
|
||||
@@ -67,29 +67,28 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
const ProfilePageWrapper = ({
|
||||
contextValue, store, match, requiresParentalConsent,
|
||||
contextValue, store, params, requiresParentalConsent,
|
||||
}) => (
|
||||
<AppContext.Provider
|
||||
value={contextValue}
|
||||
>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<ProfilePage {...requiredProfilePageProps} match={match} requiresParentalConsent={requiresParentalConsent} />
|
||||
<ProfilePage {...requiredProfilePageProps} params={params} requiresParentalConsent={requiresParentalConsent} />
|
||||
</Provider>
|
||||
</IntlProvider>
|
||||
</AppContext.Provider>
|
||||
);
|
||||
|
||||
ProfilePageWrapper.defaultProps = {
|
||||
match: { params: { username: 'staff' } },
|
||||
params: { username: 'staff' },
|
||||
requiresParentalConsent: null,
|
||||
|
||||
};
|
||||
|
||||
ProfilePageWrapper.propTypes = {
|
||||
contextValue: PropTypes.shape({}).isRequired,
|
||||
store: PropTypes.shape({}).isRequired,
|
||||
match: PropTypes.shape({}),
|
||||
params: PropTypes.shape({}),
|
||||
requiresParentalConsent: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -124,7 +123,7 @@ describe('<ProfilePage />', () => {
|
||||
<ProfilePageWrapper
|
||||
contextValue={contextValue}
|
||||
store={mockStore(storeMocks.viewOtherProfile)}
|
||||
match={{ params: { username: 'verified' } }} // Override default match
|
||||
params={{ username: 'verified' }} // Override default params
|
||||
/>
|
||||
);
|
||||
const tree = renderer.create(component).toJSON();
|
||||
@@ -279,7 +278,7 @@ describe('<ProfilePage />', () => {
|
||||
<ProfilePageWrapper
|
||||
contextValue={contextValue}
|
||||
store={mockStore(storeMocks.loadingApp)}
|
||||
match={{ params: { username: 'test-username' } }}
|
||||
params={{ username: 'test-username' }}
|
||||
/>
|
||||
);
|
||||
const wrapper = mount(component);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
AuthenticatedPageRoute,
|
||||
PageRoute,
|
||||
PageWrap,
|
||||
} from '@edx/frontend-platform/react';
|
||||
import { Switch } from 'react-router-dom';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { ProfilePage, NotFoundPage } from '../profile';
|
||||
|
||||
const AppRoutes = () => (
|
||||
<Switch>
|
||||
<AuthenticatedPageRoute path="/u/:username" component={ProfilePage} />
|
||||
<PageRoute path="/notfound" component={NotFoundPage} />
|
||||
<PageRoute path="*" component={NotFoundPage} />
|
||||
</Switch>
|
||||
<Routes>
|
||||
<Route path="/u/:username" element={<AuthenticatedPageRoute><ProfilePage /></AuthenticatedPageRoute>} />
|
||||
<Route path="/notfound" element={<PageWrap><NotFoundPage /></PageWrap>} />
|
||||
<Route path="*" element={<PageWrap><NotFoundPage /></PageWrap>} />
|
||||
</Routes>
|
||||
);
|
||||
|
||||
export default AppRoutes;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { Router } from 'react-router';
|
||||
import { MemoryRouter as Router } from 'react-router-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { getLoginRedirectUrl } from '@edx/frontend-platform/auth';
|
||||
import AppRoutes from './AppRoutes';
|
||||
|
||||
@@ -18,9 +17,9 @@ jest.mock('../profile', () => ({
|
||||
NotFoundPage: () => (<div>Not found page</div>),
|
||||
}));
|
||||
|
||||
const RoutesWithProvider = (context, history) => (
|
||||
const RoutesWithProvider = (context, path) => (
|
||||
<AppContext.Provider value={context}>
|
||||
<Router history={history}>
|
||||
<Router initialEntries={[`${path}`]}>
|
||||
<AppRoutes />
|
||||
</Router>
|
||||
</AppContext.Provider>
|
||||
@@ -32,22 +31,14 @@ const unauthenticatedUser = {
|
||||
};
|
||||
|
||||
describe('routes', () => {
|
||||
let history;
|
||||
|
||||
beforeEach(() => {
|
||||
history = createMemoryHistory();
|
||||
});
|
||||
|
||||
test('Profile page should redirect for unauthenticated users', () => {
|
||||
history.push('/u/edx');
|
||||
render(
|
||||
RoutesWithProvider(unauthenticatedUser, history),
|
||||
RoutesWithProvider(unauthenticatedUser, '/u/edx'),
|
||||
);
|
||||
expect(getLoginRedirectUrl).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Profile page should be accessible for authenticated users', () => {
|
||||
history.push('/u/edx');
|
||||
render(
|
||||
RoutesWithProvider(
|
||||
{
|
||||
@@ -57,16 +48,15 @@ describe('routes', () => {
|
||||
},
|
||||
config: getConfig(),
|
||||
},
|
||||
history,
|
||||
'/u/edx',
|
||||
),
|
||||
);
|
||||
expect(screen.getByText('Profile page')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should show NotFound page for a bad route', () => {
|
||||
history.push('/nonMatchingRoute');
|
||||
render(
|
||||
RoutesWithProvider(unauthenticatedUser, history),
|
||||
RoutesWithProvider(unauthenticatedUser, '/nonMatchingRoute'),
|
||||
);
|
||||
expect(screen.getByText('Not found page')).toBeTruthy();
|
||||
});
|
||||
|
||||
10
src/utils/hoc.jsx
Normal file
10
src/utils/hoc.jsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
const withParams = (WrappedComponent) => {
|
||||
const WithParamsComponent = (props) => <WrappedComponent params={useParams()} {...props} />;
|
||||
return WithParamsComponent;
|
||||
};
|
||||
|
||||
export default withParams;
|
||||
Reference in New Issue
Block a user