Skip to content

Commit c2e1d23

Browse files
committed
Add coverage test for createWorkspaceFromIOUPayment transaction sign conversion
Cover the Policy.ts call site of getExpenseReportSignedTransaction with a test that feeds an IOU transaction whose converted amounts are stored negative and asserts the optimistic data stores a negative magnitude (so the expense-report sign convention renders a positive table total) and that the failure data restores the original values.
1 parent 4280cb6 commit c2e1d23

1 file changed

Lines changed: 68 additions & 1 deletion

File tree

tests/actions/PolicyTest.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager';
1111
import {askToJoinPolicy, joinAccessiblePolicy} from '@src/libs/actions/Policy/Member';
1212
import * as Policy from '@src/libs/actions/Policy/Policy';
1313
import ONYXKEYS from '@src/ONYXKEYS';
14-
import type {Onboarding, PolicyJoinMember, PolicyReportField, Policy as PolicyType, Report, ReportAction, ReportActions, TransactionViolations} from '@src/types/onyx';
14+
import type {Onboarding, PolicyJoinMember, PolicyReportField, Policy as PolicyType, Report, ReportAction, ReportActions, Transaction, TransactionViolations} from '@src/types/onyx';
1515
import type {Participant} from '@src/types/onyx/Report';
1616
import createRandomPolicy from '../utils/collections/policies';
1717
import {createRandomReport} from '../utils/collections/reports';
18+
import createRandomTransaction from '../utils/collections/transaction';
1819
import getOnyxValue from '../utils/getOnyxValue';
1920
import * as TestHelper from '../utils/TestHelper';
2021
import type {MockFetch} from '../utils/TestHelper';
@@ -7093,5 +7094,71 @@ describe('actions/Policy', () => {
70937094
apiWriteSpy.mockRestore();
70947095
isIOUReportUsingReportSpy.mockRestore();
70957096
});
7097+
7098+
it('should negate the converted transaction amounts on the optimistic data so the expense-report table total stays positive', async () => {
7099+
await Onyx.set(ONYXKEYS.SESSION, {email: ESH_EMAIL, accountID: ESH_ACCOUNT_ID});
7100+
await waitForBatchedUpdates();
7101+
7102+
const employeeAccountID = 400;
7103+
const iouReportOwnerEmail = 'employee@example.com';
7104+
7105+
const iouReport: Report = {
7106+
...createRandomReport(1, undefined),
7107+
reportID: '900',
7108+
type: CONST.REPORT.TYPE.IOU,
7109+
ownerAccountID: employeeAccountID,
7110+
chatReportID: '901',
7111+
policyID: 'oldPolicyID',
7112+
currency: CONST.CURRENCY.USD,
7113+
total: 5000,
7114+
};
7115+
7116+
// IOU transactions can be stored with either sign; use the negative case here so the test fails
7117+
// if the helper ever regresses to a plain `-convertedAmount` (which would flip back to positive)
7118+
const transaction: Transaction = {
7119+
...createRandomTransaction(900),
7120+
transactionID: 'transaction900',
7121+
reportID: iouReport.reportID,
7122+
amount: 5000,
7123+
modifiedAmount: '',
7124+
convertedAmount: -6000,
7125+
convertedTaxAmount: -600,
7126+
};
7127+
7128+
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, iouReport);
7129+
await waitForBatchedUpdates();
7130+
7131+
const apiWriteSpy = jest.spyOn(require('@libs/API'), 'write').mockImplementation(() => Promise.resolve());
7132+
const isIOUReportUsingReportSpy = jest.spyOn(ReportUtils, 'isIOUReportUsingReport').mockReturnValue(true);
7133+
const getReportTransactionsSpy = jest.spyOn(ReportUtils, 'getReportTransactions').mockReturnValue([transaction]);
7134+
7135+
const mockTranslate = ((key: string) => key) as unknown as Parameters<typeof Policy.createWorkspaceFromIOUPayment>[8];
7136+
Policy.createWorkspaceFromIOUPayment(iouReport, undefined, ESH_ACCOUNT_ID, ESH_EMAIL, iouReportOwnerEmail, undefined, CONST.CURRENCY.USD, undefined, mockTranslate, {});
7137+
await waitForBatchedUpdates();
7138+
7139+
const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as {
7140+
optimisticData?: Array<{key?: string; value?: Record<string, Transaction> | null}>;
7141+
failureData?: Array<{key?: string; value?: Record<string, Transaction> | null}>;
7142+
};
7143+
7144+
const transactionOptimisticUpdate = (writeOptions?.optimisticData ?? []).find((update) => update.key === ONYXKEYS.COLLECTION.TRANSACTION);
7145+
const optimisticTransaction = transactionOptimisticUpdate?.value?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`];
7146+
7147+
// The expense-report sign convention flips the stored sign for display, so the converted magnitudes must be stored negative
7148+
expect(optimisticTransaction?.amount).toBe(-5000);
7149+
expect(optimisticTransaction?.convertedAmount).toBe(-6000);
7150+
expect(optimisticTransaction?.convertedTaxAmount).toBe(-600);
7151+
7152+
// And the failure data restores the original values on rollback
7153+
const transactionFailureUpdate = (writeOptions?.failureData ?? []).find((update) => update.key === ONYXKEYS.COLLECTION.TRANSACTION);
7154+
const rolledBackTransaction = transactionFailureUpdate?.value?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`];
7155+
expect(rolledBackTransaction?.amount).toBe(5000);
7156+
expect(rolledBackTransaction?.convertedAmount).toBe(-6000);
7157+
expect(rolledBackTransaction?.convertedTaxAmount).toBe(-600);
7158+
7159+
apiWriteSpy.mockRestore();
7160+
isIOUReportUsingReportSpy.mockRestore();
7161+
getReportTransactionsSpy.mockRestore();
7162+
});
70967163
});
70977164
});

0 commit comments

Comments
 (0)