Skip to content

Commit 8f90afa

Browse files
authored
Merge pull request Expensify#87154 from DylanDylann/refactor-66579-p3
2 parents 1276520 + da26099 commit 8f90afa

3 files changed

Lines changed: 137 additions & 3 deletions

File tree

src/components/KYCWall/BaseKYCWall.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ function KYCWall({
7171

7272
const {formatPhoneNumber, translate} = useLocalize();
7373
const currentUserDetails = useCurrentUserPersonalDetails();
74+
const currentUserAccountID = currentUserDetails.accountID;
7475
const currentUserEmail = currentUserDetails.email ?? '';
7576
const reportPreviewAction = useParentReportAction(iouReport);
7677
const personalDetails = usePersonalDetails();
@@ -170,7 +171,16 @@ function KYCWall({
170171

171172
const lastWorkspaceNumber = lastWorkspaceNumberSelector(policies, currentUserEmail);
172173
const {policyID, workspaceChatReportID, reportPreviewReportActionID, adminsChatReportID} =
173-
createWorkspaceFromIOUPayment(iouReport, reportPreviewAction, currentUserEmail, employeeEmail, conciergeReportID, lastWorkspaceNumber, translate) ?? {};
174+
createWorkspaceFromIOUPayment(
175+
iouReport,
176+
reportPreviewAction,
177+
currentUserAccountID,
178+
currentUserEmail,
179+
employeeEmail,
180+
conciergeReportID,
181+
lastWorkspaceNumber,
182+
translate,
183+
) ?? {};
174184
if (policyID && iouReport?.policyID) {
175185
savePreferredPaymentMethod(iouReport.policyID, policyID, CONST.LAST_PAYMENT_METHOD.IOU, lastPaymentMethod?.[iouReport?.policyID]);
176186
}
@@ -213,6 +223,7 @@ function KYCWall({
213223
chatReport,
214224
policies,
215225
reportPreviewAction,
226+
currentUserAccountID,
216227
currentUserEmail,
217228
employeeEmail,
218229
introSelected,

src/libs/actions/Policy/Policy.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ function leaveWorkspace(currentUserAccountID: number, currentUserEmail: string,
12961296
];
12971297

12981298
const currentTime = DateUtils.getDBTime();
1299-
const pendingChatMembers = ReportUtils.getPendingChatMembers([deprecatedSessionAccountID], [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
1299+
const pendingChatMembers = ReportUtils.getPendingChatMembers([currentUserAccountID], [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
13001300

13011301
for (const report of workspaceChats) {
13021302
if (!report?.reportID) {
@@ -3941,6 +3941,7 @@ function dismissAddedWithPrimaryLoginMessages(policyID: string) {
39413941
function createWorkspaceFromIOUPayment(
39423942
iouReport: OnyxEntry<Report>,
39433943
reportPreviewAction: ReportAction | undefined,
3944+
currentUserAccountID: number,
39443945
currentUserEmail: string,
39453946
iouReportOwnerEmail: string,
39463947
conciergeReportID: string | undefined,
@@ -3987,7 +3988,7 @@ function createWorkspaceFromIOUPayment(
39873988
name: workspaceName,
39883989
role: CONST.POLICY.ROLE.ADMIN,
39893990
owner: currentUserEmail,
3990-
ownerAccountID: deprecatedSessionAccountID,
3991+
ownerAccountID: currentUserAccountID,
39913992
isPolicyExpenseChatEnabled: true,
39923993

39933994
// Setting the new workspace currency to the currency of the iouReport

tests/actions/PolicyTest.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,61 @@ describe('actions/Policy', () => {
17791779
apiWriteSpy.mockRestore();
17801780
getAllWorkspaceReportsSpy.mockRestore();
17811781
});
1782+
1783+
it('should use explicit currentUserAccountID for pendingChatMembers instead of Onyx session', async () => {
1784+
// Set Onyx session to a DIFFERENT accountID to verify the explicit parameter is used
1785+
await Onyx.set(ONYXKEYS.SESSION, {email: ESH_EMAIL, accountID: ESH_ACCOUNT_ID});
1786+
await waitForBatchedUpdates();
1787+
1788+
const policyID = Policy.generatePolicyID();
1789+
const policy: PolicyType = {
1790+
...createRandomPolicy(0, CONST.POLICY.TYPE.TEAM),
1791+
id: policyID,
1792+
name: WORKSPACE_NAME,
1793+
};
1794+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policy);
1795+
await waitForBatchedUpdates();
1796+
1797+
// Use a non-expense-chat report so it goes through the else branch where pendingChatMembers is set
1798+
const workspaceChat: Report = {
1799+
...createRandomReport(100, undefined),
1800+
reportID: '100',
1801+
policyID,
1802+
type: CONST.REPORT.TYPE.CHAT,
1803+
};
1804+
1805+
const getAllWorkspaceReportsSpy = jest.spyOn(ReportUtils, 'getAllWorkspaceReports').mockReturnValue([workspaceChat]);
1806+
const apiWriteSpy = jest.spyOn(require('@libs/API'), 'write').mockImplementation(() => Promise.resolve());
1807+
1808+
const customAccountID = 999;
1809+
const customEmail = 'custom@example.com';
1810+
1811+
Policy.leaveWorkspace(customAccountID, customEmail, policy);
1812+
await waitForBatchedUpdates();
1813+
1814+
const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as {
1815+
optimisticData?: Array<{key?: string; value?: Record<string, unknown> | null}>;
1816+
};
1817+
1818+
// Verify pendingChatMembers uses the explicit customAccountID, not the Onyx session accountID
1819+
const metadataUpdate = (writeOptions?.optimisticData ?? []).find((update) => (update.key ?? '').startsWith(ONYXKEYS.COLLECTION.REPORT_METADATA));
1820+
const pendingMembers = (metadataUpdate?.value as {pendingChatMembers?: Array<{accountID: string}>})?.pendingChatMembers ?? [];
1821+
1822+
expect(pendingMembers).toEqual(
1823+
expect.arrayContaining([
1824+
expect.objectContaining({
1825+
accountID: String(customAccountID),
1826+
}),
1827+
]),
1828+
);
1829+
1830+
// Verify that the Onyx session accountID is NOT used
1831+
const usesOnyxSessionAccountID = pendingMembers.some((member) => member.accountID === String(ESH_ACCOUNT_ID));
1832+
expect(usesOnyxSessionAccountID).toBe(false);
1833+
1834+
apiWriteSpy.mockRestore();
1835+
getAllWorkspaceReportsSpy.mockRestore();
1836+
});
17821837
});
17831838

17841839
describe('createDraftInitialWorkspace', () => {
@@ -5647,4 +5702,71 @@ describe('actions/Policy', () => {
56475702
expect(updatedPolicy?.errorFields?.customRules).toBeDefined();
56485703
});
56495704
});
5705+
5706+
describe('createWorkspaceFromIOUPayment', () => {
5707+
it('should set ownerAccountID from explicit currentUserAccountID parameter', async () => {
5708+
// Set Onyx session to a DIFFERENT accountID to verify the explicit parameter is used
5709+
await Onyx.set(ONYXKEYS.SESSION, {email: ESH_EMAIL, accountID: ESH_ACCOUNT_ID});
5710+
await waitForBatchedUpdates();
5711+
5712+
const customAccountID = 999;
5713+
const customEmail = 'custom@example.com';
5714+
const iouReportOwnerEmail = 'owner@example.com';
5715+
const employeeAccountID = 200;
5716+
5717+
const iouReport: Report = {
5718+
...createRandomReport(1, undefined),
5719+
reportID: '500',
5720+
type: CONST.REPORT.TYPE.IOU,
5721+
ownerAccountID: employeeAccountID,
5722+
chatReportID: '501',
5723+
policyID: 'oldPolicyID',
5724+
currency: CONST.CURRENCY.USD,
5725+
total: 1000,
5726+
};
5727+
5728+
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, iouReport);
5729+
await waitForBatchedUpdates();
5730+
5731+
const apiWriteSpy = jest.spyOn(require('@libs/API'), 'write').mockImplementation(() => Promise.resolve());
5732+
const isIOUReportUsingReportSpy = jest.spyOn(ReportUtils, 'isIOUReportUsingReport').mockReturnValue(true);
5733+
5734+
// eslint-disable-next-line @typescript-eslint/naming-convention
5735+
const mockTranslate = ((key: string) => key) as unknown as Parameters<typeof Policy.createWorkspaceFromIOUPayment>[7];
5736+
Policy.createWorkspaceFromIOUPayment(iouReport, undefined, customAccountID, customEmail, iouReportOwnerEmail, undefined, undefined, mockTranslate);
5737+
await waitForBatchedUpdates();
5738+
5739+
const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as {
5740+
optimisticData?: Array<{key?: string; value?: Record<string, unknown> | null}>;
5741+
};
5742+
5743+
// Find the policy optimistic data entry
5744+
const policyOptimisticUpdate = (writeOptions?.optimisticData ?? []).find(
5745+
(update) => (update.key ?? '').startsWith(ONYXKEYS.COLLECTION.POLICY) && (update.value as {ownerAccountID?: number})?.ownerAccountID !== undefined,
5746+
);
5747+
5748+
// Verify ownerAccountID uses the explicit parameter, not the Onyx session
5749+
expect((policyOptimisticUpdate?.value as {ownerAccountID?: number})?.ownerAccountID).toBe(customAccountID);
5750+
expect((policyOptimisticUpdate?.value as {owner?: string})?.owner).toBe(customEmail);
5751+
5752+
// Verify that the Onyx session accountID is NOT used
5753+
expect((policyOptimisticUpdate?.value as {ownerAccountID?: number})?.ownerAccountID).not.toBe(ESH_ACCOUNT_ID);
5754+
5755+
apiWriteSpy.mockRestore();
5756+
isIOUReportUsingReportSpy.mockRestore();
5757+
});
5758+
5759+
it('should return undefined for non-IOU reports', () => {
5760+
const nonIOUReport: Report = {
5761+
...createRandomReport(1, undefined),
5762+
reportID: '600',
5763+
type: CONST.REPORT.TYPE.EXPENSE,
5764+
};
5765+
5766+
// eslint-disable-next-line @typescript-eslint/naming-convention
5767+
const mockTranslate = ((key: string) => key) as unknown as Parameters<typeof Policy.createWorkspaceFromIOUPayment>[7];
5768+
const result = Policy.createWorkspaceFromIOUPayment(nonIOUReport, undefined, ESH_ACCOUNT_ID, ESH_EMAIL, 'owner@example.com', undefined, undefined, mockTranslate);
5769+
expect(result).toBeUndefined();
5770+
});
5771+
});
56505772
});

0 commit comments

Comments
 (0)