11import { renderHook } from '@testing-library/react-native' ;
2- import type { OnyxCollection } from 'react-native-onyx' ;
2+ import type { OnyxCollection , OnyxEntry } from 'react-native-onyx' ;
33import Onyx from 'react-native-onyx' ;
44import useReportIsArchived from '@hooks/useReportIsArchived' ;
55import DateUtils from '@libs/DateUtils' ;
@@ -1197,6 +1197,7 @@ describe('DebugUtils', () => {
11971197 undefined ,
11981198 false ,
11991199 { } ,
1200+ false ,
12001201 ) ?? { } ;
12011202 expect ( reportAction ) . toBeUndefined ( ) ;
12021203 } ) ;
@@ -1260,6 +1261,7 @@ describe('DebugUtils', () => {
12601261 undefined ,
12611262 false ,
12621263 { } ,
1264+ false ,
12631265 ) ?? { } ;
12641266 expect ( reportAction ) . toBe ( undefined ) ;
12651267 } ) ;
@@ -1327,8 +1329,16 @@ describe('DebugUtils', () => {
13271329 } ;
13281330 const reportErrors = getAllReportErrors ( MOCK_CHAT_REPORT , MOCK_CHAT_REPORT_ACTIONS , mockTransactions ) ;
13291331 const { reportAction} =
1330- DebugUtils . getReasonAndReportActionForRBRInLHNRow ( MOCK_CHAT_REPORT , chatReportR14932 , MOCK_CHAT_REPORT_ACTIONS , mockTransactions , undefined , false , reportErrors ) ??
1331- { } ;
1332+ DebugUtils . getReasonAndReportActionForRBRInLHNRow (
1333+ MOCK_CHAT_REPORT ,
1334+ chatReportR14932 ,
1335+ MOCK_CHAT_REPORT_ACTIONS ,
1336+ mockTransactions ,
1337+ undefined ,
1338+ false ,
1339+ reportErrors ,
1340+ false ,
1341+ ) ?? { } ;
13321342 expect ( reportAction ) . toMatchObject ( MOCK_CHAT_REPORT_ACTIONS [ '1' ] ) ;
13331343 } ) ;
13341344 it ( 'returns correct report action which is a split bill and has an error' , async ( ) => {
@@ -1400,7 +1410,8 @@ describe('DebugUtils', () => {
14001410 } ;
14011411 const reportErrors = getAllReportErrors ( MOCK_CHAT_REPORT , MOCK_REPORT_ACTIONS , mockTransactions ) ;
14021412 const { reportAction} =
1403- DebugUtils . getReasonAndReportActionForRBRInLHNRow ( MOCK_CHAT_REPORT , chatReportR14932 , MOCK_REPORT_ACTIONS , mockTransactions , undefined , false , reportErrors ) ?? { } ;
1413+ DebugUtils . getReasonAndReportActionForRBRInLHNRow ( MOCK_CHAT_REPORT , chatReportR14932 , MOCK_REPORT_ACTIONS , mockTransactions , undefined , false , reportErrors , false ) ??
1414+ { } ;
14041415 expect ( reportAction ) . toMatchObject ( MOCK_REPORT_ACTIONS [ '3' ] ) ;
14051416 } ) ;
14061417 } ) ;
@@ -1458,6 +1469,7 @@ describe('DebugUtils', () => {
14581469 undefined ,
14591470 false ,
14601471 reportErrors ,
1472+ false ,
14611473 ) ?? { } ;
14621474 expect ( reportAction ) . toMatchObject ( MOCK_REPORT_ACTIONS [ '1' ] ) ;
14631475 } ) ;
@@ -1486,7 +1498,8 @@ describe('DebugUtils', () => {
14861498
14871499 const reportErrors = getAllReportErrors ( mockedReport , mockedReportActions , sharedAllTransactions ) ;
14881500 const { reason} =
1489- DebugUtils . getReasonAndReportActionForRBRInLHNRow ( mockedReport , chatReportR14932 , mockedReportActions , sharedAllTransactions , undefined , false , reportErrors ) ?? { } ;
1501+ DebugUtils . getReasonAndReportActionForRBRInLHNRow ( mockedReport , chatReportR14932 , mockedReportActions , sharedAllTransactions , undefined , false , reportErrors , false ) ??
1502+ { } ;
14901503 expect ( reason ) . toBe ( 'debug.reasonRBR.hasErrors' ) ;
14911504 } ) ;
14921505 it ( 'returns correct reason when there are violations' , ( ) => {
@@ -1501,6 +1514,7 @@ describe('DebugUtils', () => {
15011514 undefined ,
15021515 true ,
15031516 { } ,
1517+ false ,
15041518 ) ?? { } ;
15051519 expect ( reason ) . toBe ( 'debug.reasonRBR.hasViolations' ) ;
15061520 } ) ;
@@ -1516,6 +1530,7 @@ describe('DebugUtils', () => {
15161530 undefined ,
15171531 true ,
15181532 { } ,
1533+ false ,
15191534 true ,
15201535 ) ?? { } ;
15211536 expect ( reason ) . toBe ( undefined ) ;
@@ -1572,9 +1587,92 @@ describe('DebugUtils', () => {
15721587 reportID : '1' ,
15731588 } as Transaction ,
15741589 } ;
1575- const { reason} = DebugUtils . getReasonAndReportActionForRBRInLHNRow ( report , chatReportR14932 , { } , violationTransactions , transactionViolations , false , { } ) ?? { } ;
1590+ const { reason} = DebugUtils . getReasonAndReportActionForRBRInLHNRow ( report , chatReportR14932 , { } , violationTransactions , transactionViolations , false , { } , false ) ?? { } ;
15761591 expect ( reason ) . toBe ( 'debug.reasonRBR.hasTransactionThreadViolations' ) ;
15771592 } ) ;
1593+ it ( 'forwards isOffline through to SidebarUtils so the live IOU transaction-thread receipt error surfaces only when isOffline=false excludes the deleted pending-delete action' , ( ) => {
1594+ // Given: an expense report with two IOU actions — one live (with a receipt-errored transaction) and one deleted-with-pending-delete.
1595+ const OFFLINE_EXPENSE_REPORT : Report = {
1596+ reportID : '1' ,
1597+ type : CONST . REPORT . TYPE . EXPENSE ,
1598+ chatReportID : '2' ,
1599+ } ;
1600+ const OFFLINE_CHAT_REPORT : Report = {
1601+ reportID : '2' ,
1602+ } ;
1603+ const liveTransactionID = 'tx-debug-live' ;
1604+ const deletedTransactionID = 'tx-debug-deleted' ;
1605+ const OFFLINE_REPORT_ACTIONS : OnyxEntry < ReportActions > = {
1606+ // eslint-disable-next-line @typescript-eslint/naming-convention
1607+ '1' : {
1608+ reportActionID : '1' ,
1609+ actionName : CONST . REPORT . ACTIONS . TYPE . IOU ,
1610+ actorAccountID : 12345 ,
1611+ created : '2024-08-08 18:20:44.171' ,
1612+ message : [ { type : 'TEXT' , text : 'live' } ] ,
1613+ originalMessage : {
1614+ type : CONST . IOU . REPORT_ACTION_TYPE . CREATE ,
1615+ IOUTransactionID : liveTransactionID ,
1616+ amount : 10 ,
1617+ currency : CONST . CURRENCY . USD ,
1618+ } ,
1619+ } as ReportAction ,
1620+ // eslint-disable-next-line @typescript-eslint/naming-convention
1621+ '2' : {
1622+ reportActionID : '2' ,
1623+ actionName : CONST . REPORT . ACTIONS . TYPE . IOU ,
1624+ actorAccountID : 12345 ,
1625+ created : '2024-08-08 18:25:44.171' ,
1626+ pendingAction : CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ,
1627+ message : [ { type : 'TEXT' , text : '' , html : '' } ] ,
1628+ originalMessage : {
1629+ type : CONST . IOU . REPORT_ACTION_TYPE . CREATE ,
1630+ IOUTransactionID : deletedTransactionID ,
1631+ amount : 20 ,
1632+ currency : CONST . CURRENCY . USD ,
1633+ } ,
1634+ } as ReportAction ,
1635+ } ;
1636+ const OFFLINE_TRANSACTIONS : OnyxCollection < Transaction > = {
1637+ [ `${ ONYXKEYS . COLLECTION . TRANSACTION } ${ liveTransactionID } ` ] : {
1638+ transactionID : liveTransactionID ,
1639+ amount : 10 ,
1640+ errors : {
1641+ someErrorKey : { error : CONST . IOU . RECEIPT_ERROR } ,
1642+ } ,
1643+ } as unknown as Transaction ,
1644+ [ `${ ONYXKEYS . COLLECTION . TRANSACTION } ${ deletedTransactionID } ` ] : {
1645+ transactionID : deletedTransactionID ,
1646+ amount : 20 ,
1647+ } as unknown as Transaction ,
1648+ } ;
1649+
1650+ const offline = DebugUtils . getReasonAndReportActionForRBRInLHNRow (
1651+ OFFLINE_EXPENSE_REPORT ,
1652+ OFFLINE_CHAT_REPORT ,
1653+ OFFLINE_REPORT_ACTIONS ,
1654+ OFFLINE_TRANSACTIONS ,
1655+ { } ,
1656+ false ,
1657+ { } ,
1658+ true ,
1659+ ) ;
1660+ const online = DebugUtils . getReasonAndReportActionForRBRInLHNRow (
1661+ OFFLINE_EXPENSE_REPORT ,
1662+ OFFLINE_CHAT_REPORT ,
1663+ OFFLINE_REPORT_ACTIONS ,
1664+ OFFLINE_TRANSACTIONS ,
1665+ { } ,
1666+ false ,
1667+ { } ,
1668+ false ,
1669+ ) ;
1670+
1671+ // Online: deleted pending-delete is skipped → 1 IOU thread → receipt error surfaces.
1672+ expect ( online ?. reason ) . toBe ( 'debug.reasonRBR.hasErrors' ) ;
1673+ // Offline: deleted pending-delete is counted → 2 IOU actions → no single thread → no receipt error via that path.
1674+ expect ( offline ) . toBeNull ( ) ;
1675+ } ) ;
15781676 } ) ;
15791677 } ) ;
15801678} ) ;
0 commit comments