diff options
Diffstat (limited to 'spec/frontend/lib')
-rw-r--r-- | spec/frontend/lib/dompurify_spec.js | 46 | ||||
-rw-r--r-- | spec/frontend/lib/gfm/index_spec.js | 156 | ||||
-rw-r--r-- | spec/frontend/lib/utils/common_utils_spec.js | 23 | ||||
-rw-r--r-- | spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/lib/utils/rails_ujs_spec.js | 12 | ||||
-rw-r--r-- | spec/frontend/lib/utils/recurrence_spec.js | 5 | ||||
-rw-r--r-- | spec/frontend/lib/utils/sticky_spec.js | 6 | ||||
-rw-r--r-- | spec/frontend/lib/utils/text_markdown_spec.js | 136 | ||||
-rw-r--r-- | spec/frontend/lib/utils/url_utility_spec.js | 66 |
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); + }); + }); }); |