Skip to content

Commit 4bd5eca

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 2c637cd commit 4bd5eca

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';
@@ -7025,5 +7026,71 @@ describe('actions/Policy', () => {
70257026
apiWriteSpy.mockRestore();
70267027
isIOUReportUsingReportSpy.mockRestore();
70277028
});
7029+
7030+
it('should negate the converted transaction amounts on the optimistic data so the expense-report table total stays positive', async () => {
7031+
await Onyx.set(ONYXKEYS.SESSION, {email: ESH_EMAIL, accountID: ESH_ACCOUNT_ID});
7032+
await waitForBatchedUpdates();
7033+
7034+
const employeeAccountID = 400;
7035+
const iouReportOwnerEmail = 'employee@example.com';
7036+
7037+
const iouReport: Report = {
7038+
...createRandomReport(1, undefined),
7039+
reportID: '900',
7040+
type: CONST.REPORT.TYPE.IOU,
7041+
ownerAccountID: employeeAccountID,
7042+
chatReportID: '901',
7043+
policyID: 'oldPolicyID',
7044+
currency: CONST.CURRENCY.USD,
7045+
total: 5000,
7046+
};
7047+
7048+
// IOU transactions can be stored with either sign; use the negative case here so the test fails
7049+
// if the helper ever regresses to a plain `-convertedAmount` (which would flip back to positive)
7050+
const transaction: Transaction = {
7051+
...createRandomTransaction(900),
7052+
transactionID: 'transaction900',
7053+
reportID: iouReport.reportID,
7054+
amount: 5000,
7055+
modifiedAmount: '',
7056+
convertedAmount: -6000,
7057+
convertedTaxAmount: -600,
7058+
};
7059+
7060+
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, iouReport);
7061+
await waitForBatchedUpdates();
7062+
7063+
const apiWriteSpy = jest.spyOn(require('@libs/API'), 'write').mockImplementation(() => Promise.resolve());
7064+
const isIOUReportUsingReportSpy = jest.spyOn(ReportUtils, 'isIOUReportUsingReport').mockReturnValue(true);
7065+
const getReportTransactionsSpy = jest.spyOn(ReportUtils, 'getReportTransactions').mockReturnValue([transaction]);
7066+
7067+
const mockTranslate = ((key: string) => key) as unknown as Parameters<typeof Policy.createWorkspaceFromIOUPayment>[8];
7068+
Policy.createWorkspaceFromIOUPayment(iouReport, undefined, ESH_ACCOUNT_ID, ESH_EMAIL, iouReportOwnerEmail, undefined, CONST.CURRENCY.USD, undefined, mockTranslate, {});
7069+
await waitForBatchedUpdates();
7070+
7071+
const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as {
7072+
optimisticData?: Array<{key?: string; value?: Record<string, Transaction> | null}>;
7073+
failureData?: Array<{key?: string; value?: Record<string, Transaction> | null}>;
7074+
};
7075+
7076+
const transactionOptimisticUpdate = (writeOptions?.optimisticData ?? []).find((update) => update.key === ONYXKEYS.COLLECTION.TRANSACTION);
7077+
const optimisticTransaction = transactionOptimisticUpdate?.value?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`];
7078+
7079+
// The expense-report sign convention flips the stored sign for display, so the converted magnitudes must be stored negative
7080+
expect(optimisticTransaction?.amount).toBe(-5000);
7081+
expect(optimisticTransaction?.convertedAmount).toBe(-6000);
7082+
expect(optimisticTransaction?.convertedTaxAmount).toBe(-600);
7083+
7084+
// And the failure data restores the original values on rollback
7085+
const transactionFailureUpdate = (writeOptions?.failureData ?? []).find((update) => update.key === ONYXKEYS.COLLECTION.TRANSACTION);
7086+
const rolledBackTransaction = transactionFailureUpdate?.value?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`];
7087+
expect(rolledBackTransaction?.amount).toBe(5000);
7088+
expect(rolledBackTransaction?.convertedAmount).toBe(-6000);
7089+
expect(rolledBackTransaction?.convertedTaxAmount).toBe(-600);
7090+
7091+
apiWriteSpy.mockRestore();
7092+
isIOUReportUsingReportSpy.mockRestore();
7093+
getReportTransactionsSpy.mockRestore();
7094+
});
70287095
});
70297096
});

0 commit comments

Comments
 (0)