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
47 changes: 25 additions & 22 deletions src/libs/actions/OnyxDerived/configs/reportAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,30 +86,33 @@ export default createOnyxDerivedValueConfig({

if (isFullyComputed) {
// if there are report-related updates, iterate over the updates
if (updates.length > 0) {
dataToIterate = prepareReportKeys(updates);
} else if (!!transactionsUpdates || !!transactionViolationsUpdates) {
let transactionReportIDs: string[] = [];
if (transactionsUpdates) {
transactionReportIDs = Object.values(transactionsUpdates).map((transaction) => `${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
if (updates.length > 0 || !!transactionsUpdates || !!transactionViolationsUpdates) {

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.

NAB: Please convert to an early return (if the opposite of the condition is true, return like in the else block), and where possible below, like line 93. You can do this in a follow up.

if (updates.length > 0) {
dataToIterate = prepareReportKeys(updates);
}
// Also handle transaction violations updates by extracting transaction IDs and finding their reports
if (transactionViolationsUpdates) {
const violationTransactionIDs = Object.keys(transactionViolationsUpdates).map((key) => key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, ''));
const violationReportIDs = violationTransactionIDs
.map((transactionID) => transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]?.reportID)
.filter(Boolean)
.map((reportID) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`);

// Also include chat reports for expense reports that have violations
const chatReportIDs = violationReportIDs
.map((reportKey) => reports?.[reportKey]?.chatReportID)
.filter(Boolean)
.map((chatReportID) => `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`);

transactionReportIDs = [...transactionReportIDs, ...violationReportIDs, ...chatReportIDs];
if (!!transactionsUpdates || !!transactionViolationsUpdates) {
let transactionReportIDs: string[] = [];
if (transactionsUpdates) {
transactionReportIDs = Object.values(transactionsUpdates).map((transaction) => `${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
}
// Also handle transaction violations updates by extracting transaction IDs and finding their reports
if (transactionViolationsUpdates) {
const violationTransactionIDs = Object.keys(transactionViolationsUpdates).map((key) => key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, ''));
const violationReportIDs = violationTransactionIDs
.map((transactionID) => transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]?.reportID)
.filter(Boolean)
.map((reportID) => `${ONYXKEYS.COLLECTION.REPORT}${reportID}`);

// Also include chat reports for expense reports that have violations
const chatReportIDs = violationReportIDs
.map((reportKey) => reports?.[reportKey]?.chatReportID)
.filter(Boolean)
.map((chatReportID) => `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`);

transactionReportIDs = [...transactionReportIDs, ...violationReportIDs, ...chatReportIDs];
}
dataToIterate.push(...prepareReportKeys(transactionReportIDs));
}
dataToIterate = prepareReportKeys(transactionReportIDs);
} else {
// No updates to process, return current value to prevent unnecessary computation
return currentValue ?? {reports: {}, locale: null};
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/OnyxDerivedTest.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
/* eslint-disable @typescript-eslint/naming-convention */
import Onyx from 'react-native-onyx';
import type {OnyxCollection} from 'react-native-onyx';
import OnyxUtils from 'react-native-onyx/dist/OnyxUtils';
import reportAttributes from '@libs/actions/OnyxDerived/configs/reportAttributes';
import initOnyxDerivedValues from '@userActions/OnyxDerived';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Report} from '@src/types/onyx';
import type {ReportActions} from '@src/types/onyx/ReportAction';
import {createRandomReport} from '../utils/collections/reports';
import createRandomTransaction from '../utils/collections/transaction';
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';

describe('OnyxDerived', () => {
Expand Down Expand Up @@ -72,6 +76,35 @@ describe('OnyxDerived', () => {
});
});

it('should contain both report attributes update when there are report and transaction updates', async () => {
await waitForBatchedUpdates();
// Given 2 reports and 1 transaction
const reportID1 = '0';
const reportID2 = '1';
const reports: OnyxCollection<Report> = {
[`${ONYXKEYS.COLLECTION.REPORT}${reportID1}`]: createRandomReport(Number(reportID1)),
[`${ONYXKEYS.COLLECTION.REPORT}${reportID2}`]: createRandomReport(Number(reportID2)),
};
const transaction = createRandomTransaction(1);

// When the report attributes are recomputed with both report and transaction updates
reportAttributes.compute([reports, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined], {areAllConnectionsSet: true});
const reportAttributesComputedValue = reportAttributes.compute([reports, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined], {
sourceValues: {
[ONYXKEYS.COLLECTION.REPORT]: {
[`${ONYXKEYS.COLLECTION.REPORT}${reportID1}`]: reports[`${ONYXKEYS.COLLECTION.REPORT}${reportID1}`],
},
[ONYXKEYS.COLLECTION.TRANSACTION]: {
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: transaction,
},
},
areAllConnectionsSet: true,
}).reports;

// Then the computed report attributes should contain both reports
expect(Object.keys(reportAttributesComputedValue)).toEqual([reportID1, reportID2]);
});

describe('reportErrors', () => {
it('returns empty errors when no errors exist', async () => {
const report = createRandomReport(1);
Expand Down
Loading