-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix violation shows optimistically for a partial transaction #39034
Changes from 7 commits
d65a8f3
f9fc96d
bdcdc47
39b8c46
cd2dcc2
2c9efa0
3a5827f
0612ffd
3b43ff6
9e7f5b7
37a9a6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,7 @@ | ||||||
import {beforeEach} from '@jest/globals'; | ||||||
import Onyx from 'react-native-onyx'; | ||||||
import ViolationsUtils from '@libs/Violations/ViolationsUtils'; | ||||||
import CONST from '@src/CONST'; | ||||||
import ONYXKEYS from '@src/ONYXKEYS'; | ||||||
import type {PolicyCategories, PolicyTagList, Transaction, TransactionViolation} from '@src/types/onyx'; | ||||||
|
||||||
|
@@ -57,7 +58,17 @@ describe('getViolationsOnyxData', () => { | |||||
{name: 'receiptRequired', type: 'violation'}, | ||||||
]; | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual(expect.arrayContaining(transactionViolations)); | ||||||
expect(result?.value).toEqual(expect.arrayContaining(transactionViolations)); | ||||||
}); | ||||||
|
||||||
it('should not add violation when the transaction is partial', () => { | ||||||
const partialTransaction = {...transaction, amount: 0, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT}; | ||||||
transactionViolations = [ | ||||||
{name: 'duplicatedTransaction', type: 'violation'}, | ||||||
{name: 'receiptRequired', type: 'violation'}, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use consts for this. I think we need to add one for
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have updated the test to not have an existing violation for partial transaction anymore |
||||||
]; | ||||||
const result = ViolationsUtils.getViolationsOnyxData(partialTransaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result).toBeNull(); | ||||||
}); | ||||||
|
||||||
describe('policyRequiresCategories', () => { | ||||||
|
@@ -70,18 +81,18 @@ describe('getViolationsOnyxData', () => { | |||||
it('should add missingCategory violation if no category is included', () => { | ||||||
transaction.category = undefined; | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); | ||||||
}); | ||||||
|
||||||
it('should add categoryOutOfPolicy violation when category is not in policy', () => { | ||||||
transaction.category = 'Bananas'; | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); | ||||||
}); | ||||||
|
||||||
it('should not include a categoryOutOfPolicy violation when category is in policy', () => { | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).not.toContainEqual(categoryOutOfPolicyViolation); | ||||||
expect(result?.value).not.toContainEqual(categoryOutOfPolicyViolation); | ||||||
}); | ||||||
|
||||||
it('should add categoryOutOfPolicy violation to existing violations if they exist', () => { | ||||||
|
@@ -93,7 +104,7 @@ describe('getViolationsOnyxData', () => { | |||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([categoryOutOfPolicyViolation, ...transactionViolations])); | ||||||
}); | ||||||
|
||||||
it('should add missingCategory violation to existing violations if they exist', () => { | ||||||
|
@@ -105,7 +116,7 @@ describe('getViolationsOnyxData', () => { | |||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([missingCategoryViolation, ...transactionViolations])); | ||||||
}); | ||||||
}); | ||||||
|
||||||
|
@@ -117,8 +128,8 @@ describe('getViolationsOnyxData', () => { | |||||
it('should not add any violations when categories are not required', () => { | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).not.toContainEqual([categoryOutOfPolicyViolation]); | ||||||
expect(result.value).not.toContainEqual([missingCategoryViolation]); | ||||||
expect(result?.value).not.toContainEqual([categoryOutOfPolicyViolation]); | ||||||
expect(result?.value).not.toContainEqual([missingCategoryViolation]); | ||||||
}); | ||||||
}); | ||||||
|
||||||
|
@@ -142,23 +153,23 @@ describe('getViolationsOnyxData', () => { | |||||
it("shouldn't update the transactionViolations if the policy requires tags and the transaction has a tag from the policy", () => { | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(transactionViolations); | ||||||
expect(result?.value).toEqual(transactionViolations); | ||||||
}); | ||||||
|
||||||
it('should add a missingTag violation if none is provided and policy requires tags', () => { | ||||||
transaction.tag = undefined; | ||||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}])); | ||||||
}); | ||||||
|
||||||
it('should add a tagOutOfPolicy violation when policy requires tags and tag is not in the policy', () => { | ||||||
policyTags = {}; | ||||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual([]); | ||||||
expect(result?.value).toEqual([]); | ||||||
}); | ||||||
|
||||||
it('should add tagOutOfPolicy violation to existing violations if transaction has tag that is not in the policy', () => { | ||||||
|
@@ -170,7 +181,7 @@ describe('getViolationsOnyxData', () => { | |||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations])); | ||||||
}); | ||||||
|
||||||
it('should add missingTag violation to existing violations if transaction does not have a tag', () => { | ||||||
|
@@ -182,7 +193,7 @@ describe('getViolationsOnyxData', () => { | |||||
|
||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); | ||||||
expect(result?.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations])); | ||||||
}); | ||||||
}); | ||||||
|
||||||
|
@@ -194,8 +205,8 @@ describe('getViolationsOnyxData', () => { | |||||
it('should not add any violations when tags are not required', () => { | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
|
||||||
expect(result.value).not.toContainEqual([tagOutOfPolicyViolation]); | ||||||
expect(result.value).not.toContainEqual([missingTagViolation]); | ||||||
expect(result?.value).not.toContainEqual([tagOutOfPolicyViolation]); | ||||||
expect(result?.value).not.toContainEqual([missingTagViolation]); | ||||||
}); | ||||||
}); | ||||||
describe('policy has multi level tags', () => { | ||||||
|
@@ -248,31 +259,31 @@ describe('getViolationsOnyxData', () => { | |||||
|
||||||
// Test case where transaction has no tags | ||||||
let result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
expect(result?.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
|
||||||
// Test case where transaction has 1 tag | ||||||
transaction.tag = 'Accounting'; | ||||||
someTagLevelsRequiredViolation.data = {errorIndexes: [1, 2]}; | ||||||
result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
expect(result?.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
|
||||||
// Test case where transaction has 2 tags | ||||||
transaction.tag = 'Accounting::Project1'; | ||||||
someTagLevelsRequiredViolation.data = {errorIndexes: [1]}; | ||||||
result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
expect(result?.value).toEqual([someTagLevelsRequiredViolation]); | ||||||
|
||||||
// Test case where transaction has all tags | ||||||
transaction.tag = 'Accounting:Africa:Project1'; | ||||||
result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
expect(result.value).toEqual([]); | ||||||
expect(result?.value).toEqual([]); | ||||||
}); | ||||||
it('should return tagOutOfPolicy when a tag is not enabled in the policy but is set in the transaction', () => { | ||||||
policyTags.Department.tags.Accounting.enabled = false; | ||||||
transaction.tag = 'Accounting:Africa:Project1'; | ||||||
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policyRequiresTags, policyTags, policyRequiresCategories, policyCategories); | ||||||
const violation = {...tagOutOfPolicyViolation, data: {tagName: 'Department'}}; | ||||||
expect(result.value).toEqual([violation]); | ||||||
expect(result?.value).toEqual([violation]); | ||||||
}); | ||||||
}); | ||||||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this logic under
let newTransactionViolations = [...transactionViolations];
and return the following if the transaction is partial? I think if we do that we don't need any of the other changes and the logic is simplerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's nice. Updated. Btw, do you think we can just return an empty array instead? Is it possible a transaction already has a violation while it's still a partial transaction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't, but the effect should be the same, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not possible then yes, the effect is the same.