From 2bf0c17b05510a0d51a76cfb0dd137b16b18abb4 Mon Sep 17 00:00:00 2001 From: Isaac Sanchez-Hawkins <266845420+isanchez404@users.noreply.github.com> Date: Tue, 19 May 2026 10:42:14 -0400 Subject: [PATCH] fix(ui): associate save plan title label (#1331) * fix(ui): associate save plan title label * test(ui): make save plan label test locale-independent --------- Co-authored-by: Isaac Sanchez --- .../session/SaveProjectPlanDialog.test.tsx | 42 +++++++++++++++++++ .../session/SaveProjectPlanDialog.tsx | 4 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 packages/ui/src/components/session/SaveProjectPlanDialog.test.tsx diff --git a/packages/ui/src/components/session/SaveProjectPlanDialog.test.tsx b/packages/ui/src/components/session/SaveProjectPlanDialog.test.tsx new file mode 100644 index 00000000..8a833171 --- /dev/null +++ b/packages/ui/src/components/session/SaveProjectPlanDialog.test.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { describe, expect, mock, test } from 'bun:test'; +import { renderToStaticMarkup } from 'react-dom/server'; + +import { I18nProvider } from '@/lib/i18n'; + +type MockDialogProps = React.PropsWithChildren<{ open?: boolean; className?: string }>; + +mock.module('@/components/ui/dialog', () => ({ + Dialog: ({ children, open = true }: MockDialogProps) => (open ? <>{children} : null), + DialogContent: ({ children }: MockDialogProps) =>
{children}
, + DialogDescription: ({ children }: MockDialogProps) =>

{children}

, + DialogFooter: ({ children }: MockDialogProps) =>
{children}
, + DialogHeader: ({ children }: MockDialogProps) =>
{children}
, + DialogTitle: ({ children }: MockDialogProps) =>

{children}

, +})); + +const { SaveProjectPlanDialog } = await import('./SaveProjectPlanDialog'); + +describe('SaveProjectPlanDialog', () => { + test('associates the title label with the title input', () => { + const markup = renderToStaticMarkup( + + {}} + initialTitle="Implementation plan" + sourceText="Plan content" + onSave={() => {}} + /> + , + ); + + const labelMatch = markup.match(/]*for="([^"]+)"[^>]*>/); + if (!labelMatch) { + throw new Error('Expected a label associated with the title input'); + } + + const [, titleInputId] = labelMatch; + expect(markup).toContain(`id="${titleInputId}"`); + }); +}); diff --git a/packages/ui/src/components/session/SaveProjectPlanDialog.tsx b/packages/ui/src/components/session/SaveProjectPlanDialog.tsx index 21df8bb2..a77b3670 100644 --- a/packages/ui/src/components/session/SaveProjectPlanDialog.tsx +++ b/packages/ui/src/components/session/SaveProjectPlanDialog.tsx @@ -23,6 +23,7 @@ type SaveProjectPlanDialogProps = { export function SaveProjectPlanDialog(props: SaveProjectPlanDialogProps) { const { t } = useI18n(); const { open, onOpenChange, initialTitle, sourceText, saving = false, onSave } = props; + const titleInputId = React.useId(); const [title, setTitle] = React.useState(initialTitle); React.useEffect(() => { @@ -43,8 +44,9 @@ export function SaveProjectPlanDialog(props: SaveProjectPlanDialogProps) {
- + setTitle(event.target.value)} placeholder={t('saveProjectPlanDialog.field.titlePlaceholder')}