diff options
Diffstat (limited to 'spec/frontend/behaviors/gl_emoji_spec.js')
-rw-r--r-- | spec/frontend/behaviors/gl_emoji_spec.js | 196 |
1 files changed, 123 insertions, 73 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'); + }); }); }); |