Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
commitaee0a117a889461ce8ced6fcf73207fe017f1d99 (patch)
tree891d9ef189227a8445d83f35c1b0fc99573f4380 /spec/frontend/content_editor
parent8d46af3258650d305f53b819eabf7ab18d22f59e (diff)
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'spec/frontend/content_editor')
-rw-r--r--spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap2
-rw-r--r--spec/frontend/content_editor/markdown_processing_examples.js27
-rw-r--r--spec/frontend/content_editor/markdown_processing_spec.js28
-rw-r--r--spec/frontend/content_editor/markdown_processing_spec_helper.js86
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js33
5 files changed, 129 insertions, 47 deletions
diff --git a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
index 178c7d749c8..7abd6b422ad 100644
--- a/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
+++ b/spec/frontend/content_editor/components/__snapshots__/toolbar_link_button_spec.js.snap
@@ -19,7 +19,7 @@ exports[`content_editor/components/toolbar_link_button renders dropdown componen
<div placeholder=\\"Link URL\\">
<div role=\\"group\\" class=\\"input-group\\">
<!---->
- <!----> <input type=\\"text\\" placeholder=\\"Link URL\\" class=\\"gl-form-input form-control\\">
+ <!----> <input type=\\"text\\" placeholder=\\"Link URL\\" class=\\"form-control gl-form-input\\">
<div class=\\"input-group-append\\"><button type=\\"button\\" class=\\"btn btn-confirm btn-md gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">Apply</span></button></div>
diff --git a/spec/frontend/content_editor/markdown_processing_examples.js b/spec/frontend/content_editor/markdown_processing_examples.js
deleted file mode 100644
index da895970289..00000000000
--- a/spec/frontend/content_editor/markdown_processing_examples.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import fs from 'fs';
-import path from 'path';
-import jsYaml from 'js-yaml';
-// eslint-disable-next-line import/no-deprecated
-import { getJSONFixture } from 'helpers/fixtures';
-
-export const loadMarkdownApiResult = (testName) => {
- const fixturePathPrefix = `api/markdown/${testName}.json`;
-
- // eslint-disable-next-line import/no-deprecated
- const fixture = getJSONFixture(fixturePathPrefix);
- return fixture.body || fixture.html;
-};
-
-export const loadMarkdownApiExamples = () => {
- const apiMarkdownYamlPath = path.join(__dirname, '..', 'fixtures', 'api_markdown.yml');
- const apiMarkdownYamlText = fs.readFileSync(apiMarkdownYamlPath);
- const apiMarkdownExampleObjects = jsYaml.safeLoad(apiMarkdownYamlText);
-
- return apiMarkdownExampleObjects.map(({ name, context, markdown }) => [name, context, markdown]);
-};
-
-export const loadMarkdownApiExample = (testName) => {
- return loadMarkdownApiExamples().find(([name, context]) => {
- return (context ? `${context}_${name}` : name) === testName;
- })[2];
-};
diff --git a/spec/frontend/content_editor/markdown_processing_spec.js b/spec/frontend/content_editor/markdown_processing_spec.js
index 71565768558..3930f47289a 100644
--- a/spec/frontend/content_editor/markdown_processing_spec.js
+++ b/spec/frontend/content_editor/markdown_processing_spec.js
@@ -1,20 +1,16 @@
-import { createContentEditor } from '~/content_editor';
-import { loadMarkdownApiExamples, loadMarkdownApiResult } from './markdown_processing_examples';
+import path from 'path';
+import { describeMarkdownProcessing } from 'jest/content_editor/markdown_processing_spec_helper';
jest.mock('~/emoji');
-describe('markdown processing', () => {
- // Ensure we generate same markdown that was provided to Markdown API.
- it.each(loadMarkdownApiExamples())(
- 'correctly handles %s (context: %s)',
- async (name, context, markdown) => {
- const testName = context ? `${context}_${name}` : name;
- const contentEditor = createContentEditor({
- renderMarkdown: () => loadMarkdownApiResult(testName),
- });
- await contentEditor.setSerializedContent(markdown);
+const markdownYamlPath = path.join(
+ __dirname,
+ '..',
+ '..',
+ 'fixtures',
+ 'markdown',
+ 'markdown_golden_master_examples.yml',
+);
- expect(contentEditor.getSerializedContent()).toBe(markdown);
- },
- );
-});
+// See spec/fixtures/markdown/markdown_golden_master_examples.yml for documentation on how this spec works.
+describeMarkdownProcessing('CE markdown processing in ContentEditor', markdownYamlPath);
diff --git a/spec/frontend/content_editor/markdown_processing_spec_helper.js b/spec/frontend/content_editor/markdown_processing_spec_helper.js
new file mode 100644
index 00000000000..bb7ec0030a2
--- /dev/null
+++ b/spec/frontend/content_editor/markdown_processing_spec_helper.js
@@ -0,0 +1,86 @@
+import fs from 'fs';
+import jsYaml from 'js-yaml';
+import { memoize } from 'lodash';
+import { createContentEditor } from '~/content_editor';
+import { setTestTimeoutOnce } from 'helpers/timeout';
+
+const getFocusedMarkdownExamples = memoize(
+ () => process.env.FOCUSED_MARKDOWN_EXAMPLES?.split(',') || [],
+);
+
+const includeExample = ({ name }) => {
+ const focusedMarkdownExamples = getFocusedMarkdownExamples();
+ if (!focusedMarkdownExamples.length) {
+ return true;
+ }
+ return focusedMarkdownExamples.includes(name);
+};
+
+const getPendingReason = (pendingStringOrObject) => {
+ if (!pendingStringOrObject) {
+ return null;
+ }
+ if (typeof pendingStringOrObject === 'string') {
+ return pendingStringOrObject;
+ }
+ if (pendingStringOrObject.frontend) {
+ return pendingStringOrObject.frontend;
+ }
+
+ return null;
+};
+
+const loadMarkdownApiExamples = (markdownYamlPath) => {
+ const apiMarkdownYamlText = fs.readFileSync(markdownYamlPath);
+ const apiMarkdownExampleObjects = jsYaml.safeLoad(apiMarkdownYamlText);
+
+ return apiMarkdownExampleObjects
+ .filter(includeExample)
+ .map(({ name, pending, markdown, html }) => [
+ name,
+ { pendingReason: getPendingReason(pending), markdown, html },
+ ]);
+};
+
+const testSerializesHtmlToMarkdownForElement = async ({ markdown, html }) => {
+ const contentEditor = createContentEditor({
+ // Overwrite renderMarkdown to always return this specific html
+ renderMarkdown: () => html,
+ });
+
+ await contentEditor.setSerializedContent(markdown);
+
+ // This serializes the ContentEditor document, which was based on the HTML, to markdown
+ const serializedContent = contentEditor.getSerializedContent();
+
+ // Assert that the markdown we ended up with after sending it through all the ContentEditor
+ // plumbing matches the original markdown from the YAML.
+ expect(serializedContent).toBe(markdown);
+};
+
+// describeMarkdownProcesssing
+//
+// This is used to dynamically generate examples (for both CE and EE) to ensure
+// we generate same markdown that was provided to Markdown API.
+//
+// eslint-disable-next-line jest/no-export
+export const describeMarkdownProcessing = (description, markdownYamlPath) => {
+ const examples = loadMarkdownApiExamples(markdownYamlPath);
+
+ describe(description, () => {
+ describe.each(examples)('%s', (name, { pendingReason, ...example }) => {
+ const exampleName = 'correctly serializes HTML to markdown';
+ if (pendingReason) {
+ it.todo(`${exampleName}: ${pendingReason}`);
+ return;
+ }
+
+ it(exampleName, async () => {
+ if (name === 'frontmatter_toml') {
+ setTestTimeoutOnce(2000);
+ }
+ await testSerializesHtmlToMarkdownForElement(example);
+ });
+ });
+ });
+};
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index cfd93c2df10..97f6d8f6334 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -11,6 +11,9 @@ import Division from '~/content_editor/extensions/division';
import Emoji from '~/content_editor/extensions/emoji';
import Figure from '~/content_editor/extensions/figure';
import FigureCaption from '~/content_editor/extensions/figure_caption';
+import FootnoteDefinition from '~/content_editor/extensions/footnote_definition';
+import FootnoteReference from '~/content_editor/extensions/footnote_reference';
+import FootnotesSection from '~/content_editor/extensions/footnotes_section';
import HardBreak from '~/content_editor/extensions/hard_break';
import Heading from '~/content_editor/extensions/heading';
import HorizontalRule from '~/content_editor/extensions/horizontal_rule';
@@ -28,7 +31,6 @@ import TableHeader from '~/content_editor/extensions/table_header';
import TableRow from '~/content_editor/extensions/table_row';
import TaskItem from '~/content_editor/extensions/task_item';
import TaskList from '~/content_editor/extensions/task_list';
-import Text from '~/content_editor/extensions/text';
import markdownSerializer from '~/content_editor/services/markdown_serializer';
import { createTestEditor, createDocBuilder } from '../test_utils';
@@ -47,6 +49,9 @@ const tiptapEditor = createTestEditor({
DetailsContent,
Division,
Emoji,
+ FootnoteDefinition,
+ FootnoteReference,
+ FootnotesSection,
Figure,
FigureCaption,
HardBreak,
@@ -58,7 +63,6 @@ const tiptapEditor = createTestEditor({
Link,
ListItem,
OrderedList,
- Paragraph,
Strike,
Table,
TableCell,
@@ -66,7 +70,6 @@ const tiptapEditor = createTestEditor({
TableRow,
TaskItem,
TaskList,
- Text,
],
});
@@ -84,6 +87,9 @@ const {
descriptionItem,
descriptionList,
emoji,
+ footnoteDefinition,
+ footnoteReference,
+ footnotesSection,
figure,
figureCaption,
heading,
@@ -120,6 +126,9 @@ const {
emoji: { markType: Emoji.name },
figure: { nodeType: Figure.name },
figureCaption: { nodeType: FigureCaption.name },
+ footnoteDefinition: { nodeType: FootnoteDefinition.name },
+ footnoteReference: { nodeType: FootnoteReference.name },
+ footnotesSection: { nodeType: FootnotesSection.name },
hardBreak: { nodeType: HardBreak.name },
heading: { nodeType: Heading.name },
horizontalRule: { nodeType: HorizontalRule.name },
@@ -1108,4 +1117,22 @@ there
`.trim(),
);
});
+
+ it('correctly serializes footnotes', () => {
+ expect(
+ serialize(
+ paragraph(
+ 'Oranges are orange ',
+ footnoteReference({ footnoteId: '1', footnoteNumber: '1' }),
+ ),
+ footnotesSection(footnoteDefinition(paragraph('Oranges are fruits'))),
+ ),
+ ).toBe(
+ `
+Oranges are orange [^1]
+
+[^1]: Oranges are fruits
+ `.trim(),
+ );
+ });
});