Merge pull request #3383 from benjiwheeler/join-flow-navigate-to-join-page

scratch3 join flow redirects to /join, outside editor
This commit is contained in:
Benjamin Wheeler 2019-09-30 16:44:24 -04:00 committed by GitHub
commit fdeb87fce9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 15 deletions

View file

@ -18,7 +18,6 @@ const LoginDropdown = require('../../login/login-dropdown.jsx');
const CanceledDeletionModal = require('../../login/canceled-deletion-modal.jsx'); const CanceledDeletionModal = require('../../login/canceled-deletion-modal.jsx');
const NavigationBox = require('../base/navigation.jsx'); const NavigationBox = require('../base/navigation.jsx');
const Registration = require('../../registration/registration.jsx'); const Registration = require('../../registration/registration.jsx');
const Scratch3Registration = require('../../registration/scratch3-registration.jsx');
const AccountNav = require('./accountnav.jsx'); const AccountNav = require('./accountnav.jsx');
require('./navigation.scss'); require('./navigation.scss');
@ -28,6 +27,7 @@ class Navigation extends React.Component {
super(props); super(props);
bindAll(this, [ bindAll(this, [
'getProfileUrl', 'getProfileUrl',
'handleClickRegistration',
'handleSearchSubmit' 'handleSearchSubmit'
]); ]);
this.state = { this.state = {
@ -78,6 +78,13 @@ class Navigation extends React.Component {
if (!this.props.user) return; if (!this.props.user) return;
return `/users/${this.props.user.username}/`; return `/users/${this.props.user.username}/`;
} }
handleClickRegistration (event) {
if (this.props.useScratch3Registration) {
this.props.navigateToRegistration(event);
} else {
this.props.handleOpenRegistration(event);
}
}
handleSearchSubmit (formData) { handleSearchSubmit (formData) {
let targetUrl = '/search/projects'; let targetUrl = '/search/projects';
if (formData.q) { if (formData.q) {
@ -189,9 +196,12 @@ class Navigation extends React.Component {
className="link right join" className="link right join"
key="join" key="join"
> >
{/* there's no css class registrationLink -- this is
just to make the link findable for testing */}
<a <a
className="registrationLink"
href="#" href="#"
onClick={this.props.handleOpenRegistration} onClick={this.handleClickRegistration}
> >
<FormattedMessage id="general.joinScratch" /> <FormattedMessage id="general.joinScratch" />
</a> </a>
@ -214,18 +224,10 @@ class Navigation extends React.Component {
</li> </li>
]) : [] ]) : []
} }
{this.props.registrationOpen && ( {this.props.registrationOpen && !this.props.useScratch3Registration && (
this.props.useScratch3Registration ? ( <Registration
<Scratch3Registration key="registration"
createProjectOnComplete />
isOpen
key="scratch3registration"
/>
) : (
<Registration
key="registration"
/>
)
)} )}
</ul> </ul>
<CanceledDeletionModal /> <CanceledDeletionModal />
@ -243,6 +245,7 @@ Navigation.propTypes = {
handleToggleAccountNav: PropTypes.func, handleToggleAccountNav: PropTypes.func,
handleToggleLoginOpen: PropTypes.func, handleToggleLoginOpen: PropTypes.func,
intl: intlShape, intl: intlShape,
navigateToRegistration: PropTypes.func,
permissions: PropTypes.shape({ permissions: PropTypes.shape({
admin: PropTypes.bool, admin: PropTypes.bool,
social: PropTypes.bool, social: PropTypes.bool,
@ -305,14 +308,24 @@ const mapDispatchToProps = dispatch => ({
event.preventDefault(); event.preventDefault();
dispatch(navigationActions.toggleLoginOpen()); dispatch(navigationActions.toggleLoginOpen());
}, },
navigateToRegistration: event => {
event.preventDefault();
navigationActions.navigateToRegistration();
},
setMessageCount: newCount => { setMessageCount: newCount => {
dispatch(messageCountActions.setCount(newCount)); dispatch(messageCountActions.setCount(newCount));
} }
}); });
// Allow incoming props to override redux-provided props. Used to mock in tests.
const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
{}, stateProps, dispatchProps, ownProps
);
const ConnectedNavigation = connect( const ConnectedNavigation = connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps,
mergeProps
)(Navigation); )(Navigation);
module.exports = injectIntl(ConnectedNavigation); module.exports = injectIntl(ConnectedNavigation);

View file

@ -92,6 +92,10 @@ module.exports.setSearchTerm = searchTerm => ({
searchTerm: searchTerm searchTerm: searchTerm
}); });
module.exports.navigateToRegistration = () => {
window.location = '/join';
};
module.exports.handleCompleteRegistration = createProject => (dispatch => { module.exports.handleCompleteRegistration = createProject => (dispatch => {
if (createProject) { if (createProject) {
window.location = '/projects/editor/?tutorial=getStarted'; window.location = '/projects/editor/?tutorial=getStarted';

View file

@ -0,0 +1,70 @@
const React = require('react');
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
import configureStore from 'redux-mock-store';
const Navigation = require('../../../src/components/navigation/www/navigation.jsx');
const sessionActions = require('../../../src/redux/session.js');
describe('Navigation', () => {
const mockStore = configureStore();
let store;
beforeEach(() => {
store = null;
});
const getNavigationWrapper = props => {
const wrapper = shallowWithIntl(
<Navigation
{...props}
/>
, {context: {store}}
);
return wrapper
.dive() // unwrap redux connect(injectIntl(JoinFlow))
.dive(); // unwrap injectIntl(JoinFlow)
};
test('when using old join flow, clicking Join Scratch attemps to open registration', () => {
store = mockStore({
navigation: {
useScratch3Registration: false
},
session: {
status: sessionActions.Status.FETCHED
},
messageCount: {
messageCount: 0
}
});
const props = {
handleOpenRegistration: jest.fn()
};
const navWrapper = getNavigationWrapper(props);
const navInstance = navWrapper.instance();
navWrapper.find('a.registrationLink').simulate('click');
expect(navInstance.props.handleOpenRegistration).toHaveBeenCalled();
});
test('when using new join flow, clicking Join Scratch attemps to navigate to registration', () => {
store = mockStore({
navigation: {
useScratch3Registration: true
},
session: {
status: sessionActions.Status.FETCHED
},
messageCount: {
messageCount: 0
}
});
const props = {
navigateToRegistration: jest.fn()
};
const navWrapper = getNavigationWrapper(props);
const navInstance = navWrapper.instance();
navWrapper.find('a.registrationLink').simulate('click');
expect(navInstance.props.navigateToRegistration).toHaveBeenCalled();
});
});