diff --git a/tests/perf-test/ReportActionsUtils.perf-test.js b/tests/perf-test/ReportActionsUtils.perf-test.js new file mode 100644 index 0000000000000..f643206c9f498 --- /dev/null +++ b/tests/perf-test/ReportActionsUtils.perf-test.js @@ -0,0 +1,93 @@ +import Onyx from 'react-native-onyx'; +import {measureFunction} from 'reassure'; +import _ from 'underscore'; +import CONST from '../../src/CONST'; +import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils'; +import ONYXKEYS from '../../src/ONYXKEYS'; +import * as LHNTestUtils from '../utils/LHNTestUtils'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; + +jest.setTimeout(60000); + +beforeAll(() => + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + registerStorageEventListener: () => {}, + }), +); + +// Clear out Onyx after each test so that each test starts with a clean slate +afterEach(() => { + Onyx.clear(); +}); + +const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = 100) => { + const mockReportActions = Array.from({length: actionsPerReportLength}, (_reportAction, i) => { + const reportActionKey = i + 1; + const email = `actor+${reportActionKey}@mail.com`; + const reportAction = LHNTestUtils.getFakeReportAction(email); + + return {[reportActionKey]: reportAction}; + }); + + const reportKeysMap = Array.from({length: reportsLength}, (_report, i) => { + const key = i + 1; + + return {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${key}`]: _.assign({}, ...mockReportActions)}; + }); + + return _.assign({}, ...reportKeysMap); +}; + +const mockedReportActionsMap = getMockedReportActionsMap(2, 10000); + +/** + * This function will be executed 20 times and the average time will be used on the comparison. + * It will fail based on the CI configuration around Reassure: + * @see /.github/workflows/reassurePerformanceTests.yml + * + * Max deviation on the duration is set to 20% at the time of writing. + * + * More on the measureFunction API: + * @see https://callstack.github.io/reassure/docs/api#measurefunction-function + */ +test('getLastVisibleAction on 10k reportActions', async () => { + const reportId = '1'; + + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs: 20}); +}); + +test('getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { + const reportId = '1'; + const parentReportActionId = '1'; + const fakeParentAction = mockedReportActionsMap[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportId}`][parentReportActionId]; + const actionsToMerge = { + [parentReportActionId]: { + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + previousMessage: fakeParentAction.message, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: '', + text: '', + isEdited: true, + isDeletedParentAction: true, + }, + ], + errors: null, + linkMetaData: [], + }, + }; + + await Onyx.multiSet({ + ...mockedReportActionsMap, + }); + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs: 20}); +}); diff --git a/tests/utils/LHNTestUtils.js b/tests/utils/LHNTestUtils.js index 9898063cc4967..72d7d64f12832 100644 --- a/tests/utils/LHNTestUtils.js +++ b/tests/utils/LHNTestUtils.js @@ -130,6 +130,7 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = actor, actorAccountID: 1, reportActionID: `${++lastFakeReportActionID}`, + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, shouldShow: true, timestamp, reportActionTimestamp: timestamp, @@ -142,6 +143,55 @@ function getFakeReportAction(actor = 'email1@test.com', millisecondsInThePast = ], whisperedToAccountIDs: [], automatic: false, + message: [ + { + type: 'COMMENT', + html: 'hey', + text: 'hey', + isEdited: false, + whisperedTo: [], + isDeletedParentAction: false, + reactions: [ + { + emoji: 'heart', + users: [ + { + accountID: 1, + skinTone: -1, + }, + ], + }, + ], + }, + ], + originalMessage: { + childReportID: `${++lastFakeReportActionID}`, + emojiReactions: { + heart: { + createdAt: '2023-08-28 15:27:52', + users: { + 1: { + skinTones: { + '-1': '2023-08-28 15:27:52', + }, + }, + }, + }, + }, + html: 'hey', + lastModified: '2023-08-28 15:28:12.432', + reactions: [ + { + emoji: 'heart', + users: [ + { + accountID: 1, + skinTone: -1, + }, + ], + }, + ], + }, }; }