Skip to content

Commit 8d6c57a

Browse files
authored
Merge pull request #18863 from mozilla/FXA-11642
fix(email-first): fix flicker of email-first page
2 parents 8b88fe0 + aa366a8 commit 8d6c57a

2 files changed

Lines changed: 52 additions & 9 deletions

File tree

packages/fxa-settings/src/pages/Index/container.test.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,44 @@ describe('IndexContainer', () => {
225225
});
226226
});
227227

228+
it('should display LoadingSpinner at initial load and remove when ready', async () => {
229+
// Mock the initial state and dependencies
230+
mockLocationState = {};
231+
mockUseValidatedQueryParams.mockReturnValue({
232+
queryParamModel: { email: '[email protected]' },
233+
validationError: null,
234+
});
235+
236+
// simulate rejecting from auth client after a delay
237+
const rejectingMock = jest.fn(() => new Promise((_, reject) => {
238+
setTimeout(() => reject('mock delayed error'), 50);
239+
}));
240+
241+
mockUseAuthClient.mockReturnValue({
242+
accountStatusByEmail: rejectingMock,
243+
})
244+
245+
const { getByText, queryByText } = renderWithLocalizationProvider(
246+
<LocationProvider>
247+
<IndexContainer
248+
{...{ integration, serviceName: MozServices.Default }}
249+
/>
250+
</LocationProvider>
251+
);
252+
253+
// Assert that the LoadingSpinner is rendered initially
254+
expect(getByText('LoadingSpinner')).toBeInTheDocument();
255+
256+
// Wait for the mock to be called and
257+
// then check that the LoadingSpinner is removed
258+
await waitFor(() => {
259+
expect(rejectingMock).toHaveBeenCalledTimes(1);
260+
expect(queryByText('LoadingSpinner')).not.toBeInTheDocument();
261+
});
262+
263+
expect(IndexModule.default).toHaveBeenCalled();
264+
});
265+
228266
describe('redirections', () => {
229267
it('should prioritize prefillEmail over email and prevent redirection', async () => {
230268
mockLocationState = { prefillEmail: MOCK_EMAIL };

packages/fxa-settings/src/pages/Index/container.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { getLocalizedEmailValidationErrorMessage } from './errorMessageMapper';
3030
import { IndexContainerProps, LocationState } from './interfaces';
3131
import { useNavigateWithQuery } from '../../lib/hooks/useNavigateWithQuery';
3232
import { hardNavigate } from 'fxa-react/lib/utils';
33+
import LoadingSpinner from 'fxa-react/components/LoadingSpinner';
3334

3435
export const IndexContainer = ({
3536
integration,
@@ -45,7 +46,8 @@ export const IndexContainer = ({
4546
const [errorBannerMessage, setErrorBannerMessage] = useState('');
4647
const [successBannerMessage, setSuccessBannerMessage] = useState('');
4748
const [tooltipErrorMessage, setTooltipErrorMessage] = useState('');
48-
const [hasTriedAutoProcess, setHasTriedAutoProcess] = useState(false);
49+
const [hasFailedAutoEmailProcessing, setHasFailedAutoEmailProcessing] = useState(false);
50+
const [isLoading, setIsLoading] = useState(true);
4951

5052
const { queryParamModel, validationError } = useValidatedQueryParams(
5153
IndexQueryParams,
@@ -187,6 +189,7 @@ export const IndexContainer = ({
187189
// if email verification fails, clear from params to avoid re-use
188190
if (!isManualSubmission) {
189191
clearEmailParams();
192+
setHasFailedAutoEmailProcessing(true);
190193
}
191194
handleEmailSubmissionError(email, error);
192195
}
@@ -210,16 +213,20 @@ export const IndexContainer = ({
210213
const shouldTrySuggestedEmail = suggestedEmail && !prefillEmail;
211214

212215
useEffect(() => {
213-
if (shouldTrySuggestedEmail && !hasTriedAutoProcess) {
214-
setHasTriedAutoProcess(true);
216+
if (isUnsupportedContext(integration.data.context)) {
217+
hardNavigate('/update_firefox', {}, true);
218+
} else if (shouldTrySuggestedEmail && !hasFailedAutoEmailProcessing) {
215219
processEmailSubmission(suggestedEmail, false);
220+
} else {
221+
setIsLoading(false);
216222
}
217223
}, [
218224
ftlMsgResolver,
219-
hasTriedAutoProcess,
225+
hasFailedAutoEmailProcessing,
220226
processEmailSubmission,
221227
suggestedEmail,
222228
shouldTrySuggestedEmail,
229+
integration.data.context,
223230
]);
224231

225232
useEffect(() => {
@@ -244,13 +251,11 @@ export const IndexContainer = ({
244251
}
245252
}, [ftlMsgResolver, deleteAccountSuccess]);
246253

247-
if (isUnsupportedContext(integration.data.context)) {
248-
hardNavigate('/update_firefox', {}, true);
249-
}
250-
251254
const initialPrefill = prefillEmail || suggestedEmail;
252255

253-
return (
256+
return isLoading ? (
257+
<LoadingSpinner fullScreen />
258+
) : (
254259
<Index
255260
{...{
256261
integration,

0 commit comments

Comments
 (0)