@@ -6,7 +6,10 @@ import type {PaymentActionParams} from '@components/SettlementButton/types';
66import useOnyx from '@hooks/useOnyx' ;
77import useReportWithTransactionsAndViolations from '@hooks/useReportWithTransactionsAndViolations' ;
88
9- import { payInvoice } from '@userActions/IOU/PayMoneyRequest' ;
9+ import type * as SearchActions from '@libs/actions/Search' ;
10+ import { isInvoiceReport } from '@libs/ReportUtils' ;
11+
12+ import { payInvoice , payMoneyRequest } from '@userActions/IOU/PayMoneyRequest' ;
1013
1114import CONST from '@src/CONST' ;
1215import type { Report } from '@src/types/onyx' ;
@@ -59,9 +62,21 @@ jest.mock('@userActions/IOU/ReportWorkflow', () => ({
5962 canIOUBePaid : jest . fn ( ( ) => true ) ,
6063} ) ) ;
6164
65+ const mockLogInfo = jest . fn ( ) ;
66+ jest . mock ( '@libs/Log' , ( ) => ( {
67+ __esModule : true ,
68+ default : {
69+ info : ( ...args : unknown [ ] ) => {
70+ mockLogInfo ( ...args ) ;
71+ } ,
72+ warn : jest . fn ( ) ,
73+ } ,
74+ } ) ) ;
75+
6276jest . mock ( '@libs/actions/Search' , ( ) => ( {
6377 __esModule : true ,
6478 getSearchPayOnyxData : jest . fn ( ( ) => ( { optimisticData : [ ] , successData : [ ] , failureData : [ ] } ) ) ,
79+ getChatReportWithFallback : jest . requireActual < typeof SearchActions > ( '@libs/actions/Search' ) . getChatReportWithFallback ,
6580} ) ) ;
6681
6782jest . mock ( '@libs/ReportUtils' , ( ) => {
@@ -113,6 +128,19 @@ jest.mock('@components/DelegateNoAccessModalProvider', () => ({
113128const mockedUseOnyx = jest . mocked ( useOnyx ) ;
114129const mockedUseReportWithTransactionsAndViolations = jest . mocked ( useReportWithTransactionsAndViolations ) ;
115130const mockedPayInvoice = jest . mocked ( payInvoice ) ;
131+ const mockedPayMoneyRequest = jest . mocked ( payMoneyRequest ) ;
132+ const mockedIsInvoiceReport = jest . mocked ( isInvoiceReport ) ;
133+
134+ const TEST_EXPENSE_REPORT_ID = '3003' ;
135+
136+ const expenseReport = {
137+ reportID : TEST_EXPENSE_REPORT_ID ,
138+ chatReportID : TEST_CHAT_REPORT_ID ,
139+ type : CONST . REPORT . TYPE . EXPENSE ,
140+ currency : CONST . CURRENCY . USD ,
141+ policyID : 'policy1' ,
142+ total : - 5000 ,
143+ } as Report ;
116144
117145describe ( 'PayActionCell' , ( ) => {
118146 beforeEach ( ( ) => {
@@ -170,5 +198,92 @@ describe('PayActionCell', () => {
170198 } ) ;
171199
172200 expect ( mockedPayInvoice ) . not . toHaveBeenCalled ( ) ;
201+ expect ( mockLogInfo ) . toHaveBeenCalledWith ( '[SearchPay] Dropping invoice row pay: chat report is not loaded' , false , { reportID : TEST_INVOICE_REPORT_ID } ) ;
202+ } ) ;
203+
204+ it ( 'pays a money request with a fallback chat report when no chatReport prop is supplied' , ( ) => {
205+ mockedIsInvoiceReport . mockReturnValue ( false ) ;
206+ mockedUseReportWithTransactionsAndViolations . mockReturnValue ( [ expenseReport , [ ] , undefined ] ) ;
207+
208+ render (
209+ < PayActionCell
210+ isLoading = { false }
211+ policyID = "policy1"
212+ reportID = { TEST_EXPENSE_REPORT_ID }
213+ hash = { TEST_HASH }
214+ amount = { 5000 }
215+ chatReport = { undefined }
216+ /> ,
217+ ) ;
218+
219+ act ( ( ) => {
220+ mockOnPressHolder . current ?.( {
221+ paymentType : CONST . IOU . PAYMENT_TYPE . ELSEWHERE ,
222+ payAsBusiness : false ,
223+ } ) ;
224+ } ) ;
225+
226+ expect ( mockedPayMoneyRequest ) . toHaveBeenCalledWith (
227+ expect . objectContaining ( {
228+ chatReport : { reportID : TEST_CHAT_REPORT_ID , policyID : 'policy1' } ,
229+ isFallbackChatReport : true ,
230+ } ) ,
231+ ) ;
232+ } ) ;
233+
234+ it ( 'pays a money request with the loaded chat report when it is supplied' , ( ) => {
235+ mockedIsInvoiceReport . mockReturnValue ( false ) ;
236+ mockedUseReportWithTransactionsAndViolations . mockReturnValue ( [ expenseReport , [ ] , undefined ] ) ;
237+
238+ render (
239+ < PayActionCell
240+ isLoading = { false }
241+ policyID = "policy1"
242+ reportID = { TEST_EXPENSE_REPORT_ID }
243+ hash = { TEST_HASH }
244+ amount = { 5000 }
245+ chatReport = { chatReport }
246+ /> ,
247+ ) ;
248+
249+ act ( ( ) => {
250+ mockOnPressHolder . current ?.( {
251+ paymentType : CONST . IOU . PAYMENT_TYPE . ELSEWHERE ,
252+ payAsBusiness : false ,
253+ } ) ;
254+ } ) ;
255+
256+ expect ( mockedPayMoneyRequest ) . toHaveBeenCalledWith (
257+ expect . objectContaining ( {
258+ chatReport,
259+ isFallbackChatReport : false ,
260+ } ) ,
261+ ) ;
262+ } ) ;
263+
264+ it ( 'does not pay a money request and logs the reason when the chat is not loaded and no chatReportID is available' , ( ) => {
265+ mockedIsInvoiceReport . mockReturnValue ( false ) ;
266+ mockedUseReportWithTransactionsAndViolations . mockReturnValue ( [ { ...expenseReport , chatReportID : undefined , parentReportID : undefined } , [ ] , undefined ] ) ;
267+
268+ render (
269+ < PayActionCell
270+ isLoading = { false }
271+ policyID = "policy1"
272+ reportID = { TEST_EXPENSE_REPORT_ID }
273+ hash = { TEST_HASH }
274+ amount = { 5000 }
275+ chatReport = { undefined }
276+ /> ,
277+ ) ;
278+
279+ act ( ( ) => {
280+ mockOnPressHolder . current ?.( {
281+ paymentType : CONST . IOU . PAYMENT_TYPE . ELSEWHERE ,
282+ payAsBusiness : false ,
283+ } ) ;
284+ } ) ;
285+
286+ expect ( mockedPayMoneyRequest ) . not . toHaveBeenCalled ( ) ;
287+ expect ( mockLogInfo ) . toHaveBeenCalledWith ( '[SearchPay] Dropping row pay: chat report is not loaded and no chatReportID is available' , false , { reportID : TEST_EXPENSE_REPORT_ID } ) ;
173288 } ) ;
174289} ) ;
0 commit comments