-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Move the logic of excluding contacts of DMs already included in reports to filterOptions
#50426
Merged
MonilBhavsar
merged 13 commits into
Expensify:main
from
c3024:move-deduplicating-logic-of-personal-details-to-filteredOptions
Oct 18, 2024
Merged
Changes from 6 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
a50a4df
move report deduplicating logic to filterOptions
c3024 deb1ba1
prettier and lint
c3024 ffd08a4
add missed filter case and fix tests
c3024 68709d9
extract filtering to function, fix lint in tests
c3024 b317a18
fix lint
c3024 28b226d
correct filtering logic for personal details
c3024 b69ea35
enforce empty search term with non-empty options
c3024 dfab13e
fix params for all getFilteredOptions calls
c3024 dd001f4
fix lint
c3024 f9a76cf
migrate withOnyx to useOnyx
c3024 63d5b19
pass correct maxRecentReports to getFilteredOptions
c3024 3e72ecc
review comments
c3024 0519359
comments explaining need for types and function
c3024 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -405,8 +405,10 @@ describe('OptionsListUtils', () => { | |
it('getSearchOptions()', () => { | ||
// When we filter in the Search view without providing a searchValue | ||
const results = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); | ||
// Then the 2 personalDetails that don't have reports should be returned | ||
expect(results.personalDetails.length).toBe(2); | ||
|
||
// All 2 personalDetails (including those that have reports) should be returned | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(9); | ||
|
||
// Then all of the reports should be shown including the archived rooms. | ||
expect(results.recentReports.length).toBe(Object.values(OPTIONS.reports).length); | ||
|
@@ -422,15 +424,21 @@ describe('OptionsListUtils', () => { | |
// We should expect maximimum of 5 recent reports to be returned | ||
expect(results.recentReports.length).toBe(MAX_RECENT_REPORTS); | ||
|
||
// We should expect all personalDetails to be returned, | ||
// minus the currently logged in user and recent reports count | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS.personalDetails).length - 1 - MAX_RECENT_REPORTS); | ||
// We should expect all personalDetails except the currently logged in user to be returned | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS.personalDetails).length - 1); | ||
|
||
// All personal details including those that have reports should be returned | ||
// We should expect personal details sorted alphabetically | ||
expect(results.personalDetails.at(0)?.text).toBe('Black Widow'); | ||
expect(results.personalDetails.at(1)?.text).toBe('Invisible Woman'); | ||
expect(results.personalDetails.at(2)?.text).toBe('Spider-Man'); | ||
expect(results.personalDetails.at(3)?.text).toBe('The Incredible Hulk'); | ||
expect(results.personalDetails.at(0)?.text).toBe('Black Panther'); | ||
expect(results.personalDetails.at(1)?.text).toBe('Black Widow'); | ||
expect(results.personalDetails.at(2)?.text).toBe('Captain America'); | ||
expect(results.personalDetails.at(3)?.text).toBe('Invisible Woman'); | ||
expect(results.personalDetails.at(4)?.text).toBe('Mister Fantastic'); | ||
expect(results.personalDetails.at(5)?.text).toBe('Mr Sinister'); | ||
expect(results.personalDetails.at(6)?.text).toBe('Spider-Man'); | ||
expect(results.personalDetails.at(7)?.text).toBe('The Incredible Hulk'); | ||
expect(results.personalDetails.at(8)?.text).toBe('Thor'); | ||
|
||
// Then the result which has an existing report should also have the reportID attached | ||
const personalDetailWithExistingReport = results.personalDetails.find((personalDetail) => personalDetail.login === '[email protected]'); | ||
|
@@ -481,29 +489,33 @@ describe('OptionsListUtils', () => { | |
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CONCIERGE.reports, OPTIONS_WITH_CONCIERGE.personalDetails); | ||
|
||
// Concierge is included in the results by default. We should expect all the personalDetails to show | ||
// (minus the 5 that are already showing and the currently logged in user) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 1 - MAX_RECENT_REPORTS); | ||
// (minus the currently logged in user) | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 1); | ||
expect(results.recentReports).toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Concierge from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CONCIERGE.reports, OPTIONS_WITH_CONCIERGE.personalDetails, [], '', [], [CONST.EMAIL.CONCIERGE]); | ||
|
||
// All the personalDetails should be returned minus the currently logged in user and Concierge | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 2 - MAX_RECENT_REPORTS); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Chronos from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CHRONOS.reports, OPTIONS_WITH_CHRONOS.personalDetails, [], '', [], [CONST.EMAIL.CHRONOS]); | ||
|
||
// All the personalDetails should be returned minus the currently logged in user and Concierge | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CHRONOS.personalDetails).length - 2 - MAX_RECENT_REPORTS); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CHRONOS.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Receipts from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_RECEIPTS.reports, OPTIONS_WITH_RECEIPTS.personalDetails, [], '', [], [CONST.EMAIL.RECEIPTS]); | ||
|
||
// All the personalDetails should be returned minus the currently logged in user and Concierge | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_RECEIPTS.personalDetails).length - 2 - MAX_RECENT_REPORTS); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_RECEIPTS.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
}); | ||
|
||
|
@@ -514,15 +526,21 @@ describe('OptionsListUtils', () => { | |
// Then we should expect only a maxmimum of 5 recent reports to be returned | ||
expect(results.recentReports.length).toBe(5); | ||
|
||
// And we should expect all the personalDetails to show (minus the 5 that are already | ||
// showing and the currently logged in user) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS.personalDetails).length - 6); | ||
// And we should expect all the personalDetails to show except the currently logged in user | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS.personalDetails).length - 1); | ||
|
||
// All personal details including those that have reports should be returned | ||
// We should expect personal details sorted alphabetically | ||
expect(results.personalDetails.at(0)?.text).toBe('Black Widow'); | ||
expect(results.personalDetails.at(1)?.text).toBe('Invisible Woman'); | ||
expect(results.personalDetails.at(2)?.text).toBe('Spider-Man'); | ||
expect(results.personalDetails.at(3)?.text).toBe('The Incredible Hulk'); | ||
expect(results.personalDetails.at(0)?.text).toBe('Black Panther'); | ||
expect(results.personalDetails.at(1)?.text).toBe('Black Widow'); | ||
expect(results.personalDetails.at(2)?.text).toBe('Captain America'); | ||
expect(results.personalDetails.at(3)?.text).toBe('Invisible Woman'); | ||
expect(results.personalDetails.at(4)?.text).toBe('Mister Fantastic'); | ||
expect(results.personalDetails.at(5)?.text).toBe('Mr Sinister'); | ||
expect(results.personalDetails.at(6)?.text).toBe('Spider-Man'); | ||
expect(results.personalDetails.at(7)?.text).toBe('The Incredible Hulk'); | ||
expect(results.personalDetails.at(8)?.text).toBe('Thor'); | ||
|
||
// And none of our personalDetails should include any of the users with recent reports | ||
const reportLogins = results.recentReports.map((reportOption) => reportOption.login); | ||
|
@@ -548,34 +566,38 @@ describe('OptionsListUtils', () => { | |
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CONCIERGE.reports, OPTIONS_WITH_CONCIERGE.personalDetails); | ||
|
||
// Concierge is included in the results by default. We should expect all the personalDetails to show | ||
// (minus the 5 that are already showing and the currently logged in user) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 6); | ||
// (minus the currently logged in user) | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 1); | ||
expect(results.recentReports).toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Concierge from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CONCIERGE.reports, OPTIONS_WITH_CONCIERGE.personalDetails, [], '', [], [CONST.EMAIL.CONCIERGE]); | ||
|
||
// We should expect all the personalDetails to show (minus the 5 that are already showing, | ||
// We should expect all the personalDetails to show (minus | ||
// the currently logged in user and Concierge) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 7); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CONCIERGE.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
expect(results.recentReports).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Chronos from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_CHRONOS.reports, OPTIONS_WITH_CHRONOS.personalDetails, [], '', [], [CONST.EMAIL.CHRONOS]); | ||
|
||
// We should expect all the personalDetails to show (minus the 5 that are already showing, | ||
// We should expect all the personalDetails to show (minus | ||
// the currently logged in user and Concierge) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CHRONOS.personalDetails).length - 7); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_CHRONOS.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
expect(results.recentReports).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
|
||
// Test by excluding Receipts from the results | ||
results = OptionsListUtils.getFilteredOptions(OPTIONS_WITH_RECEIPTS.reports, OPTIONS_WITH_RECEIPTS.personalDetails, [], '', [], [CONST.EMAIL.RECEIPTS]); | ||
|
||
// We should expect all the personalDetails to show (minus the 5 that are already showing, | ||
// We should expect all the personalDetails to show (minus | ||
// the currently logged in user and Concierge) | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_RECEIPTS.personalDetails).length - 7); | ||
// Filtering of personalDetails that have reports is done in filterOptions | ||
expect(results.personalDetails.length).toBe(Object.values(OPTIONS_WITH_RECEIPTS.personalDetails).length - 2); | ||
expect(results.personalDetails).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
expect(results.recentReports).not.toEqual(expect.arrayContaining([expect.objectContaining({login: '[email protected]'})])); | ||
}); | ||
|
@@ -2610,7 +2632,7 @@ describe('OptionsListUtils', () => { | |
const options = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); | ||
const filteredOptions = OptionsListUtils.filterOptions(options, ''); | ||
|
||
expect(options.recentReports.length + options.personalDetails.length).toBe(filteredOptions.recentReports.length + filteredOptions.personalDetails.length); | ||
expect(filteredOptions.recentReports.length + filteredOptions.personalDetails.length).toBe(12); | ||
}); | ||
|
||
it('should return filtered options in correct order', () => { | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is there a use case when maxRecentReportsToShow = 0 and
recentReports
is a long list? If so, then it seems there will be a performance downgrade here. Wdyt?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 will but that might not be significant.
We iterate over all
recentReports
here for each search word.App/src/libs/OptionsListUtils.ts
Lines 2520 to 2542 in 9d86f30
We iterate over the
recentReports
once more for this functionfilteredPersonalDetailsOfRecentReports
.Since, we pass
searchTerm
only to this functionfilterOptions
and notgetOptions
, we need to do this exclusion of contacts only here.