Skip to content

Commit d75b13d

Browse files
authored
Merge pull request #18333 from mozilla/fxa-10935
fix(settings): Fix bug with disconnecting an "unknown" service
2 parents aac0447 + 94b4a98 commit d75b13d

2 files changed

Lines changed: 134 additions & 1 deletion

File tree

packages/fxa-settings/src/components/Settings/ConnectedServices/index.test.tsx

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,138 @@ describe('Connected Services', () => {
389389
);
390390
});
391391

392+
it('on disconnect, with empty client name', async () => {
393+
const attachedClients = [
394+
{
395+
clientId: 'a8c528140153d1c6',
396+
refreshTokenId:
397+
'f0b7dae0043cb07cdb0f1ff160367a0b3214a91f037621e892060d9a146f2d8e',
398+
name: undefined,
399+
createdTime: 1571412069000,
400+
lastAccessTime: 1571412069000,
401+
userAgent: '',
402+
os: null,
403+
location: {
404+
city: null,
405+
country: null,
406+
state: null,
407+
stateCode: null,
408+
},
409+
isCurrentSession: false,
410+
createdTimeFormatted: 'a month ago',
411+
lastAccessTimeFormatted: 'a month ago',
412+
approximateLastAccessTime: null,
413+
approximateLastAccessTimeFormatted: null,
414+
},
415+
];
416+
417+
const account = {
418+
attachedClients,
419+
disconnectClient: jest.fn().mockResolvedValue(true),
420+
} as unknown as Account;
421+
422+
renderWithRouter(
423+
<AppContext.Provider value={mockAppContext({ account })}>
424+
<ConnectedServices />
425+
</AppContext.Provider>
426+
);
427+
428+
await clickFirstSignOutButton();
429+
expect(logViewEvent).toHaveBeenCalledWith(
430+
'settings.clients.disconnect',
431+
'submit.no-reason'
432+
);
433+
434+
expect(account.disconnectClient).toBeCalledTimes(1);
435+
});
436+
437+
it('on disconnect, with more than one empty client name', async () => {
438+
const attachedClients = [
439+
{
440+
clientId: 'a8c528140153d1c6',
441+
refreshTokenId:
442+
'f0b7dae0043cb07cdb0f1ff160367a0b3214a91f037621e892060d9a146f2d8e',
443+
name: undefined,
444+
createdTime: 1571412069000,
445+
lastAccessTime: 1571412069000,
446+
userAgent: '',
447+
os: null,
448+
location: {
449+
city: null,
450+
country: null,
451+
state: null,
452+
stateCode: null,
453+
},
454+
isCurrentSession: false,
455+
createdTimeFormatted: 'a month ago',
456+
lastAccessTimeFormatted: 'a month ago',
457+
approximateLastAccessTime: null,
458+
approximateLastAccessTimeFormatted: null,
459+
},
460+
{
461+
clientId: 'a8c528140153d1c7',
462+
refreshTokenId:
463+
'f0b7dae0043cb07cdb0f1ff160367a0b3214a91f037621e892060d9a146f2d8d',
464+
name: undefined,
465+
createdTime: 1571412069000,
466+
lastAccessTime: 1571412069000,
467+
userAgent: '',
468+
os: null,
469+
location: {
470+
city: null,
471+
country: null,
472+
state: null,
473+
stateCode: null,
474+
},
475+
isCurrentSession: false,
476+
createdTimeFormatted: 'a month ago',
477+
lastAccessTimeFormatted: 'a month ago',
478+
approximateLastAccessTime: null,
479+
approximateLastAccessTimeFormatted: null,
480+
},
481+
{
482+
clientId: 'a8c528140153d1c8',
483+
refreshTokenId:
484+
'f0b7dae0043cb07cdb0f1ff160367a0b3214a91f037621e892060d9a146f2d8c',
485+
name: undefined,
486+
createdTime: 1571412069000,
487+
lastAccessTime: 1571412069000,
488+
userAgent: '',
489+
os: null,
490+
location: {
491+
city: null,
492+
country: null,
493+
state: null,
494+
stateCode: null,
495+
},
496+
isCurrentSession: false,
497+
createdTimeFormatted: 'a month ago',
498+
lastAccessTimeFormatted: 'a month ago',
499+
approximateLastAccessTime: null,
500+
approximateLastAccessTimeFormatted: null,
501+
},
502+
];
503+
504+
const account = {
505+
attachedClients,
506+
disconnectClient: jest.fn().mockResolvedValue(true),
507+
} as unknown as Account;
508+
509+
renderWithRouter(
510+
<AppContext.Provider value={mockAppContext({ account })}>
511+
<ConnectedServices />
512+
</AppContext.Provider>
513+
);
514+
515+
await clickFirstSignOutButton();
516+
expect(logViewEvent).toHaveBeenCalledWith(
517+
'settings.clients.disconnect',
518+
'submit.no-reason'
519+
);
520+
521+
expect(account.disconnectClient).toBeCalledTimes(3);
522+
});
523+
392524
describe('redirects to /signin when active session is signed out', () => {
393525
const mockWindowAssign = jest.fn();
394526
Object.defineProperty(window, 'location', {

packages/fxa-settings/src/components/Settings/ConnectedServices/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ export const ConnectedServices = forwardRef<HTMLDivElement>((_, ref) => {
106106
// disconnect all clients/sessions with this name since only unique names
107107
// are displayed to the user. This is batched into one network request
108108
// via BatchHttpLink
109-
const clientsWithMatchingName = groupedByName[client.name || 'unknown'];
109+
const groupByKey = client.name ?? 'undefined';
110+
const clientsWithMatchingName = groupedByName[groupByKey];
110111
const hasMultipleSessions = clientsWithMatchingName.length > 1;
111112
if (hasMultipleSessions) {
112113
await Promise.all(

0 commit comments

Comments
 (0)