Skip to content

Commit 4f0c168

Browse files
authored
Merge pull request #19987 from mozilla/FXA-13002
fix(webchannel): Send 'can_link_account' on email-first for isSync/isFirefoxNonSync when fxa_status resolves
2 parents 36c3b30 + 6969b67 commit 4f0c168

4 files changed

Lines changed: 84 additions & 7 deletions

File tree

packages/fxa-settings/src/lib/hooks/useFxAStatus/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function useFxAStatus(integration: FxAStatusIntegration) {
4141
const [supportsKeysOptionalLogin, setSupportsKeysOptionalLogin] =
4242
useState<boolean>(false);
4343
const [supportsCanLinkAccountUid, setSupportsCanLinkAccountUid] =
44-
useState<boolean>(false);
44+
useState<boolean | undefined>(undefined);
4545

4646
useEffect(() => {
4747
// This sends a web channel message to the browser to prompt a response

packages/fxa-settings/src/lib/hooks/useFxAStatus/mocks.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { getSyncEngineIds, syncEngineConfigs } from '../../sync-engines';
77
export function mockUseFxAStatus({
88
offeredSyncEnginesOverride,
99
supportsKeysOptionalLogin = false,
10-
supportsCanLinkAccountUid = false,
10+
supportsCanLinkAccountUid,
1111
}: {
1212
offeredSyncEnginesOverride?: ReturnType<typeof getSyncEngineIds>;
1313
supportsKeysOptionalLogin?: boolean;
14-
supportsCanLinkAccountUid?: boolean;
14+
supportsCanLinkAccountUid?: boolean | undefined;
1515
} = {}) {
1616
const offeredSyncEngineConfigs = syncEngineConfigs;
1717
const offeredSyncEngines =

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

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as IndexModule from './index';
77
import * as ReactUtils from 'fxa-react/lib/utils';
88
import * as cache from '../../lib/cache';
99

10-
import React from 'react';
1110
import { waitFor } from '@testing-library/react';
1211
import { LocationProvider } from '@reach/router';
1312
import { useValidatedQueryParams } from '../../lib/hooks/useValidate';
@@ -971,6 +970,75 @@ describe('IndexContainer', () => {
971970
expect(currentIndexProps?.errorBannerMessage).toBeDefined();
972971
});
973972
});
973+
974+
describe('useFxAStatusResult.supportsCanLinkAccountUid and processEmailSubmission', () => {
975+
beforeEach(() => {
976+
jest.spyOn(cache, 'currentAccount').mockReturnValue({
977+
uid: 'abc123',
978+
email: MOCK_EMAIL,
979+
lastLogin: Date.now(),
980+
});
981+
});
982+
983+
it('shows loading spinner and does not call fxaCanLinkAccount when supportsCanLinkAccountUid is undefined', async () => {
984+
mockUseFxAStatusResult = mockUseFxAStatus({
985+
supportsCanLinkAccountUid: undefined,
986+
});
987+
988+
const { getByText } = renderWithLocalizationProvider(
989+
<LocationProvider>
990+
<IndexContainer
991+
integration={integration}
992+
serviceName={MozServices.FirefoxSync}
993+
useFxAStatusResult={mockUseFxAStatusResult}
994+
/>
995+
</LocationProvider>
996+
);
997+
998+
expect(getByText('LoadingSpinner')).toBeInTheDocument();
999+
expect(firefox.fxaCanLinkAccount).not.toHaveBeenCalled();
1000+
});
1001+
1002+
it('does not call fxaCanLinkAccount when supportsCanLinkAccountUid is true', async () => {
1003+
mockUseFxAStatusResult = mockUseFxAStatus({
1004+
supportsCanLinkAccountUid: true,
1005+
});
1006+
1007+
renderWithLocalizationProvider(
1008+
<LocationProvider>
1009+
<IndexContainer
1010+
integration={integration}
1011+
serviceName={MozServices.FirefoxSync}
1012+
useFxAStatusResult={mockUseFxAStatusResult}
1013+
/>
1014+
</LocationProvider>
1015+
);
1016+
1017+
await waitFor(() => {
1018+
expect(firefox.fxaCanLinkAccount).not.toHaveBeenCalled();
1019+
});
1020+
});
1021+
1022+
it('calls fxaCanLinkAccount when supportsCanLinkAccountUid is false', async () => {
1023+
mockUseFxAStatusResult = mockUseFxAStatus({
1024+
supportsCanLinkAccountUid: false,
1025+
});
1026+
1027+
renderWithLocalizationProvider(
1028+
<LocationProvider>
1029+
<IndexContainer
1030+
integration={integration}
1031+
serviceName={MozServices.FirefoxSync}
1032+
useFxAStatusResult={mockUseFxAStatusResult}
1033+
/>
1034+
</LocationProvider>
1035+
);
1036+
1037+
await waitFor(() => {
1038+
expect(firefox.fxaCanLinkAccount).toHaveBeenCalled();
1039+
});
1040+
});
1041+
});
9741042
});
9751043
});
9761044
});

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,20 @@ const IndexContainer = ({
271271
if (isUnsupportedContext(integration.data.context)) {
272272
hardNavigate('/update_firefox', {}, true);
273273
} else if (shouldTrySuggestedEmail && !attemptedEmailAutoSubmit.current) {
274-
// Without this, can_link_account can fire multiple times due to calling it in a `useEffect`,
275-
// causing multiple sync warnings to be displayed. This ensures it is called once.
276-
attemptedEmailAutoSubmit.current = true;
277274
// Must be in an async function or else `setIsLoading(false)` can be called prematurely with
278275
// the next render, before async actions in `processEmailSubmission` have finished
279276
(async () => {
277+
if (integration.isSync() || integration.isFirefoxNonSync()) {
278+
// Wait for this to resolve before calling 'processEmailSubmission'.
279+
// Otherwise, a merge warning may show on email-first for newer Fx versions
280+
// that support "can link account" by UID.
281+
if (useFxAStatusResult.supportsCanLinkAccountUid === undefined) {
282+
return;
283+
}
284+
}
285+
// Without this, can_link_account can fire multiple times due to calling it in a `useEffect`,
286+
// causing multiple sync warnings to be displayed. This ensures it is called once.
287+
attemptedEmailAutoSubmit.current = true;
280288
await processEmailSubmission(suggestedEmail, false);
281289
})();
282290
} else {
@@ -290,6 +298,7 @@ const IndexContainer = ({
290298
shouldTrySuggestedEmail,
291299
integration.data.context,
292300
integration,
301+
useFxAStatusResult.supportsCanLinkAccountUid,
293302
]);
294303

295304
useEffect(() => {

0 commit comments

Comments
 (0)