Commit 2c5dce71 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '215077-update-roadmap-app-spec-to-use-vue-test-utils' into 'master'

Update RoadmapApp spec to use vue-test-utils

See merge request gitlab-org/gitlab!31004
parents 92ccde67 9e24bc1a
import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
import Vue from 'vue';
import appComponent from 'ee/roadmap/components/roadmap_app.vue';
import createStore from 'ee/roadmap/store';
import Vuex from 'vuex';
import EpicsListEmpty from 'ee/roadmap/components/epics_list_empty.vue';
import RoadmapApp from 'ee/roadmap/components/roadmap_app.vue';
import RoadmapShell from 'ee/roadmap/components/roadmap_shell.vue';
import { PRESET_TYPES, EXTEND_AS } from 'ee/roadmap/constants';
import eventHub from 'ee/roadmap/event_hub';
import createStore from 'ee/roadmap/store';
import * as types from 'ee/roadmap/store/mutation_types';
import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils';
import { PRESET_TYPES, EXTEND_AS } from 'ee/roadmap/constants';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import {
mockTimeframeInitialDate,
basePath,
epicsPath,
mockFormattedEpic,
mockGroupId,
mockNewEpicEndpoint,
rawEpics,
mockSvgPath,
mockSortedBy,
basePath,
epicsPath,
mockSvgPath,
mockTimeframeInitialDate,
rawEpics,
} from 'ee_jest/roadmap/mock_data';
const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate);
const createComponent = () => {
const Component = Vue.extend(appComponent);
describe('RoadmapApp', () => {
const localVue = createLocalVue();
let store;
let wrapper;
localVue.use(Vuex);
const currentGroupId = mockGroupId;
const emptyStateIllustrationPath = mockSvgPath;
const epics = [mockFormattedEpic];
const hasFiltersApplied = true;
const newEpicEndpoint = mockNewEpicEndpoint;
const presetType = PRESET_TYPES.MONTHS;
const timeframe = getTimeframeForMonthsView(mockTimeframeInitialDate);
const createComponent = (mountFunction = shallowMount) => {
return mountFunction(RoadmapApp, {
localVue,
propsData: {
emptyStateIllustrationPath,
hasFiltersApplied,
newEpicEndpoint,
presetType,
},
store,
});
};
const store = createStore();
store.dispatch('setInitialData', {
currentGroupId: mockGroupId,
sortedBy: mockSortedBy,
presetType: PRESET_TYPES.MONTHS,
timeframe: mockTimeframeMonths,
filterQueryString: '',
initialEpicsPath: epicsPath,
basePath,
beforeEach(() => {
store = createStore();
store.dispatch('setInitialData', {
currentGroupId,
sortedBy: mockSortedBy,
presetType,
timeframe,
filterQueryString: '',
initialEpicsPath: epicsPath,
basePath,
});
});
return mountComponentWithStore(Component, {
store,
props: {
presetType: PRESET_TYPES.MONTHS,
hasFiltersApplied: true,
newEpicEndpoint: mockNewEpicEndpoint,
emptyStateIllustrationPath: mockSvgPath,
},
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
};
describe('Roadmap AppComponent', () => {
let vm;
describe('when the app contains epics', () => {
beforeEach(() => {
wrapper = createComponent();
store.commit(types.RECEIVE_EPICS_SUCCESS, epics);
});
beforeEach(() => {
vm = createComponent();
});
it('the roadmap is shown', () => {
expect(wrapper.contains(RoadmapShell)).toBe(true);
});
afterEach(() => {
vm.$destroy();
it('the empty state view is not shown', () => {
expect(wrapper.contains(EpicsListEmpty)).toBe(false);
});
});
describe('computed', () => {
describe('timeframeStart', () => {
it('returns first item of timeframe array', () => {
expect(vm.timeframeStart instanceof Date).toBe(true);
});
describe('when the app does not contain any epics', () => {
beforeEach(() => {
wrapper = createComponent();
store.commit(types.RECEIVE_EPICS_SUCCESS, []);
});
describe('timeframeEnd', () => {
it('returns last item of timeframe array', () => {
expect(vm.timeframeEnd instanceof Date).toBe(true);
});
it('the roadmap is not shown', () => {
expect(wrapper.contains(RoadmapShell)).toBe(false);
});
describe('showRoadmap', () => {
it('returns true if `windowResizeInProgress`, `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` are all `false`', () => {
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false;
expect(vm.showRoadmap).toBe(true);
});
it('the empty state view is shown', () => {
expect(wrapper.contains(EpicsListEmpty)).toBe(true);
});
});
it('returns false if either of `windowResizeInProgress`, `epicsFetchInProgress`, `epicsFetchResultEmpty` and `epicsFetchFailure` is `true`', () => {
vm.$store.state.windowResizeInProgress = true;
vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false;
describe('empty state view', () => {
beforeEach(() => {
wrapper = createComponent();
store.commit(types.RECEIVE_EPICS_SUCCESS, []);
});
expect(vm.showRoadmap).toBe(false);
it('contains path for the empty state illustration', () => {
expect(wrapper.find(EpicsListEmpty).props('emptyStateIllustrationPath')).toBe(
emptyStateIllustrationPath,
);
});
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = true;
vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = false;
it('contains whether to apply filters', () => {
expect(wrapper.find(EpicsListEmpty).props('hasFiltersApplied')).toBe(hasFiltersApplied);
});
expect(vm.showRoadmap).toBe(false);
it('contains whether it is child epics', () => {
expect(wrapper.find(EpicsListEmpty).props('isChildEpics')).toBe(false);
});
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = true;
vm.$store.state.epicsFetchFailure = false;
it('contains endpoint to create a new epic', () => {
expect(wrapper.find(EpicsListEmpty).props('newEpicEndpoint')).toBe(mockNewEpicEndpoint);
});
expect(vm.showRoadmap).toBe(false);
it('contains the preset type', () => {
expect(wrapper.find(EpicsListEmpty).props('presetType')).toBe(presetType);
});
vm.$store.state.windowResizeInProgress = false;
vm.$store.state.epicsFetchInProgress = false;
vm.$store.state.epicsFetchResultEmpty = false;
vm.$store.state.epicsFetchFailure = true;
it('contains the start of the timeframe', () => {
expect(wrapper.find(EpicsListEmpty).props('timeframeStart')).toStrictEqual(timeframe[0]);
});
expect(vm.showRoadmap).toBe(false);
});
it('contains the end of the timeframe', () => {
expect(wrapper.find(EpicsListEmpty).props('timeframeEnd')).toStrictEqual(
timeframe[timeframe.length - 1],
);
});
});
describe('methods', () => {
describe('processExtendedTimeline', () => {
it('updates timeline by extending timeframe from the start when called with extendType as `prepend`', () => {
vm.$store.dispatch('receiveEpicsSuccess', { rawEpics });
vm.$store.state.epicsFetchInProgress = false;
return Vue.nextTick().then(() => {
const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section');
describe('roadmap view', () => {
beforeEach(() => {
wrapper = createComponent();
store.commit(types.RECEIVE_EPICS_SUCCESS, epics);
});
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
it('contains the current group id', () => {
expect(wrapper.find(RoadmapShell).props('currentGroupId')).toBe(currentGroupId);
});
vm.processExtendedTimeline({
extendType: EXTEND_AS.PREPEND,
roadmapTimelineEl,
itemsCount: 0,
});
it('contains epics', () => {
expect(wrapper.find(RoadmapShell).props('epics')).toEqual(epics);
});
expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object));
expect(roadmapTimelineEl.parentElement.scrollBy).toHaveBeenCalled();
});
});
it('contains whether filters are applied', () => {
expect(wrapper.find(RoadmapShell).props('hasFiltersApplied')).toBe(hasFiltersApplied);
});
it('updates timeline by extending timeframe from the end when called with extendType as `append`', () => {
vm.$store.dispatch('receiveEpicsSuccess', { rawEpics });
vm.$store.state.epicsFetchInProgress = false;
it('contains milestones', () => {
expect(wrapper.find(RoadmapShell).props('milestones')).toEqual([]);
});
return Vue.nextTick().then(() => {
const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section');
it('contains the preset type', () => {
expect(wrapper.find(RoadmapShell).props('presetType')).toBe(presetType);
});
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
it('contains timeframe', () => {
expect(wrapper.find(RoadmapShell).props('timeframe')).toEqual(timeframe);
});
});
vm.processExtendedTimeline({
extendType: EXTEND_AS.PREPEND,
roadmapTimelineEl,
itemsCount: 0,
});
describe('extending the roadmap timeline', () => {
let roadmapTimelineEl;
expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object));
});
});
beforeEach(() => {
wrapper = createComponent(mount);
store.dispatch('receiveEpicsSuccess', { rawEpics });
roadmapTimelineEl = wrapper.find('.roadmap-timeline-section').element;
});
describe('handleScrollToExtend', () => {
let roadmapTimelineEl;
it('updates timeline by extending timeframe from the start when called with extendType as `prepend`', () => {
jest.spyOn(eventHub, '$emit').mockImplementation();
beforeAll(() => {
vm.$store.dispatch('receiveEpicsSuccess', { rawEpics });
vm.$store.state.epicsFetchInProgress = false;
roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section');
wrapper.vm.processExtendedTimeline({
extendType: EXTEND_AS.PREPEND,
roadmapTimelineEl,
itemsCount: 0,
});
it('updates the store and refreshes roadmap with extended timeline based on provided extendType', () => {
jest.spyOn(vm, 'extendTimeframe').mockImplementation(() => {});
jest.spyOn(vm, 'refreshEpicDates').mockImplementation(() => {});
jest.spyOn(vm, 'refreshMilestoneDates').mockImplementation(() => {});
jest.spyOn(vm, 'fetchEpicsForTimeframe').mockResolvedValue();
const extendType = EXTEND_AS.PREPEND;
expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object));
expect(roadmapTimelineEl.parentElement.scrollBy).toHaveBeenCalled();
});
vm.handleScrollToExtend(roadmapTimelineEl, extendType);
it('updates timeline by extending timeframe from the end when called with extendType as `append`', () => {
jest.spyOn(eventHub, '$emit').mockImplementation();
expect(vm.extendTimeframe).toHaveBeenCalledWith({ extendAs: extendType });
expect(vm.refreshEpicDates).toHaveBeenCalled();
expect(vm.refreshMilestoneDates).toHaveBeenCalled();
wrapper.vm.processExtendedTimeline({
extendType: EXTEND_AS.APPEND,
roadmapTimelineEl,
itemsCount: 0,
});
it('calls `fetchEpicsForTimeframe` with extended timeframe array', () => {
jest.spyOn(vm, 'extendTimeframe').mockImplementation(() => {});
jest.spyOn(vm, 'refreshEpicDates').mockImplementation(() => {});
jest.spyOn(vm, 'refreshMilestoneDates').mockImplementation(() => {});
jest.spyOn(vm, 'fetchEpicsForTimeframe').mockResolvedValue();
expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object));
});
const extendType = EXTEND_AS.PREPEND;
it('updates the store and refreshes roadmap with extended timeline based on provided extendType', () => {
jest.spyOn(wrapper.vm, 'extendTimeframe').mockImplementation();
jest.spyOn(wrapper.vm, 'refreshEpicDates').mockImplementation();
jest.spyOn(wrapper.vm, 'refreshMilestoneDates').mockImplementation();
jest.spyOn(wrapper.vm, 'fetchEpicsForTimeframe').mockResolvedValue();
vm.handleScrollToExtend(roadmapTimelineEl, extendType);
const extendType = EXTEND_AS.PREPEND;
return vm.$nextTick().then(() => {
expect(vm.fetchEpicsForTimeframe).toHaveBeenCalledWith(
expect.objectContaining({
timeframe: vm.extendedTimeframe,
}),
);
});
});
});
});
wrapper.vm.handleScrollToExtend(roadmapTimelineEl, extendType);
describe('template', () => {
it('renders roadmap container with class `roadmap-container`', () => {
expect(vm.$el.classList.contains('roadmap-container')).toBe(true);
expect(wrapper.vm.extendTimeframe).toHaveBeenCalledWith({ extendAs: extendType });
expect(wrapper.vm.refreshEpicDates).toHaveBeenCalled();
expect(wrapper.vm.refreshMilestoneDates).toHaveBeenCalled();
});
it('renders roadmap container with classes `roadmap-container overflow-reset` when isEpicsListEmpty prop is true', () => {
vm.$store.state.epicsFetchResultEmpty = true;
it('calls `fetchEpicsForTimeframe` with extended timeframe array', () => {
jest.spyOn(wrapper.vm, 'fetchEpicsForTimeframe').mockResolvedValue();
const extendType = EXTEND_AS.PREPEND;
wrapper.vm.handleScrollToExtend(roadmapTimelineEl, extendType);
return Vue.nextTick().then(() => {
expect(vm.$el.classList.contains('roadmap-container')).toBe(true);
expect(vm.$el.classList.contains('overflow-reset')).toBe(true);
return Vue.nextTick(() => {
expect(wrapper.vm.fetchEpicsForTimeframe).toHaveBeenCalledWith(
expect.objectContaining({
timeframe: wrapper.vm.extendedTimeframe,
}),
);
});
});
});
......
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