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
141 lines
3.8 KiB
TypeScript
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()
|
|
})
|
|
})
|