Skip to content

Commit

Permalink
MM-12581 Switch UserActions.loadMe to redux (mattermost#1876)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmhealey authored and saturninoabril committed Oct 12, 2018
1 parent 45ad417 commit 0dfcb81
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 92 deletions.
26 changes: 3 additions & 23 deletions actions/user_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// See LICENSE.txt for license information.

import {getChannelAndMyMember} from 'mattermost-redux/actions/channels';
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
import {deletePreferences as deletePreferencesRedux, savePreferences as savePreferencesRedux} from 'mattermost-redux/actions/preferences';
import {getMyTeamMembers, getMyTeamUnreads, getTeamMembersByIds} from 'mattermost-redux/actions/teams';
import * as UserActions from 'mattermost-redux/actions/users';
Expand All @@ -27,25 +26,6 @@ import {Constants, Preferences} from 'utils/constants.jsx';
const dispatch = store.dispatch;
const getState = store.getState;

export async function loadMe() {
await UserActions.loadMe()(dispatch, getState);
loadCurrentLocale();
}

export async function loadMeAndConfig(callback) {
await store.dispatch(getClientConfig());

const promises = [];

if (document.cookie.indexOf('MMUSERID=') > -1) {
promises.push(loadMe());
}

promises.push(getLicenseConfig()(store.dispatch, store.getState));

Promise.all(promises).then(callback);
}

export async function switchFromLdapToEmail(email, password, token, ldapPassword, success, error) {
const {data, error: err} = await UserActions.switchLdapToEmail(ldapPassword, email, password, token)(dispatch, getState);

Expand Down Expand Up @@ -518,7 +498,7 @@ export async function resendVerification(email, success, error) {
export async function loginById(userId, password, mfaToken, success, error) {
const {data: ok, error: err} = await UserActions.loginById(userId, password, mfaToken)(dispatch, getState);
if (ok && success) {
await store.dispatch(getLicenseConfig());
loadCurrentLocale();
success();
} else if (err && error) {
if (err.server_error_id === 'api.context.mfa_required.app_error') {
Expand All @@ -543,7 +523,7 @@ export async function createUserWithInvite(user, token, inviteId, success, error
export async function webLogin(loginId, password, token, success, error) {
const {data: ok, error: err} = await UserActions.login(loginId, password, token)(dispatch, getState);
if (ok && success) {
await store.dispatch(getLicenseConfig());
loadCurrentLocale();
success();
} else if (err && error) {
if (err.server_error_id === 'api.context.mfa_required.app_error') {
Expand Down Expand Up @@ -577,7 +557,7 @@ export async function getTermsOfService(success, error) {
export async function webLoginByLdap(loginId, password, token, success, error) {
const {data: ok, error: err} = await UserActions.login(loginId, password, token, true)(dispatch, getState);
if (ok && success) {
await store.dispatch(getLicenseConfig());
loadCurrentLocale();
success();
} else if (err && error) {
if (err.server_error_id === 'api.context.mfa_required.app_error') {
Expand Down
20 changes: 20 additions & 0 deletions actions/views/root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
import * as UserActions from 'mattermost-redux/actions/users';

export function loadMeAndConfig() {
return (dispatch) => {
const promises = [
dispatch(getClientConfig()),
dispatch(getLicenseConfig()),
];

if (document.cookie.indexOf('MMUSERID=') > -1) {
promises.push(dispatch(UserActions.loadMe()));
}

return Promise.all(promises);
};
}
11 changes: 2 additions & 9 deletions components/mfa/confirm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import React from 'react';
import {FormattedMessage} from 'react-intl';

import {loadMe} from 'actions/user_actions.jsx';
import Constants from 'utils/constants.jsx';
import {isKeyPressed} from 'utils/utils.jsx';

Expand All @@ -23,9 +22,8 @@ export default class Confirm extends React.Component {

submit = (e) => {
e.preventDefault();
loadMe().then(() => {
this.props.history.push('/');
});

this.props.history.push('/');
}

onKeyPress = (e) => {
Expand Down Expand Up @@ -68,8 +66,3 @@ export default class Confirm extends React.Component {
);
}
}

Confirm.defaultProps = {
};
Confirm.propTypes = {
};
15 changes: 13 additions & 2 deletions components/root/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {getConfig} from 'mattermost-redux/selectors/entities/general';

import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {shouldShowTermsOfService} from 'mattermost-redux/selectors/entities/users';

import {loadMeAndConfig} from 'actions/views/root';

import Root from './root.jsx';

function mapStateToProps(state) {
Expand All @@ -20,4 +23,12 @@ function mapStateToProps(state) {
};
}

export default connect(mapStateToProps)(Root);
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
loadMeAndConfig,
}, dispatch),
};
}

export default connect(mapStateToProps, mapDispatchToProps)(Root);
10 changes: 7 additions & 3 deletions components/root/root.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import BrowserStore from 'stores/browser_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import LocalizationStore from 'stores/localization_store.jsx';
import UserStore from 'stores/user_store.jsx';
import {loadMeAndConfig} from 'actions/user_actions.jsx';
import {loadRecentlyUsedCustomEmojis} from 'actions/emoji_actions.jsx';
import * as I18n from 'i18n/i18n.jsx';
import {initializePlugins} from 'plugins';
Expand Down Expand Up @@ -90,8 +89,10 @@ export default class Root extends React.Component {
diagnosticsEnabled: PropTypes.bool,
diagnosticId: PropTypes.string,
noAccounts: PropTypes.bool,
children: PropTypes.object,
showTermsOfService: PropTypes.bool,
actions: PropTypes.shape({
loadMeAndConfig: PropTypes.func.isRequired,
}).isRequired,
}

constructor(props) {
Expand Down Expand Up @@ -251,7 +252,10 @@ export default class Root extends React.Component {
}

componentDidMount() {
loadMeAndConfig(this.onConfigLoaded);
this.props.actions.loadMeAndConfig().then(() => {
this.onConfigLoaded();
});

trackLoadTime();
}

Expand Down
9 changes: 2 additions & 7 deletions components/signup/signup_controller/signup_controller.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {Client4} from 'mattermost-redux/client';
import {browserHistory} from 'utils/browser_history';
import * as GlobalActions from 'actions/global_actions.jsx';
import {addUserToTeamFromInvite, getInviteInfo} from 'actions/team_actions.jsx';
import {loadMe} from 'actions/user_actions.jsx';
import logoImage from 'images/logo.png';
import AnnouncementBar from 'components/announcement_bar';
import BackButton from 'components/common/back_button.jsx';
Expand Down Expand Up @@ -98,11 +97,7 @@ export default class SignupController extends React.Component {
token,
inviteId,
(team) => {
loadMe().then(
() => {
browserHistory.push('/' + team.name + `/channels/${Constants.DEFAULT_CHANNEL}`);
}
);
browserHistory.push('/' + team.name + `/channels/${Constants.DEFAULT_CHANNEL}`);
},
this.handleInvalidInvite
);
Expand Down Expand Up @@ -393,4 +388,4 @@ export default class SignupController extends React.Component {
</div>
);
}
}
}
42 changes: 18 additions & 24 deletions components/signup/signup_email/signup_email.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {isEmail} from 'mattermost-redux/utils/helpers';
import {trackEvent} from 'actions/diagnostics_actions.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import {getInviteInfo} from 'actions/team_actions.jsx';
import {createUserWithInvite, loadMe, loginById} from 'actions/user_actions.jsx';
import {createUserWithInvite, loginById} from 'actions/user_actions.jsx';

import {browserHistory} from 'utils/browser_history';
import Constants from 'utils/constants.jsx';
Expand All @@ -26,19 +26,17 @@ import SiteNameAndDescription from 'components/common/site_name_and_description'
import FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx';

export default class SignupEmail extends React.Component {
static get propTypes() {
return {
location: PropTypes.object,
enableSignUpWithEmail: PropTypes.bool.isRequired,
siteName: PropTypes.string,
termsOfServiceLink: PropTypes.string,
privacyPolicyLink: PropTypes.string,
customDescriptionText: PropTypes.string,
passwordConfig: PropTypes.object,
actions: PropTypes.shape({
setGlobalItem: PropTypes.func.isRequired,
}).isRequired,
};
static propTypes = {
location: PropTypes.object,
enableSignUpWithEmail: PropTypes.bool.isRequired,
siteName: PropTypes.string,
termsOfServiceLink: PropTypes.string,
privacyPolicyLink: PropTypes.string,
customDescriptionText: PropTypes.string,
passwordConfig: PropTypes.object,
actions: PropTypes.shape({
setGlobalItem: PropTypes.func.isRequired,
}).isRequired,
}

constructor(props) {
Expand Down Expand Up @@ -136,16 +134,12 @@ export default class SignupEmail extends React.Component {
this.props.actions.setGlobalItem(this.state.token, JSON.stringify({usedBefore: true}));
}

loadMe().then(
() => {
const redirectTo = (new URLSearchParams(this.props.location.search)).get('redirect_to');
if (redirectTo) {
browserHistory.push(redirectTo);
} else {
GlobalActions.redirectUserToDefaultTeam();
}
}
);
const redirectTo = (new URLSearchParams(this.props.location.search)).get('redirect_to');
if (redirectTo) {
browserHistory.push(redirectTo);
} else {
GlobalActions.redirectUserToDefaultTeam();
}
},
(err) => {
if (err.id === 'api.user.login.not_verified.app_error') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ exports[`components/mfa/components/Confirm should match snapshot 1`] = `
onSubmit={[Function]}
>
<p>
<FormattedHTMLMessage
defaultMessage="<strong>Set up complete!</strong>"
<InjectIntl(FormattedMarkdownMessage)
defaultMessage="**Set up complete!**"
id="mfa.confirm.complete"
values={Object {}}
/>
</p>
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,59 @@
import React from 'react';
import {shallow} from 'enzyme';

import {loadMe} from 'actions/user_actions.jsx';
import {browserHistory} from 'utils/browser_history';
import {mountWithIntl} from 'tests/helpers/intl-test-helper.jsx';
import Confirm from 'components/mfa/confirm.jsx';
import Confirm from 'components/mfa/confirm';
import Constants from 'utils/constants.jsx';

jest.mock('actions/user_actions.jsx', () => ({
loadMe: jest.fn().mockImplementation(() => Promise.resolve()),
}));

describe('components/mfa/components/Confirm', () => {
const baseProps = {
history: browserHistory,
};

const originalAddEventListener = document.body.addEventListener;
afterAll(() => {
document.body.addEventListener = originalAddEventListener;
});

test('should match snapshot', () => {
const wrapper = shallow(<Confirm history={browserHistory}/>);
const wrapper = shallow(<Confirm {...baseProps}/>);
expect(wrapper).toMatchSnapshot();
});

test('should submit on form submit', () => {
browserHistory.push = jest.fn();
const wrapper = mountWithIntl(<Confirm history={browserHistory}/>);
const props = {
history: {
push: jest.fn(),
},
};

const wrapper = mountWithIntl(<Confirm {...props}/>);
wrapper.find('form').simulate('submit');

return Promise.resolve().then(() => {
expect(loadMe).toBeCalled();
expect(browserHistory.push).toHaveBeenCalledWith('/');
});
expect(props.history.push).toHaveBeenCalledWith('/');
});

test('should submit on enter', () => {
var map = {};
const props = {
history: {
push: jest.fn(),
},
};

const map = {};
document.body.addEventListener = jest.fn().mockImplementation((event, cb) => {
console.log(event);
map[event] = cb;
});

browserHistory.push = jest.fn();
mountWithIntl(<Confirm history={browserHistory}/>);
mountWithIntl(<Confirm {...props}/>);

const event = {
preventDefault: jest.fn(),
key: Constants.KeyCodes.ENTER[0],
};
map.keydown(event);

return Promise.resolve().then(() => {
expect(loadMe).toBeCalled();
expect(browserHistory.push).toHaveBeenCalledWith('/');
});
expect(props.history.push).toHaveBeenCalledWith('/');
});
});
Loading

0 comments on commit 0dfcb81

Please sign in to comment.