1
+ import type { OnyxCollection } from 'react-native-onyx' ;
2
+ import Onyx from 'react-native-onyx' ;
3
+ import { shouldShowBrokenConnectionViolation } from '@libs/TransactionUtils' ;
1
4
import CONST from '@src/CONST' ;
5
+ import ONYXKEYS from '@src/ONYXKEYS' ;
2
6
import type { Attendee } from '@src/types/onyx/IOU' ;
7
+ import type { ReportCollectionDataSet } from '@src/types/onyx/Report' ;
3
8
import * as TransactionUtils from '../../src/libs/TransactionUtils' ;
4
- import type { Policy , Transaction } from '../../src/types/onyx' ;
9
+ import type { Policy , Transaction , TransactionViolation } from '../../src/types/onyx' ;
5
10
import createRandomPolicy , { createCategoryTaxExpenseRules } from '../utils/collections/policies' ;
6
11
7
12
function generateTransaction ( values : Partial < Transaction > = { } ) : Transaction {
@@ -25,7 +30,56 @@ function generateTransaction(values: Partial<Transaction> = {}): Transaction {
25
30
return { ...baseValues , ...values } ;
26
31
}
27
32
33
+ const CURRENT_USER_ID = 1 ;
34
+ const SECOND_USER_ID = 2 ;
35
+ const FAKE_OPEN_REPORT_ID = 'FAKE_OPEN_REPORT_ID' ;
36
+ const FAKE_OPEN_REPORT_SECOND_USER_ID = 'FAKE_OPEN_REPORT_SECOND_USER_ID' ;
37
+ const FAKE_PROCESSING_REPORT_ID = 'FAKE_PROCESSING_REPORT_ID' ;
38
+ const FAKE_APPROVED_REPORT_ID = 'FAKE_APPROVED_REPORT_ID' ;
39
+ const openReport = {
40
+ reportID : FAKE_OPEN_REPORT_ID ,
41
+ ownerAccountID : CURRENT_USER_ID ,
42
+ type : CONST . REPORT . TYPE . EXPENSE ,
43
+ stateNum : CONST . REPORT . STATE_NUM . OPEN ,
44
+ statusNum : CONST . REPORT . STATUS_NUM . OPEN ,
45
+ } ;
46
+ const processingReport = {
47
+ reportID : FAKE_PROCESSING_REPORT_ID ,
48
+ ownerAccountID : CURRENT_USER_ID ,
49
+ type : CONST . REPORT . TYPE . EXPENSE ,
50
+ stateNum : CONST . REPORT . STATE_NUM . SUBMITTED ,
51
+ } ;
52
+ const approvedReport = {
53
+ reportID : FAKE_APPROVED_REPORT_ID ,
54
+ ownerAccountID : SECOND_USER_ID ,
55
+ type : CONST . REPORT . TYPE . EXPENSE ,
56
+ stateNum : CONST . REPORT . STATE_NUM . APPROVED ,
57
+ } ;
58
+ const secondUserOpenReport = {
59
+ reportID : FAKE_OPEN_REPORT_SECOND_USER_ID ,
60
+ ownerAccountID : SECOND_USER_ID ,
61
+ type : CONST . REPORT . TYPE . EXPENSE ,
62
+ stateNum : CONST . REPORT . STATE_NUM . OPEN ,
63
+ statusNum : CONST . REPORT . STATUS_NUM . OPEN ,
64
+ } ;
65
+ const reportCollectionDataSet : ReportCollectionDataSet = {
66
+ [ `${ ONYXKEYS . COLLECTION . REPORT } ${ FAKE_OPEN_REPORT_ID } ` ] : openReport ,
67
+ [ `${ ONYXKEYS . COLLECTION . REPORT } ${ FAKE_PROCESSING_REPORT_ID } ` ] : processingReport ,
68
+ [ `${ ONYXKEYS . COLLECTION . REPORT } ${ FAKE_APPROVED_REPORT_ID } ` ] : approvedReport ,
69
+ [ `${ ONYXKEYS . COLLECTION . REPORT } ${ FAKE_OPEN_REPORT_SECOND_USER_ID } ` ] : secondUserOpenReport ,
70
+ } ;
71
+
28
72
describe ( 'TransactionUtils' , ( ) => {
73
+ beforeAll ( ( ) => {
74
+ Onyx . init ( {
75
+ keys : ONYXKEYS ,
76
+ initialKeyStates : {
77
+ [ ONYXKEYS . SESSION ] : { accountID : CURRENT_USER_ID } ,
78
+ ...reportCollectionDataSet ,
79
+ } ,
80
+ } ) ;
81
+ } ) ;
82
+
29
83
describe ( 'getCreated' , ( ) => {
30
84
describe ( 'when the transaction property "modifiedCreated" has value' , ( ) => {
31
85
const transaction = generateTransaction ( {
@@ -279,4 +333,110 @@ describe('TransactionUtils', () => {
279
333
expect ( result ) . toBe ( 9.09 ) ;
280
334
} ) ;
281
335
} ) ;
336
+
337
+ describe ( 'shouldShowBrokenConnectionViolation' , ( ) => {
338
+ it ( 'should return false when the provided transaction is undefined' , ( ) => {
339
+ const transaction = undefined ;
340
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER } ] ;
341
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , undefined , undefined , transactionViolations ) ;
342
+
343
+ expect ( showBrokenConnectionViolation ) . toBe ( false ) ;
344
+ } ) ;
345
+
346
+ it ( 'should throw an error when both transactionIDs and transactionViolations are arrays' , ( ) => {
347
+ const transactionIDs = [ 'FAKE_1' , 'FAKE_2' ] ;
348
+ const transactionViolations : TransactionViolation [ ] = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER } ] ;
349
+
350
+ expect ( ( ) => {
351
+ shouldShowBrokenConnectionViolation ( transactionIDs , undefined , undefined , transactionViolations ) ;
352
+ } ) . toThrow ( 'Invalid argument combination. If a transactionIDList is passed in, then an OnyxCollection of violations is expected' ) ;
353
+ } ) ;
354
+
355
+ it ( 'should throw an error when only one transaction is provided and transactionViolations are not an array' , ( ) => {
356
+ const transaction = generateTransaction ( ) ;
357
+ const transactionViolations : OnyxCollection < TransactionViolation [ ] > = {
358
+ violationID : [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER } ] ,
359
+ } ;
360
+
361
+ expect ( ( ) => {
362
+ shouldShowBrokenConnectionViolation ( transaction , undefined , undefined , transactionViolations ) ;
363
+ } ) . toThrow ( 'Invalid argument combination. If a single transaction is passed in, then an array of violations for that transaction is expected' ) ;
364
+ } ) ;
365
+
366
+ it ( 'should return false when no broken connection violations are found for the provided transaction' , ( ) => {
367
+ const transaction = generateTransaction ( ) ;
368
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . DUPLICATED_TRANSACTION } ] ;
369
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , undefined , undefined , transactionViolations ) ;
370
+
371
+ expect ( showBrokenConnectionViolation ) . toBe ( false ) ;
372
+ } ) ;
373
+
374
+ it ( 'should return true when a broken connection violation exists for one transaction and the user is the policy member' , ( ) => {
375
+ const policy = { role : CONST . POLICY . ROLE . USER } as Policy ;
376
+ const transaction = generateTransaction ( ) ;
377
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER , data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } } ] ;
378
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , undefined , policy , transactionViolations ) ;
379
+
380
+ expect ( showBrokenConnectionViolation ) . toBe ( true ) ;
381
+ } ) ;
382
+
383
+ it ( 'should return true when a broken connection violation exists for any of the provided transactions and the user is the policy member' , ( ) => {
384
+ const policy = { role : CONST . POLICY . ROLE . USER } as Policy ;
385
+ const transaction1 = generateTransaction ( ) ;
386
+ const transaction2 = generateTransaction ( ) ;
387
+ const transactionIDs = [ transaction1 . transactionID , transaction2 . transactionID ] ;
388
+ const transactionViolations = {
389
+ [ `${ ONYXKEYS . COLLECTION . TRANSACTION_VIOLATIONS } ${ transaction1 . transactionID } ` ] : [
390
+ {
391
+ type : CONST . VIOLATION_TYPES . VIOLATION ,
392
+ name : CONST . VIOLATIONS . RTER ,
393
+ data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } ,
394
+ } ,
395
+ ] ,
396
+ } ;
397
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transactionIDs , undefined , policy , transactionViolations ) ;
398
+
399
+ expect ( showBrokenConnectionViolation ) . toBe ( true ) ;
400
+ } ) ;
401
+
402
+ it ( 'should return true when a broken connection violation exists and the user is the policy admin and the expense submitter' , ( ) => {
403
+ const policy = { role : CONST . POLICY . ROLE . ADMIN } as Policy ;
404
+ const report = processingReport ;
405
+ const transaction = generateTransaction ( ) ;
406
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER , data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } } ] ;
407
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , report , policy , transactionViolations ) ;
408
+
409
+ expect ( showBrokenConnectionViolation ) . toBe ( true ) ;
410
+ } ) ;
411
+
412
+ it ( 'should return true when a broken connection violation exists, the user is the policy admin and the expense report is in the open state' , ( ) => {
413
+ const policy = { role : CONST . POLICY . ROLE . ADMIN } as Policy ;
414
+ const report = secondUserOpenReport ;
415
+ const transaction = generateTransaction ( ) ;
416
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER , data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } } ] ;
417
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , report , policy , transactionViolations ) ;
418
+
419
+ expect ( showBrokenConnectionViolation ) . toBe ( true ) ;
420
+ } ) ;
421
+
422
+ it ( 'should return true when a broken connection violation exists, the user is the policy admin, the expense report is in the processing state and instant submit is enabled' , ( ) => {
423
+ const policy = { role : CONST . POLICY . ROLE . ADMIN , autoReporting : true , autoReportingFrequency : CONST . POLICY . AUTO_REPORTING_FREQUENCIES . INSTANT } as Policy ;
424
+ const report = processingReport ;
425
+ const transaction = generateTransaction ( ) ;
426
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER , data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } } ] ;
427
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , report , policy , transactionViolations ) ;
428
+
429
+ expect ( showBrokenConnectionViolation ) . toBe ( true ) ;
430
+ } ) ;
431
+
432
+ it ( 'should return false when a broken connection violation exists, the user is the policy admin but the expense report is in the approved state' , ( ) => {
433
+ const policy = { role : CONST . POLICY . ROLE . ADMIN } as Policy ;
434
+ const report = approvedReport ;
435
+ const transaction = generateTransaction ( ) ;
436
+ const transactionViolations = [ { type : CONST . VIOLATION_TYPES . VIOLATION , name : CONST . VIOLATIONS . RTER , data : { rterType : CONST . RTER_VIOLATION_TYPES . BROKEN_CARD_CONNECTION } } ] ;
437
+ const showBrokenConnectionViolation = shouldShowBrokenConnectionViolation ( transaction , report , policy , transactionViolations ) ;
438
+
439
+ expect ( showBrokenConnectionViolation ) . toBe ( false ) ;
440
+ } ) ;
441
+ } ) ;
282
442
} ) ;
0 commit comments