1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight';
import CodeSuggestion from '~/content_editor/extensions/code_suggestion';
import {
createTestEditor,
createDocBuilder,
triggerNodeInputRule,
expectDocumentAfterTransaction,
sleep,
} from '../test_utils';
const SAMPLE_README_CONTENT = `# Sample README
This is a sample README.
## Usage
\`\`\`yaml
foo: bar
\`\`\`
`;
jest.mock('~/content_editor/services/utils', () => ({
memoizedGet: jest.fn().mockResolvedValue(SAMPLE_README_CONTENT),
}));
describe('content_editor/extensions/code_suggestion', () => {
let tiptapEditor;
let doc;
let codeSuggestion;
const codeSuggestionConfig = {
canSuggest: true,
line: { new_line: 5 },
lines: [{ new_line: 5 }],
showPopover: false,
diffFile: {
view_path:
'/gitlab-org/gitlab-test/-/blob/468abc807a2b2572f43e72c743b76cee6db24025/README.md',
},
};
const createEditor = (config = {}) => {
tiptapEditor = createTestEditor({
extensions: [
CodeBlockHighlight,
CodeSuggestion.configure({ config: { ...codeSuggestionConfig, ...config } }),
],
});
({
builders: { doc, codeSuggestion },
} = createDocBuilder({
tiptapEditor,
names: {
codeBlock: { nodeType: CodeBlockHighlight.name },
codeSuggestion: { nodeType: CodeSuggestion.name },
},
}));
};
describe('insertCodeSuggestion command', () => {
it('creates a correct suggestion for a single line selection', async () => {
createEditor({ line: { new_line: 5 }, lines: [] });
await expectDocumentAfterTransaction({
number: 1,
tiptapEditor,
action: () => tiptapEditor.commands.insertCodeSuggestion(),
expectedDoc: doc(codeSuggestion({ langParams: '-0+0' }, '## Usage')),
});
});
it('creates a correct suggestion for a multi-line selection', async () => {
createEditor({
line: { new_line: 9 },
lines: [
{ new_line: 5 },
{ new_line: 6 },
{ new_line: 7 },
{ new_line: 8 },
{ new_line: 9 },
],
});
await expectDocumentAfterTransaction({
number: 1,
tiptapEditor,
action: () => tiptapEditor.commands.insertCodeSuggestion(),
expectedDoc: doc(
codeSuggestion({ langParams: '-4+0' }, '## Usage\n\n```yaml\nfoo: bar\n```'),
),
});
});
it('does not insert a new suggestion if already inside a suggestion', async () => {
const initialDoc = codeSuggestion({ langParams: '-0+0' }, '## Usage');
createEditor({ line: { new_line: 5 }, lines: [] });
tiptapEditor.commands.setContent(doc(initialDoc).toJSON());
jest.spyOn(tiptapEditor, 'isActive').mockReturnValue(true);
tiptapEditor.commands.insertCodeSuggestion();
// wait some time to be sure no other transaction happened
await sleep();
expect(tiptapEditor.getJSON()).toEqual(doc(initialDoc).toJSON());
});
});
describe('when typing ```suggestion input rule', () => {
beforeEach(() => {
createEditor();
triggerNodeInputRule({
tiptapEditor,
inputRuleText: '```suggestion ',
});
});
it('creates a new code suggestion block with lines -0+0', () => {
const expectedDoc = doc(codeSuggestion({ language: 'suggestion', langParams: '-0+0' }));
expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON());
});
});
});
|