diff options
Diffstat (limited to 'spec/frontend')
4 files changed, 132 insertions, 34 deletions
diff --git a/spec/frontend/behaviors/markdown/render_metrics_spec.js b/spec/frontend/behaviors/markdown/render_metrics_spec.js index 3f7beeb817b..ab81ed6b8f0 100644 --- a/spec/frontend/behaviors/markdown/render_metrics_spec.js +++ b/spec/frontend/behaviors/markdown/render_metrics_spec.js @@ -11,20 +11,20 @@ const getElements = () => Array.from(document.getElementsByClassName('js-render- describe('Render metrics for Gitlab Flavoured Markdown', () => { it('does nothing when no elements are found', () => { - renderMetrics([]); - - expect(mockEmbedGroup).not.toHaveBeenCalled(); + return renderMetrics([]).then(() => { + expect(mockEmbedGroup).not.toHaveBeenCalled(); + }); }); it('renders a vue component when elements are found', () => { document.body.innerHTML = `<div class="js-render-metrics" data-dashboard-url="${TEST_HOST}"></div>`; - renderMetrics(getElements()); - - expect(mockEmbedGroup).toHaveBeenCalledTimes(1); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}`] } }), - ); + return renderMetrics(getElements()).then(() => { + expect(mockEmbedGroup).toHaveBeenCalledTimes(1); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}`] } }), + ); + }); }); it('takes sibling metrics and groups them under a shared parent', () => { @@ -36,14 +36,14 @@ describe('Render metrics for Gitlab Flavoured Markdown', () => { <div class="js-render-metrics" data-dashboard-url="${TEST_HOST}/3"></div> `; - renderMetrics(getElements()); - - expect(mockEmbedGroup).toHaveBeenCalledTimes(2); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/1`, `${TEST_HOST}/2`] } }), - ); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/3`] } }), - ); + return renderMetrics(getElements()).then(() => { + expect(mockEmbedGroup).toHaveBeenCalledTimes(2); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/1`, `${TEST_HOST}/2`] } }), + ); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/3`] } }), + ); + }); }); }); diff --git a/spec/frontend/ide/stores/utils_spec.js b/spec/frontend/ide/stores/utils_spec.js index 90f2644de62..b87f6c1f05a 100644 --- a/spec/frontend/ide/stores/utils_spec.js +++ b/spec/frontend/ide/stores/utils_spec.js @@ -685,4 +685,75 @@ describe('Multi-file store utils', () => { }); }); }); + + describe('extractMarkdownImagesFromEntries', () => { + let mdFile; + let entries; + + beforeEach(() => { + const img = { content: '/base64/encoded/image+' }; + mdFile = { path: 'path/to/some/directory/myfile.md' }; + entries = { + // invalid (or lack of) extensions are also supported as long as there's + // a real image inside and can go into an <img> tag's `src` and the browser + // can render it + img, + 'img.js': img, + 'img.png': img, + 'img.with.many.dots.png': img, + 'path/to/img.gif': img, + 'path/to/some/img.jpg': img, + 'path/to/some/img 1/img.png': img, + 'path/to/some/directory/img.png': img, + 'path/to/some/directory/img 1.png': img, + }; + }); + + it.each` + markdownBefore | ext | imgAlt | imgTitle + ${'* ![img](/img)'} | ${'jpeg'} | ${'img'} | ${undefined} + ${'* ![img](/img.js)'} | ${'js'} | ${'img'} | ${undefined} + ${'* ![img](img.png)'} | ${'png'} | ${'img'} | ${undefined} + ${'* ![img](./img.png)'} | ${'png'} | ${'img'} | ${undefined} + ${'* ![with spaces](../img 1/img.png)'} | ${'png'} | ${'with spaces'} | ${undefined} + ${'* ![img](../../img.gif " title ")'} | ${'gif'} | ${'img'} | ${' title '} + ${'* ![img](../img.jpg)'} | ${'jpg'} | ${'img'} | ${undefined} + ${'* ![img](/img.png "title")'} | ${'png'} | ${'img'} | ${'title'} + ${'* ![img](/img.with.many.dots.png)'} | ${'png'} | ${'img'} | ${undefined} + ${'* ![img](img 1.png)'} | ${'png'} | ${'img'} | ${undefined} + ${'* ![img](img.png "title here")'} | ${'png'} | ${'img'} | ${'title here'} + `( + 'correctly transforms markdown with uncommitted images: $markdownBefore', + ({ markdownBefore, ext, imgAlt, imgTitle }) => { + mdFile.content = markdownBefore; + + expect(utils.extractMarkdownImagesFromEntries(mdFile, entries)).toEqual({ + content: '* {{gl_md_img_1}}', + images: { + '{{gl_md_img_1}}': { + src: `data:image/${ext};base64,/base64/encoded/image+`, + alt: imgAlt, + title: imgTitle, + }, + }, + }); + }, + ); + + it.each` + markdown + ${'* ![img](i.png)'} + ${'* ![img](img.png invalid title)'} + ${'* ![img](img.png "incorrect" "markdown")'} + ${'* ![img](https://gitlab.com/logo.png)'} + ${'* ![img](https://gitlab.com/some/deep/nested/path/logo.png)'} + `("doesn't touch invalid or non-existant images in markdown: $markdown", ({ markdown }) => { + mdFile.content = markdown; + + expect(utils.extractMarkdownImagesFromEntries(mdFile, entries)).toEqual({ + content: markdown, + images: {}, + }); + }); + }); }); diff --git a/spec/frontend/reports/accessibility_report/store/getters_spec.js b/spec/frontend/reports/accessibility_report/store/getters_spec.js index db8f48c067a..d74c71cfa09 100644 --- a/spec/frontend/reports/accessibility_report/store/getters_spec.js +++ b/spec/frontend/reports/accessibility_report/store/getters_spec.js @@ -115,39 +115,33 @@ describe('Accessibility reports store getters', () => { }); describe('unresolvedIssues', () => { - it('returns concatenated array of unresolved errors, warnings, and notes', () => { + it('returns the array unresolved errors', () => { localState.report = { existing_errors: [1], - existing_warnings: [2], - existing_notes: [3], }; - const result = [1, 2, 3]; + const result = [1]; expect(getters.unresolvedIssues(localState)).toEqual(result); }); }); describe('resolvedIssues', () => { - it('returns concatenated array of resolved errors, warnings, and notes', () => { + it('returns array of resolved errors', () => { localState.report = { resolved_errors: [1], - resolved_warnings: [2], - resolved_notes: [3], }; - const result = [1, 2, 3]; + const result = [1]; expect(getters.resolvedIssues(localState)).toEqual(result); }); }); describe('newIssues', () => { - it('returns concatenated array of new errors, warnings, and notes', () => { + it('returns array of new errors', () => { localState.report = { new_errors: [1], - new_warnings: [2], - new_notes: [3], }; - const result = [1, 2, 3]; + const result = [1]; expect(getters.newIssues(localState)).toEqual(result); }); diff --git a/spec/frontend/vue_shared/components/content_viewer/viewers/markdown_viewer_spec.js b/spec/frontend/vue_shared/components/content_viewer/viewers/markdown_viewer_spec.js index 587b9f07e53..8d3fcdd48d2 100644 --- a/spec/frontend/vue_shared/components/content_viewer/viewers/markdown_viewer_spec.js +++ b/spec/frontend/vue_shared/components/content_viewer/viewers/markdown_viewer_spec.js @@ -35,7 +35,7 @@ describe('MarkdownViewer', () => { describe('success', () => { beforeEach(() => { mock.onPost(`${gon.relative_url_root}/testproject/preview_markdown`).replyOnce(200, { - body: '<b>testing</b>', + body: '<b>testing</b> {{gl_md_img_1}}', }); }); @@ -53,15 +53,48 @@ describe('MarkdownViewer', () => { }); }); - it('receives the filePath as a parameter and passes it on to the server', () => { - createComponent({ filePath: 'foo/test.md' }); + it('receives the filePath and commitSha as a parameters and passes them on to the server', () => { + createComponent({ filePath: 'foo/test.md', commitSha: 'abcdef' }); expect(axios.post).toHaveBeenCalledWith( `${gon.relative_url_root}/testproject/preview_markdown`, - { path: 'foo/test.md', text: '* Test' }, + { path: 'foo/test.md', text: '* Test', ref: 'abcdef' }, expect.any(Object), ); }); + + it.each` + imgSrc | imgAlt + ${'data:image/jpeg;base64,AAAAAA+/'} | ${'my image title'} + ${'data:image/jpeg;base64,AAAAAA+/'} | ${'"somebody\'s image" &'} + ${'hack" onclick=alert(0)'} | ${'hack" onclick=alert(0)'} + ${'hack\\" onclick=alert(0)'} | ${'hack\\" onclick=alert(0)'} + ${"hack' onclick=alert(0)"} | ${"hack' onclick=alert(0)"} + ${"hack'><script>alert(0)</script>"} | ${"hack'><script>alert(0)</script>"} + `( + 'transforms template tags with base64 encoded images available locally', + ({ imgSrc, imgAlt }) => { + createComponent({ + images: { + '{{gl_md_img_1}}': { + src: imgSrc, + alt: imgAlt, + title: imgAlt, + }, + }, + }); + + return waitForPromises().then(() => { + const img = wrapper.find('.md-previewer img').element; + + // if the values are the same as the input, it means + // they were escaped correctly + expect(img).toHaveAttr('src', imgSrc); + expect(img).toHaveAttr('alt', imgAlt); + expect(img).toHaveAttr('title', imgAlt); + }); + }, + ); }); describe('error', () => { |