Skip to content

Commit e65db2e

Browse files
authored
Merge pull request #61796 from ishakakkad/60907
60907: Receipt thumbnail doesn't update when a new receipt is attached
2 parents e4401b6 + 079eab6 commit e65db2e

File tree

2 files changed

+166
-1
lines changed

2 files changed

+166
-1
lines changed

src/libs/actions/IOU.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9963,6 +9963,7 @@ function replaceReceipt({transactionID, file, source}: ReplaceReceipt) {
99639963
};
99649964

99659965
const retryParams = {transactionID, file: undefined, source};
9966+
const currentSearchQueryJSON = getCurrentSearchQueryJSON();
99669967

99679968
const optimisticData: OnyxUpdate[] = [
99689969
{
@@ -10006,6 +10007,34 @@ function replaceReceipt({transactionID, file, source}: ReplaceReceipt) {
1000610007
},
1000710008
];
1000810009

10010+
if (currentSearchQueryJSON?.hash) {
10011+
optimisticData.push({
10012+
onyxMethod: Onyx.METHOD.MERGE,
10013+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}`,
10014+
value: {
10015+
data: {
10016+
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: {
10017+
receipt: receiptOptimistic,
10018+
filename: file.name,
10019+
},
10020+
},
10021+
},
10022+
});
10023+
10024+
failureData.push({
10025+
onyxMethod: Onyx.METHOD.MERGE,
10026+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}`,
10027+
value: {
10028+
data: {
10029+
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: {
10030+
receipt: !isEmptyObject(oldReceipt) ? oldReceipt : null,
10031+
filename: transaction?.filename,
10032+
},
10033+
},
10034+
},
10035+
});
10036+
}
10037+
1000910038
const parameters: ReplaceReceiptParams = {
1001010039
transactionID,
1001110040
receipt: file,

tests/actions/IOUTest.ts

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
initMoneyRequest,
1717
payMoneyRequest,
1818
putOnHold,
19+
replaceReceipt,
1920
requestMoney,
2021
resolveDuplicates,
2122
sendInvoice,
@@ -58,7 +59,7 @@ import * as API from '@src/libs/API';
5859
import DateUtils from '@src/libs/DateUtils';
5960
import ONYXKEYS from '@src/ONYXKEYS';
6061
import ROUTES from '@src/ROUTES';
61-
import type {Policy, Report, ReportNameValuePairs} from '@src/types/onyx';
62+
import type {Policy, Report, ReportNameValuePairs, SearchResults} from '@src/types/onyx';
6263
import type {Accountant} from '@src/types/onyx/IOU';
6364
import type {Participant, ReportCollectionDataSet} from '@src/types/onyx/Report';
6465
import type {ReportActions, ReportActionsCollectionDataSet} from '@src/types/onyx/ReportAction';
@@ -115,6 +116,13 @@ jest.mock('@libs/Navigation/helpers/isSearchTopmostFullScreenRoute', () => jest.
115116
// This keeps the error "@rnmapbox/maps native code not available." from causing the tests to fail
116117
jest.mock('@components/ConfirmedRoute.tsx');
117118

119+
jest.mock('@src/libs/SearchQueryUtils', () => ({
120+
getCurrentSearchQueryJSON: jest.fn().mockImplementation(() => ({
121+
hash: 12345,
122+
query: 'test',
123+
})),
124+
}));
125+
118126
const CARLOS_EMAIL = '[email protected]';
119127
const CARLOS_ACCOUNT_ID = 1;
120128
const CARLOS_PARTICIPANT: Participant = {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, role: 'member'};
@@ -5846,4 +5854,132 @@ describe('actions/IOU', () => {
58465854
});
58475855
});
58485856
});
5857+
5858+
describe('replaceReceipt', () => {
5859+
it('should replace the receipt of the transaction', async () => {
5860+
const transactionID = '123';
5861+
const file = new File([new Blob(['test'])], 'test.jpg', {type: 'image/jpeg'});
5862+
file.source = 'test';
5863+
const source = 'test';
5864+
5865+
const transaction = {
5866+
transactionID,
5867+
receipt: {
5868+
source: 'test1',
5869+
},
5870+
};
5871+
5872+
// Given a transaction with a receipt
5873+
await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, transaction);
5874+
await waitForBatchedUpdates();
5875+
const searchQueryJSON = {
5876+
hash: 12345,
5877+
query: 'test',
5878+
};
5879+
5880+
// Given a snapshot of the transaction
5881+
await Onyx.set(`${ONYXKEYS.COLLECTION.SNAPSHOT}${searchQueryJSON.hash}`, {
5882+
// @ts-expect-error: Allow partial record in snapshot update
5883+
data: {
5884+
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: transaction,
5885+
},
5886+
});
5887+
await waitForBatchedUpdates();
5888+
5889+
// When the receipt is replaced
5890+
replaceReceipt({transactionID, file, source});
5891+
await waitForBatchedUpdates();
5892+
5893+
// Then the transaction should have the new receipt source
5894+
const updatedTransaction = await new Promise<OnyxEntry<Transaction>>((resolve) => {
5895+
const connection = Onyx.connect({
5896+
key: ONYXKEYS.COLLECTION.TRANSACTION,
5897+
waitForCollectionCallback: true,
5898+
callback: (transactions) => {
5899+
Onyx.disconnect(connection);
5900+
const newTransaction = transactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
5901+
resolve(newTransaction);
5902+
},
5903+
});
5904+
});
5905+
expect(updatedTransaction?.receipt?.source).toBe(source);
5906+
5907+
// Then the snapshot should have the new receipt source
5908+
const updatedSnapshot = await new Promise<OnyxEntry<SearchResults>>((resolve) => {
5909+
const connection = Onyx.connect({
5910+
key: ONYXKEYS.COLLECTION.SNAPSHOT,
5911+
waitForCollectionCallback: true,
5912+
callback: (snapshots) => {
5913+
Onyx.disconnect(connection);
5914+
const newSnapshot = snapshots[`${ONYXKEYS.COLLECTION.SNAPSHOT}${searchQueryJSON.hash}`];
5915+
resolve(newSnapshot);
5916+
},
5917+
});
5918+
});
5919+
5920+
expect(updatedSnapshot?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]?.receipt?.source).toBe(source);
5921+
});
5922+
5923+
it('should add receipt if it does not exist', async () => {
5924+
const transactionID = '123';
5925+
const file = new File([new Blob(['test'])], 'test.jpg', {type: 'image/jpeg'});
5926+
file.source = 'test';
5927+
const source = 'test';
5928+
5929+
const transaction = {
5930+
transactionID,
5931+
};
5932+
5933+
// Given a transaction without a receipt
5934+
await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, transaction);
5935+
await waitForBatchedUpdates();
5936+
5937+
const searchQueryJSON = {
5938+
hash: 12345,
5939+
query: 'test',
5940+
};
5941+
5942+
// Given a snapshot of the transaction
5943+
await Onyx.set(`${ONYXKEYS.COLLECTION.SNAPSHOT}${searchQueryJSON.hash}`, {
5944+
// @ts-expect-error: Allow partial record in snapshot update
5945+
data: {
5946+
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: transaction,
5947+
},
5948+
});
5949+
await waitForBatchedUpdates();
5950+
5951+
// When the receipt is replaced
5952+
replaceReceipt({transactionID, file, source});
5953+
await waitForBatchedUpdates();
5954+
5955+
// Then the transaction should have the new receipt source
5956+
const updatedTransaction = await new Promise<OnyxEntry<Transaction>>((resolve) => {
5957+
const connection = Onyx.connect({
5958+
key: ONYXKEYS.COLLECTION.TRANSACTION,
5959+
waitForCollectionCallback: true,
5960+
callback: (transactions) => {
5961+
Onyx.disconnect(connection);
5962+
const newTransaction = transactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
5963+
resolve(newTransaction);
5964+
},
5965+
});
5966+
});
5967+
expect(updatedTransaction?.receipt?.source).toBe(source);
5968+
5969+
// Then the snapshot should have the new receipt source
5970+
const updatedSnapshot = await new Promise<OnyxEntry<SearchResults>>((resolve) => {
5971+
const connection = Onyx.connect({
5972+
key: ONYXKEYS.COLLECTION.SNAPSHOT,
5973+
waitForCollectionCallback: true,
5974+
callback: (snapshots) => {
5975+
Onyx.disconnect(connection);
5976+
const newSnapshot = snapshots[`${ONYXKEYS.COLLECTION.SNAPSHOT}${searchQueryJSON.hash}`];
5977+
resolve(newSnapshot);
5978+
},
5979+
});
5980+
});
5981+
5982+
expect(updatedSnapshot?.data?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]?.receipt?.source).toBe(source);
5983+
});
5984+
});
58495985
});

0 commit comments

Comments
 (0)