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>2023-08-31 06:10:52 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-31 06:10:52 +0300
commit2f3007bc70786204d82739e0775ad0f6707ddbc1 (patch)
treec4597f5283fca092d3e903cc43a508571fd96e24 /spec/frontend
parenta3df40b2c393e1540d237938240ee12d2774cd13 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/drawio/drawio_editor_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js69
2 files changed, 61 insertions, 13 deletions
diff --git a/spec/frontend/drawio/drawio_editor_spec.js b/spec/frontend/drawio/drawio_editor_spec.js
index 5a77b9d4689..0b863edc13b 100644
--- a/spec/frontend/drawio/drawio_editor_spec.js
+++ b/spec/frontend/drawio/drawio_editor_spec.js
@@ -5,6 +5,7 @@ import {
DRAWIO_IFRAME_TIMEOUT,
DIAGRAM_MAX_SIZE,
} from '~/drawio/constants';
+import { base64EncodeUnicode } from '~/lib/utils/text_utility';
import { createAlert, VARIANT_SUCCESS } from '~/alert';
const DRAWIO_EDITOR_URL =
@@ -19,8 +20,8 @@ describe('drawio/drawio_editor', () => {
let editorFacade;
let drawioIFrameReceivedMessages;
const diagramURL = `${window.location.origin}/uploads/diagram.drawio.svg`;
- const testSvg = '<svg></svg>';
- const testEncodedSvg = `data:image/svg+xml;base64,${btoa(testSvg)}`;
+ const testSvg = '<svg>😀</svg>';
+ const testEncodedSvg = `data:image/svg+xml;base64,${base64EncodeUnicode(testSvg)}`;
const filename = 'diagram.drawio.svg';
const findDrawioIframe = () => document.getElementById(DRAWIO_FRAME_ID);
diff --git a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
index fc8155bd381..6a3337aa046 100644
--- a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
@@ -3,6 +3,10 @@ import { shallowMount } from '@vue/test-utils';
import { handleBlobRichViewer } from '~/blob/viewer';
import RichViewer from '~/vue_shared/components/blob_viewers/rich_viewer.vue';
import MarkdownFieldView from '~/vue_shared/components/markdown/field_view.vue';
+import {
+ MARKUP_FILE_TYPE,
+ CONTENT_LOADED_EVENT,
+} from '~/vue_shared/components/blob_viewers/constants';
import { handleLocationHash } from '~/lib/utils/common_utils';
jest.mock('~/blob/viewer');
@@ -10,10 +14,10 @@ jest.mock('~/lib/utils/common_utils');
describe('Blob Rich Viewer component', () => {
let wrapper;
- const content = '<h1 id="markdown">Foo Bar</h1>';
+ const dummyContent = '<h1 id="markdown">Foo Bar</h1>';
const defaultType = 'markdown';
- function createComponent(type = defaultType, richViewer) {
+ function createComponent(type = defaultType, richViewer, content = dummyContent) {
wrapper = shallowMount(RichViewer, {
propsData: {
richViewer,
@@ -23,26 +27,69 @@ describe('Blob Rich Viewer component', () => {
});
}
- beforeEach(() => {
- const execImmediately = (callback) => callback();
- jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
+ beforeEach(() => createComponent());
- createComponent();
- });
+ describe('Markdown content', () => {
+ const generateDummyContent = (contentLength) => {
+ let generatedContent = '';
+ for (let i = 0; i < contentLength; i += 1) {
+ generatedContent += `<span>Line: ${i + 1}</span>\n`;
+ }
+
+ generatedContent += '<img src="x" onerror="alert(`XSS`)">'; // for testing against XSS
+ return `<div class="js-markup-content">${generatedContent}</div>`;
+ };
+
+ describe('Large file', () => {
+ const content = generateDummyContent(50);
+ beforeEach(() => createComponent(MARKUP_FILE_TYPE, null, content));
+
+ it('renders the top of the file immediately and does not emit a content loaded event', () => {
+ expect(wrapper.text()).toContain('Line: 10');
+ expect(wrapper.text()).not.toContain('Line: 50');
+ expect(wrapper.emitted(CONTENT_LOADED_EVENT)).toBeUndefined();
+ });
+
+ it('renders the rest of the file later and emits a content loaded event', () => {
+ jest.runAllTimers();
+
+ expect(wrapper.text()).toContain('Line: 10');
+ expect(wrapper.text()).toContain('Line: 50');
+ expect(wrapper.emitted(CONTENT_LOADED_EVENT)).toHaveLength(1);
+ });
- it('listens to requestIdleCallback', () => {
- expect(window.requestIdleCallback).toHaveBeenCalled();
+ it('sanitizes the content', () => {
+ jest.runAllTimers();
+
+ expect(wrapper.html()).toContain('<img src="x">');
+ });
+ });
+
+ describe('Small file', () => {
+ const content = generateDummyContent(5);
+ beforeEach(() => createComponent(MARKUP_FILE_TYPE, null, content));
+
+ it('renders the entire file immediately and emits a content loaded event', () => {
+ expect(wrapper.text()).toContain('Line: 5');
+ expect(wrapper.emitted(CONTENT_LOADED_EVENT)).toHaveLength(1);
+ });
+
+ it('sanitizes the content', () => {
+ expect(wrapper.html()).toContain('<img src="x">');
+ });
+ });
});
it('renders the passed content without transformations', () => {
- expect(wrapper.html()).toContain(content);
+ expect(wrapper.html()).toContain(dummyContent);
});
- it('renders the richViewer if one is present', async () => {
+ it('renders the richViewer if one is present and emits a content loaded event', async () => {
const richViewer = '<div class="js-pdf-viewer"></div>';
createComponent('pdf', richViewer);
await nextTick();
expect(wrapper.html()).toContain(richViewer);
+ expect(wrapper.emitted(CONTENT_LOADED_EVENT)).toHaveLength(1);
});
it('queries for advanced viewer', () => {