From feff0a1c83d2406f11c6b64af130d5496cf61cb6 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 15 Feb 2025 16:40:53 +0800 Subject: [PATCH 1/6] optimistically add and remove members from admins room --- src/libs/actions/Policy/Member.ts | 131 ++++---- tests/actions/PolicyMemberTest.ts | 477 ++++++++++++++++++------------ 2 files changed, 376 insertions(+), 232 deletions(-) diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index 834812013b5c..541a5b430df6 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -33,7 +33,7 @@ import type {OnyxData} from '@src/types/onyx/Request'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {createPolicyExpenseChats} from './Policy'; -type AnnounceRoomMembersOnyxData = { +type RoomMembersOnyxData = { onyxOptimisticData: OnyxUpdate[]; onyxSuccessData: OnyxUpdate[]; onyxFailureData: OnyxUpdate[]; @@ -133,43 +133,47 @@ function getPolicy(policyID: string | undefined): OnyxEntry { /** * Build optimistic data for adding members to the announcement room */ -function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[]): AnnounceRoomMembersOnyxData { - const announceReport = ReportUtils.getRoom(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID); - const announceReportMetadata = ReportUtils.getReportMetadata(announceReport?.reportID); - const announceRoomMembers: AnnounceRoomMembersOnyxData = { +function buildRoomMembersOnyxData( + roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + policyID: string, + accountIDs: number[], +): RoomMembersOnyxData { + const report = ReportUtils.getRoom(roomType, policyID); + const reportMetadata = ReportUtils.getReportMetadata(report?.reportID); + const roomMembers: RoomMembersOnyxData = { onyxOptimisticData: [], onyxFailureData: [], onyxSuccessData: [], }; - if (!announceReport) { - return announceRoomMembers; + if (!report || accountIDs.length === 0) { + return roomMembers; } - const participantAccountIDs = [...Object.keys(announceReport.participants ?? {}).map(Number), ...accountIDs]; - const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, announceReportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); + const participantAccountIDs = [...Object.keys(report.participants ?? {}).map(Number), ...accountIDs]; + const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, reportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); - announceRoomMembers.onyxOptimisticData.push( + roomMembers.onyxOptimisticData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${report?.reportID}`, value: { participants: ReportUtils.buildParticipantsFromAccountIDs(participantAccountIDs), }, }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`, value: { pendingChatMembers, }, }, ); - announceRoomMembers.onyxFailureData.push( + roomMembers.onyxFailureData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${report?.reportID}`, value: { participants: accountIDs.reduce((acc, curr) => { Object.assign(acc, {[curr]: null}); @@ -179,20 +183,20 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[] }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`, value: { - pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null, + pendingChatMembers: reportMetadata?.pendingChatMembers ?? null, }, }, ); - announceRoomMembers.onyxSuccessData.push({ + roomMembers.onyxSuccessData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`, value: { - pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null, + pendingChatMembers: reportMetadata?.pendingChatMembers ?? null, }, }); - return announceRoomMembers; + return roomMembers; } /** * Updates the import spreadsheet data according to the result of the import @@ -231,30 +235,35 @@ function updateImportSpreadsheetData(membersLength: number): OnyxData { /** * Build optimistic data for removing users from the announcement room */ -function removeOptimisticAnnounceRoomMembers(policyID: string | undefined, policyName: string, accountIDs: number[]): AnnounceRoomMembersOnyxData { - const announceRoomMembers: AnnounceRoomMembersOnyxData = { +function removeOptimisticRoomMembers( + roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + policyID: string | undefined, + policyName: string, + accountIDs: number[], +): RoomMembersOnyxData { + const roomMembers: RoomMembersOnyxData = { onyxOptimisticData: [], onyxFailureData: [], onyxSuccessData: [], }; if (!policyID) { - return announceRoomMembers; + return roomMembers; } - const announceReport = ReportUtils.getRoom(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID); - const announceReportMetadata = ReportUtils.getReportMetadata(announceReport?.reportID); + const report = ReportUtils.getRoom(roomType, policyID); + const reportMetadata = ReportUtils.getReportMetadata(report?.reportID); - if (!announceReport) { - return announceRoomMembers; + if (!report) { + return roomMembers; } - const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, announceReportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); + const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, reportMetadata?.pendingChatMembers ?? [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); - announceRoomMembers.onyxOptimisticData.push( + roomMembers.onyxOptimisticData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, value: { ...(accountIDs.includes(sessionAccountID) ? { @@ -267,43 +276,43 @@ function removeOptimisticAnnounceRoomMembers(policyID: string | undefined, polic }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`, value: { pendingChatMembers, }, }, ); - announceRoomMembers.onyxFailureData.push( + roomMembers.onyxFailureData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, value: { ...(accountIDs.includes(sessionAccountID) ? { - statusNum: announceReport.statusNum, - stateNum: announceReport.stateNum, - oldPolicyName: announceReport.oldPolicyName, + statusNum: report.statusNum, + stateNum: report.stateNum, + oldPolicyName: report.oldPolicyName, } : {}), }, }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`, value: { - pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null, + pendingChatMembers: reportMetadata?.pendingChatMembers ?? null, }, }, ); - announceRoomMembers.onyxSuccessData.push({ + roomMembers.onyxSuccessData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${announceReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`, value: { - pendingChatMembers: announceReportMetadata?.pendingChatMembers ?? null, + pendingChatMembers: reportMetadata?.pendingChatMembers ?? null, }, }); - return announceRoomMembers; + return roomMembers; } /** @@ -326,7 +335,16 @@ function removeMembers(accountIDs: number[], policyID: string) { ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy?.name ?? '', CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY), ); - const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy?.id, policy?.name ?? '', accountIDs); + const announceRoomMembers = removeOptimisticRoomMembers(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policy?.id, policy?.name ?? '', accountIDs); + const adminRoomMembers = removeOptimisticRoomMembers( + CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + policy?.id, + policy?.name ?? '', + accountIDs.filter((accountID) => { + const login = allPersonalDetails?.[accountID]?.login; + return login && policy?.employeeList?.[login]?.role !== CONST.POLICY.ROLE.USER; + }), + ); const optimisticMembersState: OnyxCollectionInputValue = {}; const successMembersState: OnyxCollectionInputValue = {}; @@ -390,7 +408,7 @@ function removeMembers(accountIDs: number[], policyID: string) { }, }, ]; - optimisticData.push(...announceRoomMembers.onyxOptimisticData); + optimisticData.push(...announceRoomMembers.onyxOptimisticData, ...adminRoomMembers.onyxOptimisticData); const successData: OnyxUpdate[] = [ { @@ -399,7 +417,7 @@ function removeMembers(accountIDs: number[], policyID: string) { value: {employeeList: successMembersState}, }, ]; - successData.push(...announceRoomMembers.onyxSuccessData); + successData.push(...announceRoomMembers.onyxSuccessData, ...adminRoomMembers.onyxSuccessData); const failureData: OnyxUpdate[] = [ { @@ -408,7 +426,7 @@ function removeMembers(accountIDs: number[], policyID: string) { value: {employeeList: failureMembersState, approver: policy?.approver, rules: policy?.rules}, }, ]; - failureData.push(...announceRoomMembers.onyxFailureData); + failureData.push(...announceRoomMembers.onyxFailureData, ...adminRoomMembers.onyxFailureData); const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); @@ -675,7 +693,8 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount const {newAccountIDs, newLogins} = PersonalDetailsUtils.getNewAccountIDsAndLogins(logins, accountIDs); const newPersonalDetailsOnyxData = PersonalDetailsUtils.getPersonalDetailsOnyxDataForOptimisticUsers(newLogins, newAccountIDs); - const announceRoomMembers = buildAnnounceRoomMembersOnyxData(policyID, accountIDs); + const announceRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, accountIDs); + const adminRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID, role !== CONST.POLICY.ROLE.USER ? accountIDs : []); const optimisticAnnounceChat = ReportUtils.buildOptimisticAnnounceChat(policyID, [...policyMemberAccountIDs, ...accountIDs]); const announceRoomChat = optimisticAnnounceChat.announceChatData; @@ -709,7 +728,13 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount }, }, ]; - optimisticData.push(...newPersonalDetailsOnyxData.optimisticData, ...membersChats.onyxOptimisticData, ...announceRoomChat.onyxOptimisticData, ...announceRoomMembers.onyxOptimisticData); + optimisticData.push( + ...newPersonalDetailsOnyxData.optimisticData, + ...membersChats.onyxOptimisticData, + ...announceRoomChat.onyxOptimisticData, + ...announceRoomMembers.onyxOptimisticData, + ...adminRoomMembers.onyxOptimisticData, + ); const successData: OnyxUpdate[] = [ { @@ -720,7 +745,13 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount }, }, ]; - successData.push(...newPersonalDetailsOnyxData.finallyData, ...membersChats.onyxSuccessData, ...announceRoomChat.onyxSuccessData, ...announceRoomMembers.onyxSuccessData); + successData.push( + ...newPersonalDetailsOnyxData.finallyData, + ...membersChats.onyxSuccessData, + ...announceRoomChat.onyxSuccessData, + ...announceRoomMembers.onyxSuccessData, + ...adminRoomMembers.onyxSuccessData, + ); const failureData: OnyxUpdate[] = [ { @@ -734,7 +765,7 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount }, }, ]; - failureData.push(...membersChats.onyxFailureData, ...announceRoomChat.onyxFailureData, ...announceRoomMembers.onyxFailureData); + failureData.push(...membersChats.onyxFailureData, ...announceRoomChat.onyxFailureData, ...announceRoomMembers.onyxFailureData, ...adminRoomMembers.onyxFailureData); const params: AddMembersToWorkspaceParams = { employees: JSON.stringify(logins.map((login) => ({email: login, role}))), diff --git a/tests/actions/PolicyMemberTest.ts b/tests/actions/PolicyMemberTest.ts index 41d9a72f1e5f..2c00424140a9 100644 --- a/tests/actions/PolicyMemberTest.ts +++ b/tests/actions/PolicyMemberTest.ts @@ -1,11 +1,12 @@ import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager'; import * as Member from '@src/libs/actions/Policy/Member'; import * as Policy from '@src/libs/actions/Policy/Policy'; import * as ReportActionsUtils from '@src/libs/ReportActionsUtils'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy as PolicyType, Report, ReportAction} from '@src/types/onyx'; +import type {Policy as PolicyType, Report, ReportAction, ReportMetadata} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import createPersonalDetails from '../utils/collections/personalDetails'; import createRandomPolicy from '../utils/collections/policies'; @@ -30,237 +31,349 @@ describe('actions/PolicyMember', () => { return Onyx.clear().then(waitForBatchedUpdates); }); - describe('acceptJoinRequest', () => { - it('Accept user join request to a workspace', async () => { - const fakePolicy = createRandomPolicy(0); - const fakeReport: Report = { - ...createRandomReport(0), - policyID: fakePolicy.id, - }; - const fakeReportAction = { - ...createRandomReportAction(0), - actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST, - } as ReportAction; + // describe('acceptJoinRequest', () => { + // it('Accept user join request to a workspace', async () => { + // const fakePolicy = createRandomPolicy(0); + // const fakeReport: Report = { + // ...createRandomReport(0), + // policyID: fakePolicy.id, + // }; + // const fakeReportAction = { + // ...createRandomReportAction(0), + // actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST, + // } as ReportAction; - mockFetch?.pause?.(); - Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeReport.reportID}`, fakeReport); - Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, { - [fakeReportAction.reportActionID]: fakeReportAction, - }); - Member.acceptJoinRequest(fakeReport.reportID, fakeReportAction); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, - waitForCollectionCallback: false, - callback: (reportActions) => { - Onyx.disconnect(connection); + // mockFetch?.pause?.(); + // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + // Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeReport.reportID}`, fakeReport); + // Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, { + // [fakeReportAction.reportActionID]: fakeReportAction, + // }); + // Member.acceptJoinRequest(fakeReport.reportID, fakeReportAction); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, + // waitForCollectionCallback: false, + // callback: (reportActions) => { + // Onyx.disconnect(connection); - const reportAction = reportActions?.[fakeReportAction.reportActionID] as ReportAction; + // const reportAction = reportActions?.[fakeReportAction.reportActionID] as ReportAction; - if (!isEmptyObject(reportAction)) { - expect(ReportActionsUtils.getOriginalMessage(reportAction)?.choice)?.toBe(CONST.REPORT.ACTIONABLE_MENTION_JOIN_WORKSPACE_RESOLUTION.ACCEPT); - expect(reportAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); - } - resolve(); - }, - }); - }); - await mockFetch?.resume?.(); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, - waitForCollectionCallback: false, - callback: (reportActions) => { - Onyx.disconnect(connection); + // if (!isEmptyObject(reportAction)) { + // expect(ReportActionsUtils.getOriginalMessage(reportAction)?.choice)?.toBe(CONST.REPORT.ACTIONABLE_MENTION_JOIN_WORKSPACE_RESOLUTION.ACCEPT); + // expect(reportAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + // } + // resolve(); + // }, + // }); + // }); + // await mockFetch?.resume?.(); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, + // waitForCollectionCallback: false, + // callback: (reportActions) => { + // Onyx.disconnect(connection); - const reportAction = reportActions?.[fakeReportAction.reportActionID]; + // const reportAction = reportActions?.[fakeReportAction.reportActionID]; - if (!isEmptyObject(reportAction)) { - expect(reportAction?.pendingAction).toBeFalsy(); - } - resolve(); - }, - }); - }); - }); - }); - describe('updateWorkspaceMembersRole', () => { - it('Update member to admin role', async () => { - const fakeUser2 = createPersonalDetails(2); - const fakePolicy: PolicyType = { - ...createRandomPolicy(0), - employeeList: { - [fakeUser2.login ?? '']: { - email: fakeUser2.login, - role: CONST.POLICY.ROLE.USER, - }, - }, - }; + // if (!isEmptyObject(reportAction)) { + // expect(reportAction?.pendingAction).toBeFalsy(); + // } + // resolve(); + // }, + // }); + // }); + // }); + // }); + // describe('updateWorkspaceMembersRole', () => { + // it('Update member to admin role', async () => { + // const fakeUser2 = createPersonalDetails(2); + // const fakePolicy: PolicyType = { + // ...createRandomPolicy(0), + // employeeList: { + // [fakeUser2.login ?? '']: { + // email: fakeUser2.login, + // role: CONST.POLICY.ROLE.USER, + // }, + // }, + // }; - mockFetch?.pause?.(); - Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - Onyx.set(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, {[fakeUser2.accountID]: fakeUser2}); - await waitForBatchedUpdates(); - Member.updateWorkspaceMembersRole(fakePolicy.id, [fakeUser2.accountID], CONST.POLICY.ROLE.ADMIN); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - waitForCollectionCallback: false, - callback: (policy) => { - Onyx.disconnect(connection); - const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; - expect(employee?.role).toBe(CONST.POLICY.ROLE.ADMIN); + // mockFetch?.pause?.(); + // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + // Onyx.set(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, {[fakeUser2.accountID]: fakeUser2}); + // await waitForBatchedUpdates(); + // Member.updateWorkspaceMembersRole(fakePolicy.id, [fakeUser2.accountID], CONST.POLICY.ROLE.ADMIN); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; + // expect(employee?.role).toBe(CONST.POLICY.ROLE.ADMIN); - resolve(); - }, - }); - }); - await mockFetch?.resume?.(); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - waitForCollectionCallback: false, - callback: (policy) => { - Onyx.disconnect(connection); - const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; - expect(employee?.pendingAction).toBeFalsy(); - resolve(); - }, - }); + // resolve(); + // }, + // }); + // }); + // await mockFetch?.resume?.(); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; + // expect(employee?.pendingAction).toBeFalsy(); + // resolve(); + // }, + // }); + // }); + // }); + // }); + // describe('requestWorkspaceOwnerChange', () => { + // it('Change the workspace`s owner', async () => { + // const fakePolicy: PolicyType = createRandomPolicy(0); + // const fakeEmail = 'fake@gmail.com'; + // const fakeAccountID = 1; + + // mockFetch?.pause?.(); + // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + // Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); + // Member.requestWorkspaceOwnerChange(fakePolicy.id); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // expect(policy?.errorFields).toBeFalsy(); + // expect(policy?.isLoading).toBeTruthy(); + // expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); + // expect(policy?.isChangeOwnerFailed).toBeFalsy(); + // resolve(); + // }, + // }); + // }); + // await mockFetch?.resume?.(); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // expect(policy?.isLoading).toBeFalsy(); + // expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); + // expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); + // resolve(); + // }, + // }); + // }); + // }); + // }); + // describe('addBillingCardAndRequestPolicyOwnerChange', () => { + // it('Add billing card and change the workspace`s owner', async () => { + // const fakePolicy: PolicyType = createRandomPolicy(0); + // const fakeEmail = 'fake@gmail.com'; + // const fakeCard = { + // cardNumber: '1234567890123456', + // cardYear: '2023', + // cardMonth: '05', + // cardCVV: '123', + // addressName: 'John Doe', + // addressZip: '12345', + // currency: 'USD', + // }; + // const fakeAccountID = 1; + + // mockFetch?.pause?.(); + // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + // Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); + // Policy.addBillingCardAndRequestPolicyOwnerChange(fakePolicy.id, fakeCard); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // expect(policy?.errorFields).toBeFalsy(); + // expect(policy?.isLoading).toBeTruthy(); + // expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); + // expect(policy?.isChangeOwnerFailed).toBeFalsy(); + // resolve(); + // }, + // }); + // }); + // await mockFetch?.resume?.(); + // await waitForBatchedUpdates(); + // await new Promise((resolve) => { + // const connection = Onyx.connect({ + // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + // waitForCollectionCallback: false, + // callback: (policy) => { + // Onyx.disconnect(connection); + // expect(policy?.isLoading).toBeFalsy(); + // expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); + // expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); + // resolve(); + // }, + // }); + // }); + // }); + // }); + + describe('addMembersToWorkspace', () => { + it('Add a new member to a workspace', async () => { + const policyID = '1'; + const defaultApprover = 'approver@gmail.com'; + const newUserEmail = 'user@gmail.com'; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + ...createRandomPolicy(Number(policyID)), + approver: defaultApprover, }); - }); - }); - describe('requestWorkspaceOwnerChange', () => { - it('Change the workspace`s owner', async () => { - const fakePolicy: PolicyType = createRandomPolicy(0); - const fakeEmail = 'fake@gmail.com'; - const fakeAccountID = 1; mockFetch?.pause?.(); - Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); - Member.requestWorkspaceOwnerChange(fakePolicy.id); + Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policyID, [], CONST.POLICY.ROLE.USER); + await waitForBatchedUpdates(); + await new Promise((resolve) => { const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, waitForCollectionCallback: false, callback: (policy) => { Onyx.disconnect(connection); - expect(policy?.errorFields).toBeFalsy(); - expect(policy?.isLoading).toBeTruthy(); - expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); - expect(policy?.isChangeOwnerFailed).toBeFalsy(); + const newEmployee = policy?.employeeList?.[newUserEmail]; + expect(newEmployee).not.toBeUndefined(); + expect(newEmployee?.email).toBe(newUserEmail); + expect(newEmployee?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); + expect(newEmployee?.role).toBe(CONST.POLICY.ROLE.USER); + expect(newEmployee?.submitsTo).toBe(defaultApprover); resolve(); }, }); }); await mockFetch?.resume?.(); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - waitForCollectionCallback: false, - callback: (policy) => { - Onyx.disconnect(connection); - expect(policy?.isLoading).toBeFalsy(); - expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); - expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); - resolve(); - }, - }); - }); }); - }); - describe('addBillingCardAndRequestPolicyOwnerChange', () => { - it('Add billing card and change the workspace`s owner', async () => { - const fakePolicy: PolicyType = createRandomPolicy(0); - const fakeEmail = 'fake@gmail.com'; - const fakeCard = { - cardNumber: '1234567890123456', - cardYear: '2023', - cardMonth: '05', - cardCVV: '123', - addressName: 'John Doe', - addressZip: '12345', - currency: 'USD', - }; - const fakeAccountID = 1; - mockFetch?.pause?.(); - Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); - Policy.addBillingCardAndRequestPolicyOwnerChange(fakePolicy.id, fakeCard); - await waitForBatchedUpdates(); - await new Promise((resolve) => { - const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - waitForCollectionCallback: false, - callback: (policy) => { - Onyx.disconnect(connection); - expect(policy?.errorFields).toBeFalsy(); - expect(policy?.isLoading).toBeTruthy(); - expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); - expect(policy?.isChangeOwnerFailed).toBeFalsy(); - resolve(); - }, - }); + it('Add new members with admin/auditor role to the #admins room', async () => { + // Given a policy and an #admins room + const policyID = '1'; + const adminRoomID = '1'; + const defaultApprover = 'approver@gmail.com'; + const adminAccountID = 1234; + const adminEmail = 'admin@example.com'; + const auditorAccountID = 1235; + const auditorEmail = 'auditor@example.com'; + const userAccountID = 1236; + const userEmail = 'user@example.com'; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + ...createRandomPolicy(Number(policyID)), + approver: defaultApprover, }); - await mockFetch?.resume?.(); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${adminRoomID}`, { + ...createRandomReport(Number(adminRoomID)), + policyID, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + participants: { + 1: {notificationPreference: 'always'}, + }, + }); + + // When adding a new admin, auditor, and user members + Member.addMembersToWorkspace({[adminEmail]: adminAccountID}, 'Welcome', policyID, [], CONST.POLICY.ROLE.ADMIN); + Member.addMembersToWorkspace({[auditorEmail]: auditorAccountID}, 'Welcome', policyID, [], CONST.POLICY.ROLE.AUDITOR); + Member.addMembersToWorkspace({[userEmail]: userAccountID}, 'Welcome', policyID, [], CONST.POLICY.ROLE.USER); + await waitForBatchedUpdates(); - await new Promise((resolve) => { + + // Then only the admin and auditor should be added to the #admins room + const adminRoom = await new Promise>((resolve) => { const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - waitForCollectionCallback: false, - callback: (policy) => { + key: `${ONYXKEYS.COLLECTION.REPORT}${adminRoomID}`, + callback: (report) => { Onyx.disconnect(connection); - expect(policy?.isLoading).toBeFalsy(); - expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); - expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); - resolve(); + resolve(report); }, }); }); + expect(adminRoom?.participants?.[adminAccountID]).toBeTruthy(); + expect(adminRoom?.participants?.[auditorAccountID]).toBeTruthy(); + expect(adminRoom?.participants?.[userAccountID]).toBeUndefined(); }); }); - describe('addMembersToWorkspace', () => { - it('Add a new member to a workspace', async () => { + describe('removeMembers', () => { + it('Remove members with admin/auditor role from the #admins room', async () => { + // Given a policy and an #admins room const policyID = '1'; + const adminRoomID = '1'; const defaultApprover = 'approver@gmail.com'; - const newUserEmail = 'user@gmail.com'; + const adminAccountID = 1234; + const adminEmail = 'admin@example.com'; + const auditorAccountID = 1235; + const auditorEmail = 'auditor@example.com'; + const userAccountID = 1236; + const userEmail = 'user@example.com'; + await Onyx.set(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, { + [adminAccountID]: {login: adminEmail}, + [auditorAccountID]: {login: auditorEmail}, + [userAccountID]: {login: userEmail}, + }); await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { ...createRandomPolicy(Number(policyID)), approver: defaultApprover, + employeeList: { + 'owner@gmail.com': {role: CONST.POLICY.ROLE.ADMIN}, + [adminEmail]: {role: CONST.POLICY.ROLE.ADMIN}, + [auditorEmail]: {role: CONST.POLICY.ROLE.AUDITOR}, + [userEmail]: {role: CONST.POLICY.ROLE.USER}, + }, + }); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${adminRoomID}`, { + ...createRandomReport(Number(adminRoomID)), + policyID, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + participants: { + 1: {notificationPreference: 'always'}, + [adminAccountID]: {notificationPreference: 'always'}, + [auditorAccountID]: {notificationPreference: 'always'}, + [userAccountID]: {notificationPreference: 'always'}, + }, }); + // When removing am admin, auditor, and user members mockFetch?.pause?.(); - Member.addMembersToWorkspace({[newUserEmail]: 1234}, 'Welcome', policyID, [], CONST.POLICY.ROLE.USER); + Member.removeMembers([adminAccountID, auditorAccountID, userAccountID], policyID); await waitForBatchedUpdates(); - await new Promise((resolve) => { + // Then only the admin and auditor should be pending removed from the #admins room + const adminRoomMetadata = await new Promise>((resolve) => { const connection = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - waitForCollectionCallback: false, - callback: (policy) => { + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${adminRoomID}`, + callback: (reportMetadata) => { Onyx.disconnect(connection); - const newEmployee = policy?.employeeList?.[newUserEmail]; - expect(newEmployee).not.toBeUndefined(); - expect(newEmployee?.email).toBe(newUserEmail); - expect(newEmployee?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); - expect(newEmployee?.role).toBe(CONST.POLICY.ROLE.USER); - expect(newEmployee?.submitsTo).toBe(defaultApprover); - resolve(); + resolve(reportMetadata); }, }); }); + expect(adminRoomMetadata?.pendingChatMembers?.length).toBe(2); + expect(adminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(adminAccountID))?.pendingAction).toBe( + CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + ); + expect(adminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(auditorAccountID))).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); await mockFetch?.resume?.(); }); }); From 906fc7cd978e37ec4baee81ef10e2143b6ebd21b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 15 Feb 2025 16:57:55 +0800 Subject: [PATCH 2/6] update test --- tests/actions/PolicyMemberTest.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/actions/PolicyMemberTest.ts b/tests/actions/PolicyMemberTest.ts index 2c00424140a9..aa75e2c12369 100644 --- a/tests/actions/PolicyMemberTest.ts +++ b/tests/actions/PolicyMemberTest.ts @@ -359,8 +359,8 @@ describe('actions/PolicyMember', () => { await waitForBatchedUpdates(); - // Then only the admin and auditor should be pending removed from the #admins room - const adminRoomMetadata = await new Promise>((resolve) => { + // Then only the admin and auditor should be removed from the #admins room + const optimisticAdminRoomMetadata = await new Promise>((resolve) => { const connection = Onyx.connect({ key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${adminRoomID}`, callback: (reportMetadata) => { @@ -369,12 +369,25 @@ describe('actions/PolicyMember', () => { }, }); }); - expect(adminRoomMetadata?.pendingChatMembers?.length).toBe(2); - expect(adminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(adminAccountID))?.pendingAction).toBe( + expect(optimisticAdminRoomMetadata?.pendingChatMembers?.length).toBe(2); + expect(optimisticAdminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(adminAccountID))?.pendingAction).toBe( + CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + ); + expect(optimisticAdminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(auditorAccountID))?.pendingAction).toBe( CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, ); - expect(adminRoomMetadata?.pendingChatMembers?.find((pendingMember) => pendingMember.accountID === String(auditorAccountID))).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); await mockFetch?.resume?.(); + + const successAdminRoomMetadata = await new Promise>((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${adminRoomID}`, + callback: (reportMetadata) => { + Onyx.disconnect(connection); + resolve(reportMetadata); + }, + }); + }); + expect(successAdminRoomMetadata?.pendingChatMembers).toBeUndefined(); }); }); }); From de3d1fc199c2ec5900fa0b0428d0324546df07de Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 15 Feb 2025 17:01:44 +0800 Subject: [PATCH 3/6] uncomment test --- tests/actions/PolicyMemberTest.ts | 378 +++++++++++++++--------------- 1 file changed, 189 insertions(+), 189 deletions(-) diff --git a/tests/actions/PolicyMemberTest.ts b/tests/actions/PolicyMemberTest.ts index aa75e2c12369..13bbc7abda68 100644 --- a/tests/actions/PolicyMemberTest.ts +++ b/tests/actions/PolicyMemberTest.ts @@ -31,204 +31,204 @@ describe('actions/PolicyMember', () => { return Onyx.clear().then(waitForBatchedUpdates); }); - // describe('acceptJoinRequest', () => { - // it('Accept user join request to a workspace', async () => { - // const fakePolicy = createRandomPolicy(0); - // const fakeReport: Report = { - // ...createRandomReport(0), - // policyID: fakePolicy.id, - // }; - // const fakeReportAction = { - // ...createRandomReportAction(0), - // actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST, - // } as ReportAction; + describe('acceptJoinRequest', () => { + it('Accept user join request to a workspace', async () => { + const fakePolicy = createRandomPolicy(0); + const fakeReport: Report = { + ...createRandomReport(0), + policyID: fakePolicy.id, + }; + const fakeReportAction = { + ...createRandomReportAction(0), + actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST, + } as ReportAction; - // mockFetch?.pause?.(); - // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - // Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeReport.reportID}`, fakeReport); - // Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, { - // [fakeReportAction.reportActionID]: fakeReportAction, - // }); - // Member.acceptJoinRequest(fakeReport.reportID, fakeReportAction); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, - // waitForCollectionCallback: false, - // callback: (reportActions) => { - // Onyx.disconnect(connection); + mockFetch?.pause?.(); + Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeReport.reportID}`, fakeReport); + Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, { + [fakeReportAction.reportActionID]: fakeReportAction, + }); + Member.acceptJoinRequest(fakeReport.reportID, fakeReportAction); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, + waitForCollectionCallback: false, + callback: (reportActions) => { + Onyx.disconnect(connection); - // const reportAction = reportActions?.[fakeReportAction.reportActionID] as ReportAction; + const reportAction = reportActions?.[fakeReportAction.reportActionID] as ReportAction; - // if (!isEmptyObject(reportAction)) { - // expect(ReportActionsUtils.getOriginalMessage(reportAction)?.choice)?.toBe(CONST.REPORT.ACTIONABLE_MENTION_JOIN_WORKSPACE_RESOLUTION.ACCEPT); - // expect(reportAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); - // } - // resolve(); - // }, - // }); - // }); - // await mockFetch?.resume?.(); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, - // waitForCollectionCallback: false, - // callback: (reportActions) => { - // Onyx.disconnect(connection); + if (!isEmptyObject(reportAction)) { + expect(ReportActionsUtils.getOriginalMessage(reportAction)?.choice)?.toBe(CONST.REPORT.ACTIONABLE_MENTION_JOIN_WORKSPACE_RESOLUTION.ACCEPT); + expect(reportAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + } + resolve(); + }, + }); + }); + await mockFetch?.resume?.(); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${fakeReport.reportID}`, + waitForCollectionCallback: false, + callback: (reportActions) => { + Onyx.disconnect(connection); - // const reportAction = reportActions?.[fakeReportAction.reportActionID]; + const reportAction = reportActions?.[fakeReportAction.reportActionID]; - // if (!isEmptyObject(reportAction)) { - // expect(reportAction?.pendingAction).toBeFalsy(); - // } - // resolve(); - // }, - // }); - // }); - // }); - // }); - // describe('updateWorkspaceMembersRole', () => { - // it('Update member to admin role', async () => { - // const fakeUser2 = createPersonalDetails(2); - // const fakePolicy: PolicyType = { - // ...createRandomPolicy(0), - // employeeList: { - // [fakeUser2.login ?? '']: { - // email: fakeUser2.login, - // role: CONST.POLICY.ROLE.USER, - // }, - // }, - // }; + if (!isEmptyObject(reportAction)) { + expect(reportAction?.pendingAction).toBeFalsy(); + } + resolve(); + }, + }); + }); + }); + }); + describe('updateWorkspaceMembersRole', () => { + it('Update member to admin role', async () => { + const fakeUser2 = createPersonalDetails(2); + const fakePolicy: PolicyType = { + ...createRandomPolicy(0), + employeeList: { + [fakeUser2.login ?? '']: { + email: fakeUser2.login, + role: CONST.POLICY.ROLE.USER, + }, + }, + }; - // mockFetch?.pause?.(); - // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - // Onyx.set(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, {[fakeUser2.accountID]: fakeUser2}); - // await waitForBatchedUpdates(); - // Member.updateWorkspaceMembersRole(fakePolicy.id, [fakeUser2.accountID], CONST.POLICY.ROLE.ADMIN); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; - // expect(employee?.role).toBe(CONST.POLICY.ROLE.ADMIN); + mockFetch?.pause?.(); + Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + Onyx.set(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`, {[fakeUser2.accountID]: fakeUser2}); + await waitForBatchedUpdates(); + Member.updateWorkspaceMembersRole(fakePolicy.id, [fakeUser2.accountID], CONST.POLICY.ROLE.ADMIN); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; + expect(employee?.role).toBe(CONST.POLICY.ROLE.ADMIN); - // resolve(); - // }, - // }); - // }); - // await mockFetch?.resume?.(); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; - // expect(employee?.pendingAction).toBeFalsy(); - // resolve(); - // }, - // }); - // }); - // }); - // }); - // describe('requestWorkspaceOwnerChange', () => { - // it('Change the workspace`s owner', async () => { - // const fakePolicy: PolicyType = createRandomPolicy(0); - // const fakeEmail = 'fake@gmail.com'; - // const fakeAccountID = 1; + resolve(); + }, + }); + }); + await mockFetch?.resume?.(); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + const employee = policy?.employeeList?.[fakeUser2?.login ?? '']; + expect(employee?.pendingAction).toBeFalsy(); + resolve(); + }, + }); + }); + }); + }); + describe('requestWorkspaceOwnerChange', () => { + it('Change the workspace`s owner', async () => { + const fakePolicy: PolicyType = createRandomPolicy(0); + const fakeEmail = 'fake@gmail.com'; + const fakeAccountID = 1; - // mockFetch?.pause?.(); - // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - // Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); - // Member.requestWorkspaceOwnerChange(fakePolicy.id); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // expect(policy?.errorFields).toBeFalsy(); - // expect(policy?.isLoading).toBeTruthy(); - // expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); - // expect(policy?.isChangeOwnerFailed).toBeFalsy(); - // resolve(); - // }, - // }); - // }); - // await mockFetch?.resume?.(); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // expect(policy?.isLoading).toBeFalsy(); - // expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); - // expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); - // resolve(); - // }, - // }); - // }); - // }); - // }); - // describe('addBillingCardAndRequestPolicyOwnerChange', () => { - // it('Add billing card and change the workspace`s owner', async () => { - // const fakePolicy: PolicyType = createRandomPolicy(0); - // const fakeEmail = 'fake@gmail.com'; - // const fakeCard = { - // cardNumber: '1234567890123456', - // cardYear: '2023', - // cardMonth: '05', - // cardCVV: '123', - // addressName: 'John Doe', - // addressZip: '12345', - // currency: 'USD', - // }; - // const fakeAccountID = 1; + mockFetch?.pause?.(); + Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); + Member.requestWorkspaceOwnerChange(fakePolicy.id); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + expect(policy?.errorFields).toBeFalsy(); + expect(policy?.isLoading).toBeTruthy(); + expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); + expect(policy?.isChangeOwnerFailed).toBeFalsy(); + resolve(); + }, + }); + }); + await mockFetch?.resume?.(); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + expect(policy?.isLoading).toBeFalsy(); + expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); + expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); + resolve(); + }, + }); + }); + }); + }); + describe('addBillingCardAndRequestPolicyOwnerChange', () => { + it('Add billing card and change the workspace`s owner', async () => { + const fakePolicy: PolicyType = createRandomPolicy(0); + const fakeEmail = 'fake@gmail.com'; + const fakeCard = { + cardNumber: '1234567890123456', + cardYear: '2023', + cardMonth: '05', + cardCVV: '123', + addressName: 'John Doe', + addressZip: '12345', + currency: 'USD', + }; + const fakeAccountID = 1; - // mockFetch?.pause?.(); - // Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); - // Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); - // Policy.addBillingCardAndRequestPolicyOwnerChange(fakePolicy.id, fakeCard); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // expect(policy?.errorFields).toBeFalsy(); - // expect(policy?.isLoading).toBeTruthy(); - // expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); - // expect(policy?.isChangeOwnerFailed).toBeFalsy(); - // resolve(); - // }, - // }); - // }); - // await mockFetch?.resume?.(); - // await waitForBatchedUpdates(); - // await new Promise((resolve) => { - // const connection = Onyx.connect({ - // key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, - // waitForCollectionCallback: false, - // callback: (policy) => { - // Onyx.disconnect(connection); - // expect(policy?.isLoading).toBeFalsy(); - // expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); - // expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); - // resolve(); - // }, - // }); - // }); - // }); - // }); + mockFetch?.pause?.(); + Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy); + Onyx.merge(ONYXKEYS.SESSION, {email: fakeEmail, accountID: fakeAccountID}); + Policy.addBillingCardAndRequestPolicyOwnerChange(fakePolicy.id, fakeCard); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + expect(policy?.errorFields).toBeFalsy(); + expect(policy?.isLoading).toBeTruthy(); + expect(policy?.isChangeOwnerSuccessful).toBeFalsy(); + expect(policy?.isChangeOwnerFailed).toBeFalsy(); + resolve(); + }, + }); + }); + await mockFetch?.resume?.(); + await waitForBatchedUpdates(); + await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, + waitForCollectionCallback: false, + callback: (policy) => { + Onyx.disconnect(connection); + expect(policy?.isLoading).toBeFalsy(); + expect(policy?.isChangeOwnerSuccessful).toBeTruthy(); + expect(policy?.isChangeOwnerFailed)?.toBeFalsy(); + resolve(); + }, + }); + }); + }); + }); describe('addMembersToWorkspace', () => { it('Add a new member to a workspace', async () => { From 2223f0e37ca52d1153a427c7df56820830fcc389 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 15 Feb 2025 17:04:45 +0800 Subject: [PATCH 4/6] lint --- tests/actions/PolicyMemberTest.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/actions/PolicyMemberTest.ts b/tests/actions/PolicyMemberTest.ts index 13bbc7abda68..782219a8b4c1 100644 --- a/tests/actions/PolicyMemberTest.ts +++ b/tests/actions/PolicyMemberTest.ts @@ -270,6 +270,7 @@ describe('actions/PolicyMember', () => { const policyID = '1'; const adminRoomID = '1'; const defaultApprover = 'approver@gmail.com'; + const ownerAccountID = 1; const adminAccountID = 1234; const adminEmail = 'admin@example.com'; const auditorAccountID = 1235; @@ -286,7 +287,7 @@ describe('actions/PolicyMember', () => { policyID, chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, participants: { - 1: {notificationPreference: 'always'}, + [ownerAccountID]: {notificationPreference: 'always'}, }, }); @@ -319,6 +320,8 @@ describe('actions/PolicyMember', () => { const policyID = '1'; const adminRoomID = '1'; const defaultApprover = 'approver@gmail.com'; + const ownerAccountID = 1; + const ownerEmail = 'owner@gmail.com'; const adminAccountID = 1234; const adminEmail = 'admin@example.com'; const auditorAccountID = 1235; @@ -335,7 +338,7 @@ describe('actions/PolicyMember', () => { ...createRandomPolicy(Number(policyID)), approver: defaultApprover, employeeList: { - 'owner@gmail.com': {role: CONST.POLICY.ROLE.ADMIN}, + [ownerEmail]: {role: CONST.POLICY.ROLE.ADMIN}, [adminEmail]: {role: CONST.POLICY.ROLE.ADMIN}, [auditorEmail]: {role: CONST.POLICY.ROLE.AUDITOR}, [userEmail]: {role: CONST.POLICY.ROLE.USER}, @@ -346,7 +349,7 @@ describe('actions/PolicyMember', () => { policyID, chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, participants: { - 1: {notificationPreference: 'always'}, + [ownerAccountID]: {notificationPreference: 'always'}, [adminAccountID]: {notificationPreference: 'always'}, [auditorAccountID]: {notificationPreference: 'always'}, [userAccountID]: {notificationPreference: 'always'}, From 76f7c944d31303d70e5f49061fb7d7dc3d0ccdef Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sun, 16 Feb 2025 14:45:50 +0800 Subject: [PATCH 5/6] update comment --- src/libs/actions/Policy/Member.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index 541a5b430df6..de36a5199c5e 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -131,7 +131,7 @@ function getPolicy(policyID: string | undefined): OnyxEntry { } /** - * Build optimistic data for adding members to the announcement room + * Build optimistic data for adding members to the announcement/admins room */ function buildRoomMembersOnyxData( roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, @@ -233,7 +233,7 @@ function updateImportSpreadsheetData(membersLength: number): OnyxData { } /** - * Build optimistic data for removing users from the announcement room + * Build optimistic data for removing users from the announcement/admins room */ function removeOptimisticRoomMembers( roomType: typeof CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE | typeof CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, From a91abcca3d62fa8654896c5bbe466693d31ad93a Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 17 Feb 2025 12:36:37 +0800 Subject: [PATCH 6/6] update the condition to be more specific --- src/libs/actions/Policy/Member.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index de36a5199c5e..58892b486609 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -342,7 +342,8 @@ function removeMembers(accountIDs: number[], policyID: string) { policy?.name ?? '', accountIDs.filter((accountID) => { const login = allPersonalDetails?.[accountID]?.login; - return login && policy?.employeeList?.[login]?.role !== CONST.POLICY.ROLE.USER; + const role = login ? policy?.employeeList?.[login]?.role : ''; + return role === CONST.POLICY.ROLE.ADMIN || role === CONST.POLICY.ROLE.AUDITOR; }), ); @@ -694,7 +695,11 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount const newPersonalDetailsOnyxData = PersonalDetailsUtils.getPersonalDetailsOnyxDataForOptimisticUsers(newLogins, newAccountIDs); const announceRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, accountIDs); - const adminRoomMembers = buildRoomMembersOnyxData(CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID, role !== CONST.POLICY.ROLE.USER ? accountIDs : []); + const adminRoomMembers = buildRoomMembersOnyxData( + CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + policyID, + role === CONST.POLICY.ROLE.ADMIN || role === CONST.POLICY.ROLE.AUDITOR ? accountIDs : [], + ); const optimisticAnnounceChat = ReportUtils.buildOptimisticAnnounceChat(policyID, [...policyMemberAccountIDs, ...accountIDs]); const announceRoomChat = optimisticAnnounceChat.announceChatData;