diff options
Diffstat (limited to 'spec/frontend/lib')
-rw-r--r-- | spec/frontend/lib/dompurify_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/gfm/index_spec.js | 376 | ||||
-rw-r--r-- | spec/frontend/lib/utils/apollo_startup_js_link_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/common_utils_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js | 18 | ||||
-rw-r--r-- | spec/frontend/lib/utils/finite_state_machine_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/lib/utils/is_navigating_away_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/navigation_utility_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/poll_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/lib/utils/text_markdown_spec.js | 27 | ||||
-rw-r--r-- | spec/frontend/lib/utils/text_utility_spec.js | 35 | ||||
-rw-r--r-- | spec/frontend/lib/utils/vuex_module_mappers_spec.js | 2 |
12 files changed, 279 insertions, 197 deletions
diff --git a/spec/frontend/lib/dompurify_spec.js b/spec/frontend/lib/dompurify_spec.js index 29b927ef628..5523cc0606e 100644 --- a/spec/frontend/lib/dompurify_spec.js +++ b/spec/frontend/lib/dompurify_spec.js @@ -203,7 +203,7 @@ describe('~/lib/dompurify', () => { expect(el.getAttribute('rel')).toBe('noreferrer noopener'); }); - it('does not update `rel` values when target is not `_blank` ', () => { + 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); diff --git a/spec/frontend/lib/gfm/index_spec.js b/spec/frontend/lib/gfm/index_spec.js index f53f809b799..7c383ae68a4 100644 --- a/spec/frontend/lib/gfm/index_spec.js +++ b/spec/frontend/lib/gfm/index_spec.js @@ -24,12 +24,6 @@ describe('gfm', () => { }; describe('render', () => { - it('processes Commonmark and provides an ast to the renderer function', async () => { - const result = await markdownToAST('This is text'); - - expect(result.type).toBe('root'); - }); - it('transforms raw HTML into individual nodes in the AST', async () => { const result = await markdownToAST('<strong>This is bold text</strong>'); @@ -46,216 +40,270 @@ describe('gfm', () => { ); }); - it('returns the result of executing the renderer function', async () => { - const rendered = { value: 'rendered tree' }; + describe('with custom renderer', () => { + it('processes Commonmark and provides an ast to the renderer function', async () => { + const result = await markdownToAST('This is text'); - const result = await render({ - markdown: '<strong>This is bold text</strong>', - renderer: () => { - return rendered; - }, + expect(result.type).toBe('root'); }); - expect(result).toEqual(rendered); + it('returns the result of executing the renderer function', async () => { + const rendered = { value: 'rendered tree' }; + + const result = await render({ + markdown: '<strong>This is bold text</strong>', + renderer: () => { + return rendered; + }, + }); + + expect(result).toEqual(rendered); + }); }); - describe('when skipping the rendering of footnote reference and definition nodes', () => { - it('transforms footnotes into footnotedefinition and footnotereference tags', async () => { - const result = await markdownToAST( - `footnote reference [^footnote] + describe('footnote references and footnote definitions', () => { + describe('when skipping the rendering of footnote reference and definition nodes', () => { + it('transforms footnotes into footnotedefinition and footnotereference tags', async () => { + const result = await markdownToAST( + `footnote reference [^footnote] [^footnote]: Footnote definition`, - ['footnoteReference', 'footnoteDefinition'], - ); + ['footnoteReference', 'footnoteDefinition'], + ); - expectInRoot( - result, - expect.objectContaining({ - children: expect.arrayContaining([ - expect.objectContaining({ - type: 'element', - tagName: 'footnotereference', - properties: { - identifier: 'footnote', - label: 'footnote', - }, - }), - ]), - }), - ); + expectInRoot( + result, + expect.objectContaining({ + children: expect.arrayContaining([ + expect.objectContaining({ + type: 'element', + tagName: 'footnotereference', + properties: { + identifier: 'footnote', + label: 'footnote', + }, + }), + ]), + }), + ); - expectInRoot( - result, - expect.objectContaining({ - tagName: 'footnotedefinition', - properties: { - identifier: 'footnote', - label: 'footnote', - }, - }), - ); + expectInRoot( + result, + expect.objectContaining({ + tagName: 'footnotedefinition', + properties: { + identifier: 'footnote', + label: 'footnote', + }, + }), + ); + }); }); }); - describe('when skipping the rendering of code blocks', () => { - it('transforms code nodes into codeblock html tags', async () => { - const result = await markdownToAST( - ` + describe('code blocks', () => { + 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', - }, - }), - ); + 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( - ` + describe('reference definitions', () => { + 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'], - ); + ['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"', + 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( - ` + describe('link and image references', () => { + 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'], - ); + ['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', + 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', + 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( - ` + 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'], - ); + ['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('frontmatter', () => { + 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({ + type: 'element', + tagName: 'frontmatter', + properties: { + language: type, + }, + children: [ + { + type: 'text', + value: 'title: page', + }, + ], + }), + ); + }); + }); + }); + + describe('table of contents', () => { + it.each` + markdown + ${'[[_TOC_]]'} + ${' [[_TOC_]]'} + ${'[[_TOC_]] '} + ${'[TOC]'} + ${' [TOC]'} + ${'[TOC] '} + `('parses $markdown and produces a table of contents section', async ({ markdown }) => { + const result = await markdownToAST(markdown); 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', - }), - }), - ]), + type: 'element', + tagName: 'nav', }), ); }); }); - }); - 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]); + describe('when skipping the rendering of table of contents', () => { + it('transforms table of contents nodes into html tableofcontents tags', async () => { + const result = await markdownToAST('[[_TOC_]]', ['tableOfContents']); - expectInRoot( - result, - expect.objectContaining({ - type: 'element', - tagName: 'frontmatter', - properties: { - language: type, - }, - children: [ - { - type: 'text', - value: 'title: page', - }, - ], - }), - ); + expectInRoot( + result, + expect.objectContaining({ + type: 'element', + tagName: 'tableofcontents', + }), + ); + }); }); }); }); diff --git a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js index 06573f346e0..b972f669ac4 100644 --- a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js +++ b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js @@ -84,7 +84,7 @@ describe('StartupJSLink', () => { }); }); - describe('variable match errors: ', () => { + describe('variable match errors:', () => { it('forwards requests if the variables are not matching', () => { window.gl = { startup_graphql_calls: [ diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js index a2ace8857ed..a0140d1d8a8 100644 --- a/spec/frontend/lib/utils/common_utils_spec.js +++ b/spec/frontend/lib/utils/common_utils_spec.js @@ -476,7 +476,7 @@ describe('common_utils', () => { }); }); - it('catches the rejected promise from the callback ', () => { + it('catches the rejected promise from the callback', () => { const errorMessage = 'Mistakes were made!'; return commonUtils .backOff((next, stop) => { diff --git a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js index 47bb512cbb5..59b3b4c02df 100644 --- a/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js +++ b/spec/frontend/lib/utils/datetime/date_calculation_utility_spec.js @@ -1,4 +1,4 @@ -import { newDateAsLocaleTime } from '~/lib/utils/datetime/date_calculation_utility'; +import { getDateWithUTC, newDateAsLocaleTime } from '~/lib/utils/datetime/date_calculation_utility'; describe('newDateAsLocaleTime', () => { it.each` @@ -15,3 +15,19 @@ describe('newDateAsLocaleTime', () => { expect(newDateAsLocaleTime(string)).toEqual(expected); }); }); + +describe('getDateWithUTC', () => { + it.each` + date | expected + ${new Date('2022-03-22T01:23:45.678Z')} | ${new Date('2022-03-22T00:00:00.000Z')} + ${new Date('1999-12-31T23:59:59.999Z')} | ${new Date('1999-12-31T00:00:00.000Z')} + ${2022} | ${null} + ${[]} | ${null} + ${{}} | ${null} + ${true} | ${null} + ${null} | ${null} + ${undefined} | ${null} + `('returns $expected given $string', ({ date, expected }) => { + expect(getDateWithUTC(date)).toEqual(expected); + }); +}); diff --git a/spec/frontend/lib/utils/finite_state_machine_spec.js b/spec/frontend/lib/utils/finite_state_machine_spec.js index 441dd24c758..cfde3b8596e 100644 --- a/spec/frontend/lib/utils/finite_state_machine_spec.js +++ b/spec/frontend/lib/utils/finite_state_machine_spec.js @@ -50,13 +50,13 @@ describe('Finite State Machine', () => { }); it('throws an error if the machine definition is invalid', () => { - expect(() => machine(badDefinition)).toThrowError( + expect(() => machine(badDefinition)).toThrow( 'A state machine must have an initial state (`.initial`) and a dictionary of possible states (`.states`)', ); }); it('throws an error if the initial state is invalid', () => { - expect(() => machine(unstartableDefinition)).toThrowError( + expect(() => machine(unstartableDefinition)).toThrow( `Cannot initialize the state machine to state '${STATE_IMPOSSIBLE}'. Is that one of the machine's defined states?`, ); }); diff --git a/spec/frontend/lib/utils/is_navigating_away_spec.js b/spec/frontend/lib/utils/is_navigating_away_spec.js index e1230fe96bf..b8a01a1706c 100644 --- a/spec/frontend/lib/utils/is_navigating_away_spec.js +++ b/spec/frontend/lib/utils/is_navigating_away_spec.js @@ -6,7 +6,7 @@ describe('isNavigatingAway', () => { setNavigatingForTestsOnly(false); }); - it.each([false, true])('it returns the navigation flag with value %s', (flag) => { + it.each([false, true])('returns the navigation flag with value %s', (flag) => { setNavigatingForTestsOnly(flag); expect(isNavigatingAway()).toEqual(flag); }); diff --git a/spec/frontend/lib/utils/navigation_utility_spec.js b/spec/frontend/lib/utils/navigation_utility_spec.js index 6d3a871eb33..4dbd50223d5 100644 --- a/spec/frontend/lib/utils/navigation_utility_spec.js +++ b/spec/frontend/lib/utils/navigation_utility_spec.js @@ -63,7 +63,7 @@ describe('initPrefetchLinks', () => { expect(newLink.addEventListener).toHaveBeenCalled(); }); - it('it is not fired when less then 100ms over link', () => { + it('is not fired when less then 100ms over link', () => { const mouseOverEvent = new Event('mouseover'); const mouseOutEvent = new Event('mouseout'); diff --git a/spec/frontend/lib/utils/poll_spec.js b/spec/frontend/lib/utils/poll_spec.js index 1f150599983..94a5f5385b7 100644 --- a/spec/frontend/lib/utils/poll_spec.js +++ b/spec/frontend/lib/utils/poll_spec.js @@ -128,9 +128,11 @@ describe('Poll', () => { errorCallback: callbacks.error, }); + expect(Polling.timeoutID).toBeNull(); + Polling.makeDelayedRequest(1); - expect(Polling.timeoutID).toBeTruthy(); + expect(Polling.timeoutID).not.toBeNull(); return waitForAllCallsToFinish(2, () => { Polling.stop(); diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js index 733d89fe08c..8d179baa505 100644 --- a/spec/frontend/lib/utils/text_markdown_spec.js +++ b/spec/frontend/lib/utils/text_markdown_spec.js @@ -586,6 +586,33 @@ describe('init markdown', () => { ); }); + it('only converts valid URLs', () => { + const notValidUrl = 'group::label'; + const expectedUrlValue = 'url'; + const expectedText = `other [${notValidUrl}](${expectedUrlValue}) text`; + const initialValue = `other ${notValidUrl} text`; + + textArea.value = initialValue; + selectedIndex = initialValue.indexOf(notValidUrl); + textArea.setSelectionRange(selectedIndex, selectedIndex + notValidUrl.length); + + insertMarkdownText({ + textArea, + text: textArea.value, + tag, + blockTag: null, + selected: notValidUrl, + wrap: false, + select, + }); + + expect(textArea.value).toEqual(expectedText); + expect(textArea.selectionStart).toEqual(expectedText.indexOf(expectedUrlValue, 1)); + expect(textArea.selectionEnd).toEqual( + expectedText.indexOf(expectedUrlValue, 1) + expectedUrlValue.length, + ); + }); + it('adds block tags on line above and below selection', () => { selected = 'this text\nis multiple\nlines'; text = `before \n${selected}\nafter `; diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js index 8e31fc792c5..49a160c9f23 100644 --- a/spec/frontend/lib/utils/text_utility_spec.js +++ b/spec/frontend/lib/utils/text_utility_spec.js @@ -45,29 +45,18 @@ describe('text_utility', () => { }); describe('slugify', () => { - it('should remove accents and convert to lower case', () => { - expect(textUtils.slugify('João')).toEqual('jo-o'); - }); - it('should replaces whitespaces with hyphens and convert to lower case', () => { - expect(textUtils.slugify('My Input String')).toEqual('my-input-string'); - }); - it('should remove trailing whitespace and replace whitespaces within string with a hyphen', () => { - expect(textUtils.slugify(' a new project ')).toEqual('a-new-project'); - }); - it('should only remove non-allowed special characters', () => { - expect(textUtils.slugify('test!_pro-ject~')).toEqual('test-_pro-ject'); - }); - it('should squash multiple hypens', () => { - expect(textUtils.slugify('test!!!!_pro-ject~')).toEqual('test-_pro-ject'); - }); - it('should return empty string if only non-allowed characters', () => { - expect(textUtils.slugify('здрасти')).toEqual(''); - }); - it('should squash multiple separators', () => { - expect(textUtils.slugify('Test:-)')).toEqual('test'); - }); - it('should trim any separators from the beginning and end of the slug', () => { - expect(textUtils.slugify('-Test:-)-')).toEqual('test'); + it.each` + title | input | output + ${'should remove accents and convert to lower case'} | ${'João'} | ${'jo-o'} + ${'should replaces whitespaces with hyphens and convert to lower case'} | ${'My Input String'} | ${'my-input-string'} + ${'should remove trailing whitespace and replace whitespaces within string with a hyphen'} | ${' a new project '} | ${'a-new-project'} + ${'should only remove non-allowed special characters'} | ${'test!_pro-ject~'} | ${'test-_pro-ject'} + ${'should squash to multiple non-allowed special characters'} | ${'test!!!!_pro-ject~'} | ${'test-_pro-ject'} + ${'should return empty string if only non-allowed characters'} | ${'дружба'} | ${''} + ${'should squash multiple separators'} | ${'Test:-)'} | ${'test'} + ${'should trim any separators from the beginning and end of the slug'} | ${'-Test:-)-'} | ${'test'} + `('$title', ({ input, output }) => { + expect(textUtils.slugify(input)).toBe(output); }); }); diff --git a/spec/frontend/lib/utils/vuex_module_mappers_spec.js b/spec/frontend/lib/utils/vuex_module_mappers_spec.js index 1821a15f677..d25a692dfea 100644 --- a/spec/frontend/lib/utils/vuex_module_mappers_spec.js +++ b/spec/frontend/lib/utils/vuex_module_mappers_spec.js @@ -128,7 +128,7 @@ describe('~/lib/utils/vuex_module_mappers', () => { describe('with non-string object value', () => { it('throws helpful error', () => { - expect(() => mapVuexModuleActions((vm) => vm.bogus, { foo: () => {} })).toThrowError( + expect(() => mapVuexModuleActions((vm) => vm.bogus, { foo: () => {} })).toThrow( REQUIRE_STRING_ERROR_MESSAGE, ); }); |