diff --git a/src/common-components/RedirectLogistration.jsx b/src/common-components/RedirectLogistration.jsx index 32c9a3cf..a2e6a116 100644 --- a/src/common-components/RedirectLogistration.jsx +++ b/src/common-components/RedirectLogistration.jsx @@ -19,7 +19,7 @@ const RedirectLogistration = (props) => { redirectToRecommendationsPage, educationLevel, userId, - isRegistrationEmbedded, + registrationEmbedded, } = props; let finalRedirectUrl = ''; @@ -39,7 +39,7 @@ const RedirectLogistration = (props) => { // TODO: Do we still need this cookie? setCookie('van-504-returning-user', true); - if (isRegistrationEmbedded) { + if (registrationEmbedded) { window.parent.postMessage({ action: REDIRECT, redirectUrl: `${window.location.origin}${AUTHN_PROGRESSIVE_PROFILING}` }, DISCOVER_URL); return null; } @@ -87,7 +87,7 @@ RedirectLogistration.defaultProps = { optionalFields: {}, redirectToRecommendationsPage: false, userId: null, - isRegistrationEmbedded: false, + registrationEmbedded: false, }; RedirectLogistration.propTypes = { @@ -99,7 +99,7 @@ RedirectLogistration.propTypes = { optionalFields: PropTypes.shape({}), redirectToRecommendationsPage: PropTypes.bool, userId: PropTypes.number, - isRegistrationEmbedded: PropTypes.bool, + registrationEmbedded: PropTypes.bool, }; export default RedirectLogistration; diff --git a/src/common-components/UnAuthOnlyRoute.jsx b/src/common-components/UnAuthOnlyRoute.jsx index 52d532da..6208c9d2 100644 --- a/src/common-components/UnAuthOnlyRoute.jsx +++ b/src/common-components/UnAuthOnlyRoute.jsx @@ -2,9 +2,13 @@ import React, { useEffect, useState } from 'react'; import { getConfig } from '@edx/frontend-platform'; import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth'; +import PropTypes from 'prop-types'; import { Route } from 'react-router-dom'; -import { DEFAULT_REDIRECT_URL } from '../data/constants'; +import { + DEFAULT_REDIRECT_URL, REGISTER_PAGE, +} from '../data/constants'; +import { isRegistrationEmbedded } from '../data/utils/dataUtils'; /** * This wrapper redirects the requester to our default redirect url if they are @@ -13,13 +17,20 @@ import { DEFAULT_REDIRECT_URL } from '../data/constants'; const UnAuthOnlyRoute = (props) => { const [authUser, setAuthUser] = useState({}); const [isReady, setIsReady] = useState(false); + const registrationEmbedded = isRegistrationEmbedded() && props.path === REGISTER_PAGE; useEffect(() => { + if (registrationEmbedded) { return; } fetchAuthenticatedUser({ forceRefresh: !!getAuthenticatedUser() }).then((authenticatedUser) => { setAuthUser(authenticatedUser); setIsReady(true); }); - }, []); + }, [registrationEmbedded]); + + // Show registration page for embedded experience even if the user is authenticated + if (registrationEmbedded) { + return ; + } if (isReady) { if (authUser && authUser.username) { @@ -33,4 +44,8 @@ const UnAuthOnlyRoute = (props) => { return null; }; +UnAuthOnlyRoute.propTypes = { + path: PropTypes.string.isRequired, +}; + export default UnAuthOnlyRoute; diff --git a/src/common-components/tests/UnAuthOnlyRoute.test.jsx b/src/common-components/tests/UnAuthOnlyRoute.test.jsx index 06b7f310..bba7019f 100644 --- a/src/common-components/tests/UnAuthOnlyRoute.test.jsx +++ b/src/common-components/tests/UnAuthOnlyRoute.test.jsx @@ -2,12 +2,13 @@ /* eslint-disable react/function-component-definition */ import React from 'react'; +import { getConfig } from '@edx/frontend-platform'; import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { UnAuthOnlyRoute } from '..'; -import { LOGIN_PAGE } from '../../data/constants'; +import { REGISTER_PAGE } from '../../data/constants'; import { MemoryRouter, BrowserRouter as Router, Switch } from 'react-router-dom'; @@ -26,7 +27,7 @@ const TestApp = () => (
- (Login Page)} /> + (Register Page)} />
@@ -34,7 +35,7 @@ const TestApp = () => ( describe('UnAuthOnlyRoute', () => { const routerWrapper = () => ( - + ); @@ -69,4 +70,44 @@ describe('UnAuthOnlyRoute', () => { expect(fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: false }); }); + + it('should not route to register page for authenticated users with non-embedded/normal experience', async () => { + const user = { + username: 'gonzo', + other: 'data', + }; + + getAuthenticatedUser.mockReturnValue(user); + fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(user)); + + let registerPage = null; + + await act(async () => { + registerPage = await mount(routerWrapper()); + }); + + expect(registerPage.find('span').exists()).toBeFalsy(); + }); + + it('should route to register page for authenticated users with embedded experience', async () => { + const user = { + username: 'gonzo', + other: 'data', + }; + + delete window.location; + window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: '?variant=embedded' }; + + getAuthenticatedUser.mockReturnValue(user); + fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(user)); + + let registerPage = null; + + await act(async () => { + registerPage = await mount(routerWrapper()); + }); + + expect(registerPage.find('span').exists()).toBeTruthy(); + expect(registerPage.find('span').text()).toBe('Register Page'); + }); }); diff --git a/src/data/utils/dataUtils.js b/src/data/utils/dataUtils.js index 70827dbb..5bccf1f0 100644 --- a/src/data/utils/dataUtils.js +++ b/src/data/utils/dataUtils.js @@ -1,7 +1,7 @@ // Utility functions import * as QueryString from 'query-string'; -import { AUTH_PARAMS } from '../constants'; +import { AUTH_PARAMS, EMBEDDED } from '../constants'; export const getTpaProvider = (tpaHintProvider, primaryProviders, secondaryProviders) => { let tpaProvider = null; @@ -76,3 +76,8 @@ export const windowScrollTo = (options) => { return window.scrollTo(options.top, options.left); }; + +export const isRegistrationEmbedded = () => { + const queryParams = getAllPossibleQueryParams(); + return queryParams?.variant === EMBEDDED; +}; diff --git a/src/logistration/Logistration.jsx b/src/logistration/Logistration.jsx index 006c57ef..27ea4827 100644 --- a/src/logistration/Logistration.jsx +++ b/src/logistration/Logistration.jsx @@ -20,10 +20,11 @@ import { tpaProvidersSelector, } from '../common-components/data/selectors'; import messages from '../common-components/messages'; -import { EMBEDDED, LOGIN_PAGE, REGISTER_PAGE } from '../data/constants'; +import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants'; import { - getAllPossibleQueryParams, getTpaHint, getTpaProvider, updatePathWithQueryParams, + getTpaHint, getTpaProvider, updatePathWithQueryParams, } from '../data/utils'; +import { isRegistrationEmbedded } from '../data/utils/dataUtils'; import { LoginPage } from '../login'; import { RegistrationPage } from '../register'; import { backupRegistrationForm } from '../register/data/actions'; @@ -38,7 +39,7 @@ const Logistration = (props) => { const [institutionLogin, setInstitutionLogin] = useState(false); const [key, setKey] = useState(''); const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false; - const isRegistrationEmbedded = getAllPossibleQueryParams()?.variant === EMBEDDED && selectedPage === REGISTER_PAGE; + const registrationEmbedded = isRegistrationEmbedded() && selectedPage === REGISTER_PAGE; useEffect(() => { const authService = getAuthService(); @@ -109,7 +110,7 @@ const Logistration = (props) => { ) - : (!isRegistrationEmbedded && !isValidTpaHint() && ( + : (!registrationEmbedded && !isValidTpaHint() && ( @@ -133,7 +134,7 @@ const Logistration = (props) => { ); return ( - isRegistrationEmbedded ? ( + registrationEmbedded ? ( renderLogistrationTabs() ) : ( diff --git a/src/register/RegistrationPage.jsx b/src/register/RegistrationPage.jsx index ed0583ce..0f15d267 100644 --- a/src/register/RegistrationPage.jsx +++ b/src/register/RegistrationPage.jsx @@ -48,11 +48,12 @@ import { import EnterpriseSSO from '../common-components/EnterpriseSSO'; import { COMPLETE_STATE, DEFAULT_STATE, - EMBEDDED, INVALID_NAME_REGEX, LETTER_REGEX, NUMBER_REGEX, PENDING_STATE, REGISTER_PAGE, VALID_EMAIL_REGEX, + INVALID_NAME_REGEX, LETTER_REGEX, NUMBER_REGEX, PENDING_STATE, REGISTER_PAGE, VALID_EMAIL_REGEX, } from '../data/constants'; import { getAllPossibleQueryParams, getTpaHint, getTpaProvider, setCookie, } from '../data/utils'; +import { isRegistrationEmbedded } from '../data/utils/dataUtils'; const emailRegex = new RegExp(VALID_EMAIL_REGEX, 'i'); const urlRegex = new RegExp(INVALID_NAME_REGEX); @@ -87,7 +88,7 @@ const RegistrationPage = (props) => { const { formatMessage } = useIntl(); const countryList = useMemo(() => getCountryList(getLocale()), []); const queryParams = useMemo(() => getAllPossibleQueryParams(), []); - const isRegistrationEmbedded = queryParams?.variant === EMBEDDED; + const registrationEmbedded = isRegistrationEmbedded(); const tpaHint = useMemo(() => getTpaHint(), []); const flags = { showConfigurableEdxFields: getConfig().SHOW_CONFIGURABLE_EDX_FIELDS, @@ -520,7 +521,7 @@ const RegistrationPage = (props) => { redirectUrl={registrationResult.redirectUrl} finishAuthUrl={finishAuthUrl} optionalFields={optionalFields} - isRegistrationEmbedded={isRegistrationEmbedded} + registrationEmbedded={registrationEmbedded} redirectToProgressiveProfilingPage={ getConfig().ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN && Object.keys(optionalFields).includes('fields') } @@ -533,7 +534,7 @@ const RegistrationPage = (props) => {
{ onClick={handleSubmit} onMouseDown={(e) => e.preventDefault()} /> - {!isRegistrationEmbedded && ( + {!registrationEmbedded && (