import $ from 'jquery'; import htmlSnippetsShow from 'test_fixtures/snippets/show.html'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import waitForPromises from 'helpers/wait_for_promises'; import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm'; import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable'; import { getSelectedFragment } from '~/lib/utils/common_utils'; jest.mock('~/lib/utils/common_utils', () => ({ ...jest.requireActual('~/lib/utils/common_utils'), getSelectedFragment: jest.fn().mockName('getSelectedFragment'), })); describe('ShortcutsIssuable', () => { beforeAll(() => { initCopyAsGFM(); // Fake call to nodeToGfm so the import of lazy bundle happened return CopyAsGFM.nodeToGFM(document.createElement('div')); }); describe('replyWithSelectedText', () => { const FORM_SELECTOR = '.js-main-target-form .js-vue-comment-form'; beforeEach(() => { setHTMLFixture(htmlSnippetsShow); $('body').append( `
Selected text.
'); }); it('leaves existing input intact', async () => { $(FORM_SELECTOR).val('This text was already here.'); expect($(FORM_SELECTOR).val()).toBe('This text was already here.'); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect($(FORM_SELECTOR).val()).toBe('This text was already here.\n\n> Selected text.\n\n'); }); it('triggers `input`', async () => { let triggered = false; $(FORM_SELECTOR).on('input', () => { triggered = true; }); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect(triggered).toBe(true); }); it('triggers `focus`', async () => { const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus'); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect(spy).toHaveBeenCalled(); }); }); describe('with a one-line selection', () => { it('quotes the selection', async () => { stubSelection('This text has been selected.
'); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect($(FORM_SELECTOR).val()).toBe('> This text has been selected.\n\n'); }); }); describe('with a multi-line selection', () => { it('quotes the selected lines as a group', async () => { stubSelection( 'Selected line one.
\nSelected line two.
\nSelected line three.
', ); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect($(FORM_SELECTOR).val()).toBe( '> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n', ); }); }); describe('with an invalid selection', () => { beforeEach(() => { stubSelection('Selected text.
', true); }); it('does not add anything to the input', async () => { ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect($(FORM_SELECTOR).val()).toBe(''); }); it('triggers `focus`', async () => { const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus'); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect(spy).toHaveBeenCalled(); }); }); describe('with a semi-valid selection', () => { beforeEach(() => { stubSelection('Invalid selected text.
', true); }); it('only adds the valid part to the input', async () => { ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect($(FORM_SELECTOR).val()).toBe('> Selected text.\n\n'); }); it('triggers `focus`', async () => { const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus'); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect(spy).toHaveBeenCalled(); }); it('triggers `input`', async () => { let triggered = false; $(FORM_SELECTOR).on('input', () => { triggered = true; }); ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); expect(triggered).toBe(true); }); }); describe('with a selection in a valid block', () => { beforeEach(() => { getSelectedFragment.mockImplementation(() => { const documentFragment = document.createDocumentFragment(); const node = document.createElement('div'); const originalNode = document.createElement('body'); originalNode.innerHTML = `Selected text.
Valid text