diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-23 21:06:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-23 21:06:14 +0300 |
commit | c792263edfaf826c58f4aa41d26904464a17a3e7 (patch) | |
tree | b57ae96c9eeaf0a1432a29f7f50f2fce9529818d /spec/frontend/ide | |
parent | 6f9edd1a4c4942d3d13ec54793cfae56164b1a0a (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/ide')
-rw-r--r-- | spec/frontend/ide/components/file_templates/dropdown_spec.js | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/spec/frontend/ide/components/file_templates/dropdown_spec.js b/spec/frontend/ide/components/file_templates/dropdown_spec.js new file mode 100644 index 00000000000..83d797469ad --- /dev/null +++ b/spec/frontend/ide/components/file_templates/dropdown_spec.js @@ -0,0 +1,175 @@ +import Vuex from 'vuex'; +import $ from 'jquery'; +import { GlLoadingIcon } from '@gitlab/ui'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import Dropdown from '~/ide/components/file_templates/dropdown.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('IDE file templates dropdown component', () => { + let wrapper; + let element; + let fetchTemplateTypesMock; + + const defaultProps = { + label: 'label', + }; + + const findItemButtons = () => wrapper.findAll('button'); + const findSearch = () => wrapper.find('input[type="search"]'); + const triggerDropdown = () => $(element).trigger('show.bs.dropdown'); + + const createComponent = ({ props, state } = {}) => { + fetchTemplateTypesMock = jest.fn(); + const fakeStore = new Vuex.Store({ + modules: { + fileTemplates: { + namespaced: true, + state: { + templates: [], + isLoading: false, + ...state, + }, + actions: { + fetchTemplateTypes: fetchTemplateTypesMock, + }, + }, + }, + }); + + wrapper = shallowMount(Dropdown, { + propsData: { + ...defaultProps, + ...props, + }, + store: fakeStore, + localVue, + sync: false, + }); + + ({ element } = wrapper); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('calls clickItem on click', () => { + const itemData = { name: 'test.yml ' }; + createComponent({ props: { data: [itemData] } }); + const item = findItemButtons().at(0); + item.trigger('click'); + + expect(wrapper.emitted().click[0][0]).toBe(itemData); + }); + + it('renders dropdown title', () => { + const title = 'Test title'; + createComponent({ props: { title } }); + + expect(wrapper.find('.dropdown-title').text()).toContain(title); + }); + + describe('in async mode', () => { + const defaultAsyncProps = { ...defaultProps, isAsyncData: true }; + + it('calls `fetchTemplateTypes` on dropdown event', () => { + createComponent({ props: defaultAsyncProps }); + + triggerDropdown(); + + expect(fetchTemplateTypesMock).toHaveBeenCalled(); + }); + + it('does not call `fetchTemplateTypes` on dropdown event if destroyed', () => { + createComponent({ props: defaultAsyncProps }); + wrapper.destroy(); + + triggerDropdown(); + + expect(fetchTemplateTypesMock).not.toHaveBeenCalled(); + }); + + it('shows loader when isLoading is true', () => { + createComponent({ props: defaultAsyncProps, state: { isLoading: true } }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + + it('renders templates', () => { + const templates = [{ name: 'file-1' }, { name: 'file-2' }]; + createComponent({ + props: { ...defaultAsyncProps, data: [{ name: 'should-never-appear ' }] }, + state: { + templates, + }, + }); + const items = findItemButtons(); + + expect(items.wrappers.map(x => x.text())).toEqual(templates.map(x => x.name)); + }); + + it('searches template data', () => { + const templates = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; + const matches = ['match 1', 'match 2']; + createComponent({ + props: { ...defaultAsyncProps, data: matches, searchable: true }, + state: { templates }, + }); + findSearch().setValue('match'); + return wrapper.vm.$nextTick().then(() => { + const items = findItemButtons(); + + expect(items.length).toBe(matches.length); + expect(items.wrappers.map(x => x.text())).toEqual(matches); + }); + }); + + it('does not render input when `searchable` is true & `showLoading` is true', () => { + createComponent({ + props: { ...defaultAsyncProps, searchable: true }, + state: { isLoading: true }, + }); + + expect(findSearch().exists()).toBe(false); + }); + }); + + describe('in sync mode', () => { + it('renders props data', () => { + const data = [{ name: 'file-1' }, { name: 'file-2' }]; + createComponent({ + props: { data }, + state: { + templates: [{ name: 'should-never-appear ' }], + }, + }); + + const items = findItemButtons(); + + expect(items.length).toBe(data.length); + expect(items.wrappers.map(x => x.text())).toEqual(data.map(x => x.name)); + }); + + it('renders input when `searchable` is true', () => { + createComponent({ props: { searchable: true } }); + + expect(findSearch().exists()).toBe(true); + }); + + it('searches data', () => { + const data = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; + const matches = ['match 1', 'match 2']; + createComponent({ props: { searchable: true, data } }); + findSearch().setValue('match'); + return wrapper.vm.$nextTick().then(() => { + const items = findItemButtons(); + + expect(items.length).toBe(matches.length); + expect(items.wrappers.map(x => x.text())).toEqual(matches); + }); + }); + }); +}); |