Skip to content
Draft
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
2 changes: 1 addition & 1 deletion src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,7 @@
Navigation.goBack(backToRoute);
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
deleteAppReport(moneyRequestReport, selfDMReport, email ?? '', accountID, reportTransactions, allTransactionViolations, bankAccountList, currentSearchHash);
deleteAppReport(moneyRequestReport, selfDMReport, email ?? '', accountID, reportTransactions, allTransactionViolations, bankAccountList);
});
});
},
Expand Down Expand Up @@ -1776,7 +1776,7 @@
}
return option;
});
}, [originalSelectedTransactionsOptions, showDeleteModal, dismissedRejectUseExplanation]);

Check warning on line 1779 in src/components/MoneyReportHeader.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useMemo has missing dependencies: 'isDelegateAccessRestricted' and 'showDelegateNoAccessModal'. Either include them or remove the dependency array

Check warning on line 1779 in src/components/MoneyReportHeader.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useMemo has missing dependencies: 'isDelegateAccessRestricted' and 'showDelegateNoAccessModal'. Either include them or remove the dependency array

Check warning on line 1779 in src/components/MoneyReportHeader.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

React Hook useMemo has missing dependencies: 'isDelegateAccessRestricted' and 'showDelegateNoAccessModal'. Either include them or remove the dependency array

const shouldShowSelectedTransactionsButton = !!selectedTransactionsOptions.length && !transactionThreadReportID;

Expand Down
1 change: 0 additions & 1 deletion src/hooks/useSearchBulkActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
validTransactions,
allTransactionViolations,
bankAccountList,
hash,
);
}
} else {
Expand Down
24 changes: 0 additions & 24 deletions src/libs/actions/Report/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@
/** @deprecated This value is deprecated and will be removed soon after migration. Use the email from useCurrentUserPersonalDetails hook instead. */
let deprecatedCurrentUserLogin: string | undefined;

Onyx.connect({

Check warning on line 319 in src/libs/actions/Report/index.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

Check warning on line 319 in src/libs/actions/Report/index.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.SESSION,
callback: (value) => {
// When signed out, val is undefined
Expand All @@ -330,7 +330,7 @@
},
});

Onyx.connect({

Check warning on line 333 in src/libs/actions/Report/index.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.CONCIERGE_REPORT_ID,
callback: (value) => (conciergeReportIDOnyxConnect = value),
});
Expand All @@ -338,7 +338,7 @@
// map of reportID to all reportActions for that report
const allReportActions: OnyxCollection<ReportActions> = {};

Onyx.connect({

Check warning on line 341 in src/libs/actions/Report/index.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_ACTIONS,
callback: (actions, key) => {
if (!key || !actions) {
Expand All @@ -350,7 +350,7 @@
});

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

Check warning on line 353 in src/libs/actions/Report/index.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 @@ -359,7 +359,7 @@
});

let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};
Onyx.connect({

Check warning on line 362 in src/libs/actions/Report/index.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.PERSONAL_DETAILS_LIST,
callback: (value) => {
allPersonalDetails = value ?? {};
Expand All @@ -374,7 +374,7 @@
});

let onboarding: OnyxEntry<Onboarding>;
Onyx.connect({

Check warning on line 377 in src/libs/actions/Report/index.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_ONBOARDING,
callback: (val) => {
if (Array.isArray(val)) {
Expand All @@ -385,7 +385,7 @@
});

let deprecatedIntroSelected: OnyxEntry<IntroSelected> = {};
Onyx.connect({

Check warning on line 388 in src/libs/actions/Report/index.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_INTRO_SELECTED,
callback: (val) => (deprecatedIntroSelected = val),
});
Expand Down Expand Up @@ -5343,24 +5343,13 @@
reportTransactions: Record<string, Transaction>,
allTransactionViolations: OnyxCollection<TransactionViolations>,
bankAccountList: OnyxEntry<BankAccountList>,
hash?: number,
) {
if (!report?.reportID) {
Log.warn('[Report] deleteAppReport called with no reportID');
return;
}
const reportID = report.reportID;

// Update search results to mark report as deleted when called from search
if (hash) {
Onyx.merge(`${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`, {
// @ts-expect-error - will be solved in https://github.com/Expensify/App/issues/73830
data: {
[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]: {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE},
},
});
}

const optimisticData: Array<
OnyxUpdate<
| typeof ONYXKEYS.COLLECTION.REPORT
Expand Down Expand Up @@ -5715,19 +5704,6 @@
value: {hasOutstandingChildRequest: report?.hasOutstandingChildRequest},
});

if (hash) {
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
// @ts-expect-error - will be solved in https://github.com/Expensify/App/issues/73830
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
value: {
data: {
[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]: {pendingAction: null},
},
},
});
}

const parameters: DeleteAppReportParams = {
reportID,
transactionIDToReportActionAndThreadData: JSON.stringify(transactionIDToReportActionAndThreadData),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
deleteTransactions([originalMessage.IOUTransactionID], duplicateTransactions, duplicateTransactionViolations, currentSearchHash);
}
} else if (isReportPreviewAction(reportAction)) {
deleteAppReport(childReport, selfDMReport, email ?? '', currentUserAccountID, reportTransactions, allTransactionViolations, bankAccountList, currentSearchHash);
deleteAppReport(childReport, selfDMReport, email ?? '', currentUserAccountID, reportTransactions, allTransactionViolations, bankAccountList);
} else if (reportAction) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
Expand Down
47 changes: 47 additions & 0 deletions tests/actions/IOUTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7118,6 +7118,53 @@ describe('actions/IOU', () => {

afterEach(PusherHelper.teardown);

it('should set pendingAction on the transaction without sending snapshot fanout updates', async () => {
const writeSpy = jest.spyOn(API, 'write').mockImplementation(jest.fn());

try {
if (transaction && createIOUAction) {
deleteMoneyRequest({
transactionID: transaction.transactionID,
reportAction: createIOUAction,
transactions: {},
violations: {},
iouReport,
chatReport,
isChatIOUReportArchived: true,
allTransactionViolationsParam: {},
currentUserAccountID: TEST_USER_ACCOUNT_ID,
});
}
await waitForBatchedUpdates();

const deleteRequestCall = writeSpy.mock.calls.find(([command]) => command === WRITE_COMMANDS.DELETE_MONEY_REQUEST);
expect(deleteRequestCall).toBeDefined();
if (!deleteRequestCall) {
throw new Error('Expected DELETE_MONEY_REQUEST to be called');
}

const [, , requestData] = deleteRequestCall as [
ApiCommand,
Record<string, unknown>,
{optimisticData?: Array<{key: string; value?: {pendingAction?: string | null}}>; failureData?: Array<{key: string; value?: {pendingAction?: string | null}}>}
];

const optimisticData = requestData.optimisticData ?? [];
const failureData = requestData.failureData ?? [];
const transactionKey = `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`;

const optimisticTransactionUpdate = optimisticData.find((update) => update.key === transactionKey);
const failureTransactionUpdate = failureData.find((update) => update.key === transactionKey);

expect(optimisticTransactionUpdate?.value?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
expect(failureTransactionUpdate?.value?.pendingAction).toBeNull();
expect(optimisticData.some((update) => update.key.startsWith(ONYXKEYS.COLLECTION.SNAPSHOT))).toBe(false);
expect(failureData.some((update) => update.key.startsWith(ONYXKEYS.COLLECTION.SNAPSHOT))).toBe(false);
} finally {
writeSpy.mockRestore();
}
});

it('delete an expense (IOU Action and transaction) successfully', async () => {
// Given the fetch operations are paused and an expense is initiated
mockFetch?.pause?.();
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/setup/AppSetupTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Onyx from 'react-native-onyx';
import appSetup from '@src/setup';

jest.mock('array.prototype.tosorted', () => ({
__esModule: true,

Check failure on line 5 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 5 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 5 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 5 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase
default: {
shim: jest.fn(),
},
}));

jest.mock('react-native', () => ({
I18nManager: {
allowRTL: jest.fn(),
forceRTL: jest.fn(),
},
}));

jest.mock('react-native-config', () => ({}));

jest.mock('react-native-onyx', () => ({
__esModule: true,

Check failure on line 21 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 21 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 21 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase

Check failure on line 21 in tests/unit/setup/AppSetupTest.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Object Literal Property name `__esModule` must match one of the following formats: camelCase, UPPER_CASE, PascalCase
default: {
init: jest.fn(),
},
}));

jest.mock('@libs/IntlPolyfill', () => jest.fn());
jest.mock('@userActions/Device', () => ({
setDeviceID: jest.fn(),
}));
jest.mock('@userActions/OnyxDerived', () => jest.fn());
jest.mock('@src/setup/addUtilsToWindow', () => jest.fn());
jest.mock('@src/setup/platformSetup', () => jest.fn());
jest.mock('@src/setup/telemetry', () => jest.fn());

describe('appSetup', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should initialize Onyx with snapshotMergeKeys for pending state propagation', () => {
appSetup();

expect(Onyx.init).toHaveBeenCalledWith(
expect.objectContaining({
snapshotMergeKeys: ['pendingAction', 'pendingFields'],
}),
);
});
});
Loading