Skip to content

Commit 22e7d27

Browse files
authored
Merge pull request #57542 from callstack-internal/VickyStash/bugfix/57162-unit-tests
2 parents b7d924a + e3357af commit 22e7d27

File tree

1 file changed

+161
-1
lines changed

1 file changed

+161
-1
lines changed

tests/unit/TransactionUtilsTest.ts

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import type {OnyxCollection} from 'react-native-onyx';
2+
import Onyx from 'react-native-onyx';
3+
import {shouldShowBrokenConnectionViolation} from '@libs/TransactionUtils';
14
import CONST from '@src/CONST';
5+
import ONYXKEYS from '@src/ONYXKEYS';
26
import type {Attendee} from '@src/types/onyx/IOU';
7+
import type {ReportCollectionDataSet} from '@src/types/onyx/Report';
38
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';
510
import createRandomPolicy, {createCategoryTaxExpenseRules} from '../utils/collections/policies';
611

712
function generateTransaction(values: Partial<Transaction> = {}): Transaction {
@@ -25,7 +30,56 @@ function generateTransaction(values: Partial<Transaction> = {}): Transaction {
2530
return {...baseValues, ...values};
2631
}
2732

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+
2872
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+
2983
describe('getCreated', () => {
3084
describe('when the transaction property "modifiedCreated" has value', () => {
3185
const transaction = generateTransaction({
@@ -279,4 +333,110 @@ describe('TransactionUtils', () => {
279333
expect(result).toBe(9.09);
280334
});
281335
});
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+
});
282442
});

0 commit comments

Comments
 (0)