Skip to content

Commit

Permalink
MM 60445 - fix preparing workspace wrong redirect (mattermost#28332)
Browse files Browse the repository at this point in the history
* MM-60445 - fix preparing workspace wrong redirect

* add unit tests

* update unit tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
  • Loading branch information
pvev and mattermost-build authored Oct 4, 2024
1 parent 295ae8b commit 0f6f47d
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 1 deletion.
3 changes: 3 additions & 0 deletions webapp/channels/src/components/root/root_redirect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {Dispatch} from 'redux';

import {getFirstAdminSetupComplete} from 'mattermost-redux/actions/general';
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 type {GlobalState} from 'types/store';
Expand All @@ -15,6 +16,7 @@ import RootRedirect from './root_redirect';

function mapStateToProps(state: GlobalState) {
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
const teams = getActiveTeamsList(state);
let isElegibleForFirstAdmingOnboarding = onboardingFlowEnabled;
if (isElegibleForFirstAdmingOnboarding) {
isElegibleForFirstAdmingOnboarding = isCurrentUserSystemAdmin(state);
Expand All @@ -23,6 +25,7 @@ function mapStateToProps(state: GlobalState) {
currentUserId: getCurrentUserId(state),
isElegibleForFirstAdmingOnboarding,
isFirstAdmin: isFirstAdmin(state),
areThereTeams: Boolean(teams.length),
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type Props = {
currentUserId: string;
location?: Location;
isFirstAdmin: boolean;
areThereTeams: boolean;
actions: {
getFirstAdminSetupComplete: () => Promise<ActionResult>;
};
Expand All @@ -26,7 +27,7 @@ export default function RootRedirect(props: Props) {
if (props.isElegibleForFirstAdmingOnboarding) {
props.actions.getFirstAdminSetupComplete().then((firstAdminCompletedSignup) => {
// 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');
} else {
GlobalActions.redirectUserToDefaultTeam();
Expand Down

0 comments on commit 0f6f47d

Please sign in to comment.