From 1c18e79ca84064a48338dcc1a5e506aa06cb091d Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 11 Nov 2025 13:59:01 -0800 Subject: [PATCH 1/5] Add automated tests for tax calculation --- .../IOURequestStepConfirmationPageTest.tsx | 595 +++++++++++++++++- 1 file changed, 589 insertions(+), 6 deletions(-) diff --git a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx index 57736af5bdf7..456112ab961e 100644 --- a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx +++ b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx @@ -1,13 +1,18 @@ import {act, fireEvent, render, screen} from '@testing-library/react-native'; import React from 'react'; import Onyx from 'react-native-onyx'; +import OnyxUtils from 'react-native-onyx/dist/OnyxUtils'; import {CurrentUserPersonalDetailsProvider} from '@components/CurrentUserPersonalDetailsProvider'; import {LocaleContextProvider} from '@components/LocaleContextProvider'; import OnyxListItemProvider from '@components/OnyxListItemProvider'; import IOURequestStepConfirmationWithWritableReportOrNotFound from '@pages/iou/request/step/IOURequestStepConfirmation'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy, TaxRatesWithDefault} from '@src/types/onyx'; import type Transaction from '@src/types/onyx/Transaction'; +import type {WaypointCollection} from '@src/types/onyx/Transaction'; import * as IOU from '../../../src/libs/actions/IOU'; +import createRandomPolicy from '../../utils/collections/policies'; import {signInWithTestUser, translateLocal} from '../../utils/TestHelper'; import waitForBatchedUpdatesWithAct from '../../utils/waitForBatchedUpdatesWithAct'; @@ -33,19 +38,130 @@ jest.mock('@components/ProductTrainingContext', () => ({ useProductTrainingContext: () => [false], })); jest.mock('@src/hooks/useResponsiveLayout'); -jest.mock('@react-navigation/native', () => ({ - createNavigationContainerRef: jest.fn(), - useIsFocused: () => true, - useNavigation: () => ({navigate: jest.fn(), addListener: jest.fn()}), - useFocusEffect: jest.fn(), - usePreventRemove: jest.fn(), + +jest.mock('@libs/Navigation/navigationRef', () => ({ + getCurrentRoute: jest.fn(() => ({ + name: 'Money_Request_Step_Confirmation', + params: {}, + })), + getState: jest.fn(() => ({})), })); +jest.mock('@libs/Navigation/Navigation', () => { + const mockRef = { + getCurrentRoute: jest.fn(() => ({ + name: 'Money_Request_Step_Confirmation', + params: {}, + })), + getState: jest.fn(() => ({})), + }; + return { + navigate: jest.fn(), + goBack: jest.fn(), + navigationRef: mockRef, + }; +}); + +jest.mock('@react-navigation/native', () => { + const mockRef = { + getCurrentRoute: jest.fn(() => ({ + name: 'Money_Request_Step_Confirmation', + params: {}, + })), + getState: jest.fn(() => ({})), + }; + return { + createNavigationContainerRef: jest.fn(() => mockRef), + useIsFocused: () => true, + useNavigation: () => ({navigate: jest.fn(), addListener: jest.fn()}), + useFocusEffect: jest.fn(), + usePreventRemove: jest.fn(), + }; +}); + const ACCOUNT_ID = 1; const ACCOUNT_LOGIN = 'test@user.com'; const REPORT_ID = '1'; const PARTICIPANT_ACCOUNT_ID = 2; const TRANSACTION_ID = '1'; +const POLICY_ID = 'test-policy-id'; + +// Helper to create a policy with tax and distance enabled +function createPolicyWithTaxAndDistance(): Policy { + const taxRates: TaxRatesWithDefault = { + name: 'Tax', + defaultExternalID: 'taxRate1', + defaultValue: '5%', + foreignTaxDefault: 'taxRate2', + taxes: { + taxRate1: { + name: 'Tax Rate 1', + value: '5%', + code: 'taxRate1', + modifiedName: 'Tax Rate 1 (5%)', + isDisabled: false, + }, + taxRate2: { + name: 'Tax Rate 2', + value: '10%', + code: 'taxRate2', + modifiedName: 'Tax Rate 2 (10%)', + isDisabled: false, + }, + }, + }; + + return { + ...createRandomPolicy(1, CONST.POLICY.TYPE.CORPORATE, 'Test Policy'), + id: POLICY_ID, + outputCurrency: 'USD', + taxRates, + tax: { + trackingEnabled: true, + }, + customUnits: { + [CONST.CUSTOM_UNITS.NAME_DISTANCE]: { + name: CONST.CUSTOM_UNITS.NAME_DISTANCE, + customUnitID: 'customUnitID', + enabled: true, + attributes: { + unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, + }, + rates: { + altTaxRate: { + name: 'Default Rate', + customUnitRateID: 'altTaxRate', + enabled: true, + currency: 'USD', + rate: 67, + attributes: { + taxRateExternalID: 'taxRate1', + taxClaimablePercentage: 1, + }, + }, + }, + }, + }, + }; +} + +// Helper to create waypoints +function createWaypoints(startAddress: string, endAddress: string): WaypointCollection { + return { + waypoint0: { + address: startAddress, + lat: 40.7128, + lng: -74.006, + name: startAddress, + }, + waypoint1: { + address: endAddress, + lat: 40.7589, + lng: -73.9851, + name: endAddress, + }, + }; +} const DEFAULT_SPLIT_TRANSACTION: Transaction = { amount: 0, @@ -215,4 +331,471 @@ describe('IOURequestStepConfirmationPageTest', () => { fireEvent.press(await screen.findByText(translateLocal('iou.createExpenses', {expensesNumber: 2}))); expect(IOU.startSplitBill).toHaveBeenCalledTimes(2); }); + + describe('Tax Calculation Tests', () => { + beforeEach(async () => { + await signInWithTestUser(ACCOUNT_ID, ACCOUNT_LOGIN); + }); + + it('should update tax amount when waypoints change in distance request (Issue #72380)', async () => { + const policy = createPolicyWithTaxAndDistance(); + const initialWaypoints = createWaypoints('New York', 'Boston'); + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { + reportID: REPORT_ID, + policyID: POLICY_ID, + type: CONST.REPORT.TYPE.EXPENSE, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + transactionID: TRANSACTION_ID, + reportID: REPORT_ID, + amount: 5000, + currency: 'USD', + comment: { + waypoints: initialWaypoints, + customUnit: { + customUnitRateID: 'altTaxRate', + }, + }, + routes: { + route0: { + distance: 100000, + geometry: { + coordinates: [ + [-74.006, 40.7128], + [-73.9851, 40.7589], + ], + }, + }, + }, + merchant: 'Distance', + created: '2025-01-15', + taxCode: 'taxRate1', + iouRequestType: CONST.IOU.REQUEST_TYPE.DISTANCE, + participants: [{accountID: PARTICIPANT_ACCOUNT_ID, selected: true}], + }); + }); + + const {rerender} = render( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Get initial tax amount from transaction + let transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const initialTaxAmount = transaction?.taxAmount; + expect(initialTaxAmount).toBeTruthy(); + expect(initialTaxAmount).toBeGreaterThan(0); + + // Update waypoints to simulate distance change + const updatedWaypoints = createWaypoints('New York', 'Philadelphia'); + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + comment: { + waypoints: updatedWaypoints, + customUnit: { + customUnitRateID: 'altTaxRate', + }, + }, + routes: { + route0: { + distance: 70000, + geometry: { + coordinates: [ + [-74.006, 40.7128], + [-75.1652, 39.9526], + ], + }, + }, + }, + amount: 3500, + }); + }); + + rerender( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Get updated tax amount + transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const updatedTaxAmount = transaction?.taxAmount; + + // Tax amount should update based on new distance + expect(updatedTaxAmount).toBeTruthy(); + expect(updatedTaxAmount).not.toBe(initialTaxAmount); + expect(updatedTaxAmount).toBeGreaterThan(0); + }); + + it('should recalculate tax amount with foreign tax rate when currency changes (Issue #73411)', async () => { + const policy = createPolicyWithTaxAndDistance(); + + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { + reportID: REPORT_ID, + policyID: POLICY_ID, + type: CONST.REPORT.TYPE.EXPENSE, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + transactionID: TRANSACTION_ID, + reportID: REPORT_ID, + amount: 10000, + currency: 'USD', + merchant: 'Test Merchant', + created: '2025-01-15', + taxCode: 'taxRate1', + taxAmount: 476, + iouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, + participants: [{accountID: PARTICIPANT_ACCOUNT_ID, selected: true}], + }); + }); + + const {rerender} = render( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Verify initial tax with default rate (5%) + let transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + expect(transaction?.taxCode).toBe('taxRate1'); + expect(transaction?.taxAmount).toBe(476); + + // Change currency to EUR (should trigger foreign tax default) + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + currency: 'EUR', + }); + }); + + rerender( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Get tax after currency change + transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + // Tax code should change to foreign default (taxRate2 - 10%) + expect(transaction?.taxCode).toBe('taxRate2'); + + // Tax amount should be recalculated with the new 10% rate (not zero, and different from 5% rate) + expect(transaction?.taxAmount).toBeDefined(); + expect(transaction?.taxAmount).toBeGreaterThan(0); + expect(transaction?.taxAmount).not.toBe(476); + + // With 10% tax on 10000: taxAmount = (10000 - 10000/1.10) = 909 + expect(transaction?.taxAmount).toBe(909); + }); + + it('should maintain consistent tax values across multiple selections (Issue #73413)', async () => { + const policy = createPolicyWithTaxAndDistance(); + + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { + reportID: REPORT_ID, + policyID: POLICY_ID, + type: CONST.REPORT.TYPE.EXPENSE, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + transactionID: TRANSACTION_ID, + reportID: REPORT_ID, + amount: 10000, + currency: 'USD', + merchant: 'Test Merchant', + created: '2025-01-15', + taxCode: 'taxRate2', + taxAmount: 909, + iouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, + participants: [{accountID: PARTICIPANT_ACCOUNT_ID, selected: true}], + }); + }); + + render( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Read tax values first time + const firstReadTransaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const firstTaxCode = firstReadTransaction?.taxCode; + const firstTaxAmount = firstReadTransaction?.taxAmount; + + expect(firstTaxCode).toBe('taxRate2'); + expect(firstTaxAmount).toBe(909); + + // Simulate navigating away and back (common user flow) + await waitForBatchedUpdatesWithAct(); + + // Read tax values second time + const secondReadTransaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const secondTaxCode = secondReadTransaction?.taxCode; + const secondTaxAmount = secondReadTransaction?.taxAmount; + + // Values should be consistent + expect(secondTaxCode).toBe(firstTaxCode); + expect(secondTaxAmount).toBe(firstTaxAmount); + }); + + it('should handle edge case: tax calculation with changing distance rates', async () => { + const policy = createPolicyWithTaxAndDistance(); + const waypoints = createWaypoints('San Francisco', 'Los Angeles'); + + // Add a second rate to the policy + if (policy.customUnits?.[CONST.CUSTOM_UNITS.NAME_DISTANCE]) { + policy.customUnits[CONST.CUSTOM_UNITS.NAME_DISTANCE].rates = { + ...policy.customUnits[CONST.CUSTOM_UNITS.NAME_DISTANCE].rates, + altTaxRate2: { + name: 'Higher Rate', + customUnitRateID: 'altTaxRate2', + enabled: true, + currency: 'USD', + rate: 100, + attributes: { + taxRateExternalID: 'taxRate2', + taxClaimablePercentage: 1, + }, + }, + }; + } + + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { + reportID: REPORT_ID, + policyID: POLICY_ID, + type: CONST.REPORT.TYPE.EXPENSE, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + transactionID: TRANSACTION_ID, + reportID: REPORT_ID, + amount: 5000, + currency: 'USD', + comment: { + waypoints, + customUnit: { + customUnitRateID: 'altTaxRate', + }, + }, + routes: { + route0: { + distance: 100000, + geometry: { + coordinates: [ + [-122.4194, 37.7749], + [-118.2437, 34.0522], + ], + }, + }, + }, + merchant: 'Distance', + created: '2025-01-15', + taxCode: 'taxRate1', + iouRequestType: CONST.IOU.REQUEST_TYPE.DISTANCE, + participants: [{accountID: PARTICIPANT_ACCOUNT_ID, selected: true}], + }); + }); + + const {rerender} = render( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Get initial tax + let transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const initialTaxAmount = transaction?.taxAmount; + const initialTaxCode = transaction?.taxCode; + + // Switch to higher rate + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { + comment: { + waypoints, + customUnit: { + customUnitRateID: 'altTaxRate2', + }, + }, + routes: { + route0: { + distance: 100000, + geometry: { + coordinates: [ + [-122.4194, 37.7749], + [-118.2437, 34.0522], + ], + }, + }, + }, + amount: 7500, + taxCode: 'taxRate2', + }); + }); + + rerender( + + + + + + + , + ); + + await waitForBatchedUpdatesWithAct(); + + // Get updated tax + transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + + const updatedTaxAmount = transaction?.taxAmount; + const updatedTaxCode = transaction?.taxCode; + + // Tax should update appropriately with new rate + expect(updatedTaxAmount).toBeDefined(); + expect(updatedTaxAmount).toBeGreaterThan(0); + expect(updatedTaxCode).toBe('taxRate2'); + expect(updatedTaxAmount).not.toBe(initialTaxAmount); + expect(updatedTaxCode).not.toBe(initialTaxCode); + }); + }); }); From 2495f8be5c114e651a0d3e3d58b61a91e72b2cc8 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 11 Nov 2025 17:49:05 -0800 Subject: [PATCH 2/5] Fix #73411 by removing unnecessary code that was clearing the tax rate --- src/pages/iou/request/step/IOURequestStepAmount.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 59ca04cf8cee..72979de593ae 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -33,7 +33,6 @@ import { setDraftSplitTransaction, setMoneyRequestAmount, setMoneyRequestParticipantsFromReport, - setMoneyRequestTaxAmount, setSplitShares, trackExpense, updateMoneyRequestAmountAndCurrency, @@ -177,10 +176,6 @@ function IOURequestStepAmount({ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing setMoneyRequestAmount(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, shouldKeepUserInput); - // Initially when we're creating money request, we do not know the participant and hence if the request is with workspace with tax tracking enabled - // So, we reset the taxAmount here and calculate it in the hook in MoneyRequestConfirmationList component - setMoneyRequestTaxAmount(transactionID, null); - if (backTo) { Navigation.goBack(backTo); return; From 0fdf0d2e5d723f6abcfeb1a483458b5f94e6252c Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 12 Nov 2025 10:18:09 -0800 Subject: [PATCH 3/5] Default taxClaimablePercentage to 1 --- src/libs/DistanceRequestUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 0d363d599be5..2ddceaef38e9 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -335,7 +335,7 @@ function getTaxableAmount(policy: OnyxEntry, customUnitRateID: string, d const unit = distanceUnit?.attributes?.unit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES; const rate = customUnitRate?.rate ?? CONST.DEFAULT_NUMBER_ID; const amount = getDistanceRequestAmount(distance, unit, rate); - const taxClaimablePercentage = customUnitRate.attributes?.taxClaimablePercentage ?? CONST.DEFAULT_NUMBER_ID; + const taxClaimablePercentage = customUnitRate.attributes?.taxClaimablePercentage ?? 1; return amount * taxClaimablePercentage; } From a92928f926bc0b7316282c476a197e5ef16f6f27 Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 12 Nov 2025 10:22:56 -0800 Subject: [PATCH 4/5] Fix tests --- .../IOURequestStepConfirmationPageTest.tsx | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx index 456112ab961e..5d7ad00a595b 100644 --- a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx +++ b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx @@ -572,8 +572,27 @@ describe('IOURequestStepConfirmationPageTest', () => { expect(transaction?.taxAmount).toBe(909); }); - it('should maintain consistent tax values across multiple selections (Issue #73413)', async () => { + it('should not zero out tax when re-selecting distance rate without reclaimable configured (Issue #73413)', async () => { const policy = createPolicyWithTaxAndDistance(); + const waypoints = createWaypoints('New York', 'Boston'); + + // Add a second rate WITHOUT taxClaimablePercentage (simulating no reclaimable amount entered) + if (policy.customUnits?.[CONST.CUSTOM_UNITS.NAME_DISTANCE]) { + policy.customUnits[CONST.CUSTOM_UNITS.NAME_DISTANCE].rates = { + ...policy.customUnits[CONST.CUSTOM_UNITS.NAME_DISTANCE].rates, + altTaxRate2: { + name: 'Rate Without Reclaimable', + customUnitRateID: 'altTaxRate2', + enabled: true, + currency: 'USD', + rate: 100, + attributes: { + taxRateExternalID: 'taxRate2', + // Note: taxClaimablePercentage intentionally omitted to test the bug + }, + }, + }; + } await act(async () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy); @@ -585,13 +604,29 @@ describe('IOURequestStepConfirmationPageTest', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`, { transactionID: TRANSACTION_ID, reportID: REPORT_ID, - amount: 10000, + amount: 5000, currency: 'USD', - merchant: 'Test Merchant', + comment: { + waypoints, + customUnit: { + customUnitRateID: 'altTaxRate2', + }, + }, + routes: { + route0: { + distance: 100000, + geometry: { + coordinates: [ + [-74.006, 40.7128], + [-73.9851, 40.7589], + ], + }, + }, + }, + merchant: 'Distance', created: '2025-01-15', taxCode: 'taxRate2', - taxAmount: 909, - iouRequestType: CONST.IOU.REQUEST_TYPE.MANUAL, + iouRequestType: CONST.IOU.REQUEST_TYPE.DISTANCE, participants: [{accountID: PARTICIPANT_ACCOUNT_ID, selected: true}], }); }); @@ -621,27 +656,15 @@ describe('IOURequestStepConfirmationPageTest', () => { await waitForBatchedUpdatesWithAct(); - // Read tax values first time - const firstReadTransaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); + // Read tax amount - should NOT be zero even though taxClaimablePercentage is not configured + const transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); - const firstTaxCode = firstReadTransaction?.taxCode; - const firstTaxAmount = firstReadTransaction?.taxAmount; - - expect(firstTaxCode).toBe('taxRate2'); - expect(firstTaxAmount).toBe(909); - - // Simulate navigating away and back (common user flow) - await waitForBatchedUpdatesWithAct(); - - // Read tax values second time - const secondReadTransaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID}`); - - const secondTaxCode = secondReadTransaction?.taxCode; - const secondTaxAmount = secondReadTransaction?.taxAmount; + // With the fix, taxClaimablePercentage defaults to 1 (100%), so tax should calculate correctly + expect(transaction?.taxAmount).toBeDefined(); + expect(transaction?.taxAmount).toBeGreaterThan(0); - // Values should be consistent - expect(secondTaxCode).toBe(firstTaxCode); - expect(secondTaxAmount).toBe(firstTaxAmount); + // Tax code should be taxRate2 (from the distance rate configuration) + expect(transaction?.taxCode).toBe('taxRate2'); }); it('should handle edge case: tax calculation with changing distance rates', async () => { From 5ac2908baef3ca394902b4c91db552a210a60f8b Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 12 Nov 2025 10:57:52 -0800 Subject: [PATCH 5/5] Don't reference issue numbers in tests --- tests/ui/components/IOURequestStepConfirmationPageTest.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx index 5d7ad00a595b..f8f3abc93264 100644 --- a/tests/ui/components/IOURequestStepConfirmationPageTest.tsx +++ b/tests/ui/components/IOURequestStepConfirmationPageTest.tsx @@ -337,7 +337,7 @@ describe('IOURequestStepConfirmationPageTest', () => { await signInWithTestUser(ACCOUNT_ID, ACCOUNT_LOGIN); }); - it('should update tax amount when waypoints change in distance request (Issue #72380)', async () => { + it('should update tax amount when waypoints change in distance request', async () => { const policy = createPolicyWithTaxAndDistance(); const initialWaypoints = createWaypoints('New York', 'Boston'); await act(async () => { @@ -470,7 +470,7 @@ describe('IOURequestStepConfirmationPageTest', () => { expect(updatedTaxAmount).toBeGreaterThan(0); }); - it('should recalculate tax amount with foreign tax rate when currency changes (Issue #73411)', async () => { + it('should recalculate tax amount with foreign tax rate when currency changes', async () => { const policy = createPolicyWithTaxAndDistance(); await act(async () => { @@ -572,7 +572,7 @@ describe('IOURequestStepConfirmationPageTest', () => { expect(transaction?.taxAmount).toBe(909); }); - it('should not zero out tax when re-selecting distance rate without reclaimable configured (Issue #73413)', async () => { + it('should not zero out tax when re-selecting distance rate without reclaimable configured', async () => { const policy = createPolicyWithTaxAndDistance(); const waypoints = createWaypoints('New York', 'Boston');