MM 60445 - fix preparing workspace wrong redirect (#28332)
* MM-60445 - fix preparing workspace wrong redirect * add unit tests * update unit tests --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -7,6 +7,7 @@ import type {Dispatch} from 'redux';
|
|||||||
|
|
||||||
import {getFirstAdminSetupComplete} from 'mattermost-redux/actions/general';
|
import {getFirstAdminSetupComplete} from 'mattermost-redux/actions/general';
|
||||||
import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
|
import {getActiveTeamsList} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentUserId, isCurrentUserSystemAdmin, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUserId, isCurrentUserSystemAdmin, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import type {GlobalState} from 'types/store';
|
import type {GlobalState} from 'types/store';
|
||||||
@@ -15,6 +16,7 @@ import RootRedirect from './root_redirect';
|
|||||||
|
|
||||||
function mapStateToProps(state: GlobalState) {
|
function mapStateToProps(state: GlobalState) {
|
||||||
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
|
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
|
||||||
|
const teams = getActiveTeamsList(state);
|
||||||
let isElegibleForFirstAdmingOnboarding = onboardingFlowEnabled;
|
let isElegibleForFirstAdmingOnboarding = onboardingFlowEnabled;
|
||||||
if (isElegibleForFirstAdmingOnboarding) {
|
if (isElegibleForFirstAdmingOnboarding) {
|
||||||
isElegibleForFirstAdmingOnboarding = isCurrentUserSystemAdmin(state);
|
isElegibleForFirstAdmingOnboarding = isCurrentUserSystemAdmin(state);
|
||||||
@@ -23,6 +25,7 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
currentUserId: getCurrentUserId(state),
|
currentUserId: getCurrentUserId(state),
|
||||||
isElegibleForFirstAdmingOnboarding,
|
isElegibleForFirstAdmingOnboarding,
|
||||||
isFirstAdmin: isFirstAdmin(state),
|
isFirstAdmin: isFirstAdmin(state),
|
||||||
|
areThereTeams: Boolean(teams.length),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import {createMemoryHistory} from 'history';
|
||||||
|
import React from 'react';
|
||||||
|
import type {RouteComponentProps} from 'react-router-dom';
|
||||||
|
import {Redirect} from 'react-router-dom';
|
||||||
|
|
||||||
|
import {getFirstAdminSetupComplete as getFirstAdminSetupCompleteAction} from 'mattermost-redux/actions/general';
|
||||||
|
|
||||||
|
import * as GlobalActions from 'actions/global_actions';
|
||||||
|
|
||||||
|
import {renderWithContext, waitFor} from 'tests/react_testing_utils';
|
||||||
|
|
||||||
|
import RootRedirect from './root_redirect';
|
||||||
|
import type {Props} from './root_redirect';
|
||||||
|
|
||||||
|
jest.mock('actions/global_actions', () => ({
|
||||||
|
redirectUserToDefaultTeam: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('mattermost-redux/actions/general', () => ({
|
||||||
|
getFirstAdminSetupComplete: jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
data: true,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('react-router-dom', () => {
|
||||||
|
const actual = jest.requireActual('react-router-dom');
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
Redirect: jest.fn(() => null),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('components/RootRedirect', () => {
|
||||||
|
const baseProps: Props = {
|
||||||
|
currentUserId: '',
|
||||||
|
isElegibleForFirstAdmingOnboarding: false,
|
||||||
|
isFirstAdmin: false,
|
||||||
|
areThereTeams: false,
|
||||||
|
actions: {
|
||||||
|
getFirstAdminSetupComplete: getFirstAdminSetupCompleteAction as jest.Mock,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
...baseProps,
|
||||||
|
location: {
|
||||||
|
pathname: '/',
|
||||||
|
},
|
||||||
|
} as Props & RouteComponentProps;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redirect to /login when currentUserId is empty', () => {
|
||||||
|
renderWithContext(<RootRedirect {...defaultProps}/>);
|
||||||
|
|
||||||
|
expect(Redirect).toHaveBeenCalledTimes(1);
|
||||||
|
expect(Redirect).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
to: expect.objectContaining({
|
||||||
|
pathname: '/login',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should call GlobalActions.redirectUserToDefaultTeam when user is logged in and not eligible for first admin onboarding', () => {
|
||||||
|
const props = {
|
||||||
|
...defaultProps,
|
||||||
|
currentUserId: 'test-user-id',
|
||||||
|
isElegibleForFirstAdmingOnboarding: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(<RootRedirect {...props}/>);
|
||||||
|
|
||||||
|
expect(GlobalActions.redirectUserToDefaultTeam).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redirect to preparing-workspace when eligible for first admin onboarding and no teams created', async () => {
|
||||||
|
const history = createMemoryHistory({initialEntries: ['/']});
|
||||||
|
const mockHistoryPush = jest.spyOn(history, 'push');
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
currentUserId: 'test-user-id',
|
||||||
|
isElegibleForFirstAdmingOnboarding: true,
|
||||||
|
isFirstAdmin: true,
|
||||||
|
areThereTeams: false,
|
||||||
|
actions: {
|
||||||
|
getFirstAdminSetupComplete: jest.fn().mockResolvedValue({data: false}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(<RootRedirect {...props}/>, {}, {history});
|
||||||
|
|
||||||
|
expect(props.actions.getFirstAdminSetupComplete).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockHistoryPush).toHaveBeenCalledWith('/preparing-workspace');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should NOT redirect to preparing-workspace when there are teams created, even if system value for first admin onboarding complete is false', async () => {
|
||||||
|
const history = createMemoryHistory({initialEntries: ['/']});
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
...defaultProps,
|
||||||
|
currentUserId: 'test-user-id',
|
||||||
|
isElegibleForFirstAdmingOnboarding: true,
|
||||||
|
isFirstAdmin: true,
|
||||||
|
areThereTeams: true,
|
||||||
|
actions: {
|
||||||
|
getFirstAdminSetupComplete: jest.fn().mockResolvedValue({data: false}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(<RootRedirect {...props}/>, {}, {history});
|
||||||
|
|
||||||
|
expect(props.actions.getFirstAdminSetupComplete).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(GlobalActions.redirectUserToDefaultTeam).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redirect to default team when first admin setup is complete', async () => {
|
||||||
|
const props = {
|
||||||
|
...defaultProps,
|
||||||
|
currentUserId: 'test-user-id',
|
||||||
|
isElegibleForFirstAdmingOnboarding: true,
|
||||||
|
isFirstAdmin: true,
|
||||||
|
areThereTeams: false,
|
||||||
|
actions: {
|
||||||
|
getFirstAdminSetupComplete: jest.fn().mockResolvedValue({data: true}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(<RootRedirect {...props}/>);
|
||||||
|
|
||||||
|
expect(props.actions.getFirstAdminSetupComplete).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(GlobalActions.redirectUserToDefaultTeam).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redirect to default team when not first admin or teams exist', async () => {
|
||||||
|
const props = {
|
||||||
|
...defaultProps,
|
||||||
|
currentUserId: 'test-user-id',
|
||||||
|
isElegibleForFirstAdmingOnboarding: true,
|
||||||
|
isFirstAdmin: false,
|
||||||
|
areThereTeams: true,
|
||||||
|
actions: {
|
||||||
|
getFirstAdminSetupComplete: jest.fn().mockResolvedValue({data: false}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWithContext(<RootRedirect {...props}/>);
|
||||||
|
|
||||||
|
expect(props.actions.getFirstAdminSetupComplete).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(GlobalActions.redirectUserToDefaultTeam).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -13,6 +13,7 @@ export type Props = {
|
|||||||
currentUserId: string;
|
currentUserId: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
isFirstAdmin: boolean;
|
isFirstAdmin: boolean;
|
||||||
|
areThereTeams: boolean;
|
||||||
actions: {
|
actions: {
|
||||||
getFirstAdminSetupComplete: () => Promise<ActionResult>;
|
getFirstAdminSetupComplete: () => Promise<ActionResult>;
|
||||||
};
|
};
|
||||||
@@ -26,7 +27,7 @@ export default function RootRedirect(props: Props) {
|
|||||||
if (props.isElegibleForFirstAdmingOnboarding) {
|
if (props.isElegibleForFirstAdmingOnboarding) {
|
||||||
props.actions.getFirstAdminSetupComplete().then((firstAdminCompletedSignup) => {
|
props.actions.getFirstAdminSetupComplete().then((firstAdminCompletedSignup) => {
|
||||||
// root.tsx ensures admin profiles are eventually loaded
|
// root.tsx ensures admin profiles are eventually loaded
|
||||||
if (firstAdminCompletedSignup.data === false && props.isFirstAdmin) {
|
if (firstAdminCompletedSignup.data === false && props.isFirstAdmin && !props.areThereTeams) {
|
||||||
history.push('/preparing-workspace');
|
history.push('/preparing-workspace');
|
||||||
} else {
|
} else {
|
||||||
GlobalActions.redirectUserToDefaultTeam();
|
GlobalActions.redirectUserToDefaultTeam();
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user