Commit 2e0dd83d authored by Vitaly Slobodin's avatar Vitaly Slobodin
parent d0ce09be
import Vue from 'vue';
import { mapActions } from 'vuex';
import Vuex from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
......@@ -9,6 +9,8 @@ import RelatedItemsTreeApp from './components/related_items_tree_app.vue';
import TreeRoot from './components/tree_root.vue';
import TreeItem from './components/tree_item.vue';
Vue.use(Vuex);
export default () => {
const el = document.getElementById('js-tree');
......@@ -58,7 +60,7 @@ export default () => {
});
},
methods: {
...mapActions(['setInitialParentItem', 'setInitialConfig']),
...Vuex.mapActions(['setInitialParentItem', 'setInitialConfig']),
},
render: createElement => createElement('related-items-tree-app'),
});
......
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
......@@ -6,8 +5,6 @@ import * as getters from './getters';
import mutations from './mutations';
import getDefaultState from './state';
Vue.use(Vuex);
const createStore = () =>
new Vuex.Store({
state: getDefaultState(),
......
import { mount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import CreateEpicForm from 'ee/related_items_tree/components/create_epic_form.vue';
const localVue = createLocalVue();
const createComponent = (isSubmitting = false) =>
mount(localVue.extend(CreateEpicForm), {
localVue,
shallowMount(CreateEpicForm, {
propsData: {
isSubmitting,
},
......@@ -31,31 +28,29 @@ describe('RelatedItemsTree', () => {
expect(wrapper.vm.isSubmitButtonDisabled).toBe(true);
});
it('returns false when either `inputValue` prop is non-empty or `isSubmitting` prop is false', done => {
it('returns false when either `inputValue` prop is non-empty or `isSubmitting` prop is false', () => {
const wrapperWithInput = createComponent(false);
wrapperWithInput.setData({
inputValue: 'foo',
});
wrapperWithInput.vm.$nextTick(() => {
return wrapperWithInput.vm.$nextTick(() => {
expect(wrapperWithInput.vm.isSubmitButtonDisabled).toBe(false);
wrapperWithInput.destroy();
done();
});
});
});
describe('buttonLabel', () => {
it('returns string "Creating epic" when `isSubmitting` prop is true', done => {
it('returns string "Creating epic" when `isSubmitting` prop is true', () => {
const wrapperSubmitting = createComponent(true);
wrapperSubmitting.vm.$nextTick(() => {
return wrapperSubmitting.vm.$nextTick(() => {
expect(wrapperSubmitting.vm.buttonLabel).toBe('Creating epic');
wrapperSubmitting.destroy();
done();
});
});
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import {
GlButton,
GlDropdown,
......@@ -12,14 +13,13 @@ import ProjectAvatar from '~/vue_shared/components/project_avatar/default.vue';
import CreateIssueForm from 'ee/related_items_tree/components/create_issue_form.vue';
import createDefaultStore from 'ee/related_items_tree/store';
// https://gitlab.com/gitlab-org/gitlab/issues/118456
import {
mockInitialConfig,
mockParentItem,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockInitialConfig, mockParentItem } from '../mock_data';
const mockProjects = getJSONFixture('static/projects.json');
const localVue = createLocalVue();
localVue.use(Vuex);
const createComponent = () => {
const store = createDefaultStore();
......@@ -27,6 +27,7 @@ const createComponent = () => {
store.dispatch('setInitialParentItem', mockParentItem);
return shallowMount(CreateIssueForm, {
localVue,
store,
});
};
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui';
import RelatedItemsTreeApp from 'ee/related_items_tree/components/related_items_tree_app.vue';
......@@ -13,16 +14,13 @@ import AxiosMockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { getJSONFixture } from 'helpers/fixtures';
// https://gitlab.com/gitlab-org/gitlab/issues/118456
import {
mockInitialConfig,
mockParentItem,
mockEpics,
mockIssues,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockInitialConfig, mockParentItem, mockEpics, mockIssues } from '../mock_data';
const mockProjects = getJSONFixture('static/projects.json');
const localVue = createLocalVue();
localVue.use(Vuex);
const createComponent = () => {
const store = createDefaultStore();
......@@ -34,6 +32,7 @@ const createComponent = () => {
});
return shallowMount(RelatedItemsTreeApp, {
localVue,
store,
});
};
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import RelatedItemsBody from 'ee/related_items_tree/components/related_items_tree_body.vue';
import { mockParentItem } from '../mock_data';
const localVue = createLocalVue();
const createComponent = (parentItem = mockParentItem, children = []) =>
shallowMount(localVue.extend(RelatedItemsBody), {
localVue,
shallowMount(RelatedItemsBody, {
stubs: {
'tree-root': true,
},
......@@ -32,7 +29,7 @@ describe('RelatedItemsTree', () => {
describe('template', () => {
it('renders component container element with class `related-items-tree-body`', () => {
expect(wrapper.vm.$el.classList.contains('related-items-tree-body')).toBe(true);
expect(wrapper.classes('related-items-tree-body')).toBe(true);
});
it('renders tree-root component', () => {
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlButton, GlTooltip } from '@gitlab/ui';
import RelatedItemsTreeHeader from 'ee/related_items_tree/components/related_items_tree_header.vue';
......@@ -8,11 +9,10 @@ import { issuableTypesMap } from 'ee/related_issues/constants';
import EpicActionsSplitButton from 'ee/related_items_tree/components/epic_actions_split_button.vue';
import Icon from '~/vue_shared/components/icon.vue';
import {
mockInitialConfig,
mockParentItem,
mockQueryResponse,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockInitialConfig, mockParentItem, mockQueryResponse } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
const createComponent = ({ slots } = {}) => {
const store = createDefaultStore();
......@@ -32,6 +32,7 @@ const createComponent = ({ slots } = {}) => {
store.dispatch('setChildrenCount', mockParentItem.descendantCounts);
return shallowMount(RelatedItemsTreeHeader, {
localVue,
store,
slots,
});
......@@ -73,7 +74,7 @@ describe('RelatedItemsTree', () => {
let toggleAddItemForm;
beforeEach(() => {
toggleAddItemForm = jasmine.createSpy();
toggleAddItemForm = jest.fn();
wrapper.vm.$store.hotUpdate({
actions: {
toggleAddItemForm,
......@@ -86,7 +87,7 @@ describe('RelatedItemsTree', () => {
expect(toggleAddItemForm).toHaveBeenCalled();
const payload = toggleAddItemForm.calls.mostRecent().args[1];
const payload = toggleAddItemForm.mock.calls[0][1];
expect(payload).toEqual({
issuableType: issuableTypesMap.EPIC,
......@@ -99,7 +100,7 @@ describe('RelatedItemsTree', () => {
let toggleCreateEpicForm;
beforeEach(() => {
toggleCreateEpicForm = jasmine.createSpy();
toggleCreateEpicForm = jest.fn();
wrapper.vm.$store.hotUpdate({
actions: {
toggleCreateEpicForm,
......@@ -112,7 +113,8 @@ describe('RelatedItemsTree', () => {
expect(toggleCreateEpicForm).toHaveBeenCalled();
const payload = toggleCreateEpicForm.calls.mostRecent().args[1];
const payload =
toggleCreateEpicForm.mock.calls[toggleCreateEpicForm.mock.calls.length - 1][1];
expect(payload).toEqual({ toggleState: true });
});
......@@ -129,8 +131,8 @@ describe('RelatedItemsTree', () => {
let setItemInputValue;
beforeEach(() => {
setItemInputValue = jasmine.createSpy();
toggleAddItemForm = jasmine.createSpy();
setItemInputValue = jest.fn();
toggleAddItemForm = jest.fn();
wrapper.vm.$store.hotUpdate({
actions: {
setItemInputValue,
......@@ -144,11 +146,11 @@ describe('RelatedItemsTree', () => {
expect(setItemInputValue).toHaveBeenCalled();
expect(setItemInputValue.calls.mostRecent().args[1]).toEqual('');
expect(setItemInputValue.mock.calls[setItemInputValue.mock.calls.length - 1][1]).toBe('');
expect(toggleAddItemForm).toHaveBeenCalled();
const payload = toggleAddItemForm.calls.mostRecent().args[1];
const payload = toggleAddItemForm.mock.calls[setItemInputValue.mock.calls.length - 1][1];
expect(payload).toEqual({
issuableType: issuableTypesMap.ISSUE,
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { GlTooltip } from '@gitlab/ui';
......@@ -14,8 +14,6 @@ const mockClosedAt = `${currentDate.getFullYear() - 1}-${currentDate.getMonth()
1}-${currentDate.getDate()}`;
const mockClosedAtYear = currentDate.getFullYear() - 1;
const localVue = createLocalVue();
const createComponent = ({
getTargetRef = () => {},
isOpen = false,
......@@ -23,8 +21,7 @@ const createComponent = ({
createdAt = mockCreatedAt,
closedAt = mockClosedAt,
}) =>
shallowMount(localVue.extend(StateTooltip), {
localVue,
shallowMount(StateTooltip, {
propsData: {
getTargetRef,
isOpen,
......@@ -48,27 +45,23 @@ describe('RelatedItemsTree', () => {
describe('computed', () => {
describe('stateText', () => {
it('returns string `Opened` when `isOpen` prop is true', done => {
it('returns string `Opened` when `isOpen` prop is true', () => {
wrapper.setProps({
isOpen: true,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateText).toBe('Opened');
done();
});
});
it('returns string `Closed` when `isOpen` prop is false', done => {
it('returns string `Closed` when `isOpen` prop is false', () => {
wrapper.setProps({
isOpen: false,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateText).toBe('Closed');
done();
});
});
});
......@@ -98,53 +91,45 @@ describe('RelatedItemsTree', () => {
});
describe('stateTimeInWords', () => {
it('returns string using `createdAtInWords` prop when `isOpen` is true', done => {
it('returns string using `createdAtInWords` prop when `isOpen` is true', () => {
wrapper.setProps({
isOpen: true,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateTimeInWords).toBe('2 years ago');
done();
});
});
it('returns string using `closedAtInWords` prop when `isOpen` is false', done => {
it('returns string using `closedAtInWords` prop when `isOpen` is false', () => {
wrapper.setProps({
isOpen: false,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateTimeInWords).toBe('1 year ago');
done();
});
});
});
describe('stateTimestamp', () => {
it('returns string using `createdAtTimestamp` prop when `isOpen` is true', done => {
it('returns string using `createdAtTimestamp` prop when `isOpen` is true', () => {
wrapper.setProps({
isOpen: true,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateTimestamp).toContain(mockCreatedAtYear);
done();
});
});
it('returns string using `closedAtInWords` prop when `isOpen` is false', done => {
it('returns string using `closedAtInWords` prop when `isOpen` is false', () => {
wrapper.setProps({
isOpen: false,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateTimestamp).toContain(mockClosedAtYear);
done();
});
});
});
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlButton, GlLink } from '@gitlab/ui';
import ItemWeight from 'ee/boards/components/issue_card_weight.vue';
......@@ -15,12 +16,10 @@ import ItemDueDate from '~/boards/components/issue_due_date.vue';
import ItemMilestone from '~/vue_shared/components/issue/issue_milestone.vue';
import Icon from '~/vue_shared/components/icon.vue';
import {
mockParentItem,
mockInitialConfig,
mockQueryResponse,
mockIssue1,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockParentItem, mockInitialConfig, mockQueryResponse, mockIssue1 } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
const mockItem = Object.assign({}, mockIssue1, {
type: ChildType.Issue,
......@@ -45,6 +44,7 @@ const createComponent = (parentItem = mockParentItem, item = mockItem) => {
});
return shallowMount(TreeItemBody, {
localVue,
store,
propsData: {
parentItem,
......@@ -75,7 +75,7 @@ describe('RelatedItemsTree', () => {
describe('itemWebPath', () => {
const mockPath = '/foo/bar';
it('returns value of `item.path`', done => {
it('returns value of `item.path`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
path: mockPath,
......@@ -83,14 +83,12 @@ describe('RelatedItemsTree', () => {
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.itemWebPath).toBe(mockPath);
done();
});
});
it('returns value of `item.webPath` when `item.path` is undefined', done => {
it('returns value of `item.webPath` when `item.path` is undefined', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
path: undefined,
......@@ -98,42 +96,36 @@ describe('RelatedItemsTree', () => {
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.itemWebPath).toBe(mockPath);
done();
});
});
});
describe('isOpen', () => {
it('returns true when `item.state` value is `opened`', done => {
it('returns true when `item.state` value is `opened`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Open,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.isOpen).toBe(true);
done();
});
});
});
describe('isClosed', () => {
it('returns true when `item.state` value is `closed`', done => {
it('returns true when `item.state` value is `closed`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Closed,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.isClosed).toBe(true);
done();
});
});
});
......@@ -151,91 +143,79 @@ describe('RelatedItemsTree', () => {
});
describe('stateText', () => {
it('returns string `Opened` when `item.state` value is `opened`', done => {
it('returns string `Opened` when `item.state` value is `opened`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Open,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateText).toBe('Opened');
done();
});
});
it('returns string `Closed` when `item.state` value is `closed`', done => {
it('returns string `Closed` when `item.state` value is `closed`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Closed,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateText).toBe('Closed');
done();
});
});
});
describe('stateIconName', () => {
it('returns string `epic` when `item.type` value is `epic`', done => {
it('returns string `epic` when `item.type` value is `epic`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
type: ChildType.Epic,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconName).toBe('epic');
done();
});
});
it('returns string `issues` when `item.type` value is `issue`', done => {
it('returns string `issues` when `item.type` value is `issue`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
type: ChildType.Issue,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconName).toBe('issues');
done();
});
});
});
describe('stateIconClass', () => {
it('returns string `issue-token-state-icon-open` when `item.state` value is `opened`', done => {
it('returns string `issue-token-state-icon-open` when `item.state` value is `opened`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Open,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconClass).toBe('issue-token-state-icon-open');
done();
});
});
it('returns string `issue-token-state-icon-closed` when `item.state` value is `closed`', done => {
it('returns string `issue-token-state-icon-closed` when `item.state` value is `closed`', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
state: ChildState.Closed,
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconClass).toBe('issue-token-state-icon-closed');
done();
});
});
});
......@@ -257,17 +237,15 @@ describe('RelatedItemsTree', () => {
expect(wrapper.vm.computedPath).toBe(mockItem.webPath);
});
it('returns `null` when `itemWebPath` is empty', done => {
it('returns `null` when `itemWebPath` is empty', () => {
wrapper.setProps({
item: Object.assign({}, mockItem, {
webPath: '',
}),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.computedPath).toBeNull();
done();
});
});
});
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlModal } from '@gitlab/ui';
import TreeItemRemoveModal from 'ee/related_items_tree/components/tree_item_remove_modal.vue';
......@@ -10,14 +11,15 @@ import { PathIdSeparator } from 'ee/related_issues/constants';
import { mockParentItem, mockQueryResponse, mockIssue1 } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
const mockItem = Object.assign({}, mockIssue1, {
type: ChildType.Issue,
pathIdSeparator: PathIdSeparator.Issue,
assignees: epicUtils.extractIssueAssignees(mockIssue1.assignees),
});
const localVue = createLocalVue();
const createComponent = (parentItem = mockParentItem, item = mockItem) => {
const store = createDefaultStore();
const children = epicUtils.processQueryResponse(mockQueryResponse.data.group);
......@@ -37,7 +39,7 @@ const createComponent = (parentItem = mockParentItem, item = mockItem) => {
item,
});
return shallowMount(localVue.extend(TreeItemRemoveModal), {
return shallowMount(TreeItemRemoveModal, {
localVue,
store,
});
......@@ -63,61 +65,53 @@ describe('RelatedItemsTree', () => {
});
describe('modalTitle', () => {
it('returns title for modal when item.type is `Epic`', done => {
it('returns title for modal when item.type is `Epic`', () => {
wrapper.vm.$store.dispatch('setRemoveItemModalProps', {
parentItem: mockParentItem,
item: Object.assign({}, mockItem, { type: ChildType.Epic }),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.modalTitle).toBe('Remove epic');
done();
});
});
it('returns title for modal when item.type is `Issue`', done => {
it('returns title for modal when item.type is `Issue`', () => {
wrapper.vm.$store.dispatch('setRemoveItemModalProps', {
parentItem: mockParentItem,
item: mockItem,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.modalTitle).toBe('Remove issue');
done();
});
});
});
describe('modalBody', () => {
it('returns body text for modal when item.type is `Epic`', done => {
it('returns body text for modal when item.type is `Epic`', () => {
wrapper.vm.$store.dispatch('setRemoveItemModalProps', {
parentItem: mockParentItem,
item: Object.assign({}, mockItem, { type: ChildType.Epic }),
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.modalBody).toBe(
'This will also remove any descendents of <b>Nostrum cum mollitia quia recusandae fugit deleniti voluptatem delectus.</b> from <b>Some sample epic</b>. Are you sure?',
);
done();
});
});
it('returns body text for modal when item.type is `Issue`', done => {
it('returns body text for modal when item.type is `Issue`', () => {
wrapper.vm.$store.dispatch('setRemoveItemModalProps', {
parentItem: mockParentItem,
item: mockItem,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.modalBody).toBe(
'Are you sure you want to remove <b>Nostrum cum mollitia quia recusandae fugit deleniti voluptatem delectus.</b> from <b>Some sample epic</b>?',
);
done();
});
});
});
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import TreeItem from 'ee/related_items_tree/components/tree_item.vue';
......@@ -12,17 +13,16 @@ import { PathIdSeparator } from 'ee/related_issues/constants';
import Icon from '~/vue_shared/components/icon.vue';
import {
mockParentItem,
mockQueryResponse,
mockEpic1,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockParentItem, mockQueryResponse, mockEpic1 } from '../mock_data';
const mockItem = Object.assign({}, mockEpic1, {
type: ChildType.Epic,
pathIdSeparator: PathIdSeparator.Epic,
});
const localVue = createLocalVue();
localVue.use(Vuex);
const createComponent = (parentItem = mockParentItem, item = mockItem) => {
const store = createDefaultStore();
const children = epicUtils.processQueryResponse(mockQueryResponse.data.group);
......@@ -44,6 +44,7 @@ const createComponent = (parentItem = mockParentItem, item = mockItem) => {
});
return shallowMount(TreeItem, {
localVue,
store,
stubs: {
'tree-root': TreeRoot,
......@@ -158,18 +159,16 @@ describe('RelatedItemsTree', () => {
expect(collapsedIcon.props('name')).toBe('chevron-right');
});
it('renders loading icon when item expand is in progress', done => {
it('renders loading icon when item expand is in progress', () => {
wrapper.vm.$store.dispatch('requestItems', {
parentItem: mockItem,
isSubItem: true,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
const loadingIcon = wrapper.find(GlLoadingIcon);
expect(loadingIcon.isVisible()).toBe(true);
done();
});
});
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlButton } from '@gitlab/ui';
import Draggable from 'vuedraggable';
......@@ -20,6 +21,7 @@ import {
const { epic } = mockQueryResponse.data.group;
const localVue = createLocalVue();
localVue.use(Vuex);
const createComponent = ({
parentItem = mockParentItem,
......@@ -46,7 +48,7 @@ const createComponent = ({
pageInfo: issuesPageInfo,
});
return shallowMount(localVue.extend(TreeRoot), {
return shallowMount(TreeRoot, {
localVue,
store,
stubs: {
......@@ -106,7 +108,7 @@ describe('RelatedItemsTree', () => {
describe('treeRootOptions', () => {
it('should return object containing Vue.Draggable config extended from `defaultSortableConfig` when userSignedIn prop is true', () => {
expect(wrapper.vm.treeRootOptions).toEqual(
jasmine.objectContaining({
expect.objectContaining({
animation: 200,
forceFallback: true,
fallbackClass: 'is-dragging',
......@@ -128,7 +130,7 @@ describe('RelatedItemsTree', () => {
userSignedIn: false,
});
expect(wrapper.vm.treeRootOptions).toEqual(jasmine.objectContaining({}));
expect(wrapper.vm.treeRootOptions).toEqual(expect.objectContaining({}));
});
});
});
......@@ -156,7 +158,7 @@ describe('RelatedItemsTree', () => {
newIndex,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
id: mockEpic1.id,
}),
);
......@@ -167,7 +169,7 @@ describe('RelatedItemsTree', () => {
newIndex,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
id: mockIssue2.epicIssueId,
}),
);
......@@ -182,7 +184,7 @@ describe('RelatedItemsTree', () => {
newIndex: 0,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
adjacentReferenceId: mockEpic1.id,
}),
);
......@@ -193,7 +195,7 @@ describe('RelatedItemsTree', () => {
newIndex: 2,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
adjacentReferenceId: mockIssue2.epicIssueId,
}),
);
......@@ -208,7 +210,7 @@ describe('RelatedItemsTree', () => {
newIndex: 0,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
relativePosition: 'after',
}),
);
......@@ -223,7 +225,7 @@ describe('RelatedItemsTree', () => {
newIndex: wrapper.vm.children.length - 1,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
relativePosition: 'before',
}),
);
......@@ -238,7 +240,7 @@ describe('RelatedItemsTree', () => {
newIndex: 2,
}),
).toEqual(
jasmine.objectContaining({
expect.objectContaining({
relativePosition: 'after',
}),
);
......@@ -257,7 +259,7 @@ describe('RelatedItemsTree', () => {
describe('handleDragOnEnd', () => {
it('removes class `is-dragging` from document body', () => {
spyOn(wrapper.vm, 'reorderItem').and.stub();
jest.spyOn(wrapper.vm, 'reorderItem').mockImplementation(() => {});
document.body.classList.add('is-dragging');
wrapper.vm.handleDragOnEnd({
......@@ -269,7 +271,7 @@ describe('RelatedItemsTree', () => {
});
it('does not call `reorderItem` action when newIndex is same as oldIndex', () => {
spyOn(wrapper.vm, 'reorderItem').and.stub();
jest.spyOn(wrapper.vm, 'reorderItem').mockImplementation(() => {});
wrapper.vm.handleDragOnEnd({
oldIndex: 0,
......@@ -280,7 +282,7 @@ describe('RelatedItemsTree', () => {
});
it('calls `reorderItem` action when newIndex is different from oldIndex', () => {
spyOn(wrapper.vm, 'reorderItem').and.stub();
jest.spyOn(wrapper.vm, 'reorderItem').mockImplementation(() => {});
wrapper.vm.handleDragOnEnd({
oldIndex: 1,
......@@ -288,8 +290,8 @@ describe('RelatedItemsTree', () => {
});
expect(wrapper.vm.reorderItem).toHaveBeenCalledWith(
jasmine.objectContaining({
treeReorderMutation: jasmine.any(Object),
expect.objectContaining({
treeReorderMutation: expect.any(Object),
parentItem: wrapper.vm.parentItem,
targetItem: wrapper.vm.children[1],
oldIndex: 1,
......@@ -330,13 +332,15 @@ describe('RelatedItemsTree', () => {
describe('methods', () => {
describe('handleShowMoreClick', () => {
it('sets `fetchInProgress` to true and calls `fetchNextPageItems` action with parentItem as param', () => {
spyOn(wrapper.vm, 'fetchNextPageItems').and.callFake(() => new Promise(() => {}));
jest
.spyOn(wrapper.vm, 'fetchNextPageItems')
.mockImplementation(() => new Promise(() => {}));
wrapper.vm.handleShowMoreClick();
expect(wrapper.vm.fetchInProgress).toBe(true);
expect(wrapper.vm.fetchNextPageItems).toHaveBeenCalledWith(
jasmine.objectContaining({
expect.objectContaining({
parentItem: mockParentItem,
}),
);
......@@ -354,7 +358,7 @@ describe('RelatedItemsTree', () => {
});
it('calls `handleShowMoreClick` when `Show more` link is clicked', () => {
spyOn(wrapper.vm, 'handleShowMoreClick');
jest.spyOn(wrapper.vm, 'handleShowMoreClick').mockImplementation(() => {});
wrapper.find(GlButton).vm.$emit('click');
......
import MockAdapter from 'axios-mock-adapter';
import createFlash from '~/flash';
import createDefaultState from 'ee/related_items_tree/store/state';
import actionsModule, * as actions from 'ee/related_items_tree/store/actions';
import * as actions from 'ee/related_items_tree/store/actions';
import * as types from 'ee/related_items_tree/store/mutation_types';
import * as epicUtils from 'ee/related_items_tree/utils/epic_utils';
......@@ -12,7 +12,7 @@ import {
PathIdSeparator,
} from 'ee/related_issues/constants';
import testAction from 'spec/helpers/vuex_action_helper';
import testAction from 'helpers/vuex_action_helper';
import axios from '~/lib/utils/axios_utils';
import { TEST_HOST } from 'spec/test_constants';
......@@ -29,7 +29,13 @@ import {
const mockProjects = getJSONFixture('static/projects.json');
jest.mock('~/flash');
describe('RelatedItemTree', () => {
afterEach(() => {
createFlash.mockClear();
});
describe('store', () => {
describe('actions', () => {
let state;
......@@ -42,44 +48,41 @@ describe('RelatedItemTree', () => {
});
describe('setInitialConfig', () => {
it('should set initial config on state', done => {
it('should set initial config on state', () => {
testAction(
actions.setInitialConfig,
mockInitialConfig,
{},
[{ type: types.SET_INITIAL_CONFIG, payload: mockInitialConfig }],
[],
done,
);
});
});
describe('setInitialParentItem', () => {
it('should set initial parentItem on state', done => {
it('should set initial parentItem on state', () => {
testAction(
actions.setInitialParentItem,
mockParentItem,
{},
[{ type: types.SET_INITIAL_PARENT_ITEM, payload: mockParentItem }],
[],
done,
);
});
});
describe('setChildrenCount', () => {
it('should set initial descendantCounts on state', done => {
it('should set initial descendantCounts on state', () => {
testAction(
actions.setChildrenCount,
mockParentItem.descendantCounts,
{},
[{ type: types.SET_CHILDREN_COUNT, payload: mockParentItem.descendantCounts }],
[],
done,
);
});
it('should persist non overwritten descendantCounts state', done => {
it('should persist non overwritten descendantCounts state', () => {
const descendantCounts = { openedEpics: 9 };
testAction(
actions.setChildrenCount,
......@@ -92,7 +95,6 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
});
......@@ -110,7 +112,7 @@ describe('RelatedItemTree', () => {
}),
);
it('should update openedEpics, by incrementing it', done => {
it('should update openedEpics, by incrementing it', () => {
testAction(
actions.updateChildrenCount,
{ item: mockEpicsWithType[0], isRemoved: false },
......@@ -122,11 +124,10 @@ describe('RelatedItemTree', () => {
payload: { openedEpics: mockParentItem.descendantCounts.openedEpics + 1 },
},
],
done,
);
});
it('should update openedIssues, by incrementing it', done => {
it('should update openedIssues, by incrementing it', () => {
testAction(
actions.updateChildrenCount,
{ item: mockIssuesWithType[0], isRemoved: false },
......@@ -138,11 +139,10 @@ describe('RelatedItemTree', () => {
payload: { openedIssues: mockParentItem.descendantCounts.openedIssues + 1 },
},
],
done,
);
});
it('should update openedEpics, by decrementing it', done => {
it('should update openedEpics, by decrementing it', () => {
testAction(
actions.updateChildrenCount,
{ item: mockEpicsWithType[0], isRemoved: true },
......@@ -154,11 +154,10 @@ describe('RelatedItemTree', () => {
payload: { openedEpics: mockParentItem.descendantCounts.openedEpics - 1 },
},
],
done,
);
});
it('should update openedIssues, by decrementing it', done => {
it('should update openedIssues, by decrementing it', () => {
testAction(
actions.updateChildrenCount,
{ item: mockIssuesWithType[0], isRemoved: true },
......@@ -170,33 +169,24 @@ describe('RelatedItemTree', () => {
payload: { openedIssues: mockParentItem.descendantCounts.openedIssues - 1 },
},
],
done,
);
});
});
describe('expandItem', () => {
it('should set `itemExpanded` to true on state.childrenFlags', done => {
testAction(
actions.expandItem,
{},
{},
[{ type: types.EXPAND_ITEM, payload: {} }],
[],
done,
);
it('should set `itemExpanded` to true on state.childrenFlags', () => {
testAction(actions.expandItem, {}, {}, [{ type: types.EXPAND_ITEM, payload: {} }], []);
});
});
describe('collapseItem', () => {
it('should set `itemExpanded` to false on state.childrenFlags', done => {
it('should set `itemExpanded` to false on state.childrenFlags', () => {
testAction(
actions.collapseItem,
{},
{},
[{ type: types.COLLAPSE_ITEM, payload: {} }],
[],
done,
);
});
});
......@@ -209,7 +199,7 @@ describe('RelatedItemTree', () => {
append: false,
};
it('should set provided `children` values on state.children with provided parentItem.reference key', done => {
it('should set provided `children` values on state.children with provided parentItem.reference key', () => {
testAction(
actions.setItemChildren,
mockPayload,
......@@ -221,11 +211,10 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
it('should set provided `children` values on state.children with provided parentItem.reference key and also dispatch action `expandItem` when isSubItem param is true', done => {
it('should set provided `children` values on state.children with provided parentItem.reference key and also dispatch action `expandItem` when isSubItem param is true', () => {
mockPayload.isSubItem = true;
testAction(
......@@ -244,26 +233,24 @@ describe('RelatedItemTree', () => {
payload: { parentItem: mockPayload.parentItem },
},
],
done,
);
});
});
describe('setItemChildrenFlags', () => {
it('should set `state.childrenFlags` for every item in provided children param', done => {
it('should set `state.childrenFlags` for every item in provided children param', () => {
testAction(
actions.setItemChildrenFlags,
{ children: [{ reference: '&1' }] },
{},
[{ type: types.SET_ITEM_CHILDREN_FLAGS, payload: { children: [{ reference: '&1' }] } }],
[],
done,
);
});
});
describe('setEpicPageInfo', () => {
it('should set `epicEndCursor` and `hasMoreEpics` to `state.childrenFlags`', done => {
it('should set `epicEndCursor` and `hasMoreEpics` to `state.childrenFlags`', () => {
const { pageInfo } = mockQueryResponse.data.group.epic.children;
testAction(
......@@ -277,13 +264,12 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
});
describe('setIssuePageInfo', () => {
it('should set `issueEndCursor` and `hasMoreIssues` to `state.childrenFlags`', done => {
it('should set `issueEndCursor` and `hasMoreIssues` to `state.childrenFlags`', () => {
const { pageInfo } = mockQueryResponse.data.group.epic.issues;
testAction(
......@@ -297,50 +283,42 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
});
describe('requestItems', () => {
it('should set `state.itemsFetchInProgress` to true', done => {
it('should set `state.itemsFetchInProgress` to true', () => {
testAction(
actions.requestItems,
{},
{},
[{ type: types.REQUEST_ITEMS, payload: {} }],
[],
done,
);
});
});
describe('receiveItemsSuccess', () => {
it('should set `state.itemsFetchInProgress` to false', done => {
it('should set `state.itemsFetchInProgress` to false', () => {
testAction(
actions.receiveItemsSuccess,
{},
{},
[{ type: types.RECEIVE_ITEMS_SUCCESS, payload: {} }],
[],
done,
);
});
});
describe('receiveItemsFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should set `state.itemsFetchInProgress` to false', done => {
it('should set `state.itemsFetchInProgress` to false', () => {
testAction(
actions.receiveItemsFailure,
{},
{},
[{ type: types.RECEIVE_ITEMS_FAILURE, payload: {} }],
[],
done,
);
});
......@@ -353,14 +331,12 @@ describe('RelatedItemTree', () => {
{},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
describe('fetchItems', () => {
it('should dispatch `requestItems` action', done => {
it('should dispatch `requestItems` action', () => {
testAction(
actions.fetchItems,
{ parentItem: mockParentItem, isSubItem: false },
......@@ -372,12 +348,11 @@ describe('RelatedItemTree', () => {
payload: { parentItem: mockParentItem, isSubItem: false },
},
],
done,
);
});
it('should dispatch `receiveItemsSuccess`, `setItemChildren`, `setItemChildrenFlags`, `setEpicPageInfo` and `setIssuePageInfo` on request success', done => {
spyOn(epicUtils.gqClient, 'query').and.returnValue(
it('should dispatch `receiveItemsSuccess`, `setItemChildren`, `setItemChildrenFlags`, `setEpicPageInfo` and `setIssuePageInfo` on request success', () => {
jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue(
Promise.resolve({
data: mockQueryResponse.data,
}),
......@@ -442,12 +417,11 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
it('should dispatch `receiveItemsFailure` on request failure', done => {
spyOn(epicUtils.gqClient, 'query').and.returnValue(Promise.reject());
it('should dispatch `receiveItemsFailure` on request failure', () => {
jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue(Promise.reject());
testAction(
actions.fetchItems,
......@@ -467,16 +441,11 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
});
describe('receiveNextPageItemsFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should show flash error with message "Something went wrong while fetching child epics."', () => {
const message = 'Something went wrong while fetching child epics.';
actions.receiveNextPageItemsFailure(
......@@ -486,15 +455,13 @@ describe('RelatedItemTree', () => {
{},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
describe('fetchNextPageItems', () => {
it('should dispatch `setItemChildren`, `setItemChildrenFlags`, `setEpicPageInfo` and `setIssuePageInfo` on request success', done => {
spyOn(epicUtils.gqClient, 'query').and.returnValue(
it('should dispatch `setItemChildren`, `setItemChildrenFlags`, `setEpicPageInfo` and `setIssuePageInfo` on request success', () => {
jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue(
Promise.resolve({
data: mockQueryResponse.data,
}),
......@@ -540,12 +507,11 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
it('should dispatch `receiveNextPageItemsFailure` on request failure', done => {
spyOn(epicUtils.gqClient, 'query').and.returnValue(Promise.reject());
it('should dispatch `receiveNextPageItemsFailure` on request failure', () => {
jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue(Promise.reject());
testAction(
actions.fetchNextPageItems,
......@@ -560,7 +526,6 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
});
......@@ -572,7 +537,7 @@ describe('RelatedItemTree', () => {
},
};
it('should dispatch `fetchItems` when a parent item is not expanded and does not have children present in state', done => {
it('should dispatch `fetchItems` when a parent item is not expanded and does not have children present in state', () => {
state.childrenFlags[data.parentItem.reference] = {
itemExpanded: false,
};
......@@ -588,11 +553,10 @@ describe('RelatedItemTree', () => {
payload: { parentItem: data.parentItem, isSubItem: true },
},
],
done,
);
});
it('should dispatch `expandItem` when a parent item is not expanded but does have children present in state', done => {
it('should dispatch `expandItem` when a parent item is not expanded but does have children present in state', () => {
state.childrenFlags[data.parentItem.reference] = {
itemExpanded: false,
};
......@@ -609,11 +573,10 @@ describe('RelatedItemTree', () => {
payload: { parentItem: data.parentItem },
},
],
done,
);
});
it('should dispatch `collapseItem` when a parent item is expanded', done => {
it('should dispatch `collapseItem` when a parent item is expanded', () => {
state.childrenFlags[data.parentItem.reference] = {
itemExpanded: true,
};
......@@ -629,46 +592,42 @@ describe('RelatedItemTree', () => {
payload: { parentItem: data.parentItem },
},
],
done,
);
});
});
describe('setRemoveItemModalProps', () => {
it('should set values on `state.removeItemModalProps` for initializing modal', done => {
it('should set values on `state.removeItemModalProps` for initializing modal', () => {
testAction(
actions.setRemoveItemModalProps,
{},
{},
[{ type: types.SET_REMOVE_ITEM_MODAL_PROPS, payload: {} }],
[],
done,
);
});
});
describe('requestRemoveItem', () => {
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to true', done => {
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to true', () => {
testAction(
actions.requestRemoveItem,
{},
{},
[{ type: types.REQUEST_REMOVE_ITEM, payload: {} }],
[],
done,
);
});
});
describe('receiveRemoveItemSuccess', () => {
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to false', done => {
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to false', () => {
testAction(
actions.receiveRemoveItemSuccess,
{},
{},
[{ type: types.RECEIVE_REMOVE_ITEM_SUCCESS, payload: {} }],
[],
done,
);
});
});
......@@ -678,7 +637,7 @@ describe('RelatedItemTree', () => {
setFixtures('<div class="flash-container"></div>');
});
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to false', done => {
it('should set `state.childrenFlags[ref].itemRemoveInProgress` to false', () => {
testAction(
actions.receiveRemoveItemFailure,
{ item: { type: ChildType.Epic } },
......@@ -690,7 +649,6 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
......@@ -704,9 +662,7 @@ describe('RelatedItemTree', () => {
},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
'An error occurred while removing epics.',
);
expect(createFlash).toHaveBeenCalledWith('An error occurred while removing epics.');
});
});
......@@ -728,7 +684,7 @@ describe('RelatedItemTree', () => {
mock.restore();
});
it('should dispatch `requestRemoveItem` and `receiveRemoveItemSuccess` actions on request success', done => {
it('should dispatch `requestRemoveItem` and `receiveRemoveItemSuccess` actions on request success', () => {
mock.onDelete(data.item.relationPath).replyOnce(200, {});
testAction(
......@@ -750,11 +706,10 @@ describe('RelatedItemTree', () => {
payload: { item: data.item, isRemoved: true },
},
],
done,
);
});
it('should dispatch `requestRemoveItem` and `receiveRemoveItemFailure` actions on request failure', done => {
it('should dispatch `requestRemoveItem` and `receiveRemoveItemFailure` actions on request failure', () => {
mock.onDelete(data.item.relationPath).replyOnce(500, {});
testAction(
......@@ -772,110 +727,102 @@ describe('RelatedItemTree', () => {
payload: { item: data.item, status: undefined },
},
],
done,
);
});
});
describe('toggleAddItemForm', () => {
it('should set `state.showAddItemForm` to true', done => {
it('should set `state.showAddItemForm` to true', () => {
testAction(
actions.toggleAddItemForm,
{},
{},
[{ type: types.TOGGLE_ADD_ITEM_FORM, payload: {} }],
[],
done,
);
});
});
describe('toggleCreateEpicForm', () => {
it('should set `state.showCreateEpicForm` to true', done => {
it('should set `state.showCreateEpicForm` to true', () => {
testAction(
actions.toggleCreateEpicForm,
{},
{},
[{ type: types.TOGGLE_CREATE_EPIC_FORM, payload: {} }],
[],
done,
);
});
});
describe('toggleCreateIssueForm', () => {
it('should set `state.showCreateIssueForm` to true and `state.showAddItemForm` to false', done => {
it('should set `state.showCreateIssueForm` to true and `state.showAddItemForm` to false', () => {
testAction(
actions.toggleCreateIssueForm,
{},
{},
[{ type: types.TOGGLE_CREATE_ISSUE_FORM, payload: {} }],
[],
done,
);
});
});
describe('setPendingReferences', () => {
it('should set param value to `state.pendingReference`', done => {
it('should set param value to `state.pendingReference`', () => {
testAction(
actions.setPendingReferences,
{},
{},
[{ type: types.SET_PENDING_REFERENCES, payload: {} }],
[],
done,
);
});
});
describe('addPendingReferences', () => {
it('should add param value to `state.pendingReference`', done => {
it('should add param value to `state.pendingReference`', () => {
testAction(
actions.addPendingReferences,
{},
{},
[{ type: types.ADD_PENDING_REFERENCES, payload: {} }],
[],
done,
);
});
});
describe('removePendingReference', () => {
it('should remove param value to `state.pendingReference`', done => {
it('should remove param value to `state.pendingReference`', () => {
testAction(
actions.removePendingReference,
{},
{},
[{ type: types.REMOVE_PENDING_REFERENCE, payload: {} }],
[],
done,
);
});
});
describe('setItemInputValue', () => {
it('should set param value to `state.itemInputValue`', done => {
it('should set param value to `state.itemInputValue`', () => {
testAction(
actions.setItemInputValue,
{},
{},
[{ type: types.SET_ITEM_INPUT_VALUE, payload: {} }],
[],
done,
);
});
});
describe('requestAddItem', () => {
it('should set `state.itemAddInProgress` to true', done => {
testAction(actions.requestAddItem, {}, {}, [{ type: types.REQUEST_ADD_ITEM }], [], done);
it('should set `state.itemAddInProgress` to true', () => {
testAction(actions.requestAddItem, {}, {}, [{ type: types.REQUEST_ADD_ITEM }], []);
});
});
describe('receiveAddItemSuccess', () => {
it('should set `state.itemAddInProgress` to false and dispatches actions `setPendingReferences`, `setItemInputValue` and `toggleAddItemForm`', done => {
it('should set `state.itemAddInProgress` to false and dispatches actions `setPendingReferences`, `setItemInputValue` and `toggleAddItemForm`', () => {
state.issuableType = issuableTypesMap.EPIC;
state.isEpic = true;
......@@ -925,13 +872,12 @@ describe('RelatedItemTree', () => {
payload: { toggleState: false },
},
],
done,
);
});
});
describe('receiveAddItemFailure', () => {
it('should set `state.itemAddInProgress` to false', done => {
it('should set `state.itemAddInProgress` to false', () => {
testAction(
actions.receiveAddItemFailure,
{
......@@ -949,11 +895,10 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
it('should set `state.itemAddInProgress` to false, no payload', done => {
it('should set `state.itemAddInProgress` to false, no payload', () => {
testAction(
actions.receiveAddItemFailure,
undefined,
......@@ -965,7 +910,6 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
});
......@@ -981,7 +925,7 @@ describe('RelatedItemTree', () => {
mock.restore();
});
it('should dispatch `requestAddItem` and `receiveAddItemSuccess` actions on request success', done => {
it('should dispatch `requestAddItem` and `receiveAddItemSuccess` actions on request success', () => {
state.issuableType = issuableTypesMap.EPIC;
state.epicsEndpoint = '/foo/bar';
state.pendingReferences = ['foo'];
......@@ -1003,11 +947,10 @@ describe('RelatedItemTree', () => {
payload: { rawItems: [mockEpic1] },
},
],
done,
);
});
it('should dispatch `requestAddItem` and `receiveAddItemFailure` actions on request failure', done => {
it('should dispatch `requestAddItem` and `receiveAddItemFailure` actions on request failure', () => {
state.issuableType = issuableTypesMap.EPIC;
state.epicsEndpoint = '/foo/bar';
state.pendingReferences = ['foo'];
......@@ -1030,26 +973,18 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
});
describe('requestCreateItem', () => {
it('should set `state.itemCreateInProgress` to true', done => {
testAction(
actions.requestCreateItem,
{},
{},
[{ type: types.REQUEST_CREATE_ITEM }],
[],
done,
);
it('should set `state.itemCreateInProgress` to true', () => {
testAction(actions.requestCreateItem, {}, {}, [{ type: types.REQUEST_CREATE_ITEM }], []);
});
});
describe('receiveCreateItemSuccess', () => {
it('should set `state.itemCreateInProgress` to false', done => {
it('should set `state.itemCreateInProgress` to false', () => {
const createdEpic = Object.assign({}, mockEpics[0], {
id: `gid://gitlab/Epic/${mockEpics[0].id}`,
reference: `${mockEpics[0].group.fullPath}${mockEpics[0].reference}`,
......@@ -1085,24 +1020,18 @@ describe('RelatedItemTree', () => {
payload: { toggleState: false },
},
],
done,
);
});
});
describe('receiveCreateItemFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should set `state.itemCreateInProgress` to false', done => {
it('should set `state.itemCreateInProgress` to false', () => {
testAction(
actions.receiveCreateItemFailure,
{},
{},
[{ type: types.RECEIVE_CREATE_ITEM_FAILURE }],
[],
done,
);
});
......@@ -1118,9 +1047,7 @@ describe('RelatedItemTree', () => {
},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
......@@ -1137,7 +1064,7 @@ describe('RelatedItemTree', () => {
mock.restore();
});
it('should dispatch `requestCreateItem` and `receiveCreateItemSuccess` actions on request success', done => {
it('should dispatch `requestCreateItem` and `receiveCreateItemSuccess` actions on request success', () => {
mock.onPost(/(.*)/).replyOnce(200, mockEpic1);
testAction(
......@@ -1160,11 +1087,10 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
it('should dispatch `requestCreateItem` and `receiveCreateItemFailure` actions on request failure', done => {
it('should dispatch `requestCreateItem` and `receiveCreateItemFailure` actions on request failure', () => {
mock.onPost(/(.*)/).replyOnce(500, {});
testAction(
......@@ -1180,24 +1106,18 @@ describe('RelatedItemTree', () => {
type: 'receiveCreateItemFailure',
},
],
done,
);
});
});
describe('receiveReorderItemFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should revert reordered item back to its original position via REORDER_ITEM mutation', done => {
it('should revert reordered item back to its original position via REORDER_ITEM mutation', () => {
testAction(
actions.receiveReorderItemFailure,
{},
{},
[{ type: types.REORDER_ITEM, payload: {} }],
[],
done,
);
});
......@@ -1212,15 +1132,13 @@ describe('RelatedItemTree', () => {
},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
describe('reorderItem', () => {
it('should perform REORDER_ITEM mutation before request and do nothing on request success', done => {
spyOn(epicUtils.gqClient, 'mutate').and.returnValue(
it('should perform REORDER_ITEM mutation before request and do nothing on request success', () => {
jest.spyOn(epicUtils.gqClient, 'mutate').mockReturnValue(
Promise.resolve({
data: mockReorderMutationResponse,
}),
......@@ -1248,12 +1166,11 @@ describe('RelatedItemTree', () => {
},
],
[],
done,
);
});
it('should perform REORDER_ITEM mutation before request and dispatch `receiveReorderItemFailure` when request response has errors on request success', done => {
spyOn(epicUtils.gqClient, 'mutate').and.returnValue(
it('should perform REORDER_ITEM mutation before request and dispatch `receiveReorderItemFailure` when request response has errors on request success', () => {
jest.spyOn(epicUtils.gqClient, 'mutate').mockReturnValue(
Promise.resolve({
data: {
epicTreeReorder: {
......@@ -1296,12 +1213,11 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
it('should perform REORDER_ITEM mutation before request and dispatch `receiveReorderItemFailure` on request failure', done => {
spyOn(epicUtils.gqClient, 'mutate').and.returnValue(Promise.reject());
it('should perform REORDER_ITEM mutation before request and dispatch `receiveReorderItemFailure` on request failure', () => {
jest.spyOn(epicUtils.gqClient, 'mutate').mockReturnValue(Promise.reject());
testAction(
actions.reorderItem,
......@@ -1335,37 +1251,30 @@ describe('RelatedItemTree', () => {
},
},
],
done,
);
});
});
describe('receiveCreateIssueSuccess', () => {
it('should set `state.itemCreateInProgress` & `state.itemsFetchResultEmpty` to false', done => {
it('should set `state.itemCreateInProgress` & `state.itemsFetchResultEmpty` to false', () => {
testAction(
actions.receiveCreateIssueSuccess,
{ insertAt: 0, items: [] },
{},
[{ type: types.RECEIVE_CREATE_ITEM_SUCCESS, payload: { insertAt: 0, items: [] } }],
[],
done,
);
});
});
describe('receiveCreateIssueFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should set `state.itemCreateInProgress` to false', done => {
it('should set `state.itemCreateInProgress` to false', () => {
testAction(
actions.receiveCreateIssueFailure,
{},
{},
[{ type: types.RECEIVE_CREATE_ITEM_FAILURE }],
[],
done,
);
});
......@@ -1380,9 +1289,7 @@ describe('RelatedItemTree', () => {
},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
......@@ -1393,14 +1300,13 @@ describe('RelatedItemTree', () => {
const parentItem = {
id: `gid://gitlab/Epic/${epicId}`,
};
const expectedRequest = jasmine.objectContaining({
const expectedRequest = expect.objectContaining({
data: JSON.stringify({
epic_id: epicId,
title,
}),
});
let flashSpy;
let axiosMock;
let requestSpy;
let context;
......@@ -1415,16 +1321,14 @@ describe('RelatedItemTree', () => {
});
beforeEach(() => {
flashSpy = spyOnDependency(actionsModule, 'flash');
requestSpy = jasmine.createSpy('request');
requestSpy = jest.fn();
axiosMock.onPost(issuesEndpoint).replyOnce(config => requestSpy(config));
context = {
state: {
parentItem,
},
dispatch: jasmine.createSpy('dispatch'),
dispatch: jest.fn(),
};
payload = {
......@@ -1435,79 +1339,68 @@ describe('RelatedItemTree', () => {
describe('for successful request', () => {
beforeEach(() => {
requestSpy.and.returnValue([201, '']);
requestSpy.mockReturnValue([201, '']);
});
it('dispatches fetchItems', done => {
actions
.createNewIssue(context, payload)
.then(() => {
expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
expect(context.dispatch).toHaveBeenCalledWith('requestCreateItem');
expect(context.dispatch).toHaveBeenCalledWith('receiveCreateIssueSuccess', '');
expect(context.dispatch).toHaveBeenCalledWith(
'fetchItems',
jasmine.objectContaining({ parentItem }),
);
expect(flashSpy).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
it('dispatches fetchItems', () => {
return actions.createNewIssue(context, payload).then(() => {
expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
expect(context.dispatch).toHaveBeenCalledWith('requestCreateItem');
expect(context.dispatch).toHaveBeenCalledWith('receiveCreateIssueSuccess', '');
expect(context.dispatch).toHaveBeenCalledWith(
'fetchItems',
expect.objectContaining({ parentItem }),
);
expect(createFlash).not.toHaveBeenCalled();
});
});
});
describe('for failed request', () => {
beforeEach(() => {
requestSpy.and.returnValue([500, '']);
requestSpy.mockReturnValue([500, '']);
});
it('fails and shows flash message', done => {
actions
return actions
.createNewIssue(context, payload)
.then(() => done.fail('expected action to throw error!'))
.catch(() => {
expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
expect(context.dispatch).toHaveBeenCalledWith('receiveCreateIssueFailure');
})
.then(done)
.catch(done.fail);
done();
});
});
});
});
describe('requestProjects', () => {
it('should set `state.projectsFetchInProgress` to true', done => {
testAction(actions.requestProjects, {}, {}, [{ type: types.REQUEST_PROJECTS }], [], done);
it('should set `state.projectsFetchInProgress` to true', () => {
testAction(actions.requestProjects, {}, {}, [{ type: types.REQUEST_PROJECTS }], []);
});
});
describe('receiveProjectsSuccess', () => {
it('should set `state.projectsFetchInProgress` to false and set provided `projects` param to state', done => {
it('should set `state.projectsFetchInProgress` to false and set provided `projects` param to state', () => {
testAction(
actions.receiveProjectsSuccess,
mockProjects,
{},
[{ type: types.RECIEVE_PROJECTS_SUCCESS, payload: mockProjects }],
[],
done,
);
});
});
describe('receiveProjectsFailure', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('should set `state.projectsFetchInProgress` to false', done => {
it('should set `state.projectsFetchInProgress` to false', () => {
testAction(
actions.receiveProjectsFailure,
{},
{},
[{ type: types.RECIEVE_PROJECTS_FAILURE }],
[],
done,
);
});
......@@ -1522,9 +1415,7 @@ describe('RelatedItemTree', () => {
},
);
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
message,
);
expect(createFlash).toHaveBeenCalledWith(message);
});
});
......@@ -1541,7 +1432,7 @@ describe('RelatedItemTree', () => {
mock.restore();
});
it('should dispatch `requestProjects` and `receiveProjectsSuccess` actions on request success', done => {
it('should dispatch `requestProjects` and `receiveProjectsSuccess` actions on request success', () => {
mock.onGet(/(.*)/).replyOnce(200, mockProjects);
testAction(
......@@ -1558,11 +1449,10 @@ describe('RelatedItemTree', () => {
payload: mockProjects,
},
],
done,
);
});
it('should dispatch `requestProjects` and `receiveProjectsFailure` actions on request failure', done => {
it('should dispatch `requestProjects` and `receiveProjectsFailure` actions on request failure', () => {
mock.onGet(/(.*)/).replyOnce(500, {});
testAction(
......@@ -1578,7 +1468,6 @@ describe('RelatedItemTree', () => {
type: 'receiveProjectsFailure',
},
],
done,
);
});
});
......
......@@ -2,7 +2,7 @@ import * as getters from 'ee/related_items_tree/store/getters';
import createDefaultState from 'ee/related_items_tree/store/state';
import { issuableTypesMap } from 'ee/related_issues/constants';
import { mockEpic1, mockEpic2 } from '../../../javascripts/related_items_tree/mock_data';
import { mockEpic1, mockEpic2 } from '../mock_data';
window.gl = window.gl || {};
......
......@@ -3,11 +3,7 @@ import * as epicUtils from 'ee/related_items_tree/utils/epic_utils';
import { PathIdSeparator } from 'ee/related_issues/constants';
import { ChildType } from 'ee/related_items_tree/constants';
import {
mockQueryResponse2,
mockEpic1,
mockIssue1,
} from '../../../javascripts/related_items_tree/mock_data';
import { mockQueryResponse2, mockEpic1, mockIssue1 } from '../mock_data';
describe('RelatedItemsTree', () => {
describe('epicUtils', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment