diff --git a/src/libs/SidebarUtils.js b/src/libs/SidebarUtils.js index 9736ed957416..cd419b3b1a9a 100644 --- a/src/libs/SidebarUtils.js +++ b/src/libs/SidebarUtils.js @@ -1,5 +1,6 @@ import Onyx from 'react-native-onyx'; import _ from 'underscore'; +import lodashOrderBy from 'lodash/orderBy'; import Str from 'expensify-common/lib/str'; import ONYXKEYS from '../ONYXKEYS'; import * as ReportUtils from './ReportUtils'; @@ -148,14 +149,15 @@ function getOrderedReportIDs(reportIDFromRoute) { // Sort each group of reports accordingly pinnedReports = _.sortBy(pinnedReports, report => report.displayName.toLowerCase()); - outstandingIOUReports = _.sortBy(outstandingIOUReports, 'iouReportAmount').reverse(); + outstandingIOUReports = lodashOrderBy(outstandingIOUReports, ['iouReportAmount', report => report.displayName.toLowerCase()], ['desc', 'asc']); draftReports = _.sortBy(draftReports, report => report.displayName.toLowerCase()); - nonArchivedReports = _.sortBy(nonArchivedReports, report => (isInDefaultMode ? report.lastActionCreated : report.displayName.toLowerCase())); + nonArchivedReports = isInDefaultMode + ? lodashOrderBy(nonArchivedReports, ['lastActionCreated', report => report.displayName.toLowerCase()], ['desc', 'asc']) + : lodashOrderBy(nonArchivedReports, [report => report.displayName.toLowerCase()], ['asc']); archivedReports = _.sortBy(archivedReports, report => (isInDefaultMode ? report.lastActionCreated : report.displayName.toLowerCase())); - // For archived and non-archived reports, ensure that most recent reports are at the top by reversing the order of the arrays because underscore will only sort them in ascending order + // For archived reports ensure that most recent reports are at the top by reversing the order of the arrays because underscore will only sort them in ascending order if (isInDefaultMode) { - nonArchivedReports.reverse(); archivedReports.reverse(); } diff --git a/tests/unit/SidebarOrderTest.js b/tests/unit/SidebarOrderTest.js index 56d6398c0423..5414a9afdb5e 100644 --- a/tests/unit/SidebarOrderTest.js +++ b/tests/unit/SidebarOrderTest.js @@ -616,5 +616,122 @@ describe('Sidebar', () => { expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Report (archived)'); }); }); + + it('orders IOU reports by displayName if amounts are the same', () => { + // Given three IOU reports containing the same IOU amounts + const report1 = { + ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com']), + hasOutstandingIOU: true, + + // This has to be added after the IOU report is generated + iouReportID: null, + }; + const report2 = { + ...LHNTestUtils.getFakeReport(['email3@test.com', 'email4@test.com']), + hasOutstandingIOU: true, + + // This has to be added after the IOU report is generated + iouReportID: null, + }; + const report3 = { + ...LHNTestUtils.getFakeReport(['email5@test.com', 'email6@test.com']), + hasOutstandingIOU: true, + + // This has to be added after the IOU report is generated + iouReportID: null, + }; + const iouReport1 = { + ...LHNTestUtils.getFakeReport(['email7@test.com', 'email8@test.com']), + ownerEmail: 'email2@test.com', + hasOutstandingIOU: true, + total: 10000, + currency: 'USD', + chatReportID: report3.reportID, + }; + const iouReport2 = { + ...LHNTestUtils.getFakeReport(['email9@test.com', 'email10@test.com']), + ownerEmail: 'email2@test.com', + hasOutstandingIOU: true, + total: 10000, + currency: 'USD', + chatReportID: report3.reportID, + }; + const iouReport3 = { + ...LHNTestUtils.getFakeReport(['email11@test.com', 'email12@test.com']), + ownerEmail: 'email2@test.com', + hasOutstandingIOU: true, + total: 10000, + currency: 'USD', + chatReportID: report3.reportID, + }; + + report1.iouReportID = iouReport1.reportID; + report2.iouReportID = iouReport2.reportID; + report3.iouReportID = iouReport3.reportID; + + const currentlyLoggedInUserEmail = 'email13@test.com'; + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks('0'); + return waitForPromisesToResolve() + + // When Onyx is updated with the data and the sidebar re-renders + .then(() => Onyx.multiSet({ + [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, + [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, + [ONYXKEYS.SESSION]: {email: currentlyLoggedInUserEmail}, + [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, + [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, + [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, + [`${ONYXKEYS.COLLECTION.REPORT}${iouReport1.reportID}`]: iouReport1, + [`${ONYXKEYS.COLLECTION.REPORT}${iouReport2.reportID}`]: iouReport2, + [`${ONYXKEYS.COLLECTION.REPORT}${iouReport3.reportID}`]: iouReport3, + })) + + // Then the reports are ordered alphabetically since their amounts are the same + .then(() => { + const displayNames = sidebarLinks.queryAllByA11yLabel('Chat user display names'); + expect(displayNames).toHaveLength(3); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + }); + }); + + it('orders nonArchived reports by displayName if created timestamps are the same', () => { + // Given three nonArchived reports created at the same time + const lastActionCreated = DateUtils.getDBTime(); + const report1 = { + ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com']), + lastActionCreated, + }; + const report2 = { + ...LHNTestUtils.getFakeReport(['email3@test.com', 'email4@test.com']), + lastActionCreated, + }; + const report3 = { + ...LHNTestUtils.getFakeReport(['email5@test.com', 'email6@test.com']), + lastActionCreated, + }; + + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks('0'); + return waitForPromisesToResolve() + + // When Onyx is updated with the data and the sidebar re-renders + .then(() => Onyx.multiSet({ + [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, + [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, + [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, + [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, + [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, + })) + + // Then the reports are ordered alphabetically since their lastActionCreated are the same + .then(() => { + const displayNames = sidebarLinks.queryAllByA11yLabel('Chat user display names'); + expect(displayNames).toHaveLength(3); + expect(lodashGet(displayNames, [0, 'props', 'children'])).toBe('Five, Six'); + expect(lodashGet(displayNames, [1, 'props', 'children'])).toBe('One, Two'); + expect(lodashGet(displayNames, [2, 'props', 'children'])).toBe('Three, Four'); + }); + }); }); });