Merge pull request #38 from edx/waheed/VAN-131
Redirect to dashboard if user already logged in.
This commit is contained in:
19
src/common-components/HeaderLayout.jsx
Normal file
19
src/common-components/HeaderLayout.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Header from '@edx/frontend-component-header';
|
||||
|
||||
const HeaderLayout = ({ children }) => (
|
||||
<div className="d-flex flex-column">
|
||||
<Header />
|
||||
<main className="flex-grow-1">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
HeaderLayout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default HeaderLayout;
|
||||
26
src/common-components/LoggedInRedirect.jsx
Normal file
26
src/common-components/LoggedInRedirect.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
|
||||
import { DEFAULT_REDIRECT_URL } from '../data/constants';
|
||||
|
||||
/**
|
||||
* This wrapper component redirects the requester to our default redirect url if they are
|
||||
* already authenticated.
|
||||
*
|
||||
* @param {node} children The child nodes to render if there is an unauthenticated user.
|
||||
*/
|
||||
export default function LoggedInRedirect({ children }) {
|
||||
const { authenticatedUser, config } = useContext(AppContext);
|
||||
|
||||
if (authenticatedUser) {
|
||||
global.location.href = config.LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
|
||||
return null;
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
LoggedInRedirect.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
4
src/common-components/index.jsx
Normal file
4
src/common-components/index.jsx
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as HeaderLayout } from './HeaderLayout';
|
||||
export { default as LoggedInRedirect } from './LoggedInRedirect';
|
||||
export { default as RedirectLogistration } from './RedirectLogistration';
|
||||
export { default as registerIcons } from './RegisterFaIcons';
|
||||
46
src/common-components/tests/LoggedInRedirect.test.jsx
Normal file
46
src/common-components/tests/LoggedInRedirect.test.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
|
||||
import LoggedInRedirect from '../LoggedInRedirect';
|
||||
import { DEFAULT_REDIRECT_URL } from '../../data/constants';
|
||||
|
||||
describe('LoggedInRedirect', () => {
|
||||
const loggedInRedirect = (
|
||||
<LoggedInRedirect>
|
||||
<div>test</div>
|
||||
</LoggedInRedirect>
|
||||
);
|
||||
const dashboardURL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
|
||||
|
||||
it('should redirect to dashboard if already logged in', () => {
|
||||
delete window.location;
|
||||
window.location = { href: '' };
|
||||
const user = {
|
||||
username: 'gonzo',
|
||||
other: 'data',
|
||||
};
|
||||
const mockUseContext = jest.fn().mockImplementation(() => ({
|
||||
authenticatedUser: user,
|
||||
config: getConfig(),
|
||||
}));
|
||||
|
||||
React.useContext = mockUseContext;
|
||||
mount(loggedInRedirect);
|
||||
|
||||
expect(window.location.href).toBe(dashboardURL);
|
||||
});
|
||||
|
||||
it('should render child components', () => {
|
||||
const mockUseContext = jest.fn().mockImplementation(() => ({
|
||||
authenticatedUser: null,
|
||||
config: null,
|
||||
}));
|
||||
|
||||
React.useContext = mockUseContext;
|
||||
const wrapper = mount(loggedInRedirect);
|
||||
|
||||
expect(wrapper.find('div').length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -6,15 +6,15 @@ import {
|
||||
import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import Header, { messages as headerMessages } from '@edx/frontend-component-header';
|
||||
import { messages as headerMessages } from '@edx/frontend-component-header';
|
||||
|
||||
import configureStore from './data/configureStore';
|
||||
import { LoginPage, RegistrationPage, NotFoundPage } from './logistration';
|
||||
import { LOGIN_PAGE, REGISTER_PAGE, RESET_PAGE } from './data/constants';
|
||||
import ForgotPasswordPage from './forgot-password';
|
||||
import registerIcons from './RegisterFaIcons';
|
||||
import { HeaderLayout, LoggedInRedirect, registerIcons } from './common-components';
|
||||
import ResetPasswordPage from './reset-password';
|
||||
import appMessages from './i18n';
|
||||
|
||||
@@ -23,28 +23,24 @@ import './assets/favicon.ico';
|
||||
|
||||
registerIcons();
|
||||
|
||||
const HeaderLayout = ({ children }) => ( // eslint-disable-line react/prop-types
|
||||
<div className="d-flex flex-column" style={{ minHeight: '100vh' }}>
|
||||
<Header />
|
||||
<main className="flex-grow-1">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
subscribe(APP_READY, () => {
|
||||
ReactDOM.render(
|
||||
<AppProvider store={configureStore()}>
|
||||
<HeaderLayout>
|
||||
<Switch>
|
||||
<Route path={LOGIN_PAGE} component={LoginPage} />
|
||||
<Route path={REGISTER_PAGE} component={RegistrationPage} />
|
||||
<Route path={RESET_PAGE} component={ForgotPasswordPage} />
|
||||
<Route path="/password_reset_confirm/:token/" component={ResetPasswordPage} />
|
||||
<Route path="/notfound" component={NotFoundPage} />
|
||||
<Route path="*" component={NotFoundPage} />
|
||||
</Switch>
|
||||
</HeaderLayout>
|
||||
<LoggedInRedirect>
|
||||
<HeaderLayout>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
<Redirect to={LOGIN_PAGE} />
|
||||
</Route>
|
||||
<Route exact path={LOGIN_PAGE} component={LoginPage} />
|
||||
<Route exact path={REGISTER_PAGE} component={RegistrationPage} />
|
||||
<Route exact path={RESET_PAGE} component={ForgotPasswordPage} />
|
||||
<Route exact path="/password_reset_confirm/:token/" component={ResetPasswordPage} />
|
||||
<Route path="/notfound" component={NotFoundPage} />
|
||||
<Route path="*" component={NotFoundPage} />
|
||||
</Switch>
|
||||
</HeaderLayout>
|
||||
</LoggedInRedirect>
|
||||
</AppProvider>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ import InstitutionLogistration, { RenderInstitutionButton } from './InstitutionL
|
||||
import LoginHelpLinks from './LoginHelpLinks';
|
||||
import LoginFailureMessage from './LoginFailure';
|
||||
import messages from './messages';
|
||||
import RedirectLogistration from './RedirectLogistration';
|
||||
import { RedirectLogistration } from '../common-components';
|
||||
import SocialAuthProviders from './SocialAuthProviders';
|
||||
import ThirdPartyAuthAlert from './ThirdPartyAuthAlert';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
|
||||
import { getThirdPartyAuthContext, registerNewUser } from './data/actions';
|
||||
import { registrationRequestSelector, thirdPartyAuthContextSelector } from './data/selectors';
|
||||
import RedirectLogistration from './RedirectLogistration';
|
||||
import { RedirectLogistration } from '../common-components';
|
||||
import RegistrationFailure from './RegistrationFailure';
|
||||
import {
|
||||
DEFAULT_REDIRECT_URL, DEFAULT_STATE, LOGIN_PAGE, REGISTER_PAGE,
|
||||
|
||||
@@ -3,7 +3,7 @@ import renderer from 'react-test-renderer';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import SocialAuthProviders from '../SocialAuthProviders';
|
||||
import registerIcons from '../../RegisterFaIcons';
|
||||
import { registerIcons } from '../../common-components';
|
||||
|
||||
registerIcons();
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ describe('ResetPasswordPage', () => {
|
||||
expect(resetPasswordPage.find('#reset-password-input-invalid-feedback').text()).toEqual(validationMessage);
|
||||
});
|
||||
|
||||
it('with valid inputs resetPassword action is dispatch', () => {
|
||||
it('with valid inputs resetPassword action is dispatch', async () => {
|
||||
const newPassword = 'test-password1';
|
||||
store = mockStore({
|
||||
...store,
|
||||
@@ -151,6 +151,13 @@ describe('ResetPasswordPage', () => {
|
||||
token: 'token',
|
||||
};
|
||||
|
||||
auth.getHttpClient = jest.fn(() => ({
|
||||
post: async () => ({
|
||||
data: {},
|
||||
catch: () => {},
|
||||
}),
|
||||
}));
|
||||
|
||||
const formPayload = {
|
||||
new_password1: newPassword,
|
||||
new_password2: newPassword,
|
||||
@@ -158,7 +165,9 @@ describe('ResetPasswordPage', () => {
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const resetPage = mount(reduxWrapper(<IntlResetPasswordPage {...props} />));
|
||||
resetPage.find('input#reset-password-input').simulate('blur', { target: { value: newPassword } });
|
||||
await act(async () => {
|
||||
resetPage.find('input#reset-password-input').simulate('blur', { target: { value: newPassword } });
|
||||
});
|
||||
resetPage.find('input#confirm-password-input').simulate('change', { target: { value: newPassword } });
|
||||
resetPage.find('button.submit').simulate('click');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user