diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-08 18:08:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-08 18:08:17 +0300 |
commit | 1ec1bec4ee7ef7cb2e6faa7af625950f6d7aa290 (patch) | |
tree | 515047b93cfb054156b99c612684eb9a4c45330d /spec/frontend/boards | |
parent | 2f5c5b1081fe544ecb9a71d8adf88e00f01f3732 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/boards')
-rw-r--r-- | spec/frontend/boards/board_list_new_spec.js | 234 | ||||
-rw-r--r-- | spec/frontend/boards/board_list_spec.js | 3 | ||||
-rw-r--r-- | spec/frontend/boards/stores/actions_spec.js | 36 | ||||
-rw-r--r-- | spec/frontend/boards/stores/mutations_spec.js | 12 |
4 files changed, 275 insertions, 10 deletions
diff --git a/spec/frontend/boards/board_list_new_spec.js b/spec/frontend/boards/board_list_new_spec.js new file mode 100644 index 00000000000..163611c2197 --- /dev/null +++ b/spec/frontend/boards/board_list_new_spec.js @@ -0,0 +1,234 @@ +/* global List */ +/* global ListIssue */ + +import Vuex from 'vuex'; +import { useFakeRequestAnimationFrame } from 'helpers/fake_request_animation_frame'; +import { createLocalVue, mount } from '@vue/test-utils'; +import eventHub from '~/boards/eventhub'; +import BoardList from '~/boards/components/board_list_new.vue'; +import BoardCard from '~/boards/components/board_card.vue'; +import '~/boards/models/issue'; +import '~/boards/models/list'; +import { listObj, mockIssuesByListId, issues } from './mock_data'; +import defaultState from '~/boards/stores/state'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +const actions = { + fetchIssuesForList: jest.fn(), +}; + +const createStore = (state = defaultState) => { + return new Vuex.Store({ + state, + actions, + }); +}; + +const createComponent = ({ + listIssueProps = {}, + componentProps = {}, + listProps = {}, + state = {}, +} = {}) => { + const store = createStore({ + issuesByListId: mockIssuesByListId, + issues, + pageInfoByListId: { + 'gid://gitlab/List/1': { hasNextPage: true }, + 'gid://gitlab/List/2': {}, + }, + listsFlags: { + 'gid://gitlab/List/1': {}, + 'gid://gitlab/List/2': {}, + }, + ...state, + }); + + const list = new List({ + ...listObj, + id: 'gid://gitlab/List/1', + ...listProps, + doNotFetchIssues: true, + }); + const issue = new ListIssue({ + title: 'Testing', + id: 1, + iid: 1, + confidential: false, + labels: [], + assignees: [], + ...listIssueProps, + }); + if (!Object.prototype.hasOwnProperty.call(listProps, 'issuesSize')) { + list.issuesSize = 1; + } + + const component = mount(BoardList, { + localVue, + propsData: { + disabled: false, + list, + issues: [issue], + ...componentProps, + }, + store, + provide: { + groupId: null, + rootPath: '/', + }, + }); + + return component; +}; + +describe('Board list component', () => { + let wrapper; + useFakeRequestAnimationFrame(); + + describe('When Expanded', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders component', () => { + expect(wrapper.find('.board-list-component').exists()).toBe(true); + }); + + it('renders loading icon', () => { + wrapper = createComponent({ + state: { listsFlags: { 'gid://gitlab/List/1': { isLoading: true } } }, + }); + + expect(wrapper.find('[data-testid="board_list_loading"').exists()).toBe(true); + }); + + it('renders issues', () => { + expect(wrapper.findAll(BoardCard).length).toBe(1); + }); + + it('sets data attribute with issue id', () => { + expect(wrapper.find('.board-card').attributes('data-issue-id')).toBe('1'); + }); + + it('shows new issue form', async () => { + wrapper.vm.toggleForm(); + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-new-issue-form').exists()).toBe(true); + }); + + it('shows new issue form after eventhub event', async () => { + eventHub.$emit(`toggle-issue-form-${wrapper.vm.list.id}`); + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-new-issue-form').exists()).toBe(true); + }); + + it('does not show new issue form for closed list', () => { + wrapper.setProps({ list: { type: 'closed' } }); + wrapper.vm.toggleForm(); + + expect(wrapper.find('.board-new-issue-form').exists()).toBe(false); + }); + + it('shows count list item', async () => { + wrapper.vm.showCount = true; + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-list-count').exists()).toBe(true); + + expect(wrapper.find('.board-list-count').text()).toBe('Showing all issues'); + }); + + it('sets data attribute with invalid id', async () => { + wrapper.vm.showCount = true; + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-list-count').attributes('data-issue-id')).toBe('-1'); + }); + + it('shows how many more issues to load', async () => { + wrapper.vm.showCount = true; + wrapper.setProps({ list: { issuesSize: 20 } }); + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-list-count').text()).toBe('Showing 1 of 20 issues'); + }); + }); + + describe('load more issues', () => { + beforeEach(() => { + wrapper = createComponent({ + listProps: { issuesSize: 25 }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('loads more issues after scrolling', () => { + wrapper.vm.$refs.list.dispatchEvent(new Event('scroll')); + + expect(actions.fetchIssuesForList).toHaveBeenCalled(); + }); + + it('does not load issues if already loading', () => { + wrapper.vm.$refs.list.dispatchEvent(new Event('scroll')); + wrapper.vm.$refs.list.dispatchEvent(new Event('scroll')); + + expect(actions.fetchIssuesForList).toHaveBeenCalledTimes(1); + }); + + it('shows loading more spinner', async () => { + wrapper.vm.showCount = true; + wrapper.vm.list.loadingMore = true; + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.board-list-count .gl-spinner').exists()).toBe(true); + }); + }); + + describe('max issue count warning', () => { + beforeEach(() => { + wrapper = createComponent({ + listProps: { issuesSize: 50 }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('when issue count exceeds max issue count', () => { + it('sets background to bg-danger-100', async () => { + wrapper.setProps({ list: { issuesSize: 4, maxIssueCount: 3 } }); + + await wrapper.vm.$nextTick(); + expect(wrapper.find('.bg-danger-100').exists()).toBe(true); + }); + }); + + describe('when list issue count does NOT exceed list max issue count', () => { + it('does not sets background to bg-danger-100', () => { + wrapper.setProps({ list: { issuesSize: 2, maxIssueCount: 3 } }); + + expect(wrapper.find('.bg-danger-100').exists()).toBe(false); + }); + }); + + describe('when list max issue count is 0', () => { + it('does not sets background to bg-danger-100', () => { + wrapper.setProps({ list: { maxIssueCount: 0 } }); + + expect(wrapper.find('.bg-danger-100').exists()).toBe(false); + }); + }); + }); +}); diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js index 88883ae61d4..0fe3c88f518 100644 --- a/spec/frontend/boards/board_list_spec.js +++ b/spec/frontend/boards/board_list_spec.js @@ -44,7 +44,6 @@ const createComponent = ({ done, listIssueProps = {}, componentProps = {}, listP disabled: false, list, issues: list.issues, - loading: false, ...componentProps, }, provide: { @@ -94,7 +93,7 @@ describe('Board list component', () => { }); it('renders loading icon', () => { - component.loading = true; + component.list.loading = true; return Vue.nextTick().then(() => { expect(component.$el.querySelector('.board-list-loading')).not.toBeNull(); diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 6415a5a5d3a..0e5fee9a563 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -250,6 +250,13 @@ describe('fetchIssuesForList', () => { boardType: 'group', }; + const mockIssuesNodes = mockIssues.map(issue => ({ node: issue })); + + const pageInfo = { + endCursor: '', + hasNextPage: false, + }; + const queryResponse = { data: { group: { @@ -259,7 +266,8 @@ describe('fetchIssuesForList', () => { { id: listId, issues: { - nodes: mockIssues, + edges: mockIssuesNodes, + pageInfo, }, }, ], @@ -271,17 +279,25 @@ describe('fetchIssuesForList', () => { const formattedIssues = formatListIssues(queryResponse.data.group.board.lists); - it('should commit mutation RECEIVE_ISSUES_FOR_LIST_SUCCESS on success', done => { + const listPageInfo = { + [listId]: pageInfo, + }; + + it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_SUCCESS on success', done => { jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse); testAction( actions.fetchIssuesForList, - listId, + { listId }, state, [ { + type: types.REQUEST_ISSUES_FOR_LIST, + payload: { listId, fetchNext: false }, + }, + { type: types.RECEIVE_ISSUES_FOR_LIST_SUCCESS, - payload: { listIssues: formattedIssues, listId }, + payload: { listIssues: formattedIssues, listPageInfo, listId }, }, ], [], @@ -289,14 +305,20 @@ describe('fetchIssuesForList', () => { ); }); - it('should commit mutation RECEIVE_ISSUES_FOR_LIST_FAILURE on failure', done => { + it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_FAILURE on failure', done => { jest.spyOn(gqlClient, 'query').mockResolvedValue(Promise.reject()); testAction( actions.fetchIssuesForList, - listId, + { listId }, state, - [{ type: types.RECEIVE_ISSUES_FOR_LIST_FAILURE, payload: listId }], + [ + { + type: types.REQUEST_ISSUES_FOR_LIST, + payload: { listId, fetchNext: false }, + }, + { type: types.RECEIVE_ISSUES_FOR_LIST_FAILURE, payload: listId }, + ], [], done, ); diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js index 306f24e5240..4e60a78f443 100644 --- a/spec/frontend/boards/stores/mutations_spec.js +++ b/spec/frontend/boards/stores/mutations_spec.js @@ -173,13 +173,23 @@ describe('Board Store Mutations', () => { state = { ...state, - issuesByListId: {}, + issuesByListId: { + 'gid://gitlab/List/1': [], + }, issues: {}, boardLists: mockListsWithModel, }; + const listPageInfo = { + 'gid://gitlab/List/1': { + endCursor: '', + hasNextPage: false, + }, + }; + mutations.RECEIVE_ISSUES_FOR_LIST_SUCCESS(state, { listIssues: { listData: listIssues, issues }, + listPageInfo, listId: 'gid://gitlab/List/1', }); |