From ac03a09eb9054a9a41545716df90cd253d4f8078 Mon Sep 17 00:00:00 2001 From: KJ21-ENG <140263938+KJ21-ENG@users.noreply.github.com> Date: Thu, 23 Jul 2026 00:39:38 +0530 Subject: [PATCH] fix: clean tests/unit/ReportSecondaryActionUtilsTest.ts --- tests/unit/ReportSecondaryActionUtilsTest.ts | 127 ++++++++++--------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/tests/unit/ReportSecondaryActionUtilsTest.ts b/tests/unit/ReportSecondaryActionUtilsTest.ts index 3b2ee9c25f14..f8d58b6cfc09 100644 --- a/tests/unit/ReportSecondaryActionUtilsTest.ts +++ b/tests/unit/ReportSecondaryActionUtilsTest.ts @@ -210,14 +210,14 @@ describe('getSecondaryAction', () => { }); it('does not include PRINT option when the report is in OPEN state', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, stateNum: CONST.REPORT.STATE_NUM.OPEN, statusNum: CONST.REPORT.STATUS_NUM.OPEN, - } as unknown as Report; - const policy = {} as unknown as Policy; + }); + const policy = createMock({}); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -226,7 +226,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -240,14 +240,14 @@ describe('getSecondaryAction', () => { }); it('includes PRINT option when the report is submitted', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, - } as unknown as Report; - const policy = {} as unknown as Policy; + }); + const policy = createMock({}); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -256,7 +256,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -2180,7 +2180,7 @@ describe('getSecondaryAction', () => { }); it('includes RECEIVED_PAYMENT for submitter on Outstanding (Processing) report in Submit workspace', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, @@ -2188,11 +2188,11 @@ describe('getSecondaryAction', () => { statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, total: -100, nonReimbursableTotal: 0, - } as unknown as Report; - const policy = { + }); + const policy = createMock({ type: CONST.POLICY.TYPE.SUBMIT, role: CONST.POLICY.ROLE.EDITOR, - } as unknown as Policy; + }); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -2201,7 +2201,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -2212,7 +2212,7 @@ describe('getSecondaryAction', () => { }); it('does not include RECEIVED_PAYMENT when current user did not submit the report (Submit workspace)', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: MANAGER_ACCOUNT_ID, @@ -2220,11 +2220,11 @@ describe('getSecondaryAction', () => { statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, total: -100, nonReimbursableTotal: 0, - } as unknown as Report; - const policy = { + }); + const policy = createMock({ type: CONST.POLICY.TYPE.SUBMIT, role: CONST.POLICY.ROLE.EDITOR, - } as unknown as Policy; + }); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -2233,7 +2233,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -2244,7 +2244,7 @@ describe('getSecondaryAction', () => { }); it('does not include RECEIVED_PAYMENT for submitter on Submit workspace report waiting on bank account', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, @@ -2253,11 +2253,11 @@ describe('getSecondaryAction', () => { total: -100, nonReimbursableTotal: 0, isWaitingOnBankAccount: true, - } as unknown as Report; - const policy = { + }); + const policy = createMock({ type: CONST.POLICY.TYPE.SUBMIT, role: CONST.POLICY.ROLE.EDITOR, - } as unknown as Policy; + }); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -2266,7 +2266,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -2277,11 +2277,11 @@ describe('getSecondaryAction', () => { }); it('does not include RECEIVED_PAYMENT for submitter on Submit workspace report with held expenses', () => { - const heldTransaction = { + const heldTransaction = createMock({ transactionID: '1', comment: {hold: 'hold-id'}, - } as unknown as Transaction; - const report = { + }); + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, @@ -2289,11 +2289,11 @@ describe('getSecondaryAction', () => { statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, total: -100, nonReimbursableTotal: 0, - } as unknown as Report; - const policy = { + }); + const policy = createMock({ type: CONST.POLICY.TYPE.SUBMIT, role: CONST.POLICY.ROLE.EDITOR, - } as unknown as Policy; + }); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -2302,7 +2302,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [heldTransaction], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -2313,7 +2313,7 @@ describe('getSecondaryAction', () => { }); it('does not include RECEIVED_PAYMENT for submitter on Outstanding report in non-Submit workspace', () => { - const report = { + const report = createMock({ reportID: REPORT_ID, type: CONST.REPORT.TYPE.EXPENSE, ownerAccountID: EMPLOYEE_ACCOUNT_ID, @@ -2321,11 +2321,11 @@ describe('getSecondaryAction', () => { statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, total: -100, nonReimbursableTotal: 0, - } as unknown as Report; - const policy = { + }); + const policy = createMock({ type: CONST.POLICY.TYPE.TEAM, role: CONST.POLICY.ROLE.USER, - } as unknown as Policy; + }); const result = getSecondaryReportActions({ currentUserLogin: EMPLOYEE_EMAIL, @@ -2334,7 +2334,7 @@ describe('getSecondaryAction', () => { report, chatReport, reportTransactions: [], - originalTransaction: {} as Transaction, + originalTransaction: createMock({}), violations: {}, bankAccountList: {}, policy, @@ -5307,37 +5307,35 @@ describe('getSecondaryTransactionThreadActions', () => { return acc; }, createMock>({})); - type MockFunction = ((...args: unknown[]) => unknown) | boolean; + type IsWorkspaceEligibleForReportChangeMock = ( + ...args: Parameters + ) => ReturnType; type MockConfig = Partial<{ isIOUReport: boolean; doesReportContainRequestsFromMultipleUsers: boolean; isCurrentUserSubmitter: boolean; isReportManager: boolean; - isWorkspaceEligibleForReportChange: MockFunction; + isWorkspaceEligibleForReportChange: boolean | IsWorkspaceEligibleForReportChangeMock; canEditReportPolicy: boolean; isExported: boolean; isSettled: boolean; }>; const setupMocks = (mocks: MockConfig = {}) => { - const defaults = { - isIOUReport: false, - doesReportContainRequestsFromMultipleUsers: false, - isCurrentUserSubmitter: false, - isReportManager: false, - isWorkspaceEligibleForReportChange: true, - canEditReportPolicy: true, - isExported: false, - isSettled: false, - }; - - for (const [method, value] of Object.entries({...defaults, ...mocks})) { - if (typeof value === 'function') { - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument - jest.spyOn(ReportUtils, method as keyof typeof ReportUtils).mockImplementation(value as any); - } else { - jest.spyOn(ReportUtils, method as keyof typeof ReportUtils).mockReturnValue(value); - } + jest.spyOn(ReportUtils, 'isIOUReport').mockReturnValue(mocks.isIOUReport ?? false); + jest.spyOn(ReportUtils, 'doesReportContainRequestsFromMultipleUsers').mockReturnValue(mocks.doesReportContainRequestsFromMultipleUsers ?? false); + jest.spyOn(ReportUtils, 'isCurrentUserSubmitter').mockReturnValue(mocks.isCurrentUserSubmitter ?? false); + jest.spyOn(ReportUtils, 'isReportManager').mockReturnValue(mocks.isReportManager ?? false); + jest.spyOn(ReportUtils, 'canEditReportPolicy').mockReturnValue(mocks.canEditReportPolicy ?? true); + jest.spyOn(ReportUtils, 'isExported').mockReturnValue(mocks.isExported ?? false); + jest.spyOn(ReportUtils, 'isSettled').mockReturnValue(mocks.isSettled ?? false); + + const workspaceEligibilityMock = jest.spyOn(ReportUtils, 'isWorkspaceEligibleForReportChange'); + const workspaceEligibility = mocks.isWorkspaceEligibleForReportChange ?? true; + if (typeof workspaceEligibility === 'function') { + workspaceEligibilityMock.mockImplementation(workspaceEligibility); + } else { + workspaceEligibilityMock.mockReturnValue(workspaceEligibility); } }; @@ -5386,7 +5384,12 @@ describe('getSecondaryTransactionThreadActions', () => { }); it('should return true when only one available policy and it is different from current report policy', () => { - setupMocks({isWorkspaceEligibleForReportChange: ((_, policy: Policy) => policy?.id === POLICY_ID) as MockFunction}); + setupMocks({ + isWorkspaceEligibleForReportChange: ( + _submitterEmail: Parameters[0], + policy: Parameters[1], + ) => policy?.id === POLICY_ID, + }); const report = createReport({policyID: OLD_POLICY_ID}); const policies = createPolicies(POLICY_ID, OLD_POLICY_ID); @@ -5435,7 +5438,7 @@ describe('getSecondaryTransactionThreadActions', () => { it('should return true when report is settled and currentUserLogin is admin of available policies', () => { setupMocks({isSettled: true}); - const mockedIsPolicyAdmin = jest.requireMock('@libs/PolicyUtils').isPolicyAdmin as jest.Mock; + const mockedIsPolicyAdmin = jest.mocked(jest.requireMock('@libs/PolicyUtils').isPolicyAdmin); mockedIsPolicyAdmin.mockReturnValue(true); const report = createReport({policyID: OLD_POLICY_ID}); @@ -5446,7 +5449,7 @@ describe('getSecondaryTransactionThreadActions', () => { it('should return false when report is settled and currentUserLogin is not admin of any policy', () => { setupMocks({isSettled: true}); - const mockedIsPolicyAdmin = jest.requireMock('@libs/PolicyUtils').isPolicyAdmin as jest.Mock; + const mockedIsPolicyAdmin = jest.mocked(jest.requireMock('@libs/PolicyUtils').isPolicyAdmin); mockedIsPolicyAdmin.mockReturnValue(false); const report = createReport({policyID: OLD_POLICY_ID}); @@ -5457,8 +5460,8 @@ describe('getSecondaryTransactionThreadActions', () => { it('should filter policies by admin role using currentUserLogin when report is settled', () => { setupMocks({isSettled: true}); - const mockedIsPolicyAdmin = jest.requireMock('@libs/PolicyUtils').isPolicyAdmin as jest.Mock; - mockedIsPolicyAdmin.mockImplementation((policy: Policy, login?: string) => { + const mockedIsPolicyAdmin = jest.mocked(jest.requireMock('@libs/PolicyUtils').isPolicyAdmin); + mockedIsPolicyAdmin.mockImplementation((policy, login) => { return login === ADMIN_EMAIL && policy?.id === POLICY_ID; }); @@ -5473,7 +5476,7 @@ describe('getSecondaryTransactionThreadActions', () => { it('should not filter policies by admin role when report is not settled', () => { setupMocks({isSettled: false}); - const mockedIsPolicyAdmin = jest.requireMock('@libs/PolicyUtils').isPolicyAdmin as jest.Mock; + const mockedIsPolicyAdmin = jest.mocked(jest.requireMock('@libs/PolicyUtils').isPolicyAdmin); mockedIsPolicyAdmin.mockReturnValue(false); const report = createReport({policyID: OLD_POLICY_ID}); @@ -5485,7 +5488,7 @@ describe('getSecondaryTransactionThreadActions', () => { it('should pass currentUserLogin to isPolicyAdmin for each candidate policy when settled', () => { setupMocks({isSettled: true}); - const mockedIsPolicyAdmin = jest.requireMock('@libs/PolicyUtils').isPolicyAdmin as jest.Mock; + const mockedIsPolicyAdmin = jest.mocked(jest.requireMock('@libs/PolicyUtils').isPolicyAdmin); mockedIsPolicyAdmin.mockReturnValue(true); const report = createReport({policyID: OLD_POLICY_ID});