diff --git a/packages/worker/client/routes/account-profile-panel.node.test.ts b/packages/worker/client/routes/account-profile-panel.node.test.ts new file mode 100644 index 0000000000..eea1e9992a --- /dev/null +++ b/packages/worker/client/routes/account-profile-panel.node.test.ts @@ -0,0 +1,59 @@ +import { jsx } from 'remix/ui/jsx-runtime' +import { renderToString } from 'remix/ui/server' +import { expect, test } from 'vitest' +import { renderAccountProfilePanel } from './account-profile-panel.tsx' + +function panelProps( + overrides: Partial[0]> = {}, +) { + return { + email: 'jaimie@example.com', + emailVerified: true, + username: 'jklotz08', + draftUsername: 'jklotz', + draftDisplayName: 'Jaimie', + draftBio: '', + draftProfileVisibility: 'public' as const, + draftEmail: 'jaimie@example.com', + emailChangePassword: '', + avatarUrl: null, + avatarStatus: 'idle' as const, + isSaving: false, + isSendingEmailChange: false, + profileUnchanged: false, + normalizedDraftUsername: 'jklotz', + normalizedDraftEmail: 'jaimie@example.com', + emailChangeMessage: null, + emailChangeTone: 'info' as const, + emailChangeOpen: false, + usernameFieldError: null, + onProfileSubmit: () => undefined, + onEmailChangeSubmit: () => undefined, + onAvatarSelected: () => undefined, + onRemoveAvatar: () => undefined, + onDraftUsernameInput: () => undefined, + onDraftDisplayNameChange: () => undefined, + onDraftBioChange: () => undefined, + onDraftProfileVisibilityChange: () => undefined, + onDraftEmailInput: () => undefined, + onEmailChangePasswordInput: () => undefined, + ...overrides, + } +} + +test('profile panel keeps the typed username and shows a save error without success chrome', async () => { + const html = await renderToString( + jsx('div', { + children: renderAccountProfilePanel( + panelProps({ + usernameFieldError: '`jklotz` is taken.', + }), + ), + }), + ) + + expect(html).toContain('value="jklotz"') + expect(html).toContain('data-testid="account-username-error"') + expect(html).toContain('`jklotz` is taken.') + expect(html).not.toContain('Profile saved.') +}) diff --git a/packages/worker/client/routes/account-profile-panel.tsx b/packages/worker/client/routes/account-profile-panel.tsx index a8a6045b16..3158da8988 100644 --- a/packages/worker/client/routes/account-profile-panel.tsx +++ b/packages/worker/client/routes/account-profile-panel.tsx @@ -43,6 +43,7 @@ export type AccountProfilePanelProps = { emailChangeMessage: string | null emailChangeTone: 'error' | 'info' emailChangeOpen: boolean + usernameFieldError: string | null onProfileSubmit: (event: SubmitEvent) => void onEmailChangeSubmit: (event: SubmitEvent) => void onAvatarSelected: (event: Event) => void @@ -76,6 +77,7 @@ export function renderAccountProfilePanel(props: AccountProfilePanelProps) { emailChangeMessage, emailChangeTone, emailChangeOpen, + usernameFieldError, onProfileSubmit, onEmailChangeSubmit, onAvatarSelected, @@ -154,14 +156,29 @@ export function renderAccountProfilePanel(props: AccountProfilePanelProps) { + {usernameFieldError ? ( + + ) : null}