@gitlab/ui 78.9.0 → 78.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ * Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ * Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
  */
5
5
 
6
6
  :root.gl-dark {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ * Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#133a03";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ * Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#ddfab7";
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ // Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
 
5
5
  $gl-text-tertiary: #737278 !default;
6
6
  $gl-text-secondary: #89888d !default;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 04 Apr 2024 20:52:08 GMT
3
+ // Generated on Tue, 09 Apr 2024 14:01:48 GMT
4
4
 
5
5
  $gl-text-tertiary: #89888d !default;
6
6
  $gl-text-secondary: #737278 !default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "78.9.0",
3
+ "version": "78.10.1",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -102,7 +102,7 @@
102
102
  "@gitlab/eslint-plugin": "19.5.0",
103
103
  "@gitlab/fonts": "^1.3.0",
104
104
  "@gitlab/stylelint-config": "6.1.0",
105
- "@gitlab/svgs": "3.94.0",
105
+ "@gitlab/svgs": "3.95.0",
106
106
  "@rollup/plugin-commonjs": "^11.1.0",
107
107
  "@rollup/plugin-node-resolve": "^7.1.3",
108
108
  "@rollup/plugin-replace": "^2.3.2",
@@ -17,7 +17,7 @@ $label-close-button: '.gl-label-close.gl-button';
17
17
  }
18
18
 
19
19
  &:focus-within {
20
- @include gl-focus($color: var(--label-background-color), $important: true);
20
+ @include gl-focus($color: var(--label-background-color, $white), $important: true);
21
21
  }
22
22
 
23
23
  .gl-label-link {
@@ -1,7 +1,11 @@
1
1
  import { nextTick } from 'vue';
2
2
  import { shallowMount } from '@vue/test-utils';
3
3
  import GlDuoUserFeedback from '../../../user_feedback/user_feedback.vue';
4
- import { MOCK_USER_PROMPT_MESSAGE, MOCK_RESPONSE_MESSAGE } from '../../mock_data';
4
+ import {
5
+ MOCK_USER_PROMPT_MESSAGE,
6
+ MOCK_RESPONSE_MESSAGE,
7
+ generateSeparateChunks,
8
+ } from '../../mock_data';
5
9
  import DocumentationSources from '../duo_chat_message_sources/duo_chat_message_sources.vue';
6
10
  import GlDuoChatMessage from './duo_chat_message.vue';
7
11
 
@@ -35,7 +39,7 @@ describe('DuoChatMessage', () => {
35
39
  };
36
40
 
37
41
  beforeEach(() => {
38
- renderMarkdown = jest.fn().mockImplementation((val) => `markdown: ${val}`);
42
+ renderMarkdown = jest.fn().mockImplementation((val) => val);
39
43
  renderGFM = jest.fn();
40
44
  });
41
45
 
@@ -49,18 +53,26 @@ describe('DuoChatMessage', () => {
49
53
  expect(customElements.get('copy-code')).toBeDefined();
50
54
  });
51
55
 
52
- describe('rendering with user message', () => {
56
+ describe('rendering', () => {
53
57
  beforeEach(() => {
54
58
  renderMarkdown.mockImplementation(() => mockMarkdownContent);
55
- createComponent();
56
59
  });
57
60
 
58
- it('converts the message `content` to Markdown', () => {
59
- expect(renderMarkdown).toHaveBeenCalledWith(MOCK_USER_PROMPT_MESSAGE.content);
61
+ it('renders html content of the message by default', () => {
62
+ createComponent();
63
+ expect(renderMarkdown).not.toHaveBeenCalled();
64
+ expect(wrapper.html()).toContain(MOCK_USER_PROMPT_MESSAGE.contentHtml);
60
65
  });
61
66
 
62
- it('renders message content', () => {
63
- expect(wrapper.text()).toBe(mockMarkdownContent);
67
+ it('converts the message `content` to Markdown if there is no contentHtml', () => {
68
+ createComponent({
69
+ message: {
70
+ ...MOCK_USER_PROMPT_MESSAGE,
71
+ contentHtml: undefined,
72
+ },
73
+ });
74
+ expect(renderMarkdown).toHaveBeenCalledWith(MOCK_USER_PROMPT_MESSAGE.content);
75
+ expect(findContent().text()).toBe(mockMarkdownContent);
64
76
  });
65
77
 
66
78
  it('does not render the documentation sources component', () => {
@@ -135,8 +147,6 @@ describe('DuoChatMessage', () => {
135
147
  ...MOCK_USER_PROMPT_MESSAGE,
136
148
  errors,
137
149
  contentHtml: 'fooHtml barHtml',
138
- content: 'foo bar',
139
- chunks: ['a', 'b', 'c'],
140
150
  },
141
151
  });
142
152
 
@@ -155,7 +165,6 @@ describe('DuoChatMessage', () => {
155
165
  errors: [],
156
166
  contentHtml: 'fooHtml barHtml',
157
167
  content: 'foo bar',
158
- chunks: ['a', 'b', 'c'],
159
168
  },
160
169
  });
161
170
 
@@ -169,47 +178,14 @@ describe('DuoChatMessage', () => {
169
178
  message: {
170
179
  ...MOCK_USER_PROMPT_MESSAGE,
171
180
  errors: [],
172
- contentHtml: '',
181
+ contentHtml: undefined,
173
182
  content: 'foo bar',
174
- chunks: ['a', 'b', 'c'],
175
183
  },
176
184
  });
177
185
 
178
186
  await nextTick();
179
187
 
180
- expect(findContent().text()).toContain('markdown: foo bar');
181
- });
182
-
183
- it('outputs chunks if there is no content', async () => {
184
- createComponent({
185
- message: {
186
- ...MOCK_USER_PROMPT_MESSAGE,
187
- errors: [],
188
- contentHtml: '',
189
- content: '',
190
- chunks: ['a', 'b', 'c'],
191
- },
192
- });
193
-
194
- await nextTick();
195
-
196
- expect(findContent().text()).toContain('markdown: abc');
197
- });
198
-
199
- it('outputs chunks until first undefined', async () => {
200
- createComponent({
201
- message: {
202
- ...MOCK_USER_PROMPT_MESSAGE,
203
- errors: [],
204
- contentHtml: '',
205
- content: '',
206
- chunks: ['a', undefined, 'c'],
207
- },
208
- });
209
-
210
- await nextTick();
211
-
212
- expect(findContent().text()).toContain('markdown: a');
188
+ expect(findContent().text()).toContain('foo bar');
213
189
  });
214
190
 
215
191
  it('hydrates the message with GFM when mounting with contentHtml', async () => {
@@ -231,44 +207,33 @@ describe('DuoChatMessage', () => {
231
207
  },
232
208
  });
233
209
 
234
- wrapper.setProps({
210
+ await wrapper.setProps({
235
211
  message: {
236
212
  ...MOCK_USER_PROMPT_MESSAGE,
237
213
  contentHtml: 'foo bar',
238
214
  },
239
215
  });
240
-
241
- await nextTick();
242
216
  expect(renderGFM).toHaveBeenCalled();
243
217
  });
244
- });
245
-
246
- describe('default renderers', () => {
247
- it('outputs errors if they are present', async () => {
248
- const errors = ['error1', 'error2', 'error3'];
249
218
 
219
+ it('sanitizes html produced by errors', async () => {
250
220
  createComponent({
251
221
  options: {
252
222
  provide: null,
253
223
  },
254
224
  message: {
255
225
  ...MOCK_USER_PROMPT_MESSAGE,
256
- errors,
257
- contentHtml: 'fooHtml barHtml',
258
- content: 'foo bar',
259
- chunks: ['a', 'b', 'c'],
226
+ errors: ['[click here](javascript:prompt(1))'],
227
+ contentHtml: undefined,
228
+ content: '',
260
229
  },
261
230
  });
262
231
 
263
232
  await nextTick();
264
-
265
- const contentText = findContent().text();
266
- expect(contentText).toContain(errors[0]);
267
- expect(contentText).toContain(errors[1]);
268
- expect(contentText).toContain(errors[2]);
233
+ expect(findContent().html()).toContain('<p><a>click here</a></p>');
269
234
  });
270
235
 
271
- it('outputs contentHtml if it is present', async () => {
236
+ it('sanitizes html produced by content', async () => {
272
237
  createComponent({
273
238
  options: {
274
239
  provide: null,
@@ -276,20 +241,17 @@ describe('DuoChatMessage', () => {
276
241
  message: {
277
242
  ...MOCK_USER_PROMPT_MESSAGE,
278
243
  errors: [],
279
- contentHtml: 'fooHtml barHtml',
280
- content: 'foo bar',
281
- chunks: ['a', 'b', 'c'],
244
+ contentHtml: undefined,
245
+ content: '[click here](javascript:prompt(1))',
282
246
  },
283
247
  });
284
248
 
285
249
  await nextTick();
286
250
 
287
- expect(findContent().html()).toBe(
288
- '<div class="gl-markdown gl-compact-markdown">fooHtml barHtml</div>'
289
- );
251
+ expect(findContent().html()).toContain('<p><a>click here</a></p>');
290
252
  });
291
253
 
292
- it('outputs markdown content if there is no contentHtml', async () => {
254
+ it('deprecated: sanitizes html produced by chunks', async () => {
293
255
  createComponent({
294
256
  options: {
295
257
  provide: null,
@@ -297,18 +259,18 @@ describe('DuoChatMessage', () => {
297
259
  message: {
298
260
  ...MOCK_USER_PROMPT_MESSAGE,
299
261
  errors: [],
300
- contentHtml: '',
301
- content: 'foo bar',
302
- chunks: ['a', 'b', 'c'],
262
+ contentHtml: undefined,
263
+ content: '',
264
+ chunks: ['[click here]', '(javascript:prompt(1))'],
303
265
  },
304
266
  });
305
267
 
306
268
  await nextTick();
307
269
 
308
- expect(findContent().html()).toBe('<div>\n <p>foo bar</p>\n</div>');
270
+ expect(findContent().html()).toContain('<p><a>click here</a></p>');
309
271
  });
310
272
 
311
- it('outputs chunks if there is no content', async () => {
273
+ it('sanitizes contentHtml', async () => {
312
274
  createComponent({
313
275
  options: {
314
276
  provide: null,
@@ -316,92 +278,250 @@ describe('DuoChatMessage', () => {
316
278
  message: {
317
279
  ...MOCK_USER_PROMPT_MESSAGE,
318
280
  errors: [],
319
- contentHtml: '',
281
+ contentHtml: `<a href="javascript:prompt(1)">click here</a>`,
320
282
  content: '',
321
- chunks: ['a', 'b', 'c'],
283
+ chunks: [],
322
284
  },
323
285
  });
324
286
 
325
287
  await nextTick();
326
288
 
327
- expect(findContent().html()).toBe('<div>\n <p>abc</p>\n</div>');
289
+ expect(findContent().html()).toBe(
290
+ '<div class="gl-markdown gl-compact-markdown"><a>click here</a></div>'
291
+ );
328
292
  });
329
293
 
330
- it('sanitizes html produced by errors', async () => {
331
- createComponent({
332
- options: {
333
- provide: null,
334
- },
335
- message: {
336
- ...MOCK_USER_PROMPT_MESSAGE,
337
- errors: ['[click here](javascript:prompt(1))'],
338
- contentHtml: '',
339
- content: '',
340
- chunks: [],
341
- },
294
+ describe('message updates watcher', () => {
295
+ const newContent = 'new foo content';
296
+ beforeEach(() => {
297
+ createComponent();
342
298
  });
343
299
 
344
- await nextTick();
300
+ it('listens to the message changes', async () => {
301
+ expect(findContent().text()).toContain(MOCK_USER_PROMPT_MESSAGE.content);
302
+ // setProps is justified here because we are testing the component's
303
+ // reactive behavior which consistutes an exception
304
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
305
+ await wrapper.setProps({
306
+ message: {
307
+ ...MOCK_USER_PROMPT_MESSAGE,
308
+ contentHtml: `<p>${newContent}</p>`,
309
+ },
310
+ });
311
+ expect(findContent().text()).not.toContain(MOCK_USER_PROMPT_MESSAGE.content);
312
+ expect(findContent().text()).toContain(newContent);
313
+ });
345
314
 
346
- expect(findContent().html()).toBe('<div>\n <p><a>click here</a></p>\n</div>');
347
- });
315
+ it('prioritises the output of contentHtml over content', async () => {
316
+ // setProps is justified here because we are testing the component's
317
+ // reactive behavior which consistutes an exception
318
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
319
+ await wrapper.setProps({
320
+ message: {
321
+ ...MOCK_USER_PROMPT_MESSAGE,
322
+ contentHtml: `<p>${MOCK_USER_PROMPT_MESSAGE.content}</p>`,
323
+ content: newContent,
324
+ },
325
+ });
326
+ expect(findContent().text()).not.toContain(newContent);
327
+ expect(findContent().text()).toContain(MOCK_USER_PROMPT_MESSAGE.content);
328
+ });
348
329
 
349
- it('sanitizes html produced by content', async () => {
350
- createComponent({
351
- options: {
352
- provide: null,
353
- },
354
- message: {
355
- ...MOCK_USER_PROMPT_MESSAGE,
356
- errors: [],
357
- contentHtml: '',
358
- content: '[click here](javascript:prompt(1))',
359
- chunks: [],
360
- },
330
+ it('outputs errors if message has no content', async () => {
331
+ // setProps is justified here because we are testing the component's
332
+ // reactive behavior which consistutes an exception
333
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
334
+ await wrapper.setProps({
335
+ message: {
336
+ ...MOCK_USER_PROMPT_MESSAGE,
337
+ contentHtml: '',
338
+ content: '',
339
+ errors: ['error'],
340
+ },
341
+ });
342
+ expect(findContent().text()).not.toContain(newContent);
343
+ expect(findContent().text()).not.toContain(MOCK_USER_PROMPT_MESSAGE.content);
344
+ expect(findContent().text()).toContain('error');
361
345
  });
362
346
 
363
- await nextTick();
347
+ it('merges all the errors for output', async () => {
348
+ const errors = ['foo', 'bar', 'baz'];
349
+ // setProps is justified here because we are testing the component's
350
+ // reactive behavior which consistutes an exception
351
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
352
+ await wrapper.setProps({
353
+ message: {
354
+ ...MOCK_USER_PROMPT_MESSAGE,
355
+ contentHtml: '',
356
+ content: '',
357
+ errors,
358
+ },
359
+ });
360
+ expect(findContent().text()).toContain(errors[0]);
361
+ expect(findContent().text()).toContain(errors[1]);
362
+ expect(findContent().text()).toContain(errors[2]);
363
+ });
364
364
 
365
- expect(findContent().html()).toBe('<div>\n <p><a>click here</a></p>\n</div>');
365
+ it('hydrates the output message with GLFM if its not a chunk', async () => {
366
+ // setProps is justified here because we are testing the component's
367
+ // reactive behavior which consistutes an exception
368
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
369
+ await wrapper.setProps({
370
+ message: {
371
+ ...MOCK_USER_PROMPT_MESSAGE,
372
+ contentHtml: `<p>${newContent}</p>`,
373
+ },
374
+ });
375
+ expect(renderGFM).toHaveBeenCalled();
376
+ });
366
377
  });
367
378
 
368
- it('sanitizes html produced by chunks', async () => {
369
- createComponent({
370
- options: {
371
- provide: null,
372
- },
373
- message: {
374
- ...MOCK_USER_PROMPT_MESSAGE,
375
- errors: [],
376
- contentHtml: '',
377
- content: '',
378
- chunks: ['[click here]', '(javascript:prompt(1))'],
379
- },
379
+ describe('updates to the message', () => {
380
+ const [CHUNK1, CHUNK2, CHUNK3] = generateSeparateChunks(3);
381
+ const consolidatedContent = CHUNK1.content + CHUNK2.content;
382
+
383
+ beforeEach(() => {
384
+ createComponent({ message: MOCK_RESPONSE_MESSAGE });
380
385
  });
381
386
 
382
- await nextTick();
387
+ it('does not handle message updates with chunks for the user messages', async () => {
388
+ createComponent({ message: MOCK_USER_PROMPT_MESSAGE });
389
+ expect(findContent().text()).toContain(MOCK_USER_PROMPT_MESSAGE.content);
390
+ // setProps is justified here because we are testing the component's
391
+ // reactive behavior which consistutes an exception
392
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
393
+ await wrapper.setProps({
394
+ message: {
395
+ ...MOCK_USER_PROMPT_MESSAGE,
396
+ content: 'foo bar',
397
+ chunkId: 1,
398
+ },
399
+ });
400
+ expect(findContent().text()).toContain(MOCK_USER_PROMPT_MESSAGE.content);
401
+ });
383
402
 
384
- expect(findContent().html()).toBe('<div>\n <p><a>click here</a></p>\n</div>');
385
- });
403
+ it('does not fail if the message has no chunkId', async () => {
404
+ // setProps is justified here because we are testing the component's
405
+ // reactive behavior which consistutes an exception
406
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
407
+ await wrapper.setProps({
408
+ message: {
409
+ ...CHUNK1,
410
+ chunkId: null,
411
+ },
412
+ });
413
+ expect(findContent().text()).toContain(CHUNK1.content);
414
+ });
386
415
 
387
- it('sanitizes contentHtml', async () => {
388
- createComponent({
389
- options: {
390
- provide: null,
391
- },
392
- message: {
393
- ...MOCK_USER_PROMPT_MESSAGE,
394
- errors: [],
395
- contentHtml: `<a href="javascript:prompt(1)">click here</a>`,
396
- content: '',
397
- chunks: [],
398
- },
416
+ it('renders chunks correctly when the chunks arrive out of order', async () => {
417
+ expect(CHUNK1.content).toBe('chunk #1');
418
+ expect(CHUNK2.content).toBe('chunk #2');
419
+ expect(CHUNK3.content).toBe('chunk #3');
420
+ // setProps is justified here because we are testing the component's
421
+ // reactive behavior which consistutes an exception
422
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
423
+ await wrapper.setProps({
424
+ message: CHUNK2,
425
+ });
426
+ expect(findContent().text()).toBe('');
427
+
428
+ await wrapper.setProps({
429
+ message: CHUNK1,
430
+ });
431
+ expect(findContent().text()).toBe(CHUNK1.content + CHUNK2.content);
432
+
433
+ await wrapper.setProps({
434
+ message: CHUNK3,
435
+ });
436
+ expect(findContent().text()).toBe(CHUNK1.content + CHUNK2.content + CHUNK3.content);
399
437
  });
400
438
 
401
- await nextTick();
439
+ it('renders the chunks as they arrive when they arrive in the correct order', async () => {
440
+ // setProps is justified here because we are testing the component's
441
+ // reactive behavior which consistutes an exception
442
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
443
+ await wrapper.setProps({
444
+ message: CHUNK1,
445
+ });
446
+ expect(findContent().text()).toBe(CHUNK1.content);
402
447
 
403
- expect(findContent().html()).toBe(
404
- '<div class="gl-markdown gl-compact-markdown"><a>click here</a></div>'
448
+ await wrapper.setProps({
449
+ message: CHUNK2,
450
+ });
451
+ expect(findContent().text()).toBe(consolidatedContent);
452
+ });
453
+
454
+ it('treats the initial message content as chunk if message has chunkId', async () => {
455
+ createComponent({
456
+ message: CHUNK1,
457
+ });
458
+ await nextTick();
459
+ expect(findContent().text()).toBe(CHUNK1.content);
460
+
461
+ // setProps is justified here because we are testing the component's
462
+ // reactive behavior which consistutes an exception
463
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
464
+ await wrapper.setProps({
465
+ message: CHUNK2,
466
+ });
467
+ expect(findContent().text()).toBe(consolidatedContent);
468
+ });
469
+
470
+ it('does not hydrate the chunk messages with GLFM', async () => {
471
+ createComponent({
472
+ propsData: {
473
+ message: CHUNK1,
474
+ },
475
+ });
476
+ await nextTick();
477
+ renderGFM.mockClear();
478
+ expect(renderGFM).not.toHaveBeenCalled();
479
+
480
+ // setProps is justified here because we are testing the component's
481
+ // reactive behavior which consistutes an exception
482
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
483
+ await wrapper.setProps({
484
+ message: CHUNK2,
485
+ });
486
+ expect(renderGFM).not.toHaveBeenCalled();
487
+ });
488
+
489
+ it.each`
490
+ content | contentHtml | errors | expectedContent
491
+ ${'alpha'} | ${'beta'} | ${['foo', 'bar']} | ${'foo; bar'}
492
+ ${'alpha'} | ${'beta'} | ${[]} | ${'beta'}
493
+ ${'alpha'} | ${undefined} | ${['foo', 'bar']} | ${'foo; bar'}
494
+ ${'alpha'} | ${undefined} | ${[]} | ${'alpha'}
495
+ ${''} | ${'beta'} | ${['foo', 'bar']} | ${'foo; bar'}
496
+ ${''} | ${'beta'} | ${[]} | ${'beta'}
497
+ ${''} | ${undefined} | ${['foo', 'bar']} | ${'foo; bar'}
498
+ `(
499
+ 'outputs "$expectedContent" and hydrates this content when content is "$content", contentHtml is "$contentHtml" and errors is "$errors" with "chunkId: null"',
500
+ async ({ content, contentHtml, errors, expectedContent } = {}) => {
501
+ createComponent({
502
+ propsData: {
503
+ message: CHUNK1,
504
+ },
505
+ });
506
+ await nextTick();
507
+ renderGFM.mockClear();
508
+ expect(renderGFM).not.toHaveBeenCalled();
509
+
510
+ // setProps is justified here because we are testing the component's
511
+ // reactive behavior which consistutes an exception
512
+ // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
513
+ await wrapper.setProps({
514
+ message: {
515
+ ...CHUNK2,
516
+ chunkId: null,
517
+ content,
518
+ contentHtml,
519
+ errors,
520
+ },
521
+ });
522
+ expect(renderGFM).toHaveBeenCalled();
523
+ expect(findContent().text()).toBe(expectedContent);
524
+ }
405
525
  );
406
526
  });
407
527
  });