diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 70327599ca22..aad3582df481 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -24,9 +24,6 @@ export default { // Stores current date CURRENT_DATE: 'currentDate', - // Currently viewed reportID - CURRENTLY_VIEWED_REPORTID: 'currentlyViewedReportID', - // Credentials to authenticate the user CREDENTIALS: 'credentials', diff --git a/src/components/ReportActionItem/IOUAction.js b/src/components/ReportActionItem/IOUAction.js index 1baa2305b378..83730269a909 100644 --- a/src/components/ReportActionItem/IOUAction.js +++ b/src/components/ReportActionItem/IOUAction.js @@ -14,7 +14,7 @@ const propTypes = { action: PropTypes.shape(reportActionPropTypes).isRequired, /** The associated chatReport */ - chatReportID: PropTypes.number.isRequired, + chatReportID: PropTypes.string.isRequired, /** Is this IOUACTION the most recent? */ isMostRecentIOUReportAction: PropTypes.bool.isRequired, @@ -47,7 +47,7 @@ const IOUAction = (props) => { {((props.isMostRecentIOUReportAction && Boolean(props.action.originalMessage.IOUReportID)) || (props.action.originalMessage.type === 'pay')) && ( { // This is usually needed after login/create account and re-launches return ( } + drawerContent={({navigation, state}) => { + // This state belongs to the drawer so it should always have the ReportScreen as it's initial (and only) route + const reportIDFromRoute = lodashGet(state, ['routes', 0, 'params', 'reportID']); + return ( + + ); + }} screens={[ { name: SCREENS.REPORT, diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index ab88b8a600c8..ae54d59f7aca 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -1,4 +1,5 @@ import _ from 'underscore'; +import lodashGet from 'lodash/get'; import {Keyboard} from 'react-native'; import {DrawerActions, getPathFromState, StackActions} from '@react-navigation/native'; import Onyx from 'react-native-onyx'; @@ -182,6 +183,19 @@ function getActiveRoute() { : ''; } +/** + * @returns {String} + */ +function getReportIDFromRoute() { + if (!navigationRef.current) { + return ''; + } + + const drawerState = lodashGet(navigationRef.current.getState(), ['routes', 0, 'state']); + const reportRoute = lodashGet(drawerState, ['routes', 0]); + return lodashGet(reportRoute, ['params', 'reportID'], ''); +} + /** * Check whether the passed route is currently Active or not. * @@ -230,6 +244,7 @@ export default { setDidTapNotification, isNavigationReady, setIsNavigationReady, + getReportIDFromRoute, isDrawerReady, setIsDrawerReady, isDrawerRoute, diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index 4ae6da7fbf56..cbe712d4282a 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -9,6 +9,7 @@ import * as ReportUtils from './ReportUtils'; import * as Localize from './Localize'; import Permissions from './Permissions'; import * as CollectionUtils from './CollectionUtils'; +import Navigation from './Navigation/Navigation'; /** * OptionsListUtils is used to build a list options passed to the OptionsList component. Several different UI views can @@ -22,12 +23,6 @@ Onyx.connect({ callback: val => currentUserLogin = val && val.email, }); -let currentlyViewedReportID; -Onyx.connect({ - key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID, - callback: val => currentlyViewedReportID = val, -}); - let priorityMode; Onyx.connect({ key: ONYXKEYS.NVP_PRIORITY_MODE, @@ -428,12 +423,11 @@ function isCurrentUser(userDetails) { * * @param {Object} reports * @param {Object} personalDetails - * @param {String} activeReportID * @param {Object} options * @returns {Object} * @private */ -function getOptions(reports, personalDetails, activeReportID, { +function getOptions(reports, personalDetails, { reportActions = {}, betas = [], selectedOptions = [], @@ -457,7 +451,15 @@ function getOptions(reports, personalDetails, activeReportID, { const reportMapForLogins = {}; // Filter out all the reports that shouldn't be displayed - const filteredReports = _.filter(reports, report => ReportUtils.shouldReportBeInOptionList(report, currentlyViewedReportID, isInGSDMode, currentUserLogin, iouReports, betas, policies)); + const filteredReports = _.filter(reports, report => ReportUtils.shouldReportBeInOptionList( + report, + Navigation.getReportIDFromRoute(), + isInGSDMode, + currentUserLogin, + iouReports, + betas, + policies, + )); // Sorting the reports works like this: // - Order everything by the last message timestamp (descending) @@ -639,7 +641,7 @@ function getSearchOptions( searchValue = '', betas, ) { - return getOptions(reports, personalDetails, 0, { + return getOptions(reports, personalDetails, { betas, searchValue: searchValue.trim(), includeRecentReports: true, @@ -706,7 +708,7 @@ function getNewChatOptions( selectedOptions = [], excludeLogins = [], ) { - return getOptions(reports, personalDetails, 0, { + return getOptions(reports, personalDetails, { betas, searchValue: searchValue.trim(), selectedOptions, @@ -733,7 +735,7 @@ function getMemberInviteOptions( searchValue = '', excludeLogins = [], ) { - return getOptions([], personalDetails, 0, { + return getOptions([], personalDetails, { betas, searchValue: searchValue.trim(), excludeDefaultRooms: true, diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 2445df626ac0..3e907289077a 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -890,7 +890,7 @@ function hasOutstandingIOU(report, currentUserLogin, iouReports) { * filter out the majority of reports before filtering out very specific minority of reports. * * @param {Object} report - * @param {String} currentlyViewedReportID + * @param {String} reportIDFromRoute * @param {Boolean} isInGSDMode * @param {String} currentUserLogin * @param {Object} iouReports @@ -898,7 +898,7 @@ function hasOutstandingIOU(report, currentUserLogin, iouReports) { * @param {Object} policies * @returns {boolean} */ -function shouldReportBeInOptionList(report, currentlyViewedReportID, isInGSDMode, currentUserLogin, iouReports, betas, policies) { +function shouldReportBeInOptionList(report, reportIDFromRoute, isInGSDMode, currentUserLogin, iouReports, betas, policies) { // Exclude reports that have no data because there wouldn't be anything to show in the option item. // This can happen if data is currently loading from the server or a report is in various stages of being created. if (!report || !report.reportID || !report.participants || _.isEmpty(report.participants)) { @@ -908,7 +908,7 @@ function shouldReportBeInOptionList(report, currentlyViewedReportID, isInGSDMode // Include the currently viewed report. If we excluded the currently viewed report, then there // would be no way to highlight it in the options list and it would be confusing to users because they lose // a sense of context. - if (report.reportID === currentlyViewedReportID) { + if (report.reportID === reportIDFromRoute) { return true; } diff --git a/src/libs/SidebarUtils.js b/src/libs/SidebarUtils.js index a73755e0fb61..e9365750daf1 100644 --- a/src/libs/SidebarUtils.js +++ b/src/libs/SidebarUtils.js @@ -12,7 +12,7 @@ import * as CollectionUtils from './CollectionUtils'; // keys that are connected to SidebarLinks withOnyx(). If there was a key missing from SidebarLinks and it's data was updated // for that key, then there would be no re-render and the options wouldn't reflect the new data because SidebarUtils.getOrderedReportIDs() wouldn't be triggered. // There are a couple of keys here which are OK to have stale data. iouReports for example, doesn't need to exist in withOnyx() because -// when IOUs change, it also triggers a change on the reports collection. Having redudant subscriptions causes more re-renders which should be avoided. +// when IOUs change, it also triggers a change on the reports collection. Having redundant subscriptions causes more re-renders which should be avoided. // Session also can remain stale because the only way for the current user to change is to sign out and sign in, which would clear out all the Onyx // data anyway and cause SidebarLinks to rerender. @@ -29,12 +29,6 @@ Onyx.connect({ callback: val => personalDetails = val, }); -let currentlyViewedReportID; -Onyx.connect({ - key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID, - callback: val => currentlyViewedReportID = val, -}); - let priorityMode; Onyx.connect({ key: ONYXKEYS.NVP_PRIORITY_MODE, @@ -88,9 +82,10 @@ Onyx.connect({ }); /** + * @param {String} reportIDFromRoute * @returns {String[]} An array of reportIDs sorted in the proper order */ -function getOrderedReportIDs() { +function getOrderedReportIDs(reportIDFromRoute) { let recentReportOptions = []; const pinnedReportOptions = []; const iouDebtReportOptions = []; @@ -100,7 +95,7 @@ function getOrderedReportIDs() { const isInDefaultMode = !isInGSDMode; // Filter out all the reports that shouldn't be displayed - const filteredReports = _.filter(reports, report => ReportUtils.shouldReportBeInOptionList(report, currentlyViewedReportID, isInGSDMode, currentUserLogin, iouReports, betas, policies)); + const filteredReports = _.filter(reports, report => ReportUtils.shouldReportBeInOptionList(report, reportIDFromRoute, isInGSDMode, currentUserLogin, iouReports, betas, policies)); // Get all the display names for our reports in an easy to access property so we don't have to keep // re-running the logic @@ -142,7 +137,7 @@ function getOrderedReportIDs() { // If the active report has a draft, we do not put it in the group of draft reports because we want it to maintain it's current position. Otherwise the report's position // jumps around in the LHN and it's kind of confusing to the user to see the LHN reorder when they start typing a comment on a report. - } else if (report.hasDraft && report.reportID !== currentlyViewedReportID) { + } else if (report.hasDraft && report.reportID !== reportIDFromRoute) { draftReportOptions.push(report); } else { recentReportOptions.push(report); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 901fad841e7d..f5faf05e27d3 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -41,12 +41,6 @@ Onyx.connect({ }, }); -let lastViewedReportID; -Onyx.connect({ - key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID, - callback: val => lastViewedReportID = val ? Number(val) : null, -}); - const allReports = {}; let conciergeChatReportID; const typingWatchTimers = {}; @@ -946,13 +940,6 @@ function handleReportChanged(report) { } } -/** - * @param {String} reportID - */ -function updateCurrentlyViewedReportID(reportID) { - Onyx.merge(ONYXKEYS.CURRENTLY_VIEWED_REPORTID, String(reportID)); -} - Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, callback: handleReportChanged, @@ -1261,7 +1248,7 @@ function addPolicyReport(policy, reportName, visibility) { ); // Onyx.set is used on the optimistic data so that it is present before navigating to the workspace room. With Onyx.merge the workspace room reportID is not present when - // storeCurrentlyViewedReport is called on the ReportScreen, so fetchChatReportsByIDs is called which is unnecessary since the optimistic data will be stored in Onyx. + // fetchReportIfNeeded is called on the ReportScreen, so fetchChatReportsByIDs is called which is unnecessary since the optimistic data will be stored in Onyx. // If there was an error creating the room, then fetchChatReportsByIDs throws an error and the user is navigated away from the report instead of showing the RBR error message. // Therefore, Onyx.set is used instead of Onyx.merge. const optimisticData = [ @@ -1433,7 +1420,7 @@ function viewNewReportAction(reportID, action) { } // If we are currently viewing this report do not show a notification. - if (reportID === lastViewedReportID && Visibility.isVisible()) { + if (reportID === Navigation.getReportIDFromRoute() && Visibility.isVisible()) { Log.info('[LOCAL_NOTIFICATION] No notification because it was a comment for the current report'); return; } @@ -1469,7 +1456,7 @@ Onyx.connect({ initWithStoredValues: false, callback: (actions, key) => { // reportID can be derived from the Onyx key - const reportID = parseInt(key.split('_')[1], 10); + const reportID = key.split('_')[1]; if (!reportID) { return; } @@ -1522,7 +1509,6 @@ export { saveReportComment, broadcastUserIsTyping, togglePinnedState, - updateCurrentlyViewedReportID, editReportComment, saveReportActionDraft, deleteReportComment, diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 7554ce05a040..4e9ccc88478c 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -30,12 +30,6 @@ Onyx.connect({ }, }); -let currentlyViewedReportID = ''; -Onyx.connect({ - key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID, - callback: val => currentlyViewedReportID = val || '', -}); - /** * Changes a password for a given account * @@ -215,7 +209,6 @@ function setSecondaryLoginAndNavigate(login, password) { */ function validateLogin(accountID, validateCode) { const isLoggedIn = !_.isEmpty(sessionAuthToken); - const redirectRoute = isLoggedIn ? ROUTES.getReportRoute(currentlyViewedReportID) : ROUTES.HOME; Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, isLoading: true}); DeprecatedAPI.ValidateEmail({ @@ -237,7 +230,7 @@ function validateLogin(accountID, validateCode) { } }).finally(() => { Onyx.merge(ONYXKEYS.ACCOUNT, {isLoading: false}); - Navigation.navigate(redirectRoute); + Navigation.navigate(ROUTES.HOME); }); } diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index bdf3a608b71f..4cb8dc947ec9 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -115,7 +115,8 @@ class ReportScreen extends React.Component { } componentDidMount() { - this.storeCurrentlyViewedReport(); + this.fetchReportIfNeeded(); + toggleReportActionComposeView(true); this.removeViewportResizeListener = addViewportResizeListener(this.updateViewportOffsetTop); } @@ -123,7 +124,9 @@ class ReportScreen extends React.Component { if (this.props.route.params.reportID === prevProps.route.params.reportID) { return; } - this.storeCurrentlyViewedReport(); + + this.fetchReportIfNeeded(); + toggleReportActionComposeView(true); } componentWillUnmount() { @@ -149,16 +152,9 @@ class ReportScreen extends React.Component { return !getReportID(this.props.route) || isLoadingInitialReportActions || !this.props.report.reportID; } - /** - * Persists the currently viewed report id - */ - storeCurrentlyViewedReport() { + fetchReportIfNeeded() { const reportIDFromPath = getReportID(this.props.route); - // Always reset the state of the composer view when the current reportID changes - toggleReportActionComposeView(true); - Report.updateCurrentlyViewedReportID(reportIDFromPath); - // It possible that we may not have the report object yet in Onyx yet e.g. we navigated to a URL for an accessible report that // is not stored locally yet. If props.report.reportID exists, then the report has been stored locally and nothing more needs to be done. // If it doesn't exist, then we fetch the report from the API. diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index 109985bdc2bf..96558d6facb8 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -15,7 +15,7 @@ import reportPropTypes from '../../reportPropTypes'; const propTypes = { /** The id of the report */ - reportID: PropTypes.number.isRequired, + reportID: PropTypes.string.isRequired, /** The report currently being looked at */ report: reportPropTypes, diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index cfa72719de47..22a95997fab7 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -58,8 +58,8 @@ const propTypes = { avatar: PropTypes.string, }), - /** Currently viewed reportID */ - currentlyViewedReportID: PropTypes.string, + /** Current reportID from the route in react navigation state object */ + reportIDFromRoute: PropTypes.string, /** Whether we are viewing below the responsive breakpoint */ isSmallScreenWidth: PropTypes.bool.isRequired, @@ -77,7 +77,7 @@ const defaultProps = { currentUserPersonalDetails: { avatar: ReportUtils.getDefaultAvatar(), }, - currentlyViewedReportID: '', + reportIDFromRoute: '', priorityMode: CONST.PRIORITY_MODE.DEFAULT, }; @@ -91,7 +91,7 @@ class SidebarLinks extends React.Component { if (_.isEmpty(this.props.personalDetails)) { return null; } - const optionListItems = SidebarUtils.getOrderedReportIDs(); + const optionListItems = SidebarUtils.getOrderedReportIDs(this.props.reportIDFromRoute); return ( option.toString() === this.props.currentlyViewedReportID + option => option.toString() === this.props.reportIDFromRoute ))} onSelectRow={(option) => { Navigation.navigate(ROUTES.getReportRoute(option.reportID)); @@ -177,9 +177,6 @@ export default compose( personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, }, - currentlyViewedReportID: { - key: ONYXKEYS.CURRENTLY_VIEWED_REPORTID, - }, priorityMode: { key: ONYXKEYS.NVP_PRIORITY_MODE, }, diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index ff3b97c3f778..e2b92deb3c60 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -28,6 +28,9 @@ const propTypes = { /* Callback function before the menu is hidden */ onHideCreateMenu: PropTypes.func, + /** reportID in the current navigation state */ + reportIDFromRoute: PropTypes.string, + ...sidebarPropTypes, }; const defaultProps = { @@ -112,6 +115,7 @@ class BaseSidebarScreen extends Component { onAvatarClick={this.navigateToSettings} isSmallScreenWidth={this.props.isSmallScreenWidth} isDrawerOpen={this.props.isDrawerOpen} + reportIDFromRoute={this.props.reportIDFromRoute} /> { let baseSidebarScreen = null; @@ -40,7 +39,6 @@ SidebarScreen.defaultProps = sidebarDefaultProps; SidebarScreen.displayName = 'SidebarScreen'; export default compose( - withNavigation, withLocalize, withWindowDimensions, withOnyx({ diff --git a/src/pages/home/sidebar/SidebarScreen/index.native.js b/src/pages/home/sidebar/SidebarScreen/index.native.js index 2c865c83900d..e2cb2838efe8 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.native.js +++ b/src/pages/home/sidebar/SidebarScreen/index.native.js @@ -6,7 +6,6 @@ import withLocalize from '../../../../components/withLocalize'; import ONYXKEYS from '../../../../ONYXKEYS'; import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; import BaseSidebarScreen from './BaseSidebarScreen'; -import withNavigation from '../../../../components/withNavigation'; // eslint-disable-next-line react/jsx-props-no-spreading const SidebarScreen = props => ; @@ -16,7 +15,6 @@ SidebarScreen.defaultProps = sidebarDefaultProps; SidebarScreen.displayName = 'SidebarScreen'; export default compose( - withNavigation, withLocalize, withWindowDimensions, withOnyx({ diff --git a/src/setup/index.js b/src/setup/index.js index 61d55dba207d..b0d2d7687cc8 100644 --- a/src/setup/index.js +++ b/src/setup/index.js @@ -22,7 +22,6 @@ export default function () { Onyx.init({ keys: ONYXKEYS, safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - keysToDisableSyncEvents: [ONYXKEYS.CURRENTLY_VIEWED_REPORTID], captureMetrics: Metrics.canCaptureOnyxMetrics(), initialKeyStates: { diff --git a/tests/ui/UnreadIndicatorsTest.js b/tests/ui/UnreadIndicatorsTest.js index 9531266efe2b..7f160add48a4 100644 --- a/tests/ui/UnreadIndicatorsTest.js +++ b/tests/ui/UnreadIndicatorsTest.js @@ -26,7 +26,8 @@ beforeAll(() => { // simulate data arriving we will just set it into Onyx directly with Onyx.merge() or Onyx.set() etc. global.fetch = TestHelper.getGlobalFetchMock(); - jest.setTimeout(15000); + // We need a large timeout here as we are lazy loading React Navigation screens and this test is running against the entire mounted App + jest.setTimeout(30000); Linking.setInitialURL('https://new.expensify.com/r/1'); appSetup(); }); diff --git a/tests/unit/LHNFilterTest.js b/tests/unit/LHNFilterTest.js index cd9e4d90add2..0cf7fa020f41 100644 --- a/tests/unit/LHNFilterTest.js +++ b/tests/unit/LHNFilterTest.js @@ -10,7 +10,6 @@ jest.mock('../../src/libs/Permissions'); const ONYXKEYS = { PERSONAL_DETAILS: 'personalDetails', - CURRENTLY_VIEWED_REPORTID: 'currentlyViewedReportID', NVP_PRIORITY_MODE: 'nvp_priorityMode', SESSION: 'session', BETAS: 'betas', @@ -306,7 +305,7 @@ describe('Sidebar', () => { ...LHNTestUtils.getAdvancedFakeReport(...boolArr), policyID: policy.policyID, }; - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(report1.reportID); return waitForPromisesToResolve() @@ -314,7 +313,6 @@ describe('Sidebar', () => { .then(() => Onyx.multiSet({ [ONYXKEYS.BETAS]: betas, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: report1.reportID.toString(), [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.POLICY}${policy.policyID}`]: policy, @@ -340,8 +338,6 @@ describe('Sidebar', () => { describe('in #focus mode', () => { it('hides unread chats', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given the sidebar is rendered in #focus mode (hides read chats) // with report 1 and 2 having unread actions const report1 = { @@ -353,6 +349,7 @@ describe('Sidebar', () => { lastReadSequenceNumber: LHNTestUtils.TEST_MAX_SEQUENCE_NUMBER - 1, }; const report3 = LHNTestUtils.getFakeReport(['email5@test.com', 'email6@test.com']); + let sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(report1.reportID); return waitForPromisesToResolve() @@ -360,7 +357,6 @@ describe('Sidebar', () => { .then(() => Onyx.multiSet({ [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: report1.reportID.toString(), [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, @@ -391,7 +387,10 @@ describe('Sidebar', () => { }) // When report 2 becomes the active report - .then(() => Onyx.merge(ONYXKEYS.CURRENTLY_VIEWED_REPORTID, report2.reportID.toString())) + .then(() => { + sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(report2.reportID); + return waitForPromisesToResolve(); + }) // Then report 1 should now disappear .then(() => { diff --git a/tests/unit/LHNOrderTest.js b/tests/unit/LHNOrderTest.js index 7f8c0a974ff6..4a7bcf4f6db6 100644 --- a/tests/unit/LHNOrderTest.js +++ b/tests/unit/LHNOrderTest.js @@ -10,7 +10,6 @@ jest.mock('../../src/libs/Permissions'); const ONYXKEYS = { PERSONAL_DETAILS: 'personalDetails', - CURRENTLY_VIEWED_REPORTID: 'currentlyViewedReportID', NVP_PRIORITY_MODE: 'nvp_priorityMode', SESSION: 'session', BETAS: 'betas', @@ -63,10 +62,9 @@ describe('Sidebar', () => { }); it('contains one report when a report is in Onyx', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given a single report const report = LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com']); + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(report.reportID); return waitForPromisesToResolve() @@ -74,7 +72,6 @@ describe('Sidebar', () => { .then(() => Onyx.multiSet({ [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: report.reportID.toString(), [`${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`]: report, })) @@ -123,8 +120,6 @@ describe('Sidebar', () => { }); it('doesn\'t change the order when adding a draft to the active report', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports in the recently updated order of 3, 2, 1 // And the first report has a draft // And the currently viewed report is the first report @@ -134,15 +129,14 @@ describe('Sidebar', () => { }; const report2 = LHNTestUtils.getFakeReport(['email3@test.com', 'email4@test.com'], 2); const report3 = LHNTestUtils.getFakeReport(['email5@test.com', 'email6@test.com'], 1); - const currentlyViewedReportID = report1.reportID; - + const reportIDFromRoute = report1.reportID; + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(reportIDFromRoute); 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.CURRENTLY_VIEWED_REPORTID]: currentlyViewedReportID.toString(), [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, @@ -196,8 +190,6 @@ describe('Sidebar', () => { }); it('reorders the reports to keep draft reports on top', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports in the recently updated order of 3, 2, 1 // And the second report has a draft // And the currently viewed report is the second report @@ -207,7 +199,8 @@ describe('Sidebar', () => { hasDraft: true, }; const report3 = LHNTestUtils.getFakeReport(['email5@test.com', 'email6@test.com'], 1); - const currentlyViewedReportID = report2.reportID; + const reportIDFromRoute = report2.reportID; + let sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(reportIDFromRoute); return waitForPromisesToResolve() @@ -215,14 +208,18 @@ describe('Sidebar', () => { .then(() => Onyx.multiSet({ [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: currentlyViewedReportID.toString(), [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, })) // When the currently active chat is switched to report 1 (the one on the bottom) - .then(() => Onyx.merge(ONYXKEYS.CURRENTLY_VIEWED_REPORTID, '1')) + .then(() => { + // The changing of a route itself will re-render the component in the App, but since we are not performing this test + // inside the navigator and it has no access to the routes we need to trigger an update to the SidebarLinks manually. + sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks('1'); + return waitForPromisesToResolve(); + }) // Then the order of the reports should be 2 > 3 > 1 // ^--- (2 goes to the front and pushes 3 down) @@ -302,8 +299,6 @@ describe('Sidebar', () => { }); it('sorts chats by pinned > IOU > draft', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports in the recently updated order of 3, 2, 1 // with the current user set to email9@ (someone not participating in any of the chats) // with a report that has a draft, a report that is pinned, and @@ -331,9 +326,10 @@ describe('Sidebar', () => { currency: 'USD', chatReportID: report3.reportID, }; - report3.iouReportID = iouReport.reportID.toString(); - const currentlyViewedReportID = report2.reportID; + report3.iouReportID = iouReport.reportID; + const reportIDFromRoute = report2.reportID; const currentlyLoggedInUserEmail = 'email9@test.com'; + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(reportIDFromRoute); return waitForPromisesToResolve() @@ -341,7 +337,6 @@ describe('Sidebar', () => { .then(() => Onyx.multiSet({ [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: currentlyViewedReportID.toString(), [ONYXKEYS.SESSION]: {email: currentlyLoggedInUserEmail}, [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, @@ -364,8 +359,6 @@ describe('Sidebar', () => { }); it('alphabetizes all the chats that are pinned', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports in the recently updated order of 3, 2, 1 // and they are all pinned const report1 = { @@ -384,14 +377,13 @@ describe('Sidebar', () => { ...LHNTestUtils.getFakeReport(['email7@test.com', 'email8@test.com'], 0), isPinned: true, }; - + 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.CURRENTLY_VIEWED_REPORTID]: '0', [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, @@ -421,8 +413,6 @@ describe('Sidebar', () => { }); it('alphabetizes all the chats that have drafts', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports in the recently updated order of 3, 2, 1 // and they all have drafts const report1 = { @@ -441,14 +431,13 @@ describe('Sidebar', () => { ...LHNTestUtils.getFakeReport(['email7@test.com', 'email8@test.com'], 0), hasDraft: true, }; - + 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.CURRENTLY_VIEWED_REPORTID]: '0', [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, @@ -478,8 +467,6 @@ describe('Sidebar', () => { }); it('puts archived chats last', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three reports, with the first report being archived const report1 = { ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com']), @@ -496,7 +483,7 @@ describe('Sidebar', () => { CONST.BETAS.POLICY_ROOMS, CONST.BETAS.POLICY_EXPENSE_CHAT, ]; - + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks('0'); return waitForPromisesToResolve() // When Onyx is updated with the data and the sidebar re-renders @@ -504,7 +491,6 @@ describe('Sidebar', () => { [ONYXKEYS.BETAS]: betas, [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: '0', [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, @@ -578,8 +564,6 @@ describe('Sidebar', () => { }); it('puts archived chats last', () => { - const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks(); - // Given three unread reports, with the first report being archived const report1 = { ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com'], 3), @@ -603,7 +587,7 @@ describe('Sidebar', () => { CONST.BETAS.POLICY_ROOMS, CONST.BETAS.POLICY_EXPENSE_CHAT, ]; - + const sidebarLinks = LHNTestUtils.getDefaultRenderedSidebarLinks('0'); return waitForPromisesToResolve() // When Onyx is updated with the data and the sidebar re-renders @@ -611,7 +595,6 @@ describe('Sidebar', () => { [ONYXKEYS.BETAS]: betas, [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD, [ONYXKEYS.PERSONAL_DETAILS]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.CURRENTLY_VIEWED_REPORTID]: '0', [`${ONYXKEYS.COLLECTION.REPORT}${report1.reportID}`]: report1, [`${ONYXKEYS.COLLECTION.REPORT}${report2.reportID}`]: report2, [`${ONYXKEYS.COLLECTION.REPORT}${report3.reportID}`]: report3, diff --git a/tests/utils/LHNTestUtils.js b/tests/utils/LHNTestUtils.js index 49ee672f582d..540085fe1bf3 100644 --- a/tests/utils/LHNTestUtils.js +++ b/tests/utils/LHNTestUtils.js @@ -108,7 +108,11 @@ function getAdvancedFakeReport(hasComments, isArchived, isUserCreatedPolicyRoom, }; } -function getDefaultRenderedSidebarLinks() { +/** + * @param {String} [reportIDFromRoute] + * @returns {RenderAPI} + */ +function getDefaultRenderedSidebarLinks(reportIDFromRoute = '') { // An ErrorBoundary needs to be added to the rendering so that any errors that happen while the component // renders are logged to the console. Without an error boundary, Jest only reports the error like "The above error // occurred in your component", except, there is no "above error". It's just swallowed up by Jest somewhere. @@ -148,6 +152,7 @@ function getDefaultRenderedSidebarLinks() { }} onAvatarClick={() => {}} isSmallScreenWidth={false} + reportIDFromRoute={reportIDFromRoute} />