33import { format } from 'date-fns' ;
44import Onyx from 'react-native-onyx' ;
55import type { OnyxCollection , OnyxEntry } from 'react-native-onyx' ;
6- import { convertBulkTrackedExpensesToIOU , getDeleteTrackExpenseInformation , getTrackExpenseInformation , trackExpense } from '@libs/actions/IOU/TrackExpense' ;
6+ import { convertBulkTrackedExpensesToIOU , deleteTrackExpense , getDeleteTrackExpenseInformation , getTrackExpenseInformation , trackExpense } from '@libs/actions/IOU/TrackExpense' ;
77import initOnyxDerivedValues from '@libs/actions/OnyxDerived' ;
88import { addComment , openReport } from '@libs/actions/Report' ;
99import { subscribeToUserEvents } from '@libs/actions/User' ;
10+ import { WRITE_COMMANDS } from '@libs/API/types' ;
1011import { getLoginsByAccountIDs } from '@libs/PersonalDetailsUtils' ;
1112// eslint-disable-next-line no-restricted-syntax
1213import type * as PolicyUtils from '@libs/PolicyUtils' ;
@@ -17,8 +18,10 @@ import {getValidWaypoints, isDistanceRequest as isDistanceRequestUtil} from '@li
1718import CONST from '@src/CONST' ;
1819import IntlStore from '@src/languages/IntlStore' ;
1920import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager' ;
21+ import * as API from '@src/libs/API' ;
2022import DateUtils from '@src/libs/DateUtils' ;
2123import ONYXKEYS from '@src/ONYXKEYS' ;
24+ import ROUTES from '@src/ROUTES' ;
2225import type { IntroSelected , PersonalDetailsList , Policy , Report } from '@src/types/onyx' ;
2326import type { Accountant } from '@src/types/onyx/IOU' ;
2427import type ReportAction from '@src/types/onyx/ReportAction' ;
@@ -1550,7 +1553,9 @@ describe('actions/IOU/TrackExpense', () => {
15501553 expect ( Object . values ( allReports ?? { } ) . length ) . toBe ( 2 ) ;
15511554
15521555 // Then one of them should be a chat report with relevant properties
1553- const transactionThreadReport = Object . values ( allReports ?? { } ) . find ( ( report ) => report ?. type === CONST . REPORT . TYPE . CHAT ) ;
1556+ const transactionThreadReport = Object . values ( allReports ?? { } ) . find (
1557+ ( report ) => report ?. type === CONST . REPORT . TYPE . CHAT && report ?. parentReportID === selfDMReport . reportID && report ?. reportID !== selfDMReport . reportID ,
1558+ ) ;
15541559 if ( transactionThreadReport ) {
15551560 thread = transactionThreadReport ;
15561561 }
@@ -1761,6 +1766,151 @@ describe('actions/IOU/TrackExpense', () => {
17611766 } ) ;
17621767 } ) ;
17631768
1769+ describe ( 'deleteTrackExpense' , ( ) => {
1770+ const amount = 10000 ;
1771+ const TEST_USER_ACCOUNT_ID = 1 ;
1772+ const TEST_USER_LOGIN = 'test@test.com' ;
1773+ let selfDMReport : Report ;
1774+ let iouReportAction : OnyxEntry < ReportAction < typeof CONST . REPORT . ACTIONS . TYPE . IOU > > ;
1775+ let transaction : OnyxEntry < Transaction > ;
1776+ let thread : OptimisticChatReport ;
1777+
1778+ beforeEach ( async ( ) => {
1779+ jest . clearAllMocks ( ) ;
1780+ PusherHelper . setup ( ) ;
1781+
1782+ await signInWithTestUser ( TEST_USER_ACCOUNT_ID , TEST_USER_LOGIN ) ;
1783+ subscribeToUserEvents ( TEST_USER_ACCOUNT_ID , undefined ) ;
1784+ await waitForBatchedUpdates ( ) ;
1785+ await setPersonalDetails ( TEST_USER_LOGIN , TEST_USER_ACCOUNT_ID ) ;
1786+
1787+ selfDMReport = {
1788+ ...createRandomReport ( 1 , CONST . REPORT . CHAT_TYPE . SELF_DM ) ,
1789+ reportID : '20' ,
1790+ } ;
1791+
1792+ await Onyx . set ( `${ ONYXKEYS . COLLECTION . REPORT } ${ selfDMReport . reportID } ` , selfDMReport ) ;
1793+ const recentWaypoints = ( await getOnyxValue ( ONYXKEYS . NVP_RECENT_WAYPOINTS ) ) ?? [ ] ;
1794+
1795+ trackExpense ( {
1796+ report : selfDMReport ,
1797+ isDraftPolicy : true ,
1798+ action : CONST . IOU . ACTION . CREATE ,
1799+ participantParams : {
1800+ payeeEmail : TEST_USER_LOGIN ,
1801+ payeeAccountID : TEST_USER_ACCOUNT_ID ,
1802+ participant : { login : RORY_EMAIL , accountID : RORY_ACCOUNT_ID } ,
1803+ } ,
1804+ transactionParams : {
1805+ amount,
1806+ currency : 'USD' ,
1807+ created : format ( new Date ( ) , CONST . DATE . FNS_FORMAT_STRING ) ,
1808+ merchant : 'Delete tracked expense test' ,
1809+ billable : false ,
1810+ } ,
1811+ isASAPSubmitBetaEnabled : false ,
1812+ currentUserAccountIDParam : TEST_USER_ACCOUNT_ID ,
1813+ currentUserEmailParam : TEST_USER_LOGIN ,
1814+ introSelected : undefined ,
1815+ activePolicyID : undefined ,
1816+ quickAction : undefined ,
1817+ recentWaypoints,
1818+ betas : [ CONST . BETAS . ALL ] ,
1819+ draftTransactionIDs : [ ] ,
1820+ isSelfTourViewed : false ,
1821+ } ) ;
1822+ await waitForBatchedUpdates ( ) ;
1823+
1824+ const allReports = await new Promise < OnyxCollection < Report > > ( ( resolve ) => {
1825+ const connection = Onyx . connect ( {
1826+ key : ONYXKEYS . COLLECTION . REPORT ,
1827+ waitForCollectionCallback : true ,
1828+ callback : ( actions ) => {
1829+ Onyx . disconnect ( connection ) ;
1830+ resolve ( actions ) ;
1831+ } ,
1832+ } ) ;
1833+ } ) ;
1834+
1835+ const allReportActions = await new Promise < OnyxCollection < ReportActions > > ( ( resolve ) => {
1836+ const connection = Onyx . connect ( {
1837+ key : ONYXKEYS . COLLECTION . REPORT_ACTIONS ,
1838+ waitForCollectionCallback : true ,
1839+ callback : ( actions ) => {
1840+ Onyx . disconnect ( connection ) ;
1841+ resolve ( actions ) ;
1842+ } ,
1843+ } ) ;
1844+ } ) ;
1845+
1846+ const allTransactions = await new Promise < OnyxCollection < Transaction > > ( ( resolve ) => {
1847+ const connection = Onyx . connect ( {
1848+ key : ONYXKEYS . COLLECTION . TRANSACTION ,
1849+ waitForCollectionCallback : true ,
1850+ callback : ( actions ) => {
1851+ Onyx . disconnect ( connection ) ;
1852+ resolve ( actions ) ;
1853+ } ,
1854+ } ) ;
1855+ } ) ;
1856+
1857+ const transactionThreadReport = Object . values ( allReports ?? { } ) . find (
1858+ ( report ) => report ?. type === CONST . REPORT . TYPE . CHAT && report ?. parentReportID === selfDMReport . reportID && report ?. reportID !== selfDMReport . reportID ,
1859+ ) ;
1860+ if ( transactionThreadReport ) {
1861+ thread = transactionThreadReport ;
1862+ }
1863+
1864+ iouReportAction = Object . values ( allReportActions ?. [ `${ ONYXKEYS . COLLECTION . REPORT_ACTIONS } ${ selfDMReport . reportID } ` ] ?? { } ) . find (
1865+ ( reportAction ) : reportAction is ReportAction < typeof CONST . REPORT . ACTIONS . TYPE . IOU > => reportAction . reportActionID === thread ?. parentReportActionID ,
1866+ ) ;
1867+ transaction = Object . values ( allTransactions ?? { } ) . find ( ( trackedTransaction ) => trackedTransaction ) ;
1868+
1869+ expect ( thread ) . toBeTruthy ( ) ;
1870+ expect ( iouReportAction ) . toBeTruthy ( ) ;
1871+ expect ( transaction ) . toBeTruthy ( ) ;
1872+ } ) ;
1873+
1874+ afterEach ( PusherHelper . teardown ) ;
1875+
1876+ it ( 'should call API.write with delete money request onyx data for selfDM track expenses and return the parent report route in single transaction view' , ( ) => {
1877+ const writeSpy = jest . spyOn ( API , 'write' ) . mockImplementation ( jest . fn ( ) ) ;
1878+
1879+ const result = deleteTrackExpense ( {
1880+ chatReportID : selfDMReport . reportID ,
1881+ chatReport : selfDMReport ,
1882+ transactionID : transaction ?. transactionID ,
1883+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1884+ reportAction : iouReportAction ! ,
1885+ iouReport : undefined ,
1886+ chatIOUReport : undefined ,
1887+ transactions : { } ,
1888+ violations : { } ,
1889+ isSingleTransactionView : true ,
1890+ isChatReportArchived : false ,
1891+ isChatIOUReportArchived : false ,
1892+ allTransactionViolationsParam : { } ,
1893+ currentUserAccountID : TEST_USER_ACCOUNT_ID ,
1894+ currentUserEmail : TEST_USER_LOGIN ,
1895+ } ) ;
1896+
1897+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
1898+ expect ( result ) . toBe ( ROUTES . REPORT_WITH_ID . getRoute ( selfDMReport . reportID ) ) ;
1899+ expect ( writeSpy ) . toHaveBeenCalledWith (
1900+ WRITE_COMMANDS . DELETE_MONEY_REQUEST ,
1901+ expect . objectContaining ( {
1902+ transactionID : transaction ?. transactionID ,
1903+ reportActionID : iouReportAction ?. reportActionID ,
1904+ } ) ,
1905+ expect . objectContaining ( {
1906+ optimisticData : expect . any ( Array ) ,
1907+ successData : expect . any ( Array ) ,
1908+ failureData : expect . any ( Array ) ,
1909+ } ) ,
1910+ ) ;
1911+ } ) ;
1912+ } ) ;
1913+
17641914 describe ( 'convertBulkTrackedExpensesToIOU' , ( ) => {
17651915 it ( 'should accept personalDetails as a required parameter' , async ( ) => {
17661916 const currentUserAccountID = 1 ;
0 commit comments