diff --git a/frontend/src/components/modals/NodeModal.tsx b/frontend/src/components/modals/NodeModal.tsx index 31626b5..69b83c0 100644 --- a/frontend/src/components/modals/NodeModal.tsx +++ b/frontend/src/components/modals/NodeModal.tsx @@ -404,7 +404,12 @@ export function NodeModal({ open, onClose, onSubmit, initial, title = 'Add Node' variant="ghost" size="sm" className="text-[#f85149] hover:text-[#f85149] hover:bg-[#f85149]/10 cursor-pointer" - onClick={() => { if (window.confirm('Delete this node?')) onSubmit({ ...form, _delete: true }); onClose(); }} + onClick={() => { + if (window.confirm('Delete this node?')) { + onSubmit({ ...form, _delete: true }) + onClose() + } + }} style={{ minWidth: 64 }} > Delete diff --git a/frontend/src/components/modals/__tests__/NodeModal.test.tsx b/frontend/src/components/modals/__tests__/NodeModal.test.tsx index 828a8e8..c561495 100644 --- a/frontend/src/components/modals/__tests__/NodeModal.test.tsx +++ b/frontend/src/components/modals/__tests__/NodeModal.test.tsx @@ -83,6 +83,28 @@ describe('NodeModal', () => { expect(onClose).toHaveBeenCalledOnce() }) + // ── Delete confirm ──────────────────────────────────────────────────── + + it('deletes and closes when Delete confirm is accepted', () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true) + const { onClose, onSubmit } = renderModal({ title: 'Edit Node', initial: BASE }) + fireEvent.click(screen.getByRole('button', { name: 'Delete' })) + expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ _delete: true })) + expect(onClose).toHaveBeenCalledOnce() + confirmSpy.mockRestore() + }) + + // Regression: bare-if without braces used to call onClose() unconditionally, + // closing the modal even when the user cancelled the confirm dialog. + it('does not delete or close when Delete confirm is cancelled', () => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false) + const { onClose, onSubmit } = renderModal({ title: 'Edit Node', initial: BASE }) + fireEvent.click(screen.getByRole('button', { name: 'Delete' })) + expect(onSubmit).not.toHaveBeenCalled() + expect(onClose).not.toHaveBeenCalled() + confirmSpy.mockRestore() + }) + // ── Label validation ────────────────────────────────────────────────── it('blocks submit and shows error when label is empty', () => {