Skip to content

Commit 2aa26cc

Browse files
committed
test: add regression coverage for modifiedAmount LHN RBR exclusion
Adds two focused tests under describe('getViolatingReportIDForRBRInLHN'): 1. Processing (submitted) expense report whose only violation is a modifiedAmount NOTICE -> getViolatingReportIDForRBRInLHN returns null. Verifies the fix: modifiedAmount no longer bubbles up to the LHN RBR indicator once the report enters the processing state. 2. Open expense report whose only violation is a modifiedAmount NOTICE -> getViolatingReportIDForRBRInLHN returns the expense report ID. Regression guard: confirms the exclusion is scoped only to processing reports and does not over-suppress RBR for still-editable reports.
1 parent deb6823 commit 2aa26cc

1 file changed

Lines changed: 175 additions & 0 deletions

File tree

tests/unit/ReportUtilsTest.ts

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12440,6 +12440,181 @@ describe('ReportUtils', () => {
1244012440

1244112441
await Onyx.clear();
1244212442
});
12443+
12444+
it('should return null for a processing (submitted) expense report whose only violation is a modifiedAmount NOTICE', async () => {
12445+
await Onyx.clear();
12446+
12447+
const policyID = 'policy-rbr-modified-amount-processing';
12448+
const chatReportID = 'chat-rbr-modified-amount-processing';
12449+
const expenseReportID = 'expense-rbr-modified-amount-processing';
12450+
const transactionID = 'transaction-rbr-modified-amount-processing';
12451+
12452+
const policyData: Policy = {
12453+
id: policyID,
12454+
name: 'Modified Amount Processing Workspace',
12455+
type: CONST.POLICY.TYPE.TEAM,
12456+
role: CONST.POLICY.ROLE.ADMIN,
12457+
outputCurrency: CONST.CURRENCY.USD,
12458+
reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,
12459+
approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC,
12460+
employeeList: {
12461+
[currentUserEmail]: {
12462+
role: CONST.POLICY.ROLE.ADMIN,
12463+
},
12464+
},
12465+
owner: currentUserEmail,
12466+
isPolicyExpenseChatEnabled: true,
12467+
};
12468+
12469+
const chatReport: Report = {
12470+
...createPolicyExpenseChat(820),
12471+
reportID: chatReportID,
12472+
ownerAccountID: currentUserAccountID,
12473+
policyID,
12474+
iouReportID: expenseReportID,
12475+
};
12476+
12477+
const expenseReport: Report = {
12478+
...createExpenseReport(821),
12479+
reportID: expenseReportID,
12480+
chatReportID,
12481+
ownerAccountID: currentUserAccountID,
12482+
managerID: 42,
12483+
policyID,
12484+
type: CONST.REPORT.TYPE.EXPENSE,
12485+
currency: CONST.CURRENCY.USD,
12486+
total: 5000,
12487+
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
12488+
statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
12489+
};
12490+
12491+
const baseTransaction = createRandomTransaction(820);
12492+
const transaction: Transaction = {
12493+
...baseTransaction,
12494+
transactionID,
12495+
reportID: expenseReportID,
12496+
amount: 5000,
12497+
currency: CONST.CURRENCY.USD,
12498+
status: CONST.TRANSACTION.STATUS.POSTED,
12499+
reimbursable: true,
12500+
};
12501+
12502+
const transactionViolationsKey = `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}` as OnyxKey;
12503+
const transactionViolationsCollection: OnyxCollection<TransactionViolation[]> = {
12504+
[transactionViolationsKey]: [
12505+
{
12506+
name: CONST.VIOLATIONS.MODIFIED_AMOUNT,
12507+
type: CONST.VIOLATION_TYPES.NOTICE,
12508+
showInReview: true,
12509+
},
12510+
],
12511+
};
12512+
12513+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID, email: currentUserEmail});
12514+
await waitForBatchedUpdates();
12515+
12516+
await Promise.all([
12517+
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policyData),
12518+
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport),
12519+
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport),
12520+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transaction),
12521+
Onyx.merge(transactionViolationsKey, transactionViolationsCollection[transactionViolationsKey]),
12522+
]);
12523+
await waitForBatchedUpdates();
12524+
12525+
const result = getViolatingReportIDForRBRInLHN(chatReport, transactionViolationsCollection);
12526+
expect(result).toBeNull();
12527+
12528+
await Onyx.clear();
12529+
});
12530+
12531+
it('should still surface RBR for an open expense report whose only violation is a modifiedAmount NOTICE', async () => {
12532+
await Onyx.clear();
12533+
12534+
const policyID = 'policy-rbr-modified-amount-open';
12535+
const chatReportID = 'chat-rbr-modified-amount-open';
12536+
const expenseReportID = 'expense-rbr-modified-amount-open';
12537+
const transactionID = 'transaction-rbr-modified-amount-open';
12538+
12539+
const policyData: Policy = {
12540+
id: policyID,
12541+
name: 'Modified Amount Open Workspace',
12542+
type: CONST.POLICY.TYPE.TEAM,
12543+
role: CONST.POLICY.ROLE.ADMIN,
12544+
outputCurrency: CONST.CURRENCY.USD,
12545+
reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,
12546+
approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC,
12547+
employeeList: {
12548+
[currentUserEmail]: {
12549+
role: CONST.POLICY.ROLE.ADMIN,
12550+
},
12551+
},
12552+
owner: currentUserEmail,
12553+
isPolicyExpenseChatEnabled: true,
12554+
};
12555+
12556+
const chatReport: Report = {
12557+
...createPolicyExpenseChat(822),
12558+
reportID: chatReportID,
12559+
ownerAccountID: currentUserAccountID,
12560+
policyID,
12561+
iouReportID: expenseReportID,
12562+
hasOutstandingChildRequest: true,
12563+
};
12564+
12565+
const expenseReport: Report = {
12566+
...createExpenseReport(823),
12567+
reportID: expenseReportID,
12568+
chatReportID,
12569+
ownerAccountID: currentUserAccountID,
12570+
managerID: 42,
12571+
policyID,
12572+
type: CONST.REPORT.TYPE.EXPENSE,
12573+
currency: CONST.CURRENCY.USD,
12574+
total: 5000,
12575+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
12576+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
12577+
};
12578+
12579+
const baseTransaction = createRandomTransaction(822);
12580+
const transaction: Transaction = {
12581+
...baseTransaction,
12582+
transactionID,
12583+
reportID: expenseReportID,
12584+
amount: 5000,
12585+
currency: CONST.CURRENCY.USD,
12586+
status: CONST.TRANSACTION.STATUS.POSTED,
12587+
reimbursable: true,
12588+
};
12589+
12590+
const transactionViolationsKey = `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}` as OnyxKey;
12591+
const transactionViolationsCollection: OnyxCollection<TransactionViolation[]> = {
12592+
[transactionViolationsKey]: [
12593+
{
12594+
name: CONST.VIOLATIONS.MODIFIED_AMOUNT,
12595+
type: CONST.VIOLATION_TYPES.NOTICE,
12596+
showInReview: true,
12597+
},
12598+
],
12599+
};
12600+
12601+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID, email: currentUserEmail});
12602+
await waitForBatchedUpdates();
12603+
12604+
await Promise.all([
12605+
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policyData),
12606+
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport),
12607+
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport),
12608+
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transaction),
12609+
Onyx.merge(transactionViolationsKey, transactionViolationsCollection[transactionViolationsKey]),
12610+
]);
12611+
await waitForBatchedUpdates();
12612+
12613+
const result = getViolatingReportIDForRBRInLHN(chatReport, transactionViolationsCollection);
12614+
expect(result).toBe(expenseReportID);
12615+
12616+
await Onyx.clear();
12617+
});
1244312618
});
1244412619

1244512620
it('should surface a GBR for admin with held expenses requiring approval or payment and avoid showing an RBR', async () => {

0 commit comments

Comments
 (0)