Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/pages/workspace/WorkspaceMembersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers
if (hasApprovers) {
const ownerEmail = ownerDetails.login;
for (const login of selectedEmployees) {
if (!isApprover(policy, login)) {
continue;
}

const accountID = policyMemberEmailsToAccountIDs[login];
const removedApprover = personalDetails?.[accountID];
if (!removedApprover?.login || !ownerEmail) {
Expand All @@ -241,6 +245,7 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers
}

setRemoveMembersConfirmModalVisible(false);

// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
setSelectedEmployees([]);
Expand Down
70 changes: 70 additions & 0 deletions tests/ui/WorkspaceMembersTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import OnyxListItemProvider from '@components/OnyxListItemProvider';
import {CurrentReportIDContextProvider} from '@hooks/useCurrentReportID';
import * as useResponsiveLayoutModule from '@hooks/useResponsiveLayout';
import type ResponsiveLayoutResult from '@hooks/useResponsiveLayout/types';
import {removeApprovalWorkflow} from '@libs/actions/Workflow';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import {updateWorkflowDataOnApproverRemoval} from '@libs/WorkflowUtils';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
import WorkspaceMembersPage from '@pages/workspace/WorkspaceMembersPage';
import CONST from '@src/CONST';
Expand All @@ -24,6 +26,26 @@ jest.unmock('react-native-worklets');

jest.mock('@src/components/ConfirmedRoute.tsx');

jest.mock('@libs/WorkflowUtils', () => {
// eslint-disable-next-line
const actual = jest.requireActual('@libs/WorkflowUtils');
// eslint-disable-next-line
return {
...actual,
updateWorkflowDataOnApproverRemoval: jest.fn(() => [{members: [], approvers: [], isDefault: false, removeApprovalWorkflow: true}]),
};
});

jest.mock('@libs/actions/Workflow', () => {
// eslint-disable-next-line
const actual = jest.requireActual('@libs/actions/Workflow');
// eslint-disable-next-line
return {
...actual,
removeApprovalWorkflow: jest.fn(),
};
});

TestHelper.setupGlobalFetchMock();

const Stack = createPlatformStackNavigator<WorkspaceSplitNavigatorParamList>();
Expand Down Expand Up @@ -66,6 +88,7 @@ describe('WorkspaceMembers', () => {
owner: ownerEmail,
ownerAccountID,
type: CONST.POLICY.TYPE.CORPORATE,
approver: adminEmail,
employeeList: {
[ownerEmail]: {email: ownerEmail, role: CONST.POLICY.ROLE.ADMIN},
[adminEmail]: {email: adminEmail, role: CONST.POLICY.ROLE.ADMIN},
Expand Down Expand Up @@ -296,4 +319,51 @@ describe('WorkspaceMembers', () => {
await waitForBatchedUpdatesWithAct();
});
});

describe('Removing members who are approvers and non-approvers', () => {
it('should call workflow actions once when removing multiple members including an approver', async () => {
const {unmount} = renderPage(SCREENS.WORKSPACE.MEMBERS, {policyID: policy.id});
await waitForBatchedUpdatesWithAct();

await screen.findByText(ADMIN_OPTION);

// Select all
fireEvent.press(screen.getByTestId('selection-list-select-all-checkbox'));

// Open dropdown
fireEvent.press(await screen.findByTestId('WorkspaceMembersPage-header-dropdown-menu-button'));
await waitForBatchedUpdatesWithAct();

// Click "Remove members"
const removeText = TestHelper.translateLocal('workspace.people.removeMembersTitle', {count: 3});
const removeMenuItem = screen.getByText(removeText);
fireEvent.press(removeMenuItem, {
nativeEvent: {},
type: 'press',
target: removeMenuItem,
currentTarget: removeMenuItem,
});

await waitForBatchedUpdatesWithAct();

// Wait until confirm modal confirm button exists
const confirmText = TestHelper.translateLocal('common.remove');

await waitFor(() => {
expect(screen.getByLabelText(confirmText)).toBeOnTheScreen();
});

// Press confirm button
fireEvent.press(screen.getByLabelText(confirmText));

await waitForBatchedUpdatesWithAct();

// Verify workflow actions are only called once when an approver is removed
expect(updateWorkflowDataOnApproverRemoval).toHaveBeenCalledTimes(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment // Verify workflow actions are only called once when an approver is removed

expect(removeApprovalWorkflow).toHaveBeenCalledTimes(1);

unmount();
await waitForBatchedUpdatesWithAct();
});
});
});
Loading