diff --git a/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.js b/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.js index 1334e92f27..746a1ed7d5 100644 --- a/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.js +++ b/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.js @@ -338,7 +338,7 @@ export const StructuredContentCommands = Extension.create({ const structuredContentTags = getStructuredContentTagsById(id, state); if (!structuredContentTags.length) { - return true; + return false; } const { schema } = editor; diff --git a/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.test.js b/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.test.js index ea0caf5275..240e40d9cd 100644 --- a/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.test.js +++ b/packages/super-editor/src/editors/v1/extensions/structured-content/structured-content-commands.test.js @@ -185,6 +185,17 @@ describe('updateStructuredContentById', () => { }).toThrow('Invalid structured content id - must be an integer, got: abc-123'); }); + it('returns false when no structured content matches the requested ID', () => { + const originalDoc = editor.state.doc.toJSON(); + + const didUpdate = editor.commands.updateStructuredContentById('missing-structured-content-id', { + text: 'New Content', + }); + + expect(didUpdate).toBe(false); + expect(editor.state.doc.toJSON()).toEqual(originalDoc); + }); + describe('keepTextNodeStyles option', () => { it('preserves marks from the first text node when keepTextNodeStyles is true', () => { const didUpdate = editor.commands.updateStructuredContentById(INLINE_ID, { diff --git a/packages/template-builder/src/tests/updateField.test.tsx b/packages/template-builder/src/tests/updateField.test.tsx new file mode 100644 index 0000000000..dfed660d27 --- /dev/null +++ b/packages/template-builder/src/tests/updateField.test.tsx @@ -0,0 +1,93 @@ +import { createRef } from 'react'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { act, cleanup, render, waitFor } from '@testing-library/react'; +import SuperDocTemplateBuilder from '../index'; +import type { SuperDocTemplateBuilderHandle } from '../types'; + +const updateStructuredContentByIdMock = vi.fn(() => false); + +vi.mock('superdoc', () => { + class MockSuperDoc { + activeEditor: any; + superdocStore: any; + + constructor(options: { onReady?: () => void }) { + this.activeEditor = { + state: {}, + view: { + coordsAtPos: () => ({ left: 0, top: 0, bottom: 0 }), + }, + commands: { + updateStructuredContentById: updateStructuredContentByIdMock, + }, + helpers: { + structuredContentCommands: { + getStructuredContentTags: () => [], + }, + }, + on: vi.fn(), + }; + + this.superdocStore = { + documents: [{ getPresentationEditor: () => ({ coordsAtPos: () => ({ left: 0, top: 0, bottom: 0 }) }) }], + }; + + queueMicrotask(() => options.onReady?.()); + } + + destroy() {} + + setDocumentMode() {} + } + + return { SuperDoc: MockSuperDoc }; +}); + +const renderBuilder = async (props = {}) => { + const ref = createRef(); + const onReady = vi.fn(); + + render( + , + ); + + await waitFor(() => expect(onReady).toHaveBeenCalledTimes(1)); + await waitFor(() => expect(ref.current).not.toBeNull()); + + return ref; +}; + +describe('SuperDocTemplateBuilder updateField', () => { + beforeEach(() => { + updateStructuredContentByIdMock.mockReset(); + updateStructuredContentByIdMock.mockReturnValue(false); + }); + + afterEach(() => { + cleanup(); + }); + + it('returns false when the editor command does not update a field', async () => { + const onFieldUpdate = vi.fn(); + const onFieldsChange = vi.fn(); + const ref = await renderBuilder({ onFieldUpdate, onFieldsChange }); + let result = true; + + await act(async () => { + result = ref.current!.updateField('missing-field-id', { alias: 'New Name' }); + }); + + expect(result).toBe(false); + expect(updateStructuredContentByIdMock).toHaveBeenCalledWith('missing-field-id', { + attrs: { alias: 'New Name' }, + }); + expect(onFieldUpdate).not.toHaveBeenCalled(); + expect(onFieldsChange).not.toHaveBeenCalled(); + }); +});