import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import CommitMessageField from '~/ide/components/shared/commit_message_field.vue'; const DEFAULT_PROPS = { text: 'foo text', placeholder: 'foo placeholder', }; describe('CommitMessageField', () => { let wrapper; const createComponent = (props = {}) => { wrapper = extendedWrapper( shallowMount(CommitMessageField, { propsData: { ...DEFAULT_PROPS, ...props, }, attachTo: document.body, }), ); }; afterEach(() => { wrapper.destroy(); }); const findTextArea = () => wrapper.find('textarea'); const findHighlights = () => wrapper.findByTestId('highlights'); const findHighlightsText = () => wrapper.findByTestId('highlights-text'); const findHighlightsMark = () => wrapper.findByTestId('highlights-mark'); const findHighlightsTexts = () => wrapper.findAllByTestId('highlights-text'); const findHighlightsMarks = () => wrapper.findAllByTestId('highlights-mark'); const fillText = async (text) => { wrapper.setProps({ text }); await nextTick(); }; it('emits input event on input', () => { const value = 'foo'; createComponent(); findTextArea().setValue(value); expect(wrapper.emitted('input')[0][0]).toEqual(value); }); describe('focus classes', () => { beforeEach(async () => { createComponent(); findTextArea().trigger('focus'); await nextTick(); }); it('is added on textarea focus', async () => { expect(wrapper.attributes('class')).toEqual( expect.stringContaining('gl-outline-none! gl-focus-ring-border-1-gray-900!'), ); }); it('is removed on textarea blur', async () => { findTextArea().trigger('blur'); await nextTick(); expect(wrapper.attributes('class')).toEqual( expect.not.stringContaining('gl-outline-none! gl-focus-ring-border-1-gray-900!'), ); }); }); describe('highlights', () => { describe('subject line', () => { it('does not highlight less than 50 characters', async () => { const text = 'text less than 50 chars'; createComponent(); await fillText(text); expect(findHighlightsText().text()).toEqual(text); expect(findHighlightsMark().text()).toBeFalsy(); }); it('highlights characters over 50 length', async () => { const text = 'text less than 50 chars that should not highlighted. text more than 50 should be highlighted'; createComponent(); await fillText(text); expect(findHighlightsText().text()).toEqual(text.slice(0, 50)); expect(findHighlightsMark().text()).toEqual(text.slice(50)); }); }); describe('body text', () => { it('does not highlight body text less tan 72 characters', async () => { const text = 'subject line\nbody content'; createComponent(); await fillText(text); expect(findHighlightsTexts()).toHaveLength(2); expect(findHighlightsMarks().at(1).attributes('style')).toEqual('display: none;'); }); it('highlights body text more than 72 characters', async () => { const text = 'subject line\nbody content that will be highlighted when it is more than 72 characters in length'; createComponent(); await fillText(text); expect(findHighlightsTexts()).toHaveLength(2); expect(findHighlightsMarks().at(1).attributes('style')).not.toEqual('display: none;'); expect(findHighlightsMarks().at(1).element.textContent).toEqual(' in length'); }); it('highlights body text & subject line', async () => { const text = 'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length'; createComponent(); await fillText(text); expect(findHighlightsTexts()).toHaveLength(2); expect(findHighlightsMarks()).toHaveLength(2); expect(findHighlightsMarks().at(0).element.textContent).toEqual('d'); expect(findHighlightsMarks().at(1).element.textContent).toEqual(' in length'); }); }); }); describe('scrolling textarea', () => { it('updates transform of highlights', async () => { const yCoord = 50; createComponent(); await fillText('subject line\n\n\n\n\n\n\n\n\n\n\nbody content'); wrapper.vm.$el.querySelector('textarea').scrollTo(0, yCoord); await nextTick(); expect(wrapper.vm.scrollTop).toEqual(yCoord); expect(findHighlights().attributes('style')).toEqual('transform: translate3d(0, -50px, 0);'); }); }); });