Skip to content

Commit d45628a

Browse files
committed
test: add a test case
1 parent 70cb4db commit d45628a

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { describe, expect, it } from "vitest";
2+
3+
import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
4+
5+
/**
6+
* @vitest-environment jsdom
7+
*/
8+
9+
/**
10+
* Find the SuggestionMenu ProseMirror plugin instance from the editor state.
11+
* We need to do this because the PluginKey is not exported, and creating a new
12+
* PluginKey with the same name gives a different instance.
13+
*/
14+
function findSuggestionPlugin(editor: BlockNoteEditor) {
15+
const state = editor._tiptapEditor.state;
16+
const plugin = state.plugins.find(
17+
(p) => (p as any).key === "SuggestionMenuPlugin$",
18+
);
19+
if (!plugin) {
20+
throw new Error("SuggestionMenuPlugin not found in editor state");
21+
}
22+
return plugin;
23+
}
24+
25+
function getSuggestionPluginState(editor: BlockNoteEditor) {
26+
const plugin = findSuggestionPlugin(editor);
27+
return plugin.getState(editor._tiptapEditor.state);
28+
}
29+
30+
/**
31+
* Simulates typing a trigger character and dispatching the suggestion menu
32+
* meta, mirroring what `handleTextInput` does when the user types "/".
33+
*/
34+
function triggerSuggestionMenu(editor: BlockNoteEditor, char: string) {
35+
const plugin = findSuggestionPlugin(editor);
36+
const view = editor._tiptapEditor.view;
37+
// First insert the trigger character (like handleTextInput does)
38+
view.dispatch(view.state.tr.insertText(char));
39+
// Then dispatch the meta to activate the suggestion menu
40+
view.dispatch(
41+
view.state.tr
42+
.setMeta(plugin, {
43+
triggerCharacter: char,
44+
})
45+
.scrollIntoView(),
46+
);
47+
}
48+
49+
function createEditor() {
50+
const editor = BlockNoteEditor.create();
51+
const div = document.createElement("div");
52+
editor.mount(div);
53+
return editor;
54+
}
55+
56+
describe("SuggestionMenu", () => {
57+
it("should open suggestion menu in a paragraph", () => {
58+
const editor = createEditor();
59+
60+
editor.replaceBlocks(editor.document, [
61+
{
62+
id: "paragraph-0",
63+
type: "paragraph",
64+
content: "Hello world",
65+
},
66+
]);
67+
68+
editor.setTextCursorPosition("paragraph-0", "end");
69+
70+
// Verify we start with no active suggestion menu
71+
expect(getSuggestionPluginState(editor)).toBeUndefined();
72+
73+
// Trigger the suggestion menu
74+
triggerSuggestionMenu(editor, "/");
75+
76+
// Plugin state should now be defined (menu opened)
77+
const pluginState = getSuggestionPluginState(editor);
78+
expect(pluginState).toBeDefined();
79+
expect(pluginState.triggerCharacter).toBe("/");
80+
81+
editor._tiptapEditor.destroy();
82+
});
83+
84+
it("should not open suggestion menu in table content", () => {
85+
const editor = createEditor();
86+
87+
editor.replaceBlocks(editor.document, [
88+
{
89+
id: "table-0",
90+
type: "table",
91+
content: {
92+
type: "tableContent",
93+
rows: [
94+
{
95+
cells: ["Cell 1", "Cell 2", "Cell 3"],
96+
},
97+
{
98+
cells: ["Cell 4", "Cell 5", "Cell 6"],
99+
},
100+
],
101+
},
102+
},
103+
]);
104+
105+
// Place cursor inside a table cell
106+
editor.setTextCursorPosition("table-0", "start");
107+
108+
// Verify the cursor is inside table content (the parent node is
109+
// a tableParagraph which belongs to the "tableContent" group)
110+
const $from = editor._tiptapEditor.state.selection.$from;
111+
expect($from.parent.type.isInGroup("tableContent")).toBe(true);
112+
113+
// Verify we start with no active suggestion menu
114+
expect(getSuggestionPluginState(editor)).toBeUndefined();
115+
116+
// Attempt to trigger the suggestion menu
117+
triggerSuggestionMenu(editor, "/");
118+
119+
// Plugin state should remain undefined because the cursor is inside
120+
// table content, and the fix prevents the menu from activating there
121+
expect(getSuggestionPluginState(editor)).toBeUndefined();
122+
123+
editor._tiptapEditor.destroy();
124+
});
125+
});

0 commit comments

Comments
 (0)