diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
commit | e4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch) | |
tree | 2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /spec/frontend/behaviors | |
parent | ffda4e7bcac36987f936b4ba515995a6698698f0 (diff) |
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'spec/frontend/behaviors')
-rw-r--r-- | spec/frontend/behaviors/gl_emoji_spec.js | 196 | ||||
-rw-r--r-- | spec/frontend/behaviors/markdown/render_gfm_spec.js | 26 | ||||
-rw-r--r-- | spec/frontend/behaviors/markdown/render_metrics_spec.js | 49 |
3 files changed, 123 insertions, 148 deletions
diff --git a/spec/frontend/behaviors/gl_emoji_spec.js b/spec/frontend/behaviors/gl_emoji_spec.js index 995e4219ae3..c7f4fce0e4c 100644 --- a/spec/frontend/behaviors/gl_emoji_spec.js +++ b/spec/frontend/behaviors/gl_emoji_spec.js @@ -1,11 +1,18 @@ import { initEmojiMock, clearEmojiMock } from 'helpers/emoji'; import waitForPromises from 'helpers/wait_for_promises'; +import { createMockClient } from 'helpers/mock_apollo_helper'; import installGlEmojiElement from '~/behaviors/gl_emoji'; import { EMOJI_VERSION } from '~/emoji'; +import customEmojiQuery from '~/emoji/queries/custom_emoji.query.graphql'; import * as EmojiUnicodeSupport from '~/emoji/support'; +let mockClient; + jest.mock('~/emoji/support'); +jest.mock('~/lib/graphql', () => { + return () => mockClient; +}); describe('gl_emoji', () => { const emojiData = { @@ -36,101 +43,144 @@ describe('gl_emoji', () => { return div.firstElementChild; } - beforeEach(async () => { - await initEmojiMock(emojiData); - }); - afterEach(() => { clearEmojiMock(); document.body.innerHTML = ''; }); - describe.each([ - [ - 'bomb emoji just with name attribute', - '<gl-emoji data-name="bomb"></gl-emoji>', - '<gl-emoji data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', - `<gl-emoji data-name="bomb" data-unicode-version="6.0" title="bomb"><img class="emoji" title=":bomb:" alt=":bomb:" src="/-/emojis/${EMOJI_VERSION}/bomb.png" width="16" height="16" align="absmiddle"></gl-emoji>`, - ], - [ - 'bomb emoji with name attribute and unicode version', - '<gl-emoji data-name="bomb" data-unicode-version="6.0">💣</gl-emoji>', - '<gl-emoji data-name="bomb" data-unicode-version="6.0">💣</gl-emoji>', - `<gl-emoji data-name="bomb" data-unicode-version="6.0"><img class="emoji" title=":bomb:" alt=":bomb:" src="/-/emojis/${EMOJI_VERSION}/bomb.png" width="16" height="16" align="absmiddle"></gl-emoji>`, - ], - [ - 'bomb emoji with sprite fallback', - '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb"></gl-emoji>', - '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', - '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb" data-unicode-version="6.0" title="bomb" class="emoji-icon emoji-bomb">💣</gl-emoji>', - ], - [ - 'bomb emoji with image fallback', - '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb"></gl-emoji>', - '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', - '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb" data-unicode-version="6.0" title="bomb"><img class="emoji" title=":bomb:" alt=":bomb:" src="/bomb.png" width="16" height="16" align="absmiddle"></gl-emoji>', - ], - [ - 'invalid emoji', - '<gl-emoji data-name="invalid_emoji"></gl-emoji>', - '<gl-emoji data-name="grey_question" data-unicode-version="6.0" title="white question mark ornament">❔</gl-emoji>', - `<gl-emoji data-name="grey_question" data-unicode-version="6.0" title="white question mark ornament"><img class="emoji" title=":grey_question:" alt=":grey_question:" src="/-/emojis/${EMOJI_VERSION}/grey_question.png" width="16" height="16" align="absmiddle"></gl-emoji>`, - ], - [ - 'custom emoji with image fallback', - '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"></gl-emoji>', - '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"><img class="emoji" title=":party-parrot:" alt=":party-parrot:" src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" width="16" height="16" align="absmiddle"></gl-emoji>', - '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"><img class="emoji" title=":party-parrot:" alt=":party-parrot:" src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" width="16" height="16" align="absmiddle"></gl-emoji>', - ], - ])('%s', (name, markup, withEmojiSupport, withoutEmojiSupport) => { - it(`renders correctly with emoji support`, async () => { - jest.spyOn(EmojiUnicodeSupport, 'default').mockReturnValue(true); - const glEmojiElement = markupToDomElement(markup); + describe('standard emoji', () => { + beforeEach(async () => { + await initEmojiMock(emojiData); + }); + + describe.each([ + [ + 'bomb emoji just with name attribute', + '<gl-emoji data-name="bomb"></gl-emoji>', + '<gl-emoji data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', + `<gl-emoji data-name="bomb" data-unicode-version="6.0" title="bomb"><img class="emoji" title=":bomb:" alt=":bomb:" src="/-/emojis/${EMOJI_VERSION}/bomb.png" align="absmiddle"></gl-emoji>`, + ], + [ + 'bomb emoji with name attribute and unicode version', + '<gl-emoji data-name="bomb" data-unicode-version="6.0">💣</gl-emoji>', + '<gl-emoji data-name="bomb" data-unicode-version="6.0">💣</gl-emoji>', + `<gl-emoji data-name="bomb" data-unicode-version="6.0"><img class="emoji" title=":bomb:" alt=":bomb:" src="/-/emojis/${EMOJI_VERSION}/bomb.png" align="absmiddle"></gl-emoji>`, + ], + [ + 'bomb emoji with sprite fallback', + '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb"></gl-emoji>', + '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', + '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb" data-unicode-version="6.0" title="bomb" class="emoji-icon emoji-bomb">💣</gl-emoji>', + ], + [ + 'bomb emoji with image fallback', + '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb"></gl-emoji>', + '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb" data-unicode-version="6.0" title="bomb">💣</gl-emoji>', + '<gl-emoji data-fallback-src="/bomb.png" data-name="bomb" data-unicode-version="6.0" title="bomb"><img class="emoji" title=":bomb:" alt=":bomb:" src="/bomb.png" align="absmiddle"></gl-emoji>', + ], + [ + 'invalid emoji', + '<gl-emoji data-name="invalid_emoji"></gl-emoji>', + '<gl-emoji data-name="grey_question" data-unicode-version="6.0" title="white question mark ornament">❔</gl-emoji>', + `<gl-emoji data-name="grey_question" data-unicode-version="6.0" title="white question mark ornament"><img class="emoji" title=":grey_question:" alt=":grey_question:" src="/-/emojis/${EMOJI_VERSION}/grey_question.png" align="absmiddle"></gl-emoji>`, + ], + [ + 'custom emoji with image fallback', + '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"></gl-emoji>', + '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"><img class="emoji" title=":party-parrot:" alt=":party-parrot:" src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" align="absmiddle"></gl-emoji>', + '<gl-emoji data-fallback-src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" data-name="party-parrot" data-unicode-version="custom"><img class="emoji" title=":party-parrot:" alt=":party-parrot:" src="https://cultofthepartyparrot.com/parrots/hd/parrot.gif" align="absmiddle"></gl-emoji>', + ], + ])('%s', (name, markup, withEmojiSupport, withoutEmojiSupport) => { + it(`renders correctly with emoji support`, async () => { + jest.spyOn(EmojiUnicodeSupport, 'default').mockReturnValue(true); + const glEmojiElement = markupToDomElement(markup); + + await waitForPromises(); + + expect(glEmojiElement.outerHTML).toBe(withEmojiSupport); + }); + + it(`renders correctly without emoji support`, async () => { + jest.spyOn(EmojiUnicodeSupport, 'default').mockReturnValue(false); + const glEmojiElement = markupToDomElement(markup); + + await waitForPromises(); + + expect(glEmojiElement.outerHTML).toBe(withoutEmojiSupport); + }); + }); + + it('escapes gl-emoji name', async () => { + const glEmojiElement = markupToDomElement( + "<gl-emoji data-name='"x="y" onload="alert(document.location.href)"' data-unicode-version='x'>abc</gl-emoji>", + ); await waitForPromises(); - expect(glEmojiElement.outerHTML).toBe(withEmojiSupport); + expect(glEmojiElement.outerHTML).toBe( + '<gl-emoji data-name=""x="y" onload="alert(document.location.href)"" data-unicode-version="x"><img class="emoji" title=":"x="y" onload="alert(document.location.href)":" alt=":"x="y" onload="alert(document.location.href)":" src="/-/emojis/2/grey_question.png" align="absmiddle"></gl-emoji>', + ); }); - it(`renders correctly without emoji support`, async () => { + it('Adds sprite CSS if emojis are not supported', async () => { + const testPath = '/test-path.css'; jest.spyOn(EmojiUnicodeSupport, 'default').mockReturnValue(false); - const glEmojiElement = markupToDomElement(markup); + window.gon.emoji_sprites_css_path = testPath; + expect(document.head.querySelector(`link[href="${testPath}"]`)).toBe(null); + expect(window.gon.emoji_sprites_css_added).toBe(undefined); + + markupToDomElement( + '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb"></gl-emoji>', + ); await waitForPromises(); - expect(glEmojiElement.outerHTML).toBe(withoutEmojiSupport); + expect(document.head.querySelector(`link[href="${testPath}"]`).outerHTML).toBe( + '<link rel="stylesheet" href="/test-path.css">', + ); + expect(window.gon.emoji_sprites_css_added).toBe(true); }); }); - it('escapes gl-emoji name', async () => { - const glEmojiElement = markupToDomElement( - "<gl-emoji data-name='"x="y" onload="alert(document.location.href)"' data-unicode-version='x'>abc</gl-emoji>", - ); - - await waitForPromises(); + describe('custom emoji', () => { + beforeEach(async () => { + mockClient = createMockClient([ + [ + customEmojiQuery, + jest.fn().mockResolvedValue({ + data: { + group: { + id: 1, + customEmoji: { + nodes: [{ id: 1, name: 'parrot', url: 'parrot.gif' }], + }, + }, + }, + }), + ], + ]); + + window.gon = { features: { customEmoji: true } }; + document.body.dataset.groupFullPath = 'test-group'; + + await initEmojiMock(emojiData); + }); - expect(glEmojiElement.outerHTML).toBe( - '<gl-emoji data-name=""x="y" onload="alert(document.location.href)"" data-unicode-version="x"><img class="emoji" title=":"x="y" onload="alert(document.location.href)":" alt=":"x="y" onload="alert(document.location.href)":" src="/-/emojis/2/grey_question.png" width="16" height="16" align="absmiddle"></gl-emoji>', - ); - }); + afterEach(() => { + window.gon = {}; + delete document.body.dataset.groupFullPath; + }); - it('Adds sprite CSS if emojis are not supported', async () => { - const testPath = '/test-path.css'; - jest.spyOn(EmojiUnicodeSupport, 'default').mockReturnValue(false); - window.gon.emoji_sprites_css_path = testPath; + it('renders custom emoji', async () => { + const glEmojiElement = markupToDomElement('<gl-emoji data-name="parrot"></gl-emoji>'); - expect(document.head.querySelector(`link[href="${testPath}"]`)).toBe(null); - expect(window.gon.emoji_sprites_css_added).toBe(undefined); + await waitForPromises(); - markupToDomElement( - '<gl-emoji data-fallback-sprite-class="emoji-bomb" data-name="bomb"></gl-emoji>', - ); - await waitForPromises(); + const img = glEmojiElement.querySelector('img'); - expect(document.head.querySelector(`link[href="${testPath}"]`).outerHTML).toBe( - '<link rel="stylesheet" href="/test-path.css">', - ); - expect(window.gon.emoji_sprites_css_added).toBe(true); + expect(glEmojiElement.dataset.unicodeVersion).toBe('custom'); + expect(img.getAttribute('src')).toBe('parrot.gif'); + }); }); }); diff --git a/spec/frontend/behaviors/markdown/render_gfm_spec.js b/spec/frontend/behaviors/markdown/render_gfm_spec.js index 220ad874b47..0bbb92282e5 100644 --- a/spec/frontend/behaviors/markdown/render_gfm_spec.js +++ b/spec/frontend/behaviors/markdown/render_gfm_spec.js @@ -1,7 +1,4 @@ import { renderGFM } from '~/behaviors/markdown/render_gfm'; -import renderMetrics from '~/behaviors/markdown/render_metrics'; - -jest.mock('~/behaviors/markdown/render_metrics'); describe('renderGFM', () => { it('handles a missing element', () => { @@ -9,27 +6,4 @@ describe('renderGFM', () => { renderGFM(); }).not.toThrow(); }); - - describe('remove_monitor_metrics flag', () => { - let metricsElement; - - beforeEach(() => { - window.gon = { features: { removeMonitorMetrics: true } }; - metricsElement = document.createElement('div'); - metricsElement.setAttribute('class', '.js-render-metrics'); - }); - - it('renders metrics when the flag is disabled', () => { - window.gon.features = { features: { removeMonitorMetrics: false } }; - renderGFM(metricsElement); - - expect(renderMetrics).toHaveBeenCalled(); - }); - - it('does not render metrics when the flag is enabled', () => { - renderGFM(metricsElement); - - expect(renderMetrics).not.toHaveBeenCalled(); - }); - }); }); diff --git a/spec/frontend/behaviors/markdown/render_metrics_spec.js b/spec/frontend/behaviors/markdown/render_metrics_spec.js deleted file mode 100644 index ab81ed6b8f0..00000000000 --- a/spec/frontend/behaviors/markdown/render_metrics_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { TEST_HOST } from 'helpers/test_constants'; -import renderMetrics from '~/behaviors/markdown/render_metrics'; - -const mockEmbedGroup = jest.fn(); - -jest.mock('vue', () => ({ extend: () => mockEmbedGroup })); -jest.mock('~/monitoring/components/embeds/embed_group.vue', () => jest.fn()); -jest.mock('~/monitoring/stores/embed_group/', () => ({ createStore: jest.fn() })); - -const getElements = () => Array.from(document.getElementsByClassName('js-render-metrics')); - -describe('Render metrics for Gitlab Flavoured Markdown', () => { - it('does nothing when no elements are found', () => { - 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>`; - - 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', () => { - document.body.innerHTML = ` - <p><span>Hello</span></p> - <div class="js-render-metrics" data-dashboard-url="${TEST_HOST}/1"></div> - <div class="js-render-metrics" data-dashboard-url="${TEST_HOST}/2"></div> - <p><span>Hello</span></p> - <div class="js-render-metrics" data-dashboard-url="${TEST_HOST}/3"></div> - `; - - 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`] } }), - ); - }); - }); -}); |