diff options
Diffstat (limited to 'spec/frontend/search/sidebar/components')
4 files changed, 344 insertions, 0 deletions
diff --git a/spec/frontend/search/sidebar/components/app_spec.js b/spec/frontend/search/sidebar/components/app_spec.js new file mode 100644 index 00000000000..d2c0081080c --- /dev/null +++ b/spec/frontend/search/sidebar/components/app_spec.js @@ -0,0 +1,103 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { GlButton, GlLink } from '@gitlab/ui'; +import { MOCK_QUERY } from 'jest/search/mock_data'; +import GlobalSearchSidebar from '~/search/sidebar/components/app.vue'; +import ConfidentialityFilter from '~/search/sidebar/components/confidentiality_filter.vue'; +import StatusFilter from '~/search/sidebar/components/status_filter.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('GlobalSearchSidebar', () => { + let wrapper; + + const actionSpies = { + applyQuery: jest.fn(), + resetQuery: jest.fn(), + }; + + const createComponent = initialState => { + const store = new Vuex.Store({ + state: { + query: MOCK_QUERY, + ...initialState, + }, + actions: actionSpies, + }); + + wrapper = shallowMount(GlobalSearchSidebar, { + localVue, + store, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findSidebarForm = () => wrapper.find('form'); + const findStatusFilter = () => wrapper.find(StatusFilter); + const findConfidentialityFilter = () => wrapper.find(ConfidentialityFilter); + const findApplyButton = () => wrapper.find(GlButton); + const findResetLinkButton = () => wrapper.find(GlLink); + + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders StatusFilter always', () => { + expect(findStatusFilter().exists()).toBe(true); + }); + + it('renders ConfidentialityFilter always', () => { + expect(findConfidentialityFilter().exists()).toBe(true); + }); + + it('renders ApplyButton always', () => { + expect(findApplyButton().exists()).toBe(true); + }); + }); + + describe('ResetLinkButton', () => { + describe('with no filter selected', () => { + beforeEach(() => { + createComponent({ query: {} }); + }); + + it('does not render', () => { + expect(findResetLinkButton().exists()).toBe(false); + }); + }); + + describe('with filter selected', () => { + beforeEach(() => { + createComponent(); + }); + + it('does render when a filter selected', () => { + expect(findResetLinkButton().exists()).toBe(true); + }); + }); + }); + + describe('actions', () => { + beforeEach(() => { + createComponent(); + }); + + it('clicking ApplyButton calls applyQuery', () => { + findSidebarForm().trigger('submit'); + + expect(actionSpies.applyQuery).toHaveBeenCalled(); + }); + + it('clicking ResetLinkButton calls resetQuery', () => { + findResetLinkButton().vm.$emit('click'); + + expect(actionSpies.resetQuery).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js b/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js new file mode 100644 index 00000000000..68d20b2480e --- /dev/null +++ b/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js @@ -0,0 +1,65 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { MOCK_QUERY } from 'jest/search/mock_data'; +import ConfidentialityFilter from '~/search/sidebar/components/confidentiality_filter.vue'; +import RadioFilter from '~/search/sidebar/components/radio_filter.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('ConfidentialityFilter', () => { + let wrapper; + + const actionSpies = { + applyQuery: jest.fn(), + resetQuery: jest.fn(), + }; + + const createComponent = initialState => { + const store = new Vuex.Store({ + state: { + query: MOCK_QUERY, + ...initialState, + }, + actions: actionSpies, + }); + + wrapper = shallowMount(ConfidentialityFilter, { + localVue, + store, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findRadioFilter = () => wrapper.find(RadioFilter); + + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + describe.each` + scope | showFilter + ${'issues'} | ${true} + ${'merge_requests'} | ${false} + ${'projects'} | ${false} + ${'milestones'} | ${false} + ${'users'} | ${false} + ${'notes'} | ${false} + ${'wiki_blobs'} | ${false} + ${'blobs'} | ${false} + `(`dropdown`, ({ scope, showFilter }) => { + beforeEach(() => { + createComponent({ query: { scope } }); + }); + + it(`does${showFilter ? '' : ' not'} render when scope is ${scope}`, () => { + expect(findRadioFilter().exists()).toBe(showFilter); + }); + }); + }); +}); diff --git a/spec/frontend/search/sidebar/components/radio_filter_spec.js b/spec/frontend/search/sidebar/components/radio_filter_spec.js new file mode 100644 index 00000000000..31a4a8859ee --- /dev/null +++ b/spec/frontend/search/sidebar/components/radio_filter_spec.js @@ -0,0 +1,111 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { GlFormRadioGroup, GlFormRadio } from '@gitlab/ui'; +import { MOCK_QUERY } from 'jest/search/mock_data'; +import RadioFilter from '~/search/sidebar/components/radio_filter.vue'; +import { stateFilterData } from '~/search/sidebar/constants/state_filter_data'; +import { confidentialFilterData } from '~/search/sidebar/constants/confidential_filter_data'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('RadioFilter', () => { + let wrapper; + + const actionSpies = { + setQuery: jest.fn(), + }; + + const defaultProps = { + filterData: stateFilterData, + }; + + const createComponent = (initialState, props = {}) => { + const store = new Vuex.Store({ + state: { + query: MOCK_QUERY, + ...initialState, + }, + actions: actionSpies, + }); + + wrapper = shallowMount(RadioFilter, { + localVue, + store, + propsData: { + ...defaultProps, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findGlRadioButtonGroup = () => wrapper.find(GlFormRadioGroup); + const findGlRadioButtons = () => findGlRadioButtonGroup().findAll(GlFormRadio); + const findGlRadioButtonsText = () => findGlRadioButtons().wrappers.map(w => w.text()); + + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders GlRadioButtonGroup always', () => { + expect(findGlRadioButtonGroup().exists()).toBe(true); + }); + + describe('Radio Buttons', () => { + describe('Status Filter', () => { + it('renders a radio button for each filterOption', () => { + expect(findGlRadioButtonsText()).toStrictEqual( + stateFilterData.filterByScope[stateFilterData.scopes.ISSUES].map(f => { + return f.value === stateFilterData.filters.ANY.value + ? `Any ${stateFilterData.header.toLowerCase()}` + : f.label; + }), + ); + }); + + it('clicking a radio button item calls setQuery', () => { + const filter = stateFilterData.filters[Object.keys(stateFilterData.filters)[0]].value; + findGlRadioButtonGroup().vm.$emit('input', filter); + + expect(actionSpies.setQuery).toHaveBeenCalledWith(expect.any(Object), { + key: stateFilterData.filterParam, + value: filter, + }); + }); + }); + + describe('Confidentiality Filter', () => { + beforeEach(() => { + createComponent({}, { filterData: confidentialFilterData }); + }); + + it('renders a radio button for each filterOption', () => { + expect(findGlRadioButtonsText()).toStrictEqual( + confidentialFilterData.filterByScope[confidentialFilterData.scopes.ISSUES].map(f => { + return f.value === confidentialFilterData.filters.ANY.value + ? `Any ${confidentialFilterData.header.toLowerCase()}` + : f.label; + }), + ); + }); + + it('clicking a radio button item calls setQuery', () => { + const filter = + confidentialFilterData.filters[Object.keys(confidentialFilterData.filters)[0]].value; + findGlRadioButtonGroup().vm.$emit('input', filter); + + expect(actionSpies.setQuery).toHaveBeenCalledWith(expect.any(Object), { + key: confidentialFilterData.filterParam, + value: filter, + }); + }); + }); + }); + }); +}); diff --git a/spec/frontend/search/sidebar/components/status_filter_spec.js b/spec/frontend/search/sidebar/components/status_filter_spec.js new file mode 100644 index 00000000000..188d47b38cd --- /dev/null +++ b/spec/frontend/search/sidebar/components/status_filter_spec.js @@ -0,0 +1,65 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { MOCK_QUERY } from 'jest/search/mock_data'; +import StatusFilter from '~/search/sidebar/components/status_filter.vue'; +import RadioFilter from '~/search/sidebar/components/radio_filter.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('StatusFilter', () => { + let wrapper; + + const actionSpies = { + applyQuery: jest.fn(), + resetQuery: jest.fn(), + }; + + const createComponent = initialState => { + const store = new Vuex.Store({ + state: { + query: MOCK_QUERY, + ...initialState, + }, + actions: actionSpies, + }); + + wrapper = shallowMount(StatusFilter, { + localVue, + store, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findRadioFilter = () => wrapper.find(RadioFilter); + + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + describe.each` + scope | showFilter + ${'issues'} | ${true} + ${'merge_requests'} | ${true} + ${'projects'} | ${false} + ${'milestones'} | ${false} + ${'users'} | ${false} + ${'notes'} | ${false} + ${'wiki_blobs'} | ${false} + ${'blobs'} | ${false} + `(`dropdown`, ({ scope, showFilter }) => { + beforeEach(() => { + createComponent({ query: { scope } }); + }); + + it(`does${showFilter ? '' : ' not'} render when scope is ${scope}`, () => { + expect(findRadioFilter().exists()).toBe(showFilter); + }); + }); + }); +}); |