Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 11 additions & 3 deletions src/libs/actions/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@
import {getPolicyTagsData} from './Policy/Tag';

let recentWaypoints: RecentWaypoint[] = [];
Onyx.connect({

Check warning on line 54 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NVP_RECENT_WAYPOINTS,
callback: (val) => (recentWaypoints = val ?? []),
});

const allTransactions: Record<string, Transaction> = {};
Onyx.connect({

Check warning on line 60 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION,
callback: (transaction, key) => {
if (!key || !transaction) {
Expand All @@ -69,7 +69,7 @@
});

let allTransactionDrafts: OnyxCollection<Transaction> = {};
Onyx.connect({

Check warning on line 72 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -78,7 +78,7 @@
});

let allReports: OnyxCollection<Report> = {};
Onyx.connect({

Check warning on line 81 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -90,7 +90,7 @@
});

const allTransactionViolation: OnyxCollection<TransactionViolation[]> = {};
Onyx.connect({

Check warning on line 93 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
callback: (transactionViolation, key) => {
if (!key || !transactionViolation) {
Expand All @@ -102,7 +102,7 @@
});

let allTransactionViolations: TransactionViolations = [];
Onyx.connect({

Check warning on line 105 in src/libs/actions/Transaction.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
callback: (val) => (allTransactionViolations = val ?? []),
});
Expand All @@ -112,7 +112,15 @@
return !!(violation && typeof violation === 'object' && typeof (violation as {name?: unknown}).name === 'string');
}

function saveWaypoint(transactionID: string, index: string, waypoint: RecentWaypoint | null, isDraft = false) {
type SaveWaypointProps = {
transactionID: string;
index: string;
waypoint: RecentWaypoint | null;
isDraft?: boolean;
recentWaypointsList?: RecentWaypoint[];
};

function saveWaypoint({transactionID, index, waypoint, isDraft = false, recentWaypointsList = []}: SaveWaypointProps) {
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {
comment: {
waypoints: {
Expand Down Expand Up @@ -154,9 +162,9 @@
if (deepEqual(waypoint?.address, CONST.YOUR_LOCATION_TEXT)) {
return;
}
const recentWaypointAlreadyExists = recentWaypoints.find((recentWaypoint) => recentWaypoint?.address === waypoint?.address);
const recentWaypointAlreadyExists = recentWaypointsList.find((recentWaypoint) => recentWaypoint?.address === waypoint?.address);
if (!recentWaypointAlreadyExists && waypoint !== null) {
const clonedWaypoints = lodashClone(recentWaypoints);
const clonedWaypoints = lodashClone(recentWaypointsList);
const updatedWaypoint = {...waypoint, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD};
clonedWaypoints.unshift(updatedWaypoint);
Onyx.merge(ONYXKEYS.NVP_RECENT_WAYPOINTS, clonedWaypoints.slice(0, CONST.RECENT_WAYPOINTS_NUMBER));
Expand Down
7 changes: 5 additions & 2 deletions src/pages/iou/request/step/IOURequestStepWaypoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function IOURequestStepWaypoint({

const [userLocation] = useOnyx(ONYXKEYS.USER_LOCATION, {canBeMissing: true});
const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {selector: recentWaypointsSelector, canBeMissing: true});
const [allRecentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {canBeMissing: true});

const waypointDescriptionKey = useMemo(() => {
switch (parsedWaypointIndex) {
Expand Down Expand Up @@ -124,7 +125,9 @@ function IOURequestStepWaypoint({
return errors;
};

const save = (waypoint: FormOnyxValues<'waypointForm'>) => saveWaypoint(transactionID, pageIndex, waypoint, shouldUseTransactionDraft(action));
const save = (waypoint: FormOnyxValues<'waypointForm'>) => {
saveWaypoint({transactionID, index: pageIndex, waypoint, isDraft: shouldUseTransactionDraft(action), recentWaypointsList: allRecentWaypoints});
};

const submit = (values: FormOnyxValues<'waypointForm'>) => {
const waypointValue = values[`waypoint${pageIndex}`] ?? '';
Expand Down Expand Up @@ -166,7 +169,7 @@ function IOURequestStepWaypoint({
keyForList: `${values.name ?? 'waypoint'}_${Date.now()}`,
};

saveWaypoint(transactionID, pageIndex, waypoint, shouldUseTransactionDraft(action));
saveWaypoint({transactionID, index: pageIndex, waypoint, isDraft: shouldUseTransactionDraft(action), recentWaypointsList: allRecentWaypoints});
goBack();
};

Expand Down
107 changes: 105 additions & 2 deletions tests/unit/TransactionTest.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {renderHook} from '@testing-library/react-native';
import type {OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import OnyxUtils from 'react-native-onyx/dist/OnyxUtils';
import useOnyx from '@hooks/useOnyx';
import {changeTransactionsReport} from '@libs/actions/Transaction';
import {changeTransactionsReport, saveWaypoint} from '@libs/actions/Transaction';
import DateUtils from '@libs/DateUtils';
import {getAllNonDeletedTransactions} from '@libs/MoneyRequestReportUtils';
import {rand64} from '@libs/NumberUtils';
Expand All @@ -12,7 +13,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type {Attendee} from '@src/types/onyx/IOU';
import type {ReportCollectionDataSet} from '@src/types/onyx/Report';
import * as TransactionUtils from '../../src/libs/TransactionUtils';
import type {ReportAction, ReportActions, Transaction} from '../../src/types/onyx';
import type {RecentWaypoint, ReportAction, ReportActions, Transaction} from '../../src/types/onyx';
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';

function generateTransaction(values: Partial<Transaction> = {}): Transaction {
Expand Down Expand Up @@ -405,4 +406,106 @@ describe('Transaction', () => {
expect(result.at(0)).toEqual(transaction);
});
});

describe('saveWaypoint', () => {
it('should save a waypoint with lat/lng and not YOUR_LOCATION_TEXT', async () => {
const transactionID = 'txn1';
const index = '0';
const waypoint: RecentWaypoint = {
address: '123 Main St',
lat: 10,
lng: 20,
};
const recentWaypointsList: RecentWaypoint[] = [];
saveWaypoint({transactionID, index, waypoint, isDraft: false, recentWaypointsList});
await waitForBatchedUpdates();

const transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`);
const updatedRecentWaypoints = await OnyxUtils.get(ONYXKEYS.NVP_RECENT_WAYPOINTS);

expect(transaction?.comment?.waypoints?.[`waypoint${index}`]).toEqual(waypoint);
expect(updatedRecentWaypoints?.[0]?.address).toBe('123 Main St');
});

it('should not save waypoint if missing lat/lng', async () => {
const transactionID = 'txn2';
const index = '1';
const waypoint: RecentWaypoint = {
address: 'No LatLng',
};
const recentWaypointsList: RecentWaypoint[] = [];
saveWaypoint({transactionID, index, waypoint, isDraft: false, recentWaypointsList});
await waitForBatchedUpdates();

const updatedRecentWaypoints = await OnyxUtils.get(ONYXKEYS.NVP_RECENT_WAYPOINTS);
expect(updatedRecentWaypoints?.length ?? 0).toBe(0);
});

it('should not save waypoint if address is YOUR_LOCATION_TEXT', async () => {
const transactionID = 'txn3';
const index = '2';
const waypoint: RecentWaypoint = {
address: CONST.YOUR_LOCATION_TEXT,
lat: 1,
lng: 2,
};
const recentWaypointsList: RecentWaypoint[] = [];
saveWaypoint({transactionID, index, waypoint, isDraft: false, recentWaypointsList});
await waitForBatchedUpdates();

const updatedRecentWaypoints = await OnyxUtils.get(ONYXKEYS.NVP_RECENT_WAYPOINTS);
expect(updatedRecentWaypoints?.length ?? 0).toBe(0);
});

it('should reset amount for draft transactions', async () => {
const transactionID = 'txn4';
const index = '0';
const waypoint: RecentWaypoint = {
address: 'Draft Waypoint',
lat: 5,
lng: 6,
};
const recentWaypointsList: RecentWaypoint[] = [];
saveWaypoint({transactionID, index, waypoint, isDraft: true, recentWaypointsList});
await waitForBatchedUpdates();

const transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`);
expect(transaction?.amount).toBe(CONST.IOU.DEFAULT_AMOUNT);
});

it('should clear errorFields and routes', async () => {
const transactionID = 'txn5';
const index = '0';
const waypoint: RecentWaypoint = {
address: 'Clear Error',
lat: 7,
lng: 8,
};
const recentWaypointsList: RecentWaypoint[] = [];
// Ensure there is an existing transaction with errorFields and routes
const existingTransaction = generateTransaction({transactionID, reportID: '1'});
// Add errorFields and routes so saveWaypoint can clear them
// Populate with realistic non-null values
existingTransaction.errorFields = {route: {some: 'value'}};
existingTransaction.routes = {
route0: {
distance: 123,
geometry: {
coordinates: [
[0, 0],
[1, 1],
],
},
},
};
await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, existingTransaction);
saveWaypoint({transactionID, index, waypoint, isDraft: false, recentWaypointsList});
await waitForBatchedUpdates();

const transaction = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`);
expect(transaction?.errorFields?.route ?? null).toBeNull();
expect(transaction?.routes?.route0?.distance ?? null).toBeNull();
expect(transaction?.routes?.route0?.geometry?.coordinates ?? null).toBeNull();
});
});
});
Loading