Skip to content

Commit 2df3e19

Browse files
luacmartinsOSBotify
authored andcommitted
Merge pull request #54269 from Expensify/revert-54244-revert-53735-53360-replace-blur-listeners-with-useFocusEffect
Revert "Revert "Replace navigation blur listeners with `useFocusEffect`"" (cherry picked from commit 78105ec) (CP triggered by luacmartins)
1 parent f257e34 commit 2df3e19

File tree

6 files changed

+109
-30
lines changed

6 files changed

+109
-30
lines changed

src/components/Button/index.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ type ButtonProps = Partial<ChildrenProps> & {
122122
/** Id to use for this button */
123123
id?: string;
124124

125+
/** Used to locate this button in ui tests */
126+
testID?: string;
127+
125128
/** Accessibility label for the component */
126129
accessibilityLabel?: string;
127130

@@ -237,6 +240,7 @@ function Button(
237240
shouldShowRightIcon = false,
238241

239242
id = '',
243+
testID = undefined,
240244
accessibilityLabel = '',
241245
isSplitButton = false,
242246
link = false,
@@ -405,6 +409,7 @@ function Button(
405409
]}
406410
disabledStyle={disabledStyle}
407411
id={id}
412+
testID={testID}
408413
accessibilityLabel={accessibilityLabel}
409414
role={CONST.ROLE.BUTTON}
410415
hoverDimmingValue={1}

src/components/ConfirmationPage.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function ConfirmationPage({
8282
success
8383
large
8484
text={buttonText}
85+
testID="confirmation-button"
8586
style={styles.mt6}
8687
pressOnEnter
8788
onPress={onButtonPress}

src/hooks/useWaitForNavigation.ts

+12-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {useNavigation} from '@react-navigation/native';
2-
import {useEffect, useRef} from 'react';
1+
import {useFocusEffect} from '@react-navigation/native';
2+
import {useCallback, useRef} from 'react';
33

44
type UseWaitForNavigation = (navigate: () => void) => () => Promise<void>;
55

@@ -8,21 +8,18 @@ type UseWaitForNavigation = (navigate: () => void) => () => Promise<void>;
88
* Only use when navigating by react-navigation
99
*/
1010
export default function useWaitForNavigation(): UseWaitForNavigation {
11-
const navigation = useNavigation();
1211
const resolvePromises = useRef<Array<() => void>>([]);
1312

14-
useEffect(() => {
15-
const unsubscribeBlur = navigation.addListener('blur', () => {
16-
resolvePromises.current.forEach((resolve) => {
17-
resolve();
18-
});
19-
resolvePromises.current = [];
20-
});
21-
22-
return () => {
23-
unsubscribeBlur();
24-
};
25-
}, [navigation]);
13+
useFocusEffect(
14+
useCallback(() => {
15+
return () => {
16+
resolvePromises.current.forEach((resolve) => {
17+
resolve();
18+
});
19+
resolvePromises.current = [];
20+
};
21+
}, []),
22+
);
2623

2724
return (navigate: () => void) => () => {
2825
navigate();

src/pages/workspace/upgrade/UpgradeIntro.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizi
7575
<Button
7676
isLoading={loading}
7777
text={translate('common.upgrade')}
78+
testID="upgrade-button"
7879
success
7980
onPress={onUpgrade}
8081
isDisabled={buttonDisabled}

src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {useNavigation} from '@react-navigation/native';
2-
import React, {useCallback, useEffect} from 'react';
1+
import {useFocusEffect} from '@react-navigation/native';
2+
import React, {useCallback, useMemo} from 'react';
33
import {useOnyx} from 'react-native-onyx';
44
import HeaderWithBackButton from '@components/HeaderWithBackButton';
55
import ScreenWrapper from '@components/ScreenWrapper';
@@ -37,20 +37,19 @@ function getFeatureNameAlias(featureName: string) {
3737
}
3838

3939
function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) {
40-
const navigation = useNavigation();
4140
const styles = useThemeStyles();
4241
const policyID = route.params.policyID;
4342

4443
const featureNameAlias = getFeatureNameAlias(route.params.featureName);
4544

46-
const feature = Object.values(CONST.UPGRADE_FEATURE_INTRO_MAPPING).find((f) => f.alias === featureNameAlias);
45+
const feature = useMemo(() => Object.values(CONST.UPGRADE_FEATURE_INTRO_MAPPING).find((f) => f.alias === featureNameAlias), [featureNameAlias]);
4746
const {translate} = useLocalize();
4847
const [policy] = useOnyx(`policy_${policyID}`);
4948
const qboConfig = policy?.connections?.quickbooksOnline?.config;
5049
const {isOffline} = useNetwork();
5150

5251
const canPerformUpgrade = !!feature && !!policy && PolicyUtils.isPolicyAdmin(policy);
53-
const isUpgraded = React.useMemo(() => PolicyUtils.isControlPolicy(policy), [policy]);
52+
const isUpgraded = useMemo(() => PolicyUtils.isControlPolicy(policy), [policy]);
5453

5554
const perDiemCustomUnit = PolicyUtils.getPerDiemCustomUnit(policy);
5655
const categoryId = route.params?.categoryId;
@@ -155,16 +154,16 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) {
155154
route.params.featureName,
156155
]);
157156

158-
useEffect(() => {
159-
const unsubscribeListener = navigation.addListener('blur', () => {
160-
if (!isUpgraded || !canPerformUpgrade) {
161-
return;
162-
}
163-
confirmUpgrade();
164-
});
165-
166-
return unsubscribeListener;
167-
}, [isUpgraded, canPerformUpgrade, confirmUpgrade, navigation]);
157+
useFocusEffect(
158+
useCallback(() => {
159+
return () => {
160+
if (!isUpgraded || !canPerformUpgrade) {
161+
return;
162+
}
163+
confirmUpgrade();
164+
};
165+
}, [isUpgraded, canPerformUpgrade, confirmUpgrade]),
166+
);
168167

169168
if (!canPerformUpgrade) {
170169
return <NotFoundPage />;

tests/ui/WorkspaceUpgradeTest.tsx

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* eslint-disable @typescript-eslint/naming-convention */
2+
import {NavigationContainer} from '@react-navigation/native';
3+
import {act, fireEvent, render, screen} from '@testing-library/react-native';
4+
import React from 'react';
5+
import Onyx from 'react-native-onyx';
6+
import {WRITE_COMMANDS} from '@libs/API/types';
7+
import * as SequentialQueue from '@libs/Network/SequentialQueue';
8+
import createResponsiveStackNavigator from '@navigation/AppNavigator/createResponsiveStackNavigator';
9+
import type {SettingsNavigatorParamList} from '@navigation/types';
10+
import WorkspaceUpgradePage from '@pages/workspace/upgrade/WorkspaceUpgradePage';
11+
import ONYXKEYS from '@src/ONYXKEYS';
12+
import SCREENS from '@src/SCREENS';
13+
import type {Policy} from '@src/types/onyx';
14+
import * as LHNTestUtils from '../utils/LHNTestUtils';
15+
import * as TestHelper from '../utils/TestHelper';
16+
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
17+
import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct';
18+
19+
TestHelper.setupGlobalFetchMock();
20+
21+
const RootStack = createResponsiveStackNavigator<SettingsNavigatorParamList>();
22+
23+
const renderPage = (initialRouteName: typeof SCREENS.WORKSPACE.UPGRADE, initialParams: SettingsNavigatorParamList[typeof SCREENS.WORKSPACE.UPGRADE]) => {
24+
return render(
25+
<NavigationContainer>
26+
<RootStack.Navigator initialRouteName={initialRouteName}>
27+
<RootStack.Screen
28+
name={SCREENS.WORKSPACE.UPGRADE}
29+
component={WorkspaceUpgradePage}
30+
initialParams={initialParams}
31+
/>
32+
</RootStack.Navigator>
33+
</NavigationContainer>,
34+
);
35+
};
36+
37+
describe('WorkspaceUpgrade', () => {
38+
beforeAll(() => {
39+
Onyx.init({
40+
keys: ONYXKEYS,
41+
});
42+
});
43+
44+
afterEach(async () => {
45+
await SequentialQueue.waitForIdle();
46+
await act(async () => {
47+
await Onyx.clear();
48+
});
49+
50+
jest.clearAllMocks();
51+
});
52+
53+
it('should enable policy rules', async () => {
54+
const policy: Policy = LHNTestUtils.getFakePolicy();
55+
56+
// Given that a policy is initialized in Onyx
57+
await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy);
58+
59+
// And WorkspaceUpgradePage for rules is opened
60+
const {unmount} = renderPage(SCREENS.WORKSPACE.UPGRADE, {policyID: policy.id, featureName: 'rules'});
61+
62+
// When the policy is upgraded by clicking on the Upgrade button
63+
fireEvent.press(screen.getByTestId('upgrade-button'));
64+
await waitForBatchedUpdatesWithAct();
65+
66+
// Then "Upgrade to Corporate" API request should be made
67+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.UPGRADE_TO_CORPORATE, 1);
68+
69+
// When WorkspaceUpgradePage is unmounted
70+
unmount();
71+
await waitForBatchedUpdates();
72+
73+
// Then "Set policy rules enabled" API request should be made
74+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.SET_POLICY_RULES_ENABLED, 1);
75+
});
76+
});

0 commit comments

Comments
 (0)