diff --git a/src/libs/WorkspacesSettingsUtils.ts b/src/libs/WorkspacesSettingsUtils.ts index a27d518fe727..46927e430f67 100644 --- a/src/libs/WorkspacesSettingsUtils.ts +++ b/src/libs/WorkspacesSettingsUtils.ts @@ -63,7 +63,18 @@ const getBrickRoadForPolicy = (report: Report, altReportActions?: OnyxCollection const oneTransactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(report.reportID, reportActions); let doesReportContainErrors = Object.keys(reportErrors ?? {}).length !== 0 ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined; - if (oneTransactionThreadReportID) { + if (!doesReportContainErrors) { + const parentReportActions = (altReportActions ?? allReportActions)?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`]; + const parentReportAction = parentReportActions?.[report?.parentReportActionID ?? '-1']; + const shouldDisplayViolations = ReportUtils.shouldDisplayTransactionThreadViolations(report, allTransactionViolations, parentReportAction); + const shouldDisplayReportViolations = ReportUtils.isReportOwner(report) && ReportUtils.hasReportViolations(report.reportID); + const hasViolations = shouldDisplayViolations || shouldDisplayReportViolations; + if (hasViolations) { + doesReportContainErrors = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR; + } + } + + if (oneTransactionThreadReportID && !doesReportContainErrors) { const oneTransactionThreadReport = ReportUtils.getReport(oneTransactionThreadReportID); if ( diff --git a/tests/unit/WorkspaceSettingsUtilsTest.json b/tests/unit/WorkspaceSettingsUtilsTest.json new file mode 100644 index 000000000000..ff83fe078adf --- /dev/null +++ b/tests/unit/WorkspaceSettingsUtilsTest.json @@ -0,0 +1,86 @@ +{ + "session": { + "accountID": 18634488 + }, + "reports": { + "report_4286515777714555": { + "type": "chat", + "isOwnPolicyExpenseChat": false, + "ownerAccountID": 0, + "parentReportActionID": "8722650843049927838", + "parentReportID": "6955627196303088", + "policyID": "57D0F454E0BCE54B", + "reportID": "4286515777714555", + "stateNum": 0, + "statusNum": 0 + }, + "report_6955627196303088": { + "reportID": "6955627196303088", + "chatReportID": "1699789757771388", + "policyID": "57D0F454E0BCE54B", + "type": "expense", + "ownerAccountID": 18634488, + "stateNum": 1, + "statusNum": 1, + "parentReportID": "1699789757771388", + "parentReportActionID": "7978085421707288417" + } + }, + "transactionViolations": { + "transactionViolations_3106135972713435169": [ + { + "name": "missingCategory", + "type": "violation" + } + ], + "transactionViolations_3690687111940510713": [ + { + "name": "missingCategory", + "type": "violation" + } + ] + }, + "reportActions": { + "reportActions_6955627196303088": { + "8722650843049927838": { + "actionName": "IOU", + "actorAccountID": 18634488, + "automatic": false, + "avatar": "https: //d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_1.png", + "isAttachmentOnly": false, + "originalMessage": { + "amount": 12300, + "comment": "", + "currency": "VND", + "IOUTransactionID": "3106135972713435169", + "IOUReportID": "6955627196303088" + }, + "message": [ + { + "deleted": "", + "html": "₫123 expense", + "isDeletedParentAction": false, + "isEdited": false, + "text": "₫123 expense", + "type": "COMMENT", + "whisperedTo": [] + } + ], + "person": [ + { + "style": "strong", + "text": "adasdasd", + "type": "TEXT" + } + ], + "reportActionID": "8722650843049927838", + "shouldShow": true, + "created": "2024-11-05 11: 19: 18.706", + "childReportID": "4286515777714555", + "lastModified": "2024-11-05 11: 19: 18.706", + "childReportNotificationPreference": "hidden", + "childType": "chat" + } + } + } +} diff --git a/tests/unit/WorkspaceSettingsUtilsTest.ts b/tests/unit/WorkspaceSettingsUtilsTest.ts new file mode 100644 index 000000000000..9ee2b511379f --- /dev/null +++ b/tests/unit/WorkspaceSettingsUtilsTest.ts @@ -0,0 +1,69 @@ +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import {getBrickRoadForPolicy} from '@libs/WorkspacesSettingsUtils'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Report, ReportActions, TransactionViolations} from '@src/types/onyx'; +import type {ReportCollectionDataSet} from '@src/types/onyx/Report'; +import * as TestHelper from '../utils/TestHelper'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; +import mockData from './WorkspaceSettingsUtilsTest.json'; + +describe('WorkspacesSettingsUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + }); + }); + + beforeEach(() => { + global.fetch = TestHelper.getGlobalFetchMock(); + return Onyx.clear().then(waitForBatchedUpdates); + }); + describe('getBrickRoadForPolicy', () => { + it('Should return "error"', async () => { + // Given mock data for reports, transaction violations, sessions, and report actions. + const report = Object.values(mockData.reports)?.at(0); + const transactionViolations = mockData.transactionViolations; + const reports = mockData.reports; + const session = mockData.session; + const reportActions = mockData.reportActions; + + await Onyx.multiSet({ + ...(reports as ReportCollectionDataSet), + ...(reportActions as OnyxCollection), + ...(transactionViolations as OnyxCollection), + session, + }); + + await waitForBatchedUpdates(); + + // When calling getBrickRoadForPolicy with a report and report actions + const result = getBrickRoadForPolicy(report as Report, reportActions as OnyxCollection); + + // The result should be 'error' because there is at least one IOU action associated with a transaction that has a violation. + expect(result).toBe('error'); + }); + + it('Should return "undefined"', async () => { + // Given mock data for reports, sessions, and report actions. Note: Transaction data is intentionally excluded. + const report = Object.values(mockData.reports)?.at(0); + const reports = mockData.reports; + const session = mockData.session; + const reportActions = mockData.reportActions; + + await Onyx.multiSet({ + ...(reports as ReportCollectionDataSet), + ...(reportActions as OnyxCollection), + session, + }); + + await waitForBatchedUpdates(); + + // When calling getBrickRoadForPolicy with a report and report actions + const result = getBrickRoadForPolicy(report as Report, reportActions as OnyxCollection); + + // Then the result should be 'undefined' since no IOU action is linked to a transaction with a violation. + expect(result).toBe(undefined); + }); + }); +});