diff --git a/.changeset/mosaic-user-profile-step3-tests.md b/.changeset/mosaic-user-profile-step3-tests.md
new file mode 100644
index 00000000000..a845151cc84
--- /dev/null
+++ b/.changeset/mosaic-user-profile-step3-tests.md
@@ -0,0 +1,2 @@
+---
+---
diff --git a/packages/mosaic/src/features/user-profile/user-profile-connected-accounts-section/__tests__/user-profile-connected-accounts.reconnect.feature.test.tsx b/packages/mosaic/src/features/user-profile/user-profile-connected-accounts-section/__tests__/user-profile-connected-accounts.reconnect.feature.test.tsx
index 053eed1444e..2daba3a4ef1 100644
--- a/packages/mosaic/src/features/user-profile/user-profile-connected-accounts-section/__tests__/user-profile-connected-accounts.reconnect.feature.test.tsx
+++ b/packages/mosaic/src/features/user-profile/user-profile-connected-accounts-section/__tests__/user-profile-connected-accounts.reconnect.feature.test.tsx
@@ -55,9 +55,13 @@ describe('connected accounts', () => {
await waitFor(() => expect(navigate).toHaveBeenCalledWith('https://accounts.example/authorize'));
});
- it('recreates a disconnected account', async () => {
- serveFapi(signedIn([disconnectedGoogle]));
- const { clerk } = await renderWithClerk();
+ it('recreates a disconnected account with the scopes the app requests', async () => {
+ serveFapi(signedIn([{ ...disconnectedGoogle, approved_scopes: '' }]));
+ const { clerk } = await renderWithClerk(
+
+
+ ,
+ );
const navigate = vi.spyOn(clerk, 'navigate').mockImplementation(() => Promise.resolve());
const request = holdRequests('post', '/v1/me/external_accounts');
const user = userEvent.setup();
@@ -68,6 +72,7 @@ describe('connected accounts', () => {
await waitFor(() => expect(request.requests).toHaveLength(1));
const body = new URLSearchParams(await request.requests[0]?.text());
expect(body.get('strategy')).toBe('oauth_google');
+ expect(body.getAll('additional_scope')).toEqual(['calendar']);
request.release();
await waitFor(() => expect(navigate).toHaveBeenCalledWith('https://accounts.example/authorize'));
});
diff --git a/packages/mosaic/src/features/user-profile/user-profile-email-section/__tests__/user-profile-email-section.feature.test.tsx b/packages/mosaic/src/features/user-profile/user-profile-email-section/__tests__/user-profile-email-section.feature.test.tsx
index 5086ae72501..d48a7687ca9 100644
--- a/packages/mosaic/src/features/user-profile/user-profile-email-section/__tests__/user-profile-email-section.feature.test.tsx
+++ b/packages/mosaic/src/features/user-profile/user-profile-email-section/__tests__/user-profile-email-section.feature.test.tsx
@@ -170,6 +170,7 @@ describe('the user profile email section', () => {
});
const { actor, clerk } = await renderSection(signedInWithEmails([PRIMARY, sso], verifiesByLink));
const windowNavigate = vi.spyOn(clerk, '__internal_windowNavigate').mockImplementation(() => {});
+ const prepare = holdRequests('post', '/v1/me/email_addresses/:id/prepare_verification');
await manageEmail(actor, 'alice@acme.co', 'Verify');
const dialog = await screen.findByRole('dialog', { name: 'Verify your email' });
@@ -177,6 +178,11 @@ describe('the user profile email section', () => {
expect(screen.queryByRole('textbox', { name: 'Verification code' })).not.toBeInTheDocument();
await actor.click(within(dialog).getByRole('button', { name: 'Connect' }));
+ await waitFor(() => expect(prepare.requests).toHaveLength(1));
+ const body = new URLSearchParams(await prepare.requests[0]?.text());
+ expect(body.get('strategy')).toBe('enterprise_sso');
+ expect(body.get('redirect_url')).toBe(window.location.href);
+ prepare.release();
await waitFor(() => expect(windowNavigate).toHaveBeenCalledWith(new URL('https://idp.acme.co/sso')));
});
@@ -211,6 +217,26 @@ describe('the user profile email section', () => {
expect(screen.queryByRole('group', { name: 'Email' })).not.toBeInTheDocument();
});
+
+ it('lists addresses but does not let the user remove them when it is immutable', async () => {
+ const secondary = fapiEmailAddress({
+ id: 'idn_secondary',
+ email_address: 'work@example.com',
+ verification: VERIFIED,
+ });
+ const { actor } = await renderSection(
+ signedInWithEmails(
+ [PRIMARY, secondary],
+ fapiEnvironment({ attributes: { email_address: { enabled: true, immutable: true } } }),
+ ),
+ );
+
+ expect(emailsListed()).toEqual(['alice@example.com', 'work@example.com']);
+ expect(screen.queryByRole('button', { name: 'Add email' })).not.toBeInTheDocument();
+ await openMenu(actor, within(emailRow()).getByRole('button', { name: 'Manage work@example.com' }));
+ expect(screen.getByRole('menuitem', { name: 'Set as primary' })).toBeInTheDocument();
+ expect(screen.queryByRole('menuitem', { name: 'Remove email' })).not.toBeInTheDocument();
+ });
});
describe('the email section for a user signed in through an enterprise connection', () => {
diff --git a/packages/mosaic/src/features/user-profile/user-profile-web3-wallets-section/__tests__/user-profile-web3-wallets-section.model.test.ts b/packages/mosaic/src/features/user-profile/user-profile-web3-wallets-section/__tests__/user-profile-web3-wallets-section.model.test.ts
index 60bfde88c35..b35b021cd21 100644
--- a/packages/mosaic/src/features/user-profile/user-profile-web3-wallets-section/__tests__/user-profile-web3-wallets-section.model.test.ts
+++ b/packages/mosaic/src/features/user-profile/user-profile-web3-wallets-section/__tests__/user-profile-web3-wallets-section.model.test.ts
@@ -88,17 +88,18 @@ describe('Web3 wallet projection', () => {
});
});
- it('does not offer Verify when wallet changes are disabled', () => {
+ it.each([
+ ['wallet changes are disabled', 'unverified', ['web3_metamask_signature'], false],
+ ['the wallet is already verified', 'verified', ['web3_metamask_signature'], true],
+ ['the instance turned the provider off', 'unverified', ['web3_coinbase_wallet_signature'], true],
+ ] as const)('does not offer Verify when %s', (_, status, enabledStrategies, allowCreation) => {
const result = projectWeb3Wallets({
- wallets: [{ ...metamask, verification: { ...metamask.verification, status: 'unverified' } }],
+ wallets: [{ ...metamask, verification: { ...metamask.verification, status } }],
primaryId: null,
- enabledStrategies: ['web3_metamask_signature'],
- allowCreation: false,
- });
- expect(result).toMatchObject({
- wallets: [{ id: 'wallet_metamask', canVerify: false }],
- availableProviders: [],
+ enabledStrategies,
+ allowCreation,
});
+ expect(result).toMatchObject({ wallets: [{ id: 'wallet_metamask', canVerify: false }] });
});
it('WEB3-03 shows admin wallets without a provider and filters unknown strategies', () => {