diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-10 15:09:12 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-10 15:09:12 +0300 |
commit | 0e0df204c1a0d859ccbbe1be83a5e09a53381f17 (patch) | |
tree | e7bf6fed5fa2b74caf31957c468b0cbc303f4c45 /spec/frontend | |
parent | a2344dbf1942dc3919c55b0684d2566368e03852 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
13 files changed, 750 insertions, 145 deletions
diff --git a/spec/frontend/content_editor/components/bubble_menus/link_bubble_menu_spec.js b/spec/frontend/content_editor/components/bubble_menus/link_bubble_menu_spec.js index 2a8a1b00692..c79df9c9ed8 100644 --- a/spec/frontend/content_editor/components/bubble_menus/link_bubble_menu_spec.js +++ b/spec/frontend/content_editor/components/bubble_menus/link_bubble_menu_spec.js @@ -7,7 +7,7 @@ import eventHubFactory from '~/helpers/event_hub_factory'; import BubbleMenu from '~/content_editor/components/bubble_menus/bubble_menu.vue'; import { stubComponent } from 'helpers/stub_component'; import Link from '~/content_editor/extensions/link'; -import { createTestEditor } from '../../test_utils'; +import { createTestEditor, emitEditorEvent, createTransactionWithMeta } from '../../test_utils'; const createFakeEvent = () => ({ preventDefault: jest.fn(), stopPropagation: jest.fn() }); @@ -64,7 +64,7 @@ describe('content_editor/components/bubble_menus/link_bubble_menu', () => { tiptapEditor .chain() - .insertContent( + .setContent( 'Download <a href="/path/to/project/-/wikis/uploads/my_file.pdf" data-canonical-src="uploads/my_file.pdf">PDF File</a>', ) .setTextSelection(14) // put cursor in the middle of the link @@ -90,6 +90,36 @@ describe('content_editor/components/bubble_menus/link_bubble_menu', () => { expect(findLink().text()).toBe('uploads/my_file.pdf'); }); + it('shows a loading percentage for a file being uploaded', async () => { + const setUploadProgress = async (progress) => { + const transaction = createTransactionWithMeta('uploadProgress', { + filename: 'my_file.pdf', + progress, + }); + await emitEditorEvent({ event: 'transaction', tiptapEditor, params: { transaction } }); + }; + + tiptapEditor + .chain() + .extendMarkRange('link') + .updateAttributes('link', { uploading: 'my_file.pdf' }) + .run(); + + await buildWrapperAndDisplayMenu(); + + expect(findLink().exists()).toBe(false); + expect(wrapper.text()).toContain('Uploading: 0%'); + + await setUploadProgress(0.4); + expect(wrapper.text()).toContain('Uploading: 40%'); + + await setUploadProgress(0.7); + expect(wrapper.text()).toContain('Uploading: 70%'); + + await setUploadProgress(1); + expect(wrapper.text()).toContain('Uploading: 100%'); + }); + it('updates the bubble menu state when @selectionUpdate event is triggered', async () => { const linkUrl = 'https://gitlab.com'; diff --git a/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js b/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js index e02b36fb8e9..89beb76a6f2 100644 --- a/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js +++ b/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js @@ -1,3 +1,4 @@ +import { nextTick } from 'vue'; import { GlLink, GlForm } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import BubbleMenu from '~/content_editor/components/bubble_menus/bubble_menu.vue'; @@ -8,7 +9,12 @@ import Audio from '~/content_editor/extensions/audio'; import DrawioDiagram from '~/content_editor/extensions/drawio_diagram'; import Image from '~/content_editor/extensions/image'; import Video from '~/content_editor/extensions/video'; -import { createTestEditor, emitEditorEvent, mockChainedCommands } from '../../test_utils'; +import { + createTestEditor, + emitEditorEvent, + mockChainedCommands, + createTransactionWithMeta, +} from '../../test_utils'; import { PROJECT_WIKI_ATTACHMENT_IMAGE_HTML, PROJECT_WIKI_ATTACHMENT_AUDIO_HTML, @@ -17,7 +23,7 @@ import { } from '../../test_constants'; const TIPTAP_AUDIO_HTML = `<p> - <span class="media-container audio-container"><audio src="https://gitlab.com/favicon.png" controls="true" data-setup="{}" data-title="gitlab favicon"></audio><a href="https://gitlab.com/favicon.png">gitlab favicon</a></span> + <span class="media-container audio-container"><audio src="https://gitlab.com/favicon.png" controls="true" data-setup="{}" data-title="gitlab favicon"></audio><a href="https://gitlab.com/favicon.png" class="with-attachment-icon">gitlab favicon</a></span> </p>`; const TIPTAP_DIAGRAM_HTML = `<p> @@ -29,24 +35,23 @@ const TIPTAP_IMAGE_HTML = `<p> </p>`; const TIPTAP_VIDEO_HTML = `<p> - <span class="media-container video-container"><video src="https://gitlab.com/favicon.png" controls="true" data-setup="{}" data-title="gitlab favicon"></video><a href="https://gitlab.com/favicon.png">gitlab favicon</a></span> + <span class="media-container video-container"><video src="https://gitlab.com/favicon.png" controls="true" data-setup="{}" data-title="gitlab favicon"></video><a href="https://gitlab.com/favicon.png" class="with-attachment-icon">gitlab favicon</a></span> </p>`; const createFakeEvent = () => ({ preventDefault: jest.fn(), stopPropagation: jest.fn() }); describe.each` - mediaType | mediaHTML | filePath | mediaOutputHTML - ${'image'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_HTML} | ${'test-file.png'} | ${TIPTAP_IMAGE_HTML} - ${'drawio_diagram'} | ${PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML} | ${'test-file.drawio.svg'} | ${TIPTAP_DIAGRAM_HTML} - ${'audio'} | ${PROJECT_WIKI_ATTACHMENT_AUDIO_HTML} | ${'test-file.mp3'} | ${TIPTAP_AUDIO_HTML} - ${'video'} | ${PROJECT_WIKI_ATTACHMENT_VIDEO_HTML} | ${'test-file.mp4'} | ${TIPTAP_VIDEO_HTML} + mediaType | mediaHTML | filePath | mediaOutputHTML + ${'image'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_HTML} | ${'test-file.png'} | ${TIPTAP_IMAGE_HTML} + ${'drawioDiagram'} | ${PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML} | ${'test-file.drawio.svg'} | ${TIPTAP_DIAGRAM_HTML} + ${'audio'} | ${PROJECT_WIKI_ATTACHMENT_AUDIO_HTML} | ${'test-file.mp3'} | ${TIPTAP_AUDIO_HTML} + ${'video'} | ${PROJECT_WIKI_ATTACHMENT_VIDEO_HTML} | ${'test-file.mp4'} | ${TIPTAP_VIDEO_HTML} `( 'content_editor/components/bubble_menus/media_bubble_menu ($mediaType)', ({ mediaType, mediaHTML, filePath, mediaOutputHTML }) => { let wrapper; let tiptapEditor; let contentEditor; - let bubbleMenu; let eventHub; const buildEditor = () => { @@ -68,6 +73,24 @@ describe.each` }); }; + const findBubbleMenu = () => wrapper.findComponent(BubbleMenu); + + const showMenu = async () => { + findBubbleMenu().vm.$emit('show'); + await emitEditorEvent({ + event: 'transaction', + tiptapEditor, + params: { transaction: createTransactionWithMeta() }, + }); + await nextTick(); + }; + + const buildWrapperAndDisplayMenu = () => { + buildWrapper(); + + return showMenu(); + }; + const selectFile = async (file) => { const input = wrapper.findComponent({ ref: 'fileSelector' }); @@ -83,9 +106,8 @@ describe.each` expect(wrapper.findByTestId('delete-media').exists()).toBe(exist); }; - beforeEach(async () => { + beforeEach(() => { buildEditor(); - buildWrapper(); tiptapEditor .chain() @@ -94,17 +116,17 @@ describe.each` .run(); contentEditor.resolveUrl.mockResolvedValue(`/group1/project1/-/wikis/${filePath}`); + }); - await emitEditorEvent({ event: 'transaction', tiptapEditor }); + it('renders bubble menu component', async () => { + await buildWrapperAndDisplayMenu(); - bubbleMenu = wrapper.findComponent(BubbleMenu); + expect(findBubbleMenu().classes()).toEqual(['gl-shadow', 'gl-rounded-base', 'gl-bg-white']); }); - it('renders bubble menu component', () => { - expect(bubbleMenu.classes()).toEqual(['gl-shadow', 'gl-rounded-base', 'gl-bg-white']); - }); + it('shows a clickable link to the image', async () => { + await buildWrapperAndDisplayMenu(); - it('shows a clickable link to the image', () => { const link = wrapper.findComponent(GlLink); expect(link.attributes()).toEqual( expect.objectContaining({ @@ -117,8 +139,41 @@ describe.each` expect(link.text()).toBe(filePath); }); + it('shows a loading percentage for a file being uploaded', async () => { + jest.spyOn(tiptapEditor, 'isActive').mockImplementation((name) => name === mediaType); + + await buildWrapperAndDisplayMenu(); + + const setUploadProgress = async (progress) => { + const transaction = createTransactionWithMeta('uploadProgress', { + filename: filePath, + progress, + }); + await emitEditorEvent({ event: 'transaction', tiptapEditor, params: { transaction } }); + }; + + tiptapEditor.chain().selectAll().updateAttributes(mediaType, { uploading: filePath }).run(); + + await emitEditorEvent({ event: 'selectionUpdate', tiptapEditor }); + + expect(wrapper.findComponent(GlLink).exists()).toBe(false); + expect(wrapper.text()).toContain('Uploading: 0%'); + + await setUploadProgress(0.4); + + expect(wrapper.text()).toContain('Uploading: 40%'); + + await setUploadProgress(0.7); + expect(wrapper.text()).toContain('Uploading: 70%'); + + await setUploadProgress(1); + expect(wrapper.text()).toContain('Uploading: 100%'); + }); + describe('when BubbleMenu emits hidden event', () => { it('resets media bubble menu state', async () => { + await buildWrapperAndDisplayMenu(); + // Switch to edit mode to access component state in form fields await wrapper.findByTestId('edit-media').vm.$emit('click'); @@ -137,6 +192,8 @@ describe.each` describe('copy button', () => { it(`copies the canonical link to the ${mediaType} to clipboard`, async () => { + await buildWrapperAndDisplayMenu(); + jest.spyOn(navigator.clipboard, 'writeText'); await wrapper.findByTestId('copy-media-src').vm.$emit('click'); @@ -147,6 +204,8 @@ describe.each` describe(`remove ${mediaType} button`, () => { it(`removes the ${mediaType}`, async () => { + await buildWrapperAndDisplayMenu(); + await wrapper.findByTestId('delete-media').vm.$emit('click'); expect(tiptapEditor.getHTML()).toBe('<p>\n \n</p>'); @@ -154,7 +213,9 @@ describe.each` }); describe(`replace ${mediaType} button`, () => { - if (mediaType !== 'drawio_diagram') { + beforeEach(buildWrapperAndDisplayMenu); + + if (mediaType !== 'drawioDiagram') { it('uploads and replaces the selected image when file input changes', async () => { const commands = mockChainedCommands(tiptapEditor, [ 'focus', @@ -195,6 +256,8 @@ describe.each` let mediaAltInput; beforeEach(async () => { + await buildWrapperAndDisplayMenu(); + await wrapper.findByTestId('edit-media').vm.$emit('click'); mediaSrcInput = wrapper.findByTestId('media-src'); diff --git a/spec/frontend/content_editor/components/toolbar_attachment_button_spec.js b/spec/frontend/content_editor/components/toolbar_attachment_button_spec.js index 06ea863dbfa..c6793d5b01b 100644 --- a/spec/frontend/content_editor/components/toolbar_attachment_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_attachment_button_spec.js @@ -16,11 +16,11 @@ describe('content_editor/components/toolbar_attachment_button', () => { }); }; - const selectFile = async (file) => { + const selectFiles = async (...files) => { const input = wrapper.findComponent({ ref: 'fileSelector' }); // override the property definition because `input.files` isn't directly modifyable - Object.defineProperty(input.element, 'files', { value: [file], writable: true }); + Object.defineProperty(input.element, 'files', { value: files, writable: true }); await input.trigger('change'); }; @@ -28,6 +28,7 @@ describe('content_editor/components/toolbar_attachment_button', () => { editor = createTestEditor({ extensions: [ Link, + Image, Attachment.configure({ renderMarkdown: jest.fn(), uploadsPath: '/uploads/', @@ -44,12 +45,14 @@ describe('content_editor/components/toolbar_attachment_button', () => { it('uploads the selected attachment when file input changes', async () => { const commands = mockChainedCommands(editor, ['focus', 'uploadAttachment', 'run']); - const file = new File(['foo'], 'foo.png', { type: 'image/png' }); + const file1 = new File(['foo'], 'foo.png', { type: 'image/png' }); + const file2 = new File(['bar'], 'bar.png', { type: 'image/png' }); - await selectFile(file); + await selectFiles(file1, file2); expect(commands.focus).toHaveBeenCalled(); - expect(commands.uploadAttachment).toHaveBeenCalledWith({ file }); + expect(commands.uploadAttachment).toHaveBeenCalledWith({ file: file1 }); + expect(commands.uploadAttachment).toHaveBeenCalledWith({ file: file2 }); expect(commands.run).toHaveBeenCalled(); expect(wrapper.emitted().execute[0]).toEqual([{ contentType: 'link', value: 'upload' }]); diff --git a/spec/frontend/content_editor/extensions/attachment_spec.js b/spec/frontend/content_editor/extensions/attachment_spec.js index 3c699b05b0f..f037ac520fe 100644 --- a/spec/frontend/content_editor/extensions/attachment_spec.js +++ b/spec/frontend/content_editor/extensions/attachment_spec.js @@ -1,17 +1,15 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import waitForPromises from 'helpers/wait_for_promises'; import Attachment from '~/content_editor/extensions/attachment'; import DrawioDiagram from '~/content_editor/extensions/drawio_diagram'; import Image from '~/content_editor/extensions/image'; import Audio from '~/content_editor/extensions/audio'; import Video from '~/content_editor/extensions/video'; import Link from '~/content_editor/extensions/link'; -import Loading from '~/content_editor/extensions/loading'; import { VARIANT_DANGER } from '~/alert'; import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status'; import eventHubFactory from '~/helpers/event_hub_factory'; -import { createTestEditor, createDocBuilder } from '../test_utils'; +import { createTestEditor, createDocBuilder, expectDocumentAfterTransaction } from '../test_utils'; import { PROJECT_WIKI_ATTACHMENT_IMAGE_HTML, PROJECT_WIKI_ATTACHMENT_IMAGE_SVG_HTML, @@ -29,7 +27,6 @@ describe('content_editor/extensions/attachment', () => { let audio; let drawioDiagram; let video; - let loading; let link; let renderMarkdown; let mock; @@ -40,35 +37,35 @@ describe('content_editor/extensions/attachment', () => { const imageFileSvg = new File(['foo'], 'test-file.svg', { type: 'image/svg+xml' }); const audioFile = new File(['foo'], 'test-file.mp3', { type: 'audio/mpeg' }); const videoFile = new File(['foo'], 'test-file.mp4', { type: 'video/mp4' }); + const videoFile1 = new File(['foo'], 'test-file1.mp4', { type: 'video/mp4' }); const drawioDiagramFile = new File(['foo'], 'test-file.drawio.svg', { type: 'image/svg+xml' }); const attachmentFile = new File(['foo'], 'test-file.zip', { type: 'application/zip' }); - - const expectDocumentAfterTransaction = ({ number, expectedDoc, action }) => { - return new Promise((resolve) => { - let counter = 1; - const handleTransaction = async () => { - if (counter === number) { - expect(tiptapEditor.state.doc.toJSON()).toEqual(expectedDoc.toJSON()); - tiptapEditor.off('update', handleTransaction); - await waitForPromises(); - resolve(); - } - - counter += 1; - }; - - tiptapEditor.on('update', handleTransaction); - action(); - }); + const attachmentFile1 = new File(['foo'], 'test-file1.zip', { type: 'application/zip' }); + const attachmentFile2 = new File(['foo'], 'test-file2.zip', { type: 'application/zip' }); + + const markdownApiResult = { + 'test-file.png': PROJECT_WIKI_ATTACHMENT_IMAGE_HTML, + 'test-file.svg': PROJECT_WIKI_ATTACHMENT_IMAGE_SVG_HTML, + 'test-file.mp3': PROJECT_WIKI_ATTACHMENT_AUDIO_HTML, + 'test-file.mp4': PROJECT_WIKI_ATTACHMENT_VIDEO_HTML, + 'test-file1.mp4': PROJECT_WIKI_ATTACHMENT_VIDEO_HTML.replace(/test-file/g, 'test-file1'), + 'test-file.zip': PROJECT_WIKI_ATTACHMENT_LINK_HTML, + 'test-file1.zip': PROJECT_WIKI_ATTACHMENT_LINK_HTML.replace(/test-file/g, 'test-file1'), + 'test-file2.zip': PROJECT_WIKI_ATTACHMENT_LINK_HTML.replace(/test-file/g, 'test-file2'), + 'test-file.drawio.svg': PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML, }; + const [, group, project] = markdownApiResult[attachmentFile.name].match( + /\/(group[0-9]+)\/(project[0-9]+)\//, + ); + const blobUrl = 'blob:https://gitlab.com/048c7ac1-98de-4a37-ab1b-0206d0ea7e1b'; + beforeEach(() => { renderMarkdown = jest.fn(); eventHub = eventHubFactory(); tiptapEditor = createTestEditor({ extensions: [ - Loading, Link, Image, Audio, @@ -79,11 +76,10 @@ describe('content_editor/extensions/attachment', () => { }); ({ - builders: { doc, p, image, audio, video, loading, link, drawioDiagram }, + builders: { doc, p, image, audio, video, link, drawioDiagram }, } = createDocBuilder({ tiptapEditor, names: { - loading: { markType: Loading.name }, image: { nodeType: Image.name }, link: { nodeType: Link.name }, audio: { nodeType: Audio.name }, @@ -105,6 +101,14 @@ describe('content_editor/extensions/attachment', () => { ${'paste'} | ${'handlePaste'} | ${{ clipboardData: { getData: jest.fn(), files: [] } }} | ${undefined} ${'drop'} | ${'handleDrop'} | ${{ dataTransfer: { getData: jest.fn(), files: [attachmentFile] } }} | ${true} `('handles $eventType properly', ({ eventType, propName, eventData, output }) => { + mock.onPost().reply(HTTP_STATUS_OK, { + link: { + markdown: `![test-file](test-file.png)`, + }, + }); + + renderMarkdown.mockResolvedValue(PROJECT_WIKI_ATTACHMENT_IMAGE_HTML); + const event = Object.assign(new Event(eventType), eventData); const handled = tiptapEditor.view.someProp(propName, (eventHandler) => { return eventHandler(tiptapEditor.view, event); @@ -121,15 +125,13 @@ describe('content_editor/extensions/attachment', () => { }); describe.each` - nodeType | mimeType | html | file | mediaType - ${'image (png)'} | ${'image/png'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_HTML} | ${imageFile} | ${(attrs) => image(attrs)} - ${'image (svg)'} | ${'image/svg+xml'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_SVG_HTML} | ${imageFileSvg} | ${(attrs) => image(attrs)} - ${'audio'} | ${'audio/mpeg'} | ${PROJECT_WIKI_ATTACHMENT_AUDIO_HTML} | ${audioFile} | ${(attrs) => audio(attrs)} - ${'video'} | ${'video/mp4'} | ${PROJECT_WIKI_ATTACHMENT_VIDEO_HTML} | ${videoFile} | ${(attrs) => video(attrs)} - ${'drawioDiagram'} | ${'image/svg+xml'} | ${PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML} | ${drawioDiagramFile} | ${(attrs) => drawioDiagram(attrs)} - `('when the file has $nodeType mime type', ({ mimeType, html, file, mediaType }) => { - const base64EncodedFile = `data:${mimeType};base64,Zm9v`; - + nodeType | html | file | mediaType + ${'image (png)'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_HTML} | ${imageFile} | ${(attrs) => image(attrs)} + ${'image (svg)'} | ${PROJECT_WIKI_ATTACHMENT_IMAGE_SVG_HTML} | ${imageFileSvg} | ${(attrs) => image(attrs)} + ${'audio'} | ${PROJECT_WIKI_ATTACHMENT_AUDIO_HTML} | ${audioFile} | ${(attrs) => audio(attrs)} + ${'video'} | ${PROJECT_WIKI_ATTACHMENT_VIDEO_HTML} | ${videoFile} | ${(attrs) => video(attrs)} + ${'drawioDiagram'} | ${PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML} | ${drawioDiagramFile} | ${(attrs) => drawioDiagram(attrs)} + `('when the file is $nodeType', ({ html, file, mediaType }) => { beforeEach(() => { renderMarkdown.mockResolvedValue(html); }); @@ -145,10 +147,13 @@ describe('content_editor/extensions/attachment', () => { mock.onPost().reply(HTTP_STATUS_OK, successResponse); }); - it('inserts a media content with src set to the encoded content and uploading true', async () => { - const expectedDoc = doc(p(mediaType({ uploading: true, src: base64EncodedFile }))); + it('inserts a media content with src set to the encoded content and uploading=file_name', async () => { + const expectedDoc = doc( + p(mediaType({ uploading: file.name, src: blobUrl, alt: file.name })), + ); await expectDocumentAfterTransaction({ + tiptapEditor, number: 1, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file }), @@ -160,7 +165,7 @@ describe('content_editor/extensions/attachment', () => { p( mediaType({ canonicalSrc: file.name, - src: base64EncodedFile, + src: blobUrl, alt: expect.stringContaining('test-file'), uploading: false, }), @@ -168,6 +173,7 @@ describe('content_editor/extensions/attachment', () => { ); await expectDocumentAfterTransaction({ + tiptapEditor, number: 2, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file }), @@ -175,6 +181,25 @@ describe('content_editor/extensions/attachment', () => { }); }); + describe('when uploading a large file', () => { + beforeEach(() => { + // Set max file size to 1 byte, our file is 3 bytes + gon.max_file_size = 1 / 1024 / 1024; + }); + + it('emits an alert event that includes an error message', () => { + tiptapEditor.commands.uploadAttachment({ file }); + + return new Promise((resolve) => { + eventHub.$on('alert', ({ message, variant }) => { + expect(variant).toBe(VARIANT_DANGER); + expect(message).toContain('File is too big'); + resolve(); + }); + }); + }); + }); + describe('when uploading request fails', () => { beforeEach(() => { mock.onPost().reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); @@ -184,6 +209,7 @@ describe('content_editor/extensions/attachment', () => { const expectedDoc = doc(p('')); await expectDocumentAfterTransaction({ + tiptapEditor, number: 2, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file }), @@ -205,10 +231,8 @@ describe('content_editor/extensions/attachment', () => { }); describe('when the file has a zip (or any other attachment) mime type', () => { - const markdownApiResult = PROJECT_WIKI_ATTACHMENT_LINK_HTML; - beforeEach(() => { - renderMarkdown.mockResolvedValue(markdownApiResult); + renderMarkdown.mockResolvedValue(markdownApiResult[attachmentFile.name]); }); describe('when uploading succeeds', () => { @@ -222,18 +246,20 @@ describe('content_editor/extensions/attachment', () => { mock.onPost().reply(HTTP_STATUS_OK, successResponse); }); - it('inserts a loading mark', async () => { - const expectedDoc = doc(p(loading({ label: 'test-file' }))); + it('inserts a link with a blob url', async () => { + const expectedDoc = doc( + p(link({ uploading: attachmentFile.name, href: blobUrl }, 'test-file.zip')), + ); await expectDocumentAfterTransaction({ + tiptapEditor, number: 1, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }), }); }); - it('updates the loading mark with a link with canonicalSrc and href attrs', async () => { - const [, group, project] = markdownApiResult.match(/\/(group[0-9]+)\/(project[0-9]+)\//); + it('updates the blob url link with an actual link with canonicalSrc and href attrs', async () => { const expectedDoc = doc( p( link( @@ -241,12 +267,13 @@ describe('content_editor/extensions/attachment', () => { canonicalSrc: 'test-file.zip', href: `/${group}/${project}/-/wikis/test-file.zip`, }, - 'test-file', + 'test-file.zip', ), ), ); await expectDocumentAfterTransaction({ + tiptapEditor, number: 2, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }), @@ -263,6 +290,7 @@ describe('content_editor/extensions/attachment', () => { const expectedDoc = doc(p('')); await expectDocumentAfterTransaction({ + tiptapEditor, number: 2, expectedDoc, action: () => tiptapEditor.commands.uploadAttachment({ file: attachmentFile }), @@ -279,5 +307,433 @@ describe('content_editor/extensions/attachment', () => { }); }); }); + + describe('uploading multiple files', () => { + const uploadMultipleFiles = () => { + const files = [ + attachmentFile, + imageFile, + videoFile, + attachmentFile1, + attachmentFile2, + videoFile1, + audioFile, + ]; + + for (const file of files) { + renderMarkdown.mockImplementation((markdown) => + Promise.resolve(markdownApiResult[markdown.match(/\((.+?)\)$/)[1]]), + ); + + mock + .onPost() + .replyOnce(HTTP_STATUS_OK, { link: { markdown: `![test-file](${file.name})` } }); + + tiptapEditor.commands.uploadAttachment({ file }); + } + }; + + it.each([ + [1, () => doc(p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')))], + [ + 2, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + ), + ], + [ + 3, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + ), + ], + [ + 4, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + ), + ], + [ + 5, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + ), + ], + [ + 6, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + ), + ], + [ + 7, + () => + doc( + p(link({ href: blobUrl, uploading: 'test-file.zip' }, 'test-file.zip')), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 8, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p(image({ alt: 'test-file.png', src: blobUrl, uploading: 'test-file.png' })), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 9, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p(video({ alt: 'test-file.mp4', src: blobUrl, uploading: 'test-file.mp4' })), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 10, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p( + video({ + alt: 'test-file.mp4', + src: blobUrl, + canonicalSrc: 'test-file.mp4', + uploading: false, + }), + ), + p(link({ href: blobUrl, uploading: 'test-file1.zip' }, 'test-file1.zip')), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 11, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p( + video({ + alt: 'test-file.mp4', + src: blobUrl, + canonicalSrc: 'test-file.mp4', + uploading: false, + }), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file1.zip`, + canonicalSrc: 'test-file1.zip', + uploading: false, + }, + 'test-file1.zip', + ), + ), + p(link({ href: blobUrl, uploading: 'test-file2.zip' }, 'test-file2.zip')), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 12, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p( + video({ + alt: 'test-file.mp4', + src: blobUrl, + canonicalSrc: 'test-file.mp4', + uploading: false, + }), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file1.zip`, + canonicalSrc: 'test-file1.zip', + uploading: false, + }, + 'test-file1.zip', + ), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file2.zip`, + canonicalSrc: 'test-file2.zip', + uploading: false, + }, + 'test-file2.zip', + ), + ), + p(video({ alt: 'test-file1.mp4', src: blobUrl, uploading: 'test-file1.mp4' })), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 13, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p( + video({ + alt: 'test-file.mp4', + src: blobUrl, + canonicalSrc: 'test-file.mp4', + uploading: false, + }), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file1.zip`, + canonicalSrc: 'test-file1.zip', + uploading: false, + }, + 'test-file1.zip', + ), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file2.zip`, + canonicalSrc: 'test-file2.zip', + uploading: false, + }, + 'test-file2.zip', + ), + ), + p( + video({ + alt: 'test-file1.mp4', + src: blobUrl, + canonicalSrc: 'test-file1.mp4', + uploading: false, + }), + ), + p(audio({ alt: 'test-file.mp3', src: blobUrl, uploading: 'test-file.mp3' })), + ), + ], + [ + 14, + () => + doc( + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file.zip`, + canonicalSrc: 'test-file.zip', + uploading: false, + }, + 'test-file.zip', + ), + ), + p( + image({ + alt: 'test-file.png', + src: blobUrl, + canonicalSrc: 'test-file.png', + uploading: false, + }), + ), + p( + video({ + alt: 'test-file.mp4', + src: blobUrl, + canonicalSrc: 'test-file.mp4', + uploading: false, + }), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file1.zip`, + canonicalSrc: 'test-file1.zip', + uploading: false, + }, + 'test-file1.zip', + ), + ), + p( + link( + { + href: `/${group}/${project}/-/wikis/test-file2.zip`, + canonicalSrc: 'test-file2.zip', + uploading: false, + }, + 'test-file2.zip', + ), + ), + p( + video({ + alt: 'test-file1.mp4', + src: blobUrl, + canonicalSrc: 'test-file1.mp4', + uploading: false, + }), + ), + p( + audio({ + alt: 'test-file.mp3', + src: blobUrl, + canonicalSrc: 'test-file.mp3', + uploading: false, + }), + ), + ), + ], + ])('uploads all files of mixed types successfully (tx %i)', async (n, document) => { + await expectDocumentAfterTransaction({ + tiptapEditor, + number: n, + expectedDoc: document(), + action: uploadMultipleFiles, + }); + }); + + it('cleans up the state if all uploads fail', async () => { + await expectDocumentAfterTransaction({ + tiptapEditor, + number: 14, + expectedDoc: doc(p(), p(), p(), p(), p(), p(), p()), + action: () => { + // Set max file size to 1 byte, our file is 3 bytes + gon.max_file_size = 1 / 1024 / 1024; + uploadMultipleFiles(); + }, + }); + }); + }); }); }); diff --git a/spec/frontend/content_editor/extensions/link_spec.js b/spec/frontend/content_editor/extensions/link_spec.js index ead898554d1..3c6f28f0c32 100644 --- a/spec/frontend/content_editor/extensions/link_spec.js +++ b/spec/frontend/content_editor/extensions/link_spec.js @@ -31,11 +31,6 @@ describe('content_editor/extensions/link', () => { ${'[link 123](read me.md)'} | ${() => p(link({ href: 'read me.md' }, 'link 123'))} ${'text'} | ${() => p('text')} ${'documentation](readme.md'} | ${() => p('documentation](readme.md')} - ${'http://example.com '} | ${() => p(link({ href: 'http://example.com' }, 'http://example.com'))} - ${'https://example.com '} | ${() => p(link({ href: 'https://example.com' }, 'https://example.com'))} - ${'www.example.com '} | ${() => p(link({ href: 'www.example.com' }, 'www.example.com'))} - ${'example.com/ab.html '} | ${() => p('example.com/ab.html')} - ${'https://www.google.com '} | ${() => p(link({ href: 'https://www.google.com' }, 'https://www.google.com'))} `('with input=$input, then should insert a $insertedNode', ({ input, insertedNode }) => { const expectedDoc = doc(insertedNode()); diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js index 506db4144fc..3729b303cc6 100644 --- a/spec/frontend/content_editor/services/markdown_serializer_spec.js +++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js @@ -281,17 +281,18 @@ hi ).toBe('![GitLab][gitlab-url]'); }); - it('omits image data urls when serializing', () => { + it.each` + src + ${'data:image/png;base64,iVBORw0KGgoAAAAN'} + ${'blob:https://gitlab.com/1234-5678-9012-3456'} + `('omits images with data/blob urls when serializing', ({ src }) => { + expect(serialize(paragraph(image({ src, alt: 'image' })))).toBe(''); + }); + + it('does not escape url in an image', () => { expect( - serialize( - paragraph( - image({ - src: 'data:image/png;base64,iVBORw0KGgoAAAAN', - alt: 'image', - }), - ), - ), - ).toBe('![image]()'); + serialize(paragraph(image({ src: 'https://example.com/image__1_.png', alt: 'image' }))), + ).toBe('![image](https://example.com/image__1_.png)'); }); it('correctly serializes strikethrough', () => { diff --git a/spec/frontend/content_editor/test_utils.js b/spec/frontend/content_editor/test_utils.js index 16f90a15c24..1f4a367e46c 100644 --- a/spec/frontend/content_editor/test_utils.js +++ b/spec/frontend/content_editor/test_utils.js @@ -5,6 +5,7 @@ import { Text } from '@tiptap/extension-text'; import { Editor } from '@tiptap/vue-2'; import { builders, eq } from 'prosemirror-test-builder'; import { nextTick } from 'vue'; +import waitForPromises from 'helpers/wait_for_promises'; import Audio from '~/content_editor/extensions/audio'; import Blockquote from '~/content_editor/extensions/blockquote'; import Bold from '~/content_editor/extensions/bold'; @@ -63,6 +64,12 @@ export const emitEditorEvent = ({ tiptapEditor, event, params = {} }) => { return nextTick(); }; +export const createTransactionWithMeta = (metaKey, metaValue) => { + return { + getMeta: (key) => (key === metaKey ? metaValue : null), + }; +}; + /** * Creates an instance of the Tiptap Editor class * with a minimal configuration for testing purposes. @@ -205,6 +212,24 @@ export const waitUntilNextDocTransaction = ({ tiptapEditor, action = () => {} }) }); }; +export const expectDocumentAfterTransaction = ({ tiptapEditor, number, expectedDoc, action }) => { + return new Promise((resolve) => { + let counter = 0; + const handleTransaction = async () => { + counter += 1; + if (counter === number) { + expect(tiptapEditor.state.doc.toJSON()).toEqual(expectedDoc.toJSON()); + tiptapEditor.off('update', handleTransaction); + await waitForPromises(); + resolve(); + } + }; + + tiptapEditor.on('update', handleTransaction); + action(); + }); +}; + export const createTiptapEditor = (extensions = []) => createTestEditor({ extensions: [ diff --git a/spec/frontend/diffs/utils/merge_request_spec.js b/spec/frontend/diffs/utils/merge_request_spec.js index 21599a3be45..11c0efb9a9c 100644 --- a/spec/frontend/diffs/utils/merge_request_spec.js +++ b/spec/frontend/diffs/utils/merge_request_spec.js @@ -8,7 +8,7 @@ import { diffMetadata } from '../mock_data/diff_metadata'; describe('Merge Request utilities', () => { const derivedBaseInfo = { mrPath: '/gitlab-org/gitlab-test/-/merge_requests/4', - userOrGroup: 'gitlab-org', + namespace: 'gitlab-org', project: 'gitlab-test', id: '4', }; @@ -22,7 +22,7 @@ describe('Merge Request utilities', () => { }; const unparseableEndpoint = { mrPath: undefined, - userOrGroup: undefined, + namespace: undefined, project: undefined, id: undefined, ...noVersion, @@ -79,29 +79,41 @@ describe('Merge Request utilities', () => { }); describe('getDerivedMergeRequestInformation', () => { - let endpoint = `${diffMetadata.latest_version_path}.json?searchParam=irrelevant`; + const bare = diffMetadata.latest_version_path; it.each` - argument | response - ${{ endpoint }} | ${{ ...derivedBaseInfo, ...noVersion }} - ${{}} | ${unparseableEndpoint} - ${{ endpoint: undefined }} | ${unparseableEndpoint} - ${{ endpoint: null }} | ${unparseableEndpoint} + argument | response + ${{ endpoint: `${bare}.json?searchParam=irrelevant` }} | ${{ ...derivedBaseInfo, ...noVersion }} + ${{}} | ${unparseableEndpoint} + ${{ endpoint: undefined }} | ${unparseableEndpoint} + ${{ endpoint: null }} | ${unparseableEndpoint} `('generates the correct derived results based on $argument', ({ argument, response }) => { expect(getDerivedMergeRequestInformation(argument)).toStrictEqual(response); }); - describe('version information', () => { - const bare = diffMetadata.latest_version_path; - endpoint = diffMetadata.merge_request_diffs[0].compare_path; + describe('sub-group namespace', () => { + it('extracts the entire namespace plus the project name', () => { + const { namespace, project } = getDerivedMergeRequestInformation({ + endpoint: `/some/deep/path/of/groups${bare}`, + }); + expect(namespace).toBe('some/deep/path/of/groups/gitlab-org'); + expect(project).toBe('gitlab-test'); + }); + }); + + describe('version information', () => { it('still gets the correct derived information', () => { - expect(getDerivedMergeRequestInformation({ endpoint })).toMatchObject(derivedBaseInfo); + expect( + getDerivedMergeRequestInformation({ + endpoint: diffMetadata.merge_request_diffs[0].compare_path, + }), + ).toMatchObject(derivedBaseInfo); }); it.each` url | versionPart - ${endpoint} | ${derivedVersionInfo} + ${diffMetadata.merge_request_diffs[0].compare_path} | ${derivedVersionInfo} ${`${bare}?diff_id=${derivedVersionInfo.diffId}`} | ${{ ...derivedVersionInfo, startSha: undefined }} ${`${bare}?start_sha=${derivedVersionInfo.startSha}`} | ${{ ...derivedVersionInfo, diffId: undefined }} `( diff --git a/spec/frontend/lib/utils/tappable_promise_spec.js b/spec/frontend/lib/utils/tappable_promise_spec.js new file mode 100644 index 00000000000..654cd20a9de --- /dev/null +++ b/spec/frontend/lib/utils/tappable_promise_spec.js @@ -0,0 +1,63 @@ +import TappablePromise from '~/lib/utils/tappable_promise'; + +describe('TappablePromise', () => { + it('allows a promise to have a progress indicator', () => { + const pseudoProgress = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]; + const progressCallback = jest.fn(); + const promise = new TappablePromise((tap, resolve) => { + pseudoProgress.forEach(tap); + resolve('done'); + + return 'returned value'; + }); + + return promise + .tap(progressCallback) + .then((val) => { + expect(val).toBe('done'); + expect(val).not.toBe('returned value'); + + expect(progressCallback).toHaveBeenCalledTimes(pseudoProgress.length); + + pseudoProgress.forEach((progress, index) => { + expect(progressCallback).toHaveBeenNthCalledWith(index + 1, progress); + }); + }) + .catch(() => {}); + }); + + it('resolves with the value returned by the callback', () => { + const promise = new TappablePromise((tap) => { + tap(0.5); + return 'test'; + }); + + return promise + .tap((progress) => { + expect(progress).toBe(0.5); + }) + .then((value) => { + expect(value).toBe('test'); + }); + }); + + it('allows a promise to be rejected', () => { + const promise = new TappablePromise((tap, resolve, reject) => { + reject(new Error('test error')); + }); + + return promise.catch((e) => { + expect(e.message).toBe('test error'); + }); + }); + + it('rejects the promise if the callback throws an error', () => { + const promise = new TappablePromise(() => { + throw new Error('test error'); + }); + + return promise.catch((e) => { + expect(e.message).toBe('test error'); + }); + }); +}); diff --git a/spec/frontend/monitoring/components/dashboard_header_spec.js b/spec/frontend/monitoring/components/dashboard_header_spec.js index ab259249772..e54b87c307c 100644 --- a/spec/frontend/monitoring/components/dashboard_header_spec.js +++ b/spec/frontend/monitoring/components/dashboard_header_spec.js @@ -9,12 +9,7 @@ import RefreshButton from '~/monitoring/components/refresh_button.vue'; import { createStore } from '~/monitoring/stores'; import * as types from '~/monitoring/stores/mutation_types'; import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue'; -import { - environmentData, - dashboardGitResponse, - selfMonitoringDashboardGitResponse, - dashboardHeaderProps, -} from '../mock_data'; +import { environmentData, dashboardGitResponse, dashboardHeaderProps } from '../mock_data'; import { setupAllDashboards, setupStoreWithDashboard, setupStoreWithData } from '../store_utils'; const mockProjectPath = 'https://path/to/project'; @@ -267,14 +262,8 @@ describe('Dashboard header', () => { }); describe('actions menu', () => { - const ootbDashboards = [ - dashboardGitResponse[0].path, - selfMonitoringDashboardGitResponse[0].path, - ]; - const customDashboards = [ - dashboardGitResponse[1].path, - selfMonitoringDashboardGitResponse[1].path, - ]; + const ootbDashboards = [dashboardGitResponse[0].path]; + const customDashboards = [dashboardGitResponse[1].path]; it('is rendered', () => { createShallowWrapper(); diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js index 00be5868ba3..1d23190e586 100644 --- a/spec/frontend/monitoring/mock_data.js +++ b/spec/frontend/monitoring/mock_data.js @@ -206,32 +206,6 @@ export const dashboardGitResponse = [ ...customDashboardsData, ]; -export const selfMonitoringDashboardGitResponse = [ - { - default: true, - display_name: 'Default', - can_edit: false, - system_dashboard: true, - out_of_the_box_dashboard: true, - project_blob_path: null, - path: 'config/prometheus/self_monitoring_default.yml', - starred: false, - user_starred_path: `${mockProjectDir}/metrics_user_starred_dashboards?dashboard_path=config/prometheus/self_monitoring_default.yml`, - }, - { - default: false, - display_name: 'dashboard.yml', - can_edit: true, - system_dashboard: false, - out_of_the_box_dashboard: false, - project_blob_path: `${mockProjectDir}/-/blob/main/.gitlab/dashboards/dashboard.yml`, - path: '.gitlab/dashboards/dashboard.yml', - starred: true, - user_starred_path: `${mockProjectDir}/metrics_user_starred_dashboards?dashboard_path=.gitlab/dashboards/dashboard.yml`, - }, - ...customDashboardsData, -]; - // Metrics mocks export const metricsResult = [ diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap index c8d972b19a3..17681c08dbd 100644 --- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap +++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap @@ -24,7 +24,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] = </div> <div - class="js-vue-markdown-field md-area position-relative gfm-form js-expanded" + class="js-vue-markdown-field md-area position-relative gfm-form gl-border-none! gl-shadow-none! js-expanded" data-uploads-path="" > <markdown-header-stub diff --git a/spec/frontend/work_items/components/work_item_description_spec.js b/spec/frontend/work_items/components/work_item_description_spec.js index b7877784a2d..62cbb1bacb6 100644 --- a/spec/frontend/work_items/components/work_item_description_spec.js +++ b/spec/frontend/work_items/components/work_item_description_spec.js @@ -303,12 +303,6 @@ describe('WorkItemDescription', () => { expect(workItemResponseHandler).toHaveBeenCalled(); }); - - it('skips calling the work item query when missing workItemIid', async () => { - await createComponent({ workItemIid: null }); - - expect(workItemResponseHandler).not.toHaveBeenCalled(); - }); }, ); }); |