diff options
Diffstat (limited to 'spec/frontend/boards/project_select_spec.js')
-rw-r--r-- | spec/frontend/boards/project_select_spec.js | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/spec/frontend/boards/project_select_spec.js b/spec/frontend/boards/project_select_spec.js new file mode 100644 index 00000000000..14ddab3542b --- /dev/null +++ b/spec/frontend/boards/project_select_spec.js @@ -0,0 +1,154 @@ +import Vuex from 'vuex'; +import { createLocalVue, mount } from '@vue/test-utils'; +import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui'; +import defaultState from '~/boards/stores/state'; + +import ProjectSelect from '~/boards/components/project_select.vue'; + +import { mockList, mockGroupProjects } from './mock_data'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +const actions = { + fetchGroupProjects: jest.fn(), + setSelectedProject: jest.fn(), +}; + +const createStore = (state = defaultState) => { + return new Vuex.Store({ + state, + actions, + }); +}; + +const mockProjectsList1 = mockGroupProjects.slice(0, 1); + +describe('ProjectSelect component', () => { + let wrapper; + + const findLabel = () => wrapper.find("[data-testid='header-label']"); + const findGlDropdown = () => wrapper.find(GlDropdown); + const findGlDropdownLoadingIcon = () => + findGlDropdown().find('button:first-child').find(GlLoadingIcon); + const findGlSearchBoxByType = () => wrapper.find(GlSearchBoxByType); + const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem); + const findFirstGlDropdownItem = () => findGlDropdownItems().at(0); + const findInMenuLoadingIcon = () => wrapper.find("[data-testid='dropdown-text-loading-icon']"); + const findEmptySearchMessage = () => wrapper.find("[data-testid='empty-result-message']"); + + const createWrapper = (state = {}) => { + const store = createStore({ + groupProjects: [], + groupProjectsFlags: { + isLoading: false, + pageInfo: { + hasNextPage: false, + }, + }, + ...state, + }); + + wrapper = mount(ProjectSelect, { + localVue, + propsData: { + list: mockList, + }, + store, + provide: { + groupId: 1, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('displays a header title', () => { + createWrapper(); + + expect(findLabel().text()).toBe('Projects'); + }); + + it('renders a default dropdown text', () => { + createWrapper(); + + expect(findGlDropdown().exists()).toBe(true); + expect(findGlDropdown().text()).toContain('Select a project'); + }); + + describe('when mounted', () => { + it('displays a loading icon while projects are being fetched', async () => { + createWrapper(); + + expect(findGlDropdownLoadingIcon().exists()).toBe(true); + + await wrapper.vm.$nextTick(); + + expect(findGlDropdownLoadingIcon().exists()).toBe(false); + }); + }); + + describe('when dropdown menu is open', () => { + describe('by default', () => { + beforeEach(() => { + createWrapper({ groupProjects: mockGroupProjects }); + }); + + it('shows GlSearchBoxByType with default attributes', () => { + expect(findGlSearchBoxByType().exists()).toBe(true); + expect(findGlSearchBoxByType().vm.$attrs).toMatchObject({ + placeholder: 'Search projects', + debounce: '250', + }); + }); + + it("displays the fetched project's name", () => { + expect(findFirstGlDropdownItem().exists()).toBe(true); + expect(findFirstGlDropdownItem().text()).toContain(mockProjectsList1[0].name); + }); + + it("doesn't render loading icon in the menu", () => { + expect(findInMenuLoadingIcon().isVisible()).toBe(false); + }); + + it('does not render empty search result message', () => { + expect(findEmptySearchMessage().exists()).toBe(false); + }); + }); + + describe('when no projects are being returned', () => { + it('renders empty search result message', () => { + createWrapper(); + + expect(findEmptySearchMessage().exists()).toBe(true); + }); + }); + + describe('when a project is selected', () => { + beforeEach(() => { + createWrapper({ groupProjects: mockProjectsList1 }); + + findFirstGlDropdownItem().find('button').trigger('click'); + }); + + it('renders the name of the selected project', () => { + expect(findGlDropdown().find('.gl-new-dropdown-button-text').text()).toBe( + mockProjectsList1[0].name, + ); + }); + }); + + describe('when projects are loading', () => { + beforeEach(() => { + createWrapper({ groupProjectsFlags: { isLoading: true } }); + }); + + it('displays and hides gl-loading-icon while and after fetching data', () => { + expect(findInMenuLoadingIcon().isVisible()).toBe(true); + }); + }); + }); +}); |