Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
7adaf4c
Fetch default P2P mileage rate from Auth when creating distance expense
MelvinBot Mar 10, 2026
23f03e3
Fix: run prettier on Transaction.ts and onyx/index.ts
MelvinBot Mar 10, 2026
ba039cd
Fix: narrow MileageRate types in getDefaultMileageRateForCurrency
MelvinBot Mar 10, 2026
c782f2c
Simplify to store a single P2P mileage rate from Auth
MelvinBot Mar 23, 2026
ce02083
Rename to GetDefaultP2PMileageRate and use DEFAULT_P2P_MILEAGE_RATE O…
neil-marcellini Mar 23, 2026
189c558
Remove CURRENCY_TO_DEFAULT_MILEAGE_RATE from App
neil-marcellini Mar 23, 2026
7d3b1d1
Remove currency param from GetDefaultP2PMileageRate calls
neil-marcellini Mar 26, 2026
a81ff36
Merge main and resolve conflicts
neil-marcellini Mar 26, 2026
c8c6799
Refactor: Replace Onyx.connect with useOnyx for defaultP2PMileageRate
neil-marcellini Mar 26, 2026
c4b82e9
Fix: break circular dependency causing test failures
MelvinBot Mar 26, 2026
74048dd
Revert unintentional Mobile-Expensify submodule change and remove ext…
neil-marcellini Mar 27, 2026
816b22e
Rename fetchDefaultP2PMileageRate to getDefaultP2PMileageRate
neil-marcellini Mar 27, 2026
2d0ba40
Update Mobile-Expensify submodule to match main
neil-marcellini Mar 27, 2026
50318b8
Merge branch 'main' into claude-loadDefaultP2PRateOnDistanceExpense
neil-marcellini Mar 27, 2026
c6f4595
Fix: sort import order for DefaultP2PMileageRateStore
MelvinBot Mar 27, 2026
017e001
Fix: use default export for DefaultP2PMileageRateStore single export
MelvinBot Mar 27, 2026
01db696
Remove DefaultP2PMileageRateStore, thread param from useOnyx
neil-marcellini Mar 27, 2026
138b22d
Remove defaultP2PMileageRate from non-distance updateMoneyRequest fun…
neil-marcellini Mar 30, 2026
48723e3
Remove redundant true arg from non-distance getUpdateTrackExpensePara…
neil-marcellini Mar 30, 2026
4fc3083
Remove extra param
neil-marcellini Mar 30, 2026
f3e0771
Remove getDefaultP2PMileageRate fallback function
neil-marcellini Mar 30, 2026
4762bb5
Merge main and resolve conflicts
neil-marcellini Mar 30, 2026
8cf5b4e
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
neil-marcellini Apr 7, 2026
b8e01f7
Suppress pre-existing react-hooks/set-state-in-effect warnings in Spl…
neil-marcellini Apr 7, 2026
d78835a
Fix Prettier and ESLint CI failures
neil-marcellini Apr 7, 2026
02b88a2
Merge branch 'main' into claude-loadDefaultP2PRateOnDistanceExpense
neil-marcellini Apr 8, 2026
ed9ee57
Restore shouldShowBusinessBankAccountOptions to useMemo dependency array
neil-marcellini Apr 8, 2026
f95b4cb
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
MelvinBot Apr 8, 2026
cb08f95
Restore AddNewCardPage to use useState instead of useConfirmModal
MelvinBot Apr 8, 2026
f8ce1ec
Simplify policyForMovingExpenses pass-through in getRate call
neil-marcellini Apr 9, 2026
58af665
Make translate and toLocaleDigit required in changeTransactionsReport
neil-marcellini Apr 9, 2026
c054ec1
Refactor isUnreportedAndHasInvalidDistanceRateTransaction to use earl…
neil-marcellini Apr 9, 2026
2e19313
Remove translate/toLocaleDigit fallbacks from recalculateUnreportedTr…
neil-marcellini Apr 9, 2026
19a8693
Use early return for non-distance requests in recalculateUnreportedTr…
neil-marcellini Apr 9, 2026
00ebc42
Thread translate/toLocaleDigit from components into deleteAppReport
neil-marcellini Apr 9, 2026
f5cf791
Remove isUnreportedAndHasInvalidDistanceRateTransaction
neil-marcellini Apr 9, 2026
611a26a
Merge main and resolve conflicts
neil-marcellini Apr 9, 2026
6de9120
Fix typecheck: add translate/toLocaleDigit to changeTransactionsRepor…
MelvinBot Apr 9, 2026
4b7896a
Merge main and resolve conflicts
neil-marcellini Apr 15, 2026
56e75b2
Trim unnecessary defaultP2PMileageRate from components that don't nee…
neil-marcellini Apr 15, 2026
3a64479
Remove unused localeCompare import from IOUTest.ts
MelvinBot Apr 15, 2026
331a602
Simplify: fetch default P2P mileage rate into plain variable
neil-marcellini Apr 15, 2026
335966a
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
neil-marcellini May 22, 2026
9610209
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
neil-marcellini May 22, 2026
4fa91a4
Revert unintended ReportActionsUtils changes inherited from old merge
neil-marcellini May 22, 2026
7b43d16
Narrow DefaultP2PMileageRate.unit to Unit and add unit tests
neil-marcellini May 22, 2026
046eb43
Fix SessionTest: account for GetDefaultP2PMileageRate xhr call in moc…
MelvinBot May 22, 2026
39502d3
Merge remote-tracking branch 'origin/claude-loadDefaultP2PRateOnDista…
MelvinBot May 22, 2026
082fdd3
Reset Mobile-Expensify submodule pointer to match main
neil-marcellini May 22, 2026
05bcbac
Fix P2P fallback rate magnitude and clear stale cache before refetch
neil-marcellini May 22, 2026
fdc5429
Fetch default P2P mileage rate when starting any track distance flow …
neil-marcellini Jun 2, 2026
5d91232
WIP change approach, add module for stored default p2p mileage rate
neil-marcellini Jun 2, 2026
15e1ccb
Add Onyx key type definition
neil-marcellini Jun 2, 2026
78a6ed7
Clean up all non-test code for new approach
neil-marcellini Jun 2, 2026
9e4b9c6
Merge main and update P2P mileage rate unit tests
neil-marcellini Jun 2, 2026
c0c073a
Remove obsolete GetDefaultP2PMileageRate mock from SessionTest
neil-marcellini Jun 2, 2026
8b0d7a3
Fix typecheck and prettier failures
MelvinBot Jun 2, 2026
740bb76
Merge remote-tracking branch 'origin/claude-loadDefaultP2PRateOnDista…
MelvinBot Jun 2, 2026
ff667f0
Fix ESLint consistent-type-imports on DefaultP2PMileageRate import
MelvinBot Jun 2, 2026
181ede3
Fall back to transaction currency/unit in getRateForP2P when default …
neil-marcellini Jun 2, 2026
722d337
Simplify comment
neil-marcellini Jun 2, 2026
79aaf84
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
MelvinBot Jun 3, 2026
9440958
Extract DEFAULT_P2P_RATE_CENTS_PER_MILE constant
neil-marcellini Jun 3, 2026
5590a1b
Guard on transaction existence per review
neil-marcellini Jun 9, 2026
a5e2427
Fix: avoid unsafe type assertion in DefaultP2PMileageRateTest
MelvinBot Jun 9, 2026
153f0b2
Merge branch 'main' into claude-loadDefaultP2PRateOnDistanceExpense
neil-marcellini Jun 9, 2026
c59d552
Merge remote-tracking branch 'origin/main' into claude-loadDefaultP2P…
MelvinBot Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
673 changes: 0 additions & 673 deletions src/CONST/index.ts

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {OnboardingCompanySize} from './libs/actions/Welcome/OnboardingFlow'
import type Platform from './libs/getPlatform/types';
import type * as FormTypes from './types/form';
import type * as OnyxTypes from './types/onyx';
import type DefaultP2PMileageRate from './types/onyx/DefaultP2PMileageRate';
import type {Attendee, DistanceExpenseType, Participant} from './types/onyx/IOU';
import type Onboarding from './types/onyx/Onboarding';
import type {AnyOnyxUpdate} from './types/onyx/Request';
Expand All @@ -27,6 +28,9 @@ const ONYXKEYS = {
* which tab is the leader, and which ones are the followers */
ACTIVE_CLIENTS: 'activeClients',

/** Contains the default rate and unit to use for P2P distance expenses, based on the user's personal policy outputCurrency (default / report currency). */
DEFAULT_P2P_MILEAGE_RATE: 'defaultP2PMileageRate',

/** A unique ID for the device */
DEVICE_ID: 'deviceID',

Expand Down Expand Up @@ -1437,6 +1441,7 @@ type OnyxCollectionValuesMapping = {
type OnyxValuesMapping = {
[ONYXKEYS.ACCOUNT]: OnyxTypes.Account;
[ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string;
[ONYXKEYS.DEFAULT_P2P_MILEAGE_RATE]: DefaultP2PMileageRate;

[ONYXKEYS.NVP_ONBOARDING]: Onboarding;

Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,7 @@ type WriteCommandParameters = {
};

const READ_COMMANDS = {
GET_DEFAULT_P2P_MILEAGE_RATE: 'GetDefaultP2PMileageRate',
GET_CORPAY_BANK_ACCOUNT_FIELDS: 'GetCorpayBankAccountFields',
CONNECT_POLICY_TO_QUICKBOOKS_ONLINE: 'ConnectPolicyToQuickbooksOnline',
CONNECT_POLICY_TO_XERO: 'ConnectPolicyToXero',
Expand Down Expand Up @@ -1380,6 +1381,7 @@ const READ_COMMANDS = {
type ReadCommand = ValueOf<typeof READ_COMMANDS>;

type ReadCommandParameters = {
[READ_COMMANDS.GET_DEFAULT_P2P_MILEAGE_RATE]: null;
[READ_COMMANDS.CONNECT_POLICY_TO_QUICKBOOKS_ONLINE]: Parameters.ConnectPolicyToAccountingIntegrationParams;
[READ_COMMANDS.CONNECT_POLICY_TO_XERO]: Parameters.ConnectPolicyToAccountingIntegrationParams;
[READ_COMMANDS.CONNECT_POLICY_TO_GUSTO]: Parameters.ConnectPolicyToGustoParams;
Expand Down
24 changes: 10 additions & 14 deletions src/libs/DistanceRequestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import type {LocaleContextProps} from '@components/LocaleContextProvider';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {LastSelectedDistanceRates, OnyxInputOrEntry, Transaction} from '@src/types/onyx';
import type DefaultP2PMileageRate from '@src/types/onyx/DefaultP2PMileageRate';
import type {Unit} from '@src/types/onyx/Policy';
import type Policy from '@src/types/onyx/Policy';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import getStoredDefaultP2PMileageRate from './getStoredDefaultP2PMileageRate';
import {replaceAllDigits} from './MoneyRequestUtils';
import {getDistanceRateCustomUnit, getDistanceRateCustomUnitRate, getUnitRateValue} from './PolicyUtils';
import {getCurrency, getRateID, isCustomUnitRateIDForP2P, isExpenseUnreported} from './TransactionUtils';
Expand All @@ -33,6 +35,7 @@ Onyx.connectWithoutView({

const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters
const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter
const DEFAULT_P2P_RATE_CENTS_PER_MILE = 67;

function getMileageRates(policy: OnyxInputOrEntry<Policy>, includeDisabledRates = false, selectedRateID?: string): Record<string, MileageRate> {
const mileageRates: Record<string, MileageRate> = {};
Expand Down Expand Up @@ -276,13 +279,6 @@ function getDistanceMerchant(
return `${distanceInUnits} ${CONST.DISTANCE_MERCHANT_SEPARATOR} ${ratePerUnit}`;
}

function ensureRateDefined(rate: number | undefined): asserts rate is number {
if (rate !== undefined) {
return;
}
throw new Error('All default P2P rates should have a rate defined');
}

/**
* Retrieves the rate and unit for a P2P distance expense for a given currency.
*
Expand All @@ -292,16 +288,16 @@ function ensureRateDefined(rate: number | undefined): asserts rate is number {
* @returns The rate and unit in MileageRate object.
*/
function getRateForP2P(currency: string, transaction: OnyxEntry<Transaction>): MileageRate {
Comment thread
neil-marcellini marked this conversation as resolved.
const currencyWithExistingRate = CONST.CURRENCY_TO_DEFAULT_MILEAGE_RATE[currency] ? currency : CONST.CURRENCY.USD;
const mileageRate = CONST.CURRENCY_TO_DEFAULT_MILEAGE_RATE[currencyWithExistingRate];
ensureRateDefined(mileageRate.rate);
const defaultRate = getStoredDefaultP2PMileageRate();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Re-render consumers when the P2P rate arrives

Because this reads the new Onyx key through a connectWithoutView-backed module variable, components that call DistanceRequestUtils.getRate()/getRateForP2P() do not subscribe to DEFAULT_P2P_MILEAGE_RATE. startDistanceRequest() fires the read immediately before navigation, so on the normal async path the distance screens can render with the hardcoded miles fallback and never re-render when the fetched rate/unit arrives; for currencies whose default unit is km, a manual submit can keep the stale unit from render while later amount/merchant calculations use the newly cached rate, producing the wrong distance amount and label. Please have the relevant screens subscribe to this Onyx key or otherwise trigger recalculation when it changes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yes this is a known limitation of the approach, and maybe a good reason to load it in OpenApp instead. I think in practice though the rate will usually load before a user reaches the screen where it displays.

const p2pRate: DefaultP2PMileageRate = defaultRate ?? {rate: DEFAULT_P2P_RATE_CENTS_PER_MILE, unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES};
const rate = transaction && getCurrency(transaction) === currency ? (transaction.comment?.customUnit?.defaultP2PRate ?? p2pRate.rate) : p2pRate.rate;

// Ensure the rate is updated when the currency changes, otherwise use the stored rate
const rate = getCurrency(transaction) === currency ? (transaction?.comment?.customUnit?.defaultP2PRate ?? mileageRate.rate) : mileageRate.rate;
// If a distance expense is being edited, the defaultP2PRate may not have been loaded yet, so use data from the existing transaction.
const fallbackUnit = transaction?.comment?.customUnit?.distanceUnit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES;
return {
...mileageRate,
currency: currencyWithExistingRate,
rate,
unit: defaultRate ? p2pRate.unit : fallbackUnit,
currency: defaultRate ? currency : getCurrency(transaction),
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/libs/actions/IOU/MoneyRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
isOdometerDistanceRequest as isOdometerDistanceRequestTransactionUtils,
} from '@libs/TransactionUtils';
import type {ReceiptFile} from '@pages/iou/request/step/IOURequestStepScan/types';
import {getDefaultP2PMileageRate} from '@userActions/Transaction';
import {getRemoveDraftTransactionsByIDsData, removeDraftTransactionsByIDs} from '@userActions/TransactionEdit';
import type {IOURequestType} from '@src/CONST';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -440,6 +441,7 @@ function startDistanceRequest(
backToReport?: string,
isFromFloatingActionButton?: boolean,
) {
getDefaultP2PMileageRate();
clearMoneyRequest(CONST.IOU.OPTIMISTIC_TRANSACTION_ID, draftTransactionIDs, skipConfirmation);
if (isFromFloatingActionButton) {
Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`, {isFromFloatingActionButton});
Expand Down
5 changes: 5 additions & 0 deletions src/libs/actions/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,10 @@ function changeTransactionsReport({
});
}

function getDefaultP2PMileageRate() {
API.read(READ_COMMANDS.GET_DEFAULT_P2P_MILEAGE_RATE, null);
}

function mergeTransactionIdsHighlightOnSearchRoute(type: SearchDataTypes, data: Record<string, boolean> | null) {
return Onyx.merge(ONYXKEYS.TRANSACTION_IDS_HIGHLIGHT_ON_SEARCH_ROUTE, {[type]: data});
}
Expand Down Expand Up @@ -1845,6 +1849,7 @@ export {
revert,
changeTransactionsReport,
setTransactionReport,
getDefaultP2PMileageRate,
mergeTransactionIdsHighlightOnSearchRoute,
getDuplicateTransactionDetails,
};
24 changes: 24 additions & 0 deletions src/libs/getStoredDefaultP2PMileageRate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This module is used to load the default P2P mileage rate for a user based on their personal policy outputCurrency (default / reporting currency).
// Whenever a user starts the "Track distance" flow the getDefaultP2PMileageRate action will fetch the rate and unit from the hard coded mapping stored in Auth
// (CURRENCY_TO_DEFAULT_MILEAGE_RATE), via the API read command GetDefaultP2PMileageRate.
// The rate will be stored in Onyx and loaded into a variable here via Onyx.connectWithoutView. Normally useOnyx should be used instead, but because
// the default P2P mileage rate is used across many library functions an exception is allowed to prevent having to pass the value through many functions
// across the codebase.
// DO NOT use this pattern for other Onyx data unless you get authorization from the internal Expensify team in Slack.
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';
import type DefaultP2PMileageRate from '@src/types/onyx/DefaultP2PMileageRate';

let defaultP2PMileageRate: DefaultP2PMileageRate | undefined;
Onyx.connectWithoutView({
key: ONYXKEYS.DEFAULT_P2P_MILEAGE_RATE,
callback: (value) => {
defaultP2PMileageRate = value;
},
});

function getStoredDefaultP2PMileageRate() {
return defaultP2PMileageRate;
}

export default getStoredDefaultP2PMileageRate;
12 changes: 12 additions & 0 deletions src/types/onyx/DefaultP2PMileageRate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type {Unit} from './Policy';

/** Default P2P mileage rate fetched from Auth for the user's personal policy outputCurrency (default / report currency) */
type DefaultP2PMileageRate = {
/** Rate in cents per unit (e.g. 67 = $0.67/mile) */
rate: number;

/** Distance unit: "mi" or "km" */
unit: Unit;
};

export default DefaultP2PMileageRate;
70 changes: 70 additions & 0 deletions tests/unit/DefaultP2PMileageRateTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Onyx from 'react-native-onyx';
import {getDefaultP2PMileageRate} from '@libs/actions/Transaction';
import * as API from '@libs/API';
import {READ_COMMANDS} from '@libs/API/types';
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
import getStoredDefaultP2PMileageRate from '@libs/getStoredDefaultP2PMileageRate';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import createRandomTransaction from '../utils/collections/transaction';
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';

describe('Default P2P mileage rate', () => {
beforeAll(() => {
Onyx.init({
keys: ONYXKEYS,
});
});

beforeEach(() => {
return Onyx.clear().then(waitForBatchedUpdates);
});

afterEach(() => {
jest.restoreAllMocks();
});

describe('getDefaultP2PMileageRate', () => {
it('calls API.read with GetDefaultP2PMileageRate', () => {
const readSpy = jest.spyOn(API, 'read').mockImplementation(() => {});

getDefaultP2PMileageRate();

expect(readSpy).toHaveBeenCalledWith(READ_COMMANDS.GET_DEFAULT_P2P_MILEAGE_RATE, null);
});
});

describe('getRateForP2P', () => {
it('falls back to USD 67¢/mile when no rate has been stored in Onyx', () => {
const result = DistanceRequestUtils.getRateForP2P('EUR', undefined);

expect(result).toEqual({rate: 67, unit: 'mi', currency: CONST.CURRENCY.USD});
});

it('uses the stored Onyx rate with the caller currency once a rate is available', async () => {
await Onyx.set(ONYXKEYS.DEFAULT_P2P_MILEAGE_RATE, {rate: 5500, unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS});
await waitForBatchedUpdates();

expect(getStoredDefaultP2PMileageRate()).toEqual({rate: 5500, unit: 'km'});

const result = DistanceRequestUtils.getRateForP2P('EUR', undefined);

expect(result).toEqual({rate: 5500, unit: 'km', currency: 'EUR'});
});

it('uses the transaction defaultP2PRate when the transaction currency matches', async () => {
await Onyx.set(ONYXKEYS.DEFAULT_P2P_MILEAGE_RATE, {rate: 5500, unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES});
await waitForBatchedUpdates();

const transaction = {
...createRandomTransaction(1),
currency: CONST.CURRENCY.USD,
comment: {customUnit: {defaultP2PRate: 99}},
};

const result = DistanceRequestUtils.getRateForP2P(CONST.CURRENCY.USD, transaction);

expect(result).toEqual({rate: 99, unit: 'mi', currency: CONST.CURRENCY.USD});
});
});
});
34 changes: 34 additions & 0 deletions tests/unit/DistanceRequestUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import DistanceRequestUtils from '@libs/DistanceRequestUtils';
import CONST from '@src/CONST';
import type {Unit} from '@src/types/onyx/Policy';
import type Policy from '@src/types/onyx/Policy';
import type Transaction from '@src/types/onyx/Transaction';
import createRandomTransaction from '../utils/collections/transaction';
import {translateLocal} from '../utils/TestHelper';

Expand Down Expand Up @@ -214,6 +215,39 @@ describe('DistanceRequestUtils', () => {
});
});

describe('getRateForP2P', () => {
// These tests run with the default P2P mileage rate unloaded (it's fetched asynchronously when a
// distance request starts), which is the case for flows that don't start a new distance request,
// such as editing an existing distance expense.
it('falls back to the existing transaction currency and unit when the default P2P rate is not loaded', () => {
// Given an existing P2P distance expense in GBP measured in kilometers, with its own saved rate
const transaction = {
...createRandomTransaction(1),
currency: 'GBP',
comment: {customUnit: {distanceUnit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS, defaultP2PRate: 45}},
} as Transaction;

// When reading the P2P rate for that transaction's currency
const result = DistanceRequestUtils.getRateForP2P('GBP', transaction);

// Then it preserves the transaction's currency, unit, and saved rate instead of flipping to USD/miles
expect(result.currency).toBe('GBP');
expect(result.unit).toBe(CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS);
expect(result.rate).toBe(45);
});

it('falls back to USD and miles for a brand-new request with no transaction', () => {
// Given a brand-new distance request that has no transaction yet
// When reading the P2P rate
const result = DistanceRequestUtils.getRateForP2P('GBP', undefined);

// Then it falls back to the hardcoded USD/miles default
expect(result.currency).toBe(CONST.CURRENCY.USD);
expect(result.unit).toBe(CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES);
expect(result.rate).toBe(67);
});
});

describe('getDistanceMerchant', () => {
const toLocaleDigitMock = (dot: string): string => dot;
const getCurrencySymbolMock = (currency: string): string | undefined => {
Expand Down
Loading