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>2022-08-18 11:17:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 11:17:02 +0300
commitb39512ed755239198a9c294b6a45e65c05900235 (patch)
treed234a3efade1de67c46b9e5a38ce813627726aa7 /spec/frontend/lib
parentd31474cf3b17ece37939d20082b07f6657cc79a9 (diff)
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'spec/frontend/lib')
-rw-r--r--spec/frontend/lib/dompurify_spec.js46
-rw-r--r--spec/frontend/lib/gfm/index_spec.js156
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js23
-rw-r--r--spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js4
-rw-r--r--spec/frontend/lib/utils/rails_ujs_spec.js12
-rw-r--r--spec/frontend/lib/utils/recurrence_spec.js5
-rw-r--r--spec/frontend/lib/utils/sticky_spec.js6
-rw-r--r--spec/frontend/lib/utils/text_markdown_spec.js136
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js66
9 files changed, 397 insertions, 57 deletions
diff --git a/spec/frontend/lib/dompurify_spec.js b/spec/frontend/lib/dompurify_spec.js
index b585c69e911..29b927ef628 100644
--- a/spec/frontend/lib/dompurify_spec.js
+++ b/spec/frontend/lib/dompurify_spec.js
@@ -173,4 +173,50 @@ describe('~/lib/dompurify', () => {
expect(sanitize(html)).toBe(`<a>internal link</a>`);
});
});
+
+ describe('links with target attribute', () => {
+ const getSanitizedNode = (html) => {
+ return document.createRange().createContextualFragment(sanitize(html)).firstElementChild;
+ };
+
+ it('adds secure context', () => {
+ const html = `<a href="https://example.com" target="_blank">link</a>`;
+ const el = getSanitizedNode(html);
+
+ expect(el.getAttribute('target')).toBe('_blank');
+ expect(el.getAttribute('rel')).toBe('noopener noreferrer');
+ });
+
+ it('adds secure context and merge existing `rel` values', () => {
+ const html = `<a href="https://example.com" target="_blank" rel="help External">link</a>`;
+ const el = getSanitizedNode(html);
+
+ expect(el.getAttribute('target')).toBe('_blank');
+ expect(el.getAttribute('rel')).toBe('help external noopener noreferrer');
+ });
+
+ it('does not duplicate noopener/noreferrer `rel` values', () => {
+ const html = `<a href="https://example.com" target="_blank" rel="noreferrer noopener">link</a>`;
+ const el = getSanitizedNode(html);
+
+ expect(el.getAttribute('target')).toBe('_blank');
+ expect(el.getAttribute('rel')).toBe('noreferrer noopener');
+ });
+
+ it('does not update `rel` values when target is not `_blank` ', () => {
+ const html = `<a href="https://example.com" target="_self" rel="help">internal</a>`;
+ const el = getSanitizedNode(html);
+
+ expect(el.getAttribute('target')).toBe('_self');
+ expect(el.getAttribute('rel')).toBe('help');
+ });
+
+ it('does not update `rel` values when target attribute is not present', () => {
+ const html = `<a href="https://example.com">link</a>`;
+ const el = getSanitizedNode(html);
+
+ expect(el.hasAttribute('target')).toBe(false);
+ expect(el.hasAttribute('rel')).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/lib/gfm/index_spec.js b/spec/frontend/lib/gfm/index_spec.js
index b722315d63a..f53f809b799 100644
--- a/spec/frontend/lib/gfm/index_spec.js
+++ b/spec/frontend/lib/gfm/index_spec.js
@@ -96,26 +96,164 @@ describe('gfm', () => {
);
});
});
- });
- describe('when skipping the rendering of code blocks', () => {
- it('transforms code nodes into codeblock html tags', async () => {
- const result = await markdownToAST(
- `
+ describe('when skipping the rendering of code blocks', () => {
+ it('transforms code nodes into codeblock html tags', async () => {
+ const result = await markdownToAST(
+ `
\`\`\`javascript
console.log('Hola');
\`\`\`\
`,
- ['code'],
- );
+ ['code'],
+ );
+
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ tagName: 'codeblock',
+ properties: {
+ language: 'javascript',
+ },
+ }),
+ );
+ });
+ });
+
+ describe('when skipping the rendering of reference definitions', () => {
+ it('transforms code nodes into codeblock html tags', async () => {
+ const result = await markdownToAST(
+ `
+[gitlab][gitlab]
+
+[gitlab]: https://gitlab.com "GitLab"
+ `,
+ ['definition'],
+ );
+
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'referencedefinition',
+ properties: {
+ identifier: 'gitlab',
+ title: 'GitLab',
+ url: 'https://gitlab.com',
+ },
+ children: [
+ {
+ type: 'text',
+ value: '[gitlab]: https://gitlab.com "GitLab"',
+ },
+ ],
+ }),
+ );
+ });
+ });
+
+ describe('when skipping the rendering of link and image references', () => {
+ it('transforms linkReference and imageReference nodes into html tags', async () => {
+ const result = await markdownToAST(
+ `
+[gitlab][gitlab] and ![GitLab Logo][gitlab-logo]
+
+[gitlab]: https://gitlab.com "GitLab"
+[gitlab-logo]: https://gitlab.com/gitlab-logo.png "GitLab Logo"
+ `,
+ ['linkReference', 'imageReference'],
+ );
+
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ tagName: 'p',
+ children: expect.arrayContaining([
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'a',
+ properties: expect.objectContaining({
+ href: 'https://gitlab.com',
+ isReference: 'true',
+ identifier: 'gitlab',
+ title: 'GitLab',
+ }),
+ }),
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'img',
+ properties: expect.objectContaining({
+ src: 'https://gitlab.com/gitlab-logo.png',
+ isReference: 'true',
+ identifier: 'gitlab-logo',
+ title: 'GitLab Logo',
+ alt: 'GitLab Logo',
+ }),
+ }),
+ ]),
+ }),
+ );
+ });
+
+ it('normalizes the urls extracted from the reference definitions', async () => {
+ const result = await markdownToAST(
+ `
+[gitlab][gitlab] and ![GitLab Logo][gitlab]
+
+[gitlab]: /url\\bar*baz
+ `,
+ ['linkReference', 'imageReference'],
+ );
+
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ tagName: 'p',
+ children: expect.arrayContaining([
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'a',
+ properties: expect.objectContaining({
+ href: '/url%5Cbar*baz',
+ }),
+ }),
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'img',
+ properties: expect.objectContaining({
+ src: '/url%5Cbar*baz',
+ }),
+ }),
+ ]),
+ }),
+ );
+ });
+ });
+ });
+
+ describe('when skipping the rendering of frontmatter types', () => {
+ it.each`
+ type | input
+ ${'yaml'} | ${'---\ntitle: page\n---'}
+ ${'toml'} | ${'+++\ntitle: page\n+++'}
+ ${'json'} | ${';;;\ntitle: page\n;;;'}
+ `('transforms $type nodes into frontmatter html tags', async ({ input, type }) => {
+ const result = await markdownToAST(input, [type]);
expectInRoot(
result,
expect.objectContaining({
- tagName: 'codeblock',
+ type: 'element',
+ tagName: 'frontmatter',
properties: {
- language: 'javascript',
+ language: type,
},
+ children: [
+ {
+ type: 'text',
+ value: 'title: page',
+ },
+ ],
}),
);
});
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
index 7cf101a5e59..a2ace8857ed 100644
--- a/spec/frontend/lib/utils/common_utils_spec.js
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -292,16 +292,11 @@ describe('common_utils', () => {
const spy = jest.fn();
const debouncedSpy = commonUtils.debounceByAnimationFrame(spy);
- return new Promise((resolve) => {
- window.requestAnimationFrame(() => {
- debouncedSpy();
- debouncedSpy();
- window.requestAnimationFrame(() => {
- expect(spy).toHaveBeenCalledTimes(1);
- resolve();
- });
- });
- });
+ debouncedSpy();
+ debouncedSpy();
+ jest.runOnlyPendingTimers();
+
+ expect(spy).toHaveBeenCalledTimes(1);
});
});
@@ -633,7 +628,7 @@ describe('common_utils', () => {
it('returns an empty object if `conversionFunction` parameter is not a function', () => {
const result = commonUtils.convertObjectProps(null, mockObjects.convertObjectProps.obj);
- expect(isEmptyObject(result)).toBeTruthy();
+ expect(isEmptyObject(result)).toBe(true);
});
});
@@ -650,9 +645,9 @@ describe('common_utils', () => {
: commonUtils[functionName];
it('returns an empty object if `obj` parameter is null, undefined or an empty object', () => {
- expect(isEmptyObject(testFunction(null))).toBeTruthy();
- expect(isEmptyObject(testFunction())).toBeTruthy();
- expect(isEmptyObject(testFunction({}))).toBeTruthy();
+ expect(isEmptyObject(testFunction(null))).toBe(true);
+ expect(isEmptyObject(testFunction())).toBe(true);
+ expect(isEmptyObject(testFunction({}))).toBe(true);
});
it('converts object properties', () => {
diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js
index d6131b1a1d7..313e028d861 100644
--- a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js
+++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js
@@ -42,12 +42,12 @@ describe('Confirm Modal', () => {
it('should emit `confirmed` event on `primary` modal event', () => {
findGlModal().vm.$emit('primary');
- expect(wrapper.emitted('confirmed')).toBeTruthy();
+ expect(wrapper.emitted('confirmed')).toHaveLength(1);
});
it('should emit closed` event on `hidden` modal event', () => {
modal.vm.$emit('hidden');
- expect(wrapper.emitted('closed')).toBeTruthy();
+ expect(wrapper.emitted('closed')).toHaveLength(1);
});
});
diff --git a/spec/frontend/lib/utils/rails_ujs_spec.js b/spec/frontend/lib/utils/rails_ujs_spec.js
index c10301523c9..da9cc5c6f3c 100644
--- a/spec/frontend/lib/utils/rails_ujs_spec.js
+++ b/spec/frontend/lib/utils/rails_ujs_spec.js
@@ -18,14 +18,12 @@ function mockXHRResponse({ responseText, responseContentType } = {}) {
.mockReturnValue(responseContentType);
jest.spyOn(global.XMLHttpRequest.prototype, 'send').mockImplementation(function send() {
- requestAnimationFrame(() => {
- Object.defineProperties(this, {
- readyState: { value: XMLHttpRequest.DONE },
- status: { value: 200 },
- response: { value: responseText },
- });
- this.onreadystatechange();
+ Object.defineProperties(this, {
+ readyState: { value: XMLHttpRequest.DONE },
+ status: { value: 200 },
+ response: { value: responseText },
});
+ this.onreadystatechange();
});
}
diff --git a/spec/frontend/lib/utils/recurrence_spec.js b/spec/frontend/lib/utils/recurrence_spec.js
index fc22529dffc..8bf3ea4e25a 100644
--- a/spec/frontend/lib/utils/recurrence_spec.js
+++ b/spec/frontend/lib/utils/recurrence_spec.js
@@ -211,9 +211,10 @@ describe('recurrence', () => {
describe('eject', () => {
it('removes the handler assigned to the particular count slot', () => {
- recurInstance.handle(1, jest.fn());
+ const func = jest.fn();
+ recurInstance.handle(1, func);
- expect(recurInstance.handlers[1]).toBeTruthy();
+ expect(recurInstance.handlers[1]).toStrictEqual(func);
recurInstance.eject(1);
diff --git a/spec/frontend/lib/utils/sticky_spec.js b/spec/frontend/lib/utils/sticky_spec.js
index 01e8fe777af..ec9e746c838 100644
--- a/spec/frontend/lib/utils/sticky_spec.js
+++ b/spec/frontend/lib/utils/sticky_spec.js
@@ -34,13 +34,13 @@ describe('sticky', () => {
isSticky(el, 0, el.offsetTop);
isSticky(el, 0, el.offsetTop);
- expect(el.classList.contains('is-stuck')).toBeTruthy();
+ expect(el.classList.contains('is-stuck')).toBe(true);
});
it('adds is-stuck class', () => {
isSticky(el, 0, el.offsetTop);
- expect(el.classList.contains('is-stuck')).toBeTruthy();
+ expect(el.classList.contains('is-stuck')).toBe(true);
});
it('inserts placeholder element', () => {
@@ -64,7 +64,7 @@ describe('sticky', () => {
it('does not add is-stuck class', () => {
isSticky(el, 0, 0);
- expect(el.classList.contains('is-stuck')).toBeFalsy();
+ expect(el.classList.contains('is-stuck')).toBe(false);
});
it('removes placeholder', () => {
diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js
index d1bca3c73b6..733d89fe08c 100644
--- a/spec/frontend/lib/utils/text_markdown_spec.js
+++ b/spec/frontend/lib/utils/text_markdown_spec.js
@@ -193,6 +193,7 @@ describe('init markdown', () => {
${'- [ ] item'} | ${'- [ ] item\n- [ ] '}
${'- [x] item'} | ${'- [x] item\n- [ ] '}
${'- [X] item'} | ${'- [X] item\n- [ ] '}
+ ${'- [~] item'} | ${'- [~] item\n- [ ] '}
${'- [ ] nbsp (U+00A0)'} | ${'- [ ] nbsp (U+00A0)\n- [ ] '}
${'- item\n - second'} | ${'- item\n - second\n - '}
${'- - -'} | ${'- - -'}
@@ -205,6 +206,7 @@ describe('init markdown', () => {
${'1. [ ] item'} | ${'1. [ ] item\n2. [ ] '}
${'1. [x] item'} | ${'1. [x] item\n2. [ ] '}
${'1. [X] item'} | ${'1. [X] item\n2. [ ] '}
+ ${'1. [~] item'} | ${'1. [~] item\n2. [ ] '}
${'108. item'} | ${'108. item\n109. '}
${'108. item\n - second'} | ${'108. item\n - second\n - '}
${'108. item\n 1. second'} | ${'108. item\n 1. second\n 2. '}
@@ -228,11 +230,13 @@ describe('init markdown', () => {
${'- [ ] item\n- [ ] '} | ${'- [ ] item\n'}
${'- [x] item\n- [x] '} | ${'- [x] item\n'}
${'- [X] item\n- [X] '} | ${'- [X] item\n'}
+ ${'- [~] item\n- [~] '} | ${'- [~] item\n'}
${'- item\n - second\n - '} | ${'- item\n - second\n'}
${'1. item\n2. '} | ${'1. item\n'}
${'1. [ ] item\n2. [ ] '} | ${'1. [ ] item\n'}
${'1. [x] item\n2. [x] '} | ${'1. [x] item\n'}
${'1. [X] item\n2. [X] '} | ${'1. [X] item\n'}
+ ${'1. [~] item\n2. [~] '} | ${'1. [~] item\n'}
${'108. item\n109. '} | ${'108. item\n'}
${'108. item\n - second\n - '} | ${'108. item\n - second\n'}
${'108. item\n 1. second\n 1. '} | ${'108. item\n 1. second\n'}
@@ -301,6 +305,129 @@ describe('init markdown', () => {
});
});
+ describe('shifting selected lines left or right', () => {
+ const indentEvent = new KeyboardEvent('keydown', { key: ']', metaKey: true });
+ const outdentEvent = new KeyboardEvent('keydown', { key: '[', metaKey: true });
+
+ beforeEach(() => {
+ textArea.addEventListener('keydown', keypressNoteText);
+ textArea.addEventListener('compositionstart', compositionStartNoteText);
+ textArea.addEventListener('compositionend', compositionEndNoteText);
+ });
+
+ it.each`
+ selectionStart | selectionEnd | expected | expectedSelectionStart | expectedSelectionEnd
+ ${0} | ${0} | ${' 012\n456\n89'} | ${2} | ${2}
+ ${5} | ${5} | ${'012\n 456\n89'} | ${7} | ${7}
+ ${10} | ${10} | ${'012\n456\n 89'} | ${12} | ${12}
+ ${0} | ${2} | ${' 012\n456\n89'} | ${0} | ${4}
+ ${1} | ${2} | ${' 012\n456\n89'} | ${3} | ${4}
+ ${5} | ${7} | ${'012\n 456\n89'} | ${7} | ${9}
+ ${0} | ${7} | ${' 012\n 456\n89'} | ${0} | ${11}
+ ${2} | ${9} | ${' 012\n 456\n 89'} | ${4} | ${15}
+ `(
+ 'indents the selected lines two spaces to the right',
+ ({
+ selectionStart,
+ selectionEnd,
+ expected,
+ expectedSelectionStart,
+ expectedSelectionEnd,
+ }) => {
+ const text = '012\n456\n89';
+ textArea.value = text;
+ textArea.setSelectionRange(selectionStart, selectionEnd);
+
+ textArea.dispatchEvent(indentEvent);
+
+ expect(textArea.value).toEqual(expected);
+ expect(textArea.selectionStart).toEqual(expectedSelectionStart);
+ expect(textArea.selectionEnd).toEqual(expectedSelectionEnd);
+ },
+ );
+
+ it('indents a blank line two spaces to the right', () => {
+ textArea.value = '012\n\n89';
+ textArea.setSelectionRange(4, 4);
+
+ textArea.dispatchEvent(indentEvent);
+
+ expect(textArea.value).toEqual('012\n \n89');
+ expect(textArea.selectionStart).toEqual(6);
+ expect(textArea.selectionEnd).toEqual(6);
+ });
+
+ it.each`
+ selectionStart | selectionEnd | expected | expectedSelectionStart | expectedSelectionEnd
+ ${0} | ${0} | ${'234\n 789\n 34'} | ${0} | ${0}
+ ${3} | ${3} | ${'234\n 789\n 34'} | ${1} | ${1}
+ ${7} | ${7} | ${' 234\n789\n 34'} | ${6} | ${6}
+ ${0} | ${3} | ${'234\n 789\n 34'} | ${0} | ${1}
+ ${8} | ${10} | ${' 234\n789\n 34'} | ${7} | ${9}
+ ${14} | ${15} | ${' 234\n 789\n34'} | ${12} | ${13}
+ ${0} | ${15} | ${'234\n789\n34'} | ${0} | ${10}
+ ${3} | ${13} | ${'234\n789\n34'} | ${1} | ${8}
+ ${6} | ${6} | ${' 234\n789\n 34'} | ${6} | ${6}
+ `(
+ 'outdents the selected lines two spaces to the left',
+ ({
+ selectionStart,
+ selectionEnd,
+ expected,
+ expectedSelectionStart,
+ expectedSelectionEnd,
+ }) => {
+ const text = ' 234\n 789\n 34';
+ textArea.value = text;
+ textArea.setSelectionRange(selectionStart, selectionEnd);
+
+ textArea.dispatchEvent(outdentEvent);
+
+ expect(textArea.value).toEqual(expected);
+ expect(textArea.selectionStart).toEqual(expectedSelectionStart);
+ expect(textArea.selectionEnd).toEqual(expectedSelectionEnd);
+ },
+ );
+
+ it('outdent a blank line has no effect', () => {
+ textArea.value = '012\n\n89';
+ textArea.setSelectionRange(4, 4);
+
+ textArea.dispatchEvent(outdentEvent);
+
+ expect(textArea.value).toEqual('012\n\n89');
+ expect(textArea.selectionStart).toEqual(4);
+ expect(textArea.selectionEnd).toEqual(4);
+ });
+
+ it('does not indent if meta is not set', () => {
+ const indentNoMetaEvent = new KeyboardEvent('keydown', { key: ']' });
+ const text = '012\n456\n89';
+ textArea.value = text;
+ textArea.setSelectionRange(0, 0);
+
+ textArea.dispatchEvent(indentNoMetaEvent);
+
+ expect(textArea.value).toEqual(text);
+ });
+
+ it.each`
+ keyEvent
+ ${new KeyboardEvent('keydown', { key: ']', metaKey: false })}
+ ${new KeyboardEvent('keydown', { key: ']', metaKey: true, shiftKey: true })}
+ ${new KeyboardEvent('keydown', { key: ']', metaKey: true, altKey: true })}
+ ${new KeyboardEvent('keydown', { key: ']', metaKey: true, ctrlKey: true })}
+ `('does not indent if meta is not set', ({ keyEvent }) => {
+ const text = '012\n456\n89';
+ textArea.value = text;
+ textArea.setSelectionRange(0, 0);
+
+ textArea.dispatchEvent(keyEvent);
+
+ expect(textArea.value).toEqual(text);
+ });
+ });
+
describe('with selection', () => {
let text = 'initial selected value';
let selected = 'selected';
@@ -377,6 +504,15 @@ describe('init markdown', () => {
expect(textArea.value).toEqual(text);
});
+
+ it('does nothing if meta is set', () => {
+ const event = new KeyboardEvent('keydown', { key: '[', metaKey: true });
+
+ textArea.addEventListener('keydown', keypressNoteText);
+ textArea.dispatchEvent(event);
+
+ expect(textArea.value).toEqual(text);
+ });
});
describe('and text to be selected', () => {
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index 81cf4bd293b..2c6b603197d 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -348,15 +348,13 @@ describe('URL utility', () => {
describe('urlContainsSha', () => {
it('returns true when there is a valid 40-character SHA1 hash in the URL', () => {
shas.valid.forEach((sha) => {
- expect(
- urlUtils.urlContainsSha({ url: `http://urlstuff/${sha}/moreurlstuff` }),
- ).toBeTruthy();
+ expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${sha}/moreurlstuff` })).toBe(true);
});
});
it('returns false when there is not a valid 40-character SHA1 hash in the URL', () => {
shas.invalid.forEach((str) => {
- expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${str}/moreurlstuff` })).toBeFalsy();
+ expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${str}/moreurlstuff` })).toBe(false);
});
});
});
@@ -555,18 +553,22 @@ describe('URL utility', () => {
describe('relativePathToAbsolute', () => {
it.each`
- path | base | result
- ${'./foo'} | ${'bar/'} | ${'/bar/foo'}
- ${'../john.md'} | ${'bar/baz/foo.php'} | ${'/bar/john.md'}
- ${'../images/img.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/img.png'}
- ${'../images/Image 1.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/Image 1.png'}
- ${'/images/img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'}
- ${'/images/img.png'} | ${'/bar/baz/foo.php'} | ${'/images/img.png'}
- ${'../john.md'} | ${'/bar/baz/foo.php'} | ${'/bar/john.md'}
- ${'../john.md'} | ${'///bar/baz/foo.php'} | ${'/bar/john.md'}
- ${'/images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'}
- ${'../images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/img.png'}
- ${'../images/Image 1.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/Image%201.png'}
+ path | base | result
+ ${'./foo'} | ${'bar/'} | ${'/bar/foo'}
+ ${'../john.md'} | ${'bar/baz/foo.php'} | ${'/bar/john.md'}
+ ${'../images/img.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/img.png'}
+ ${'../images/Image 1.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/Image 1.png'}
+ ${'/images/img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'}
+ ${'/images/img.png'} | ${'bar/baz//foo.php'} | ${'/images/img.png'}
+ ${'/images//img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'}
+ ${'/images/img.png'} | ${'/bar/baz/foo.php'} | ${'/images/img.png'}
+ ${'../john.md'} | ${'/bar/baz/foo.php'} | ${'/bar/john.md'}
+ ${'../john.md'} | ${'///bar/baz/foo.php'} | ${'/bar/john.md'}
+ ${'/images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'}
+ ${'/images/img.png'} | ${'https://gitlab.com////user/project/'} | ${'https://gitlab.com/images/img.png'}
+ ${'/images////img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'}
+ ${'../images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/img.png'}
+ ${'../images/Image 1.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/Image%201.png'}
`(
'converts relative path "$path" with base "$base" to absolute path => "expected"',
({ path, base, result }) => {
@@ -809,13 +811,13 @@ describe('URL utility', () => {
});
it('should compare against the window location if no compare value is provided', () => {
- expect(urlUtils.urlIsDifferent('different')).toBeTruthy();
- expect(urlUtils.urlIsDifferent(current)).toBeFalsy();
+ expect(urlUtils.urlIsDifferent('different')).toBe(true);
+ expect(urlUtils.urlIsDifferent(current)).toBe(false);
});
it('should use the provided compare value', () => {
- expect(urlUtils.urlIsDifferent('different', current)).toBeTruthy();
- expect(urlUtils.urlIsDifferent(current, current)).toBeFalsy();
+ expect(urlUtils.urlIsDifferent('different', current)).toBe(true);
+ expect(urlUtils.urlIsDifferent(current, current)).toBe(false);
});
});
@@ -1058,4 +1060,28 @@ describe('URL utility', () => {
expect(urlUtils.PROMO_URL).toBe(url);
});
});
+
+ describe('removeUrlProtocol', () => {
+ it.each`
+ input | output
+ ${'http://gitlab.com'} | ${'gitlab.com'}
+ ${'https://gitlab.com'} | ${'gitlab.com'}
+ ${'foo:bar.com'} | ${'bar.com'}
+ ${'gitlab.com'} | ${'gitlab.com'}
+ `('transforms $input to $output', ({ input, output }) => {
+ expect(urlUtils.removeUrlProtocol(input)).toBe(output);
+ });
+ });
+
+ describe('removeLastSlashInUrlPath', () => {
+ it.each`
+ input | output
+ ${'https://www.gitlab.com/path/'} | ${'https://www.gitlab.com/path'}
+ ${'https://www.gitlab.com/?query=search'} | ${'https://www.gitlab.com?query=search'}
+ ${'https://www.gitlab.com/#fragment'} | ${'https://www.gitlab.com#fragment'}
+ ${'https://www.gitlab.com/hello'} | ${'https://www.gitlab.com/hello'}
+ `('transforms $input to $output', ({ input, output }) => {
+ expect(urlUtils.removeLastSlashInUrlPath(input)).toBe(output);
+ });
+ });
});