Files
upstream-tiptap/packages/ai-toolkit/tests/integration/serverAiToolkit.test.ts
upstream-mirror 083a46e93b
Some checks failed
Verify / Install node dependencies (push) Failing after 2s
Verify / Build packages (push) Has been skipped
Verify / Check linting & formatting (push) Has been skipped
Verify / Run unit tests (push) Has been skipped
Verify / Run e2e tests (shard 1/4) (push) Has been skipped
Verify / Run e2e tests (shard 2/4) (push) Has been skipped
Verify / Run e2e tests (shard 3/4) (push) Has been skipped
Verify / Run e2e tests (shard 4/4) (push) Has been skipped
Publish / Resolve publish config (push) Failing after 2s
Publish / Send notification to Slack (push) Has been skipped
Publish / Send failure notification to Slack (push) Failing after 8s
Verify / Merge e2e reports (push) Has been skipped
Publish / Build (push) Has been skipped
Publish / Bump Versions OR Release to Registry (push) Has been skipped
snapshot of https://github.com/ueberdosis/tiptap.git (main, 2026-09-15; blobs > 131072B omitted)
2026-09-15 21:11:02 +05:00

141 lines
3.8 KiB
TypeScript

// @vitest-environment happy-dom
import { Editor, Extension } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import { describe, expect, it } from 'vite-plus/test'
import { ServerAiToolkit } from '@tiptap/ai-toolkit'
/**
* Options for creating a test editor.
*/
interface CreateEditorOptions {
/**
* Initial document JSON.
*/
content?: Record<string, unknown>
/**
* Additional extensions to include alongside the default ones.
*/
extensions?: Extension[]
}
/**
* Creates an editor configured with the {@link ServerAiToolkit} extension.
*
* @param options - Editor configuration options.
* @return Promise resolving once the editor create lifecycle has finished.
*/
function createEditor(options: CreateEditorOptions): Promise<Editor> {
return new Promise(resolve => {
const editor = new Editor({
element: document.createElement('div'),
content: options.content,
extensions: [StarterKit, ServerAiToolkit, ...(options.extensions ?? [])],
onCreate: () => {
resolve(editor)
},
})
})
}
/**
* Creates an editor with an explicit extension order.
*
* @param extensions - Extensions to register in the desired order.
* @param content - Initial document JSON.
* @return Promise resolving once the editor create lifecycle has finished.
*/
function createEditorWithExplicitExtensions(
extensions: Extension[],
content?: Record<string, unknown>,
): Promise<Editor> {
return new Promise(resolve => {
const editor = new Editor({
element: document.createElement('div'),
content,
extensions,
onCreate: () => {
resolve(editor)
},
})
})
}
const MockAiToolkit = Extension.create({
name: 'aiToolkit',
})
describe('ServerAiToolkit', () => {
it('registers _hash attributes without generating values on creation', async () => {
const editor = await createEditor({
content: {
type: 'doc',
content: [
{ type: 'paragraph', content: [{ type: 'text', text: 'First' }] },
{ type: 'paragraph', content: [{ type: 'text', text: 'Second' }] },
],
},
})
const paragraphs = editor.getJSON().content ?? []
expect(paragraphs).toHaveLength(2)
// oxlint-disable-next-line no-underscore-dangle
expect(paragraphs[0]?.attrs?._hash ?? null).toBeNull()
// oxlint-disable-next-line no-underscore-dangle
expect(paragraphs[1]?.attrs?._hash ?? null).toBeNull()
editor.destroy()
})
it('preserves provided hashes through a JSON round-trip', async () => {
const firstEditor = await createEditor({
content: {
type: 'doc',
content: [
{
type: 'paragraph',
attrs: { _hash: 'ABC123' },
content: [{ type: 'text', text: 'Hello' }],
},
],
},
})
const firstJson = firstEditor.getJSON()
// oxlint-disable-next-line no-underscore-dangle
const firstHash = firstJson.content?.[0]?.attrs?._hash
firstEditor.destroy()
const secondEditor = await createEditor({
content: firstJson,
})
const secondJson = secondEditor.getJSON()
// oxlint-disable-next-line no-underscore-dangle
const secondHash = secondJson.content?.[0]?.attrs?._hash
expect(secondHash).toBe(firstHash)
secondEditor.destroy()
})
it('does not synthesize hashes when the AI Toolkit extension is present', async () => {
const editor = await createEditorWithExplicitExtensions(
[StarterKit, ServerAiToolkit, MockAiToolkit],
{
type: 'doc',
content: [{ type: 'paragraph', content: [{ type: 'text', text: 'First' }] }],
},
)
// oxlint-disable-next-line no-underscore-dangle
expect(editor.getJSON().content?.[0]?.attrs?._hash ?? null).toBeNull()
editor.destroy()
})
})