diff --git a/ee/spec/javascripts/roadmap/components/current_day_indicator_spec.js b/ee/spec/frontend/roadmap/components/current_day_indicator_spec.js similarity index 81% rename from ee/spec/javascripts/roadmap/components/current_day_indicator_spec.js rename to ee/spec/frontend/roadmap/components/current_day_indicator_spec.js index 58dd34535b3a23619a7c9f88469d9f5297e623bb..3160c35365af0565df849cf848c50d156f82095b 100644 --- a/ee/spec/javascripts/roadmap/components/current_day_indicator_spec.js +++ b/ee/spec/frontend/roadmap/components/current_day_indicator_spec.js @@ -8,7 +8,7 @@ import { } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import { mockTimeframeInitialDate } from '../mock_data'; +import { mockTimeframeInitialDate } from 'ee_jest/roadmap/mock_data'; const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate); const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -46,7 +46,7 @@ describe('CurrentDayIndicator', () => { describe('computed', () => { describe('hasToday', () => { - it('returns true when presetType is QUARTERS and currentDate is within current quarter', done => { + it('returns true when presetType is QUARTERS and currentDate is within current quarter', () => { wrapper.setData({ currentDate: mockTimeframeQuarters[0].range[1], }); @@ -56,13 +56,12 @@ describe('CurrentDayIndicator', () => { timeframeItem: mockTimeframeQuarters[0], }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.hasToday).toBe(true); - done(); }); }); - it('returns true when presetType is MONTHS and currentDate is within current month', done => { + it('returns true when presetType is MONTHS and currentDate is within current month', () => { wrapper.setData({ currentDate: new Date(2020, 0, 15), }); @@ -72,13 +71,12 @@ describe('CurrentDayIndicator', () => { timeframeItem: new Date(2020, 0, 1), }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.hasToday).toBe(true); - done(); }); }); - it('returns true when presetType is WEEKS and currentDate is within current week', done => { + it('returns true when presetType is WEEKS and currentDate is within current week', () => { wrapper.setData({ currentDate: mockTimeframeWeeks[0], }); @@ -88,9 +86,8 @@ describe('CurrentDayIndicator', () => { timeframeItem: mockTimeframeWeeks[0], }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.hasToday).toBe(true); - done(); }); }); }); @@ -98,7 +95,7 @@ describe('CurrentDayIndicator', () => { describe('methods', () => { describe('getIndicatorStyles', () => { - it('returns object containing `left` with value `34%` when presetType is QUARTERS', done => { + it('returns object containing `left` with value `34%` when presetType is QUARTERS', () => { wrapper.setData({ currentDate: mockTimeframeQuarters[0].range[1], }); @@ -108,17 +105,16 @@ describe('CurrentDayIndicator', () => { timeframeItem: mockTimeframeQuarters[0], }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.getIndicatorStyles()).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ left: '34%', }), ); - done(); }); }); - it('returns object containing `left` with value `48%` when presetType is MONTHS', done => { + it('returns object containing `left` with value `48%` when presetType is MONTHS', () => { wrapper.setData({ currentDate: new Date(2020, 0, 15), }); @@ -128,17 +124,16 @@ describe('CurrentDayIndicator', () => { timeframeItem: new Date(2020, 0, 1), }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.getIndicatorStyles()).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ left: '48%', }), ); - done(); }); }); - it('returns object containing `left` with value `7%` when presetType is WEEKS', done => { + it('returns object containing `left` with value `7%` when presetType is WEEKS', () => { wrapper.setData({ currentDate: mockTimeframeWeeks[0], }); @@ -148,34 +143,33 @@ describe('CurrentDayIndicator', () => { timeframeItem: mockTimeframeWeeks[0], }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.getIndicatorStyles()).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ left: '7%', }), ); - done(); }); }); }); }); describe('template', () => { - beforeEach(done => { + beforeEach(() => { + wrapper = createComponent(); wrapper.setData({ currentDate: mockTimeframeMonths[0], }); - wrapper.vm.$nextTick(() => { - done(); - }); + + return wrapper.vm.$nextTick(); }); it('renders span element containing class `current-day-indicator`', () => { - expect(wrapper.element.classList.contains('current-day-indicator')).toBe(true); + expect(wrapper.classes('current-day-indicator')).toBe(true); }); it('renders span element with style attribute containing `left: 3%;`', () => { - expect(wrapper.element.getAttribute('style')).toBe('left: 3%;'); + expect(wrapper.attributes('style')).toBe('left: 3%;'); }); }); }); diff --git a/ee/spec/javascripts/roadmap/components/epic_item_details_spec.js b/ee/spec/frontend/roadmap/components/epic_item_details_spec.js similarity index 98% rename from ee/spec/javascripts/roadmap/components/epic_item_details_spec.js rename to ee/spec/frontend/roadmap/components/epic_item_details_spec.js index ae187c98daf3a9828651b971cf0d51ef2b6d79d4..d4b1fca051a77f6ed94da4b62b3afa87ec4f3783 100644 --- a/ee/spec/javascripts/roadmap/components/epic_item_details_spec.js +++ b/ee/spec/frontend/roadmap/components/epic_item_details_spec.js @@ -7,7 +7,7 @@ import { mockFormattedEpic, mockFormattedChildEpic2, mockFormattedChildEpic1, -} from '../mock_data'; +} from 'ee_jest/roadmap/mock_data'; const createComponent = ( epic = mockFormattedEpic, @@ -159,7 +159,7 @@ describe('EpicItemDetails', () => { }); it('emits toggleIsEpicExpanded event when clicked', () => { - spyOn(eventHub, '$emit'); + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); const id = 42; const epic = { diff --git a/ee/spec/javascripts/roadmap/components/epic_item_spec.js b/ee/spec/frontend/roadmap/components/epic_item_spec.js similarity index 94% rename from ee/spec/javascripts/roadmap/components/epic_item_spec.js rename to ee/spec/frontend/roadmap/components/epic_item_spec.js index cdac2df9b5ece342b2f01739c59b78101012444e..1280cf20fc9af6a125978c372cc4680ee0c3b5a3 100644 --- a/ee/spec/javascripts/roadmap/components/epic_item_spec.js +++ b/ee/spec/frontend/roadmap/components/epic_item_spec.js @@ -8,8 +8,8 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate, mockEpic, mockGroupId } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate, mockEpic, mockGroupId } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -111,7 +111,7 @@ describe('EpicItemComponent', () => { describe('methods', () => { describe('removeHighlight', () => { it('should call _.delay after 3 seconds with a callback function which would set `epic.newEpic` to false when it is true already', done => { - spyOn(_, 'delay'); + jest.spyOn(_, 'delay').mockImplementation(() => {}); vm.epic.newEpic = true; @@ -119,7 +119,7 @@ describe('EpicItemComponent', () => { vm.$nextTick() .then(() => { - expect(_.delay).toHaveBeenCalledWith(jasmine.any(Function), 3000); + expect(_.delay).toHaveBeenCalledWith(expect.any(Function), 3000); }) .then(done) .catch(done.fail); diff --git a/ee/spec/javascripts/roadmap/components/epic_item_timeline_spec.js b/ee/spec/frontend/roadmap/components/epic_item_timeline_spec.js similarity index 96% rename from ee/spec/javascripts/roadmap/components/epic_item_timeline_spec.js rename to ee/spec/frontend/roadmap/components/epic_item_timeline_spec.js index 6a9c6060afaba994b273b6b44fc48695e8469178..017dadd4a8ba56f17ea1c327904b82ccfd2e03f2 100644 --- a/ee/spec/javascripts/roadmap/components/epic_item_timeline_spec.js +++ b/ee/spec/frontend/roadmap/components/epic_item_timeline_spec.js @@ -4,7 +4,7 @@ import CurrentDayIndicator from 'ee/roadmap/components/current_day_indicator.vue import EpicItemTimeline from 'ee/roadmap/components/epic_item_timeline.vue'; import { PRESET_TYPES } from 'ee/roadmap/constants'; import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; -import { mockTimeframeInitialDate, mockFormattedEpic } from '../mock_data'; +import { mockTimeframeInitialDate, mockFormattedEpic } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/epics_list_empty_spec.js b/ee/spec/frontend/roadmap/components/epics_list_empty_spec.js similarity index 97% rename from ee/spec/javascripts/roadmap/components/epics_list_empty_spec.js rename to ee/spec/frontend/roadmap/components/epics_list_empty_spec.js index aeaddfae228a928c14e02d58e37408aebfab03cd..0dcecc46682b2e8cbad1e75b2d2c2b32a587787e 100644 --- a/ee/spec/javascripts/roadmap/components/epics_list_empty_spec.js +++ b/ee/spec/frontend/roadmap/components/epics_list_empty_spec.js @@ -10,8 +10,12 @@ import { import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate, mockSvgPath, mockNewEpicEndpoint } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { + mockTimeframeInitialDate, + mockSvgPath, + mockNewEpicEndpoint, +} from 'ee_jest/roadmap/mock_data'; const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate); const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/epics_list_section_spec.js b/ee/spec/frontend/roadmap/components/epics_list_section_spec.js similarity index 81% rename from ee/spec/javascripts/roadmap/components/epics_list_section_spec.js rename to ee/spec/frontend/roadmap/components/epics_list_section_spec.js index 681f4b5ab160e6326fa9fc08ad3840b9ea4b41a4..aac94029b307d0b769f6341ae0c256027840df21 100644 --- a/ee/spec/javascripts/roadmap/components/epics_list_section_spec.js +++ b/ee/spec/frontend/roadmap/components/epics_list_section_spec.js @@ -1,6 +1,6 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import VirtualList from 'vue-virtual-scroll-list'; -import epicsListSectionComponent from 'ee/roadmap/components/epics_list_section.vue'; +import EpicsListSection from 'ee/roadmap/components/epics_list_section.vue'; import EpicItem from 'ee/roadmap/components/epic_item.vue'; import createStore from 'ee/roadmap/store'; import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; @@ -18,7 +18,7 @@ import { mockSortedBy, basePath, epicsPath, -} from '../mock_data'; +} from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const store = createStore(); @@ -39,6 +39,7 @@ const mockEpics = store.state.epics; store.state.epics[0].children = { edges: [mockFormattedChildEpic1, mockFormattedChildEpic2], }; +const localVue = createLocalVue(); const createComponent = ({ epics = mockEpics, @@ -47,9 +48,7 @@ const createComponent = ({ presetType = PRESET_TYPES.MONTHS, roadmapBufferedRendering = true, } = {}) => { - const localVue = createLocalVue(); - - return shallowMount(epicsListSectionComponent, { + return shallowMount(EpicsListSection, { localVue, store, stubs: { @@ -82,6 +81,13 @@ describe('EpicsListSectionComponent', () => { describe('data', () => { it('returns default data props', () => { + // Destroy the existing wrapper, and create a new one. This works around + // a race condition between how Jest runs tests and the $nextTick call in + // EpicsListSectionComponent's mounted hook. + // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27992#note_319213990 + wrapper.destroy(); + wrapper = createComponent(); + expect(wrapper.vm.offsetLeft).toBe(0); expect(wrapper.vm.emptyRowContainerStyles).toEqual({}); expect(wrapper.vm.showBottomShadow).toBe(false); @@ -115,63 +121,69 @@ describe('EpicsListSectionComponent', () => { describe('methods', () => { describe('initMounted', () => { + beforeEach(() => { + // Destroy the existing wrapper, and create a new one. This works + // around a race condition between how Jest runs tests and the + // $nextTick call in EpicsListSectionComponent's mounted hook. + // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27992#note_319213990 + wrapper.destroy(); + wrapper = createComponent(); + + jest.spyOn(wrapper.vm, 'scrollToTodayIndicator').mockImplementation(() => {}); + }); + it('sets value of `roadmapShellEl` with root component element', () => { expect(wrapper.vm.roadmapShellEl instanceof HTMLElement).toBe(true); }); it('calls action `setBufferSize` with value based on window.innerHeight and component element position', () => { - expect(wrapper.vm.bufferSize).toBe(12); + expect(wrapper.vm.bufferSize).toBe(16); }); - it('sets value of `offsetLeft` with parentElement.offsetLeft', done => { - wrapper.vm.$nextTick(() => { + it('sets value of `offsetLeft` with parentElement.offsetLeft', () => { + return wrapper.vm.$nextTick(() => { // During tests, there's no `$el.parentElement` present // hence offsetLeft is 0. expect(wrapper.vm.offsetLeft).toBe(0); - done(); }); }); - it('calls `scrollToTodayIndicator` following the component render', done => { - spyOn(wrapper.vm, 'scrollToTodayIndicator'); - + it('calls `scrollToTodayIndicator` following the component render', () => { // Original method implementation waits for render cycle // to complete at 2 levels before scrolling. - wrapper.vm.$nextTick(() => { - wrapper.vm.$nextTick(() => { + return wrapper.vm + .$nextTick() + .then(() => wrapper.vm.$nextTick()) + .then(() => { expect(wrapper.vm.scrollToTodayIndicator).toHaveBeenCalled(); - done(); }); - }); }); - it('sets style object to `emptyRowContainerStyles`', done => { - wrapper.vm.$nextTick(() => { + it('sets style object to `emptyRowContainerStyles`', () => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.emptyRowContainerStyles).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ height: '0px', }), ); - done(); }); }); }); describe('getEmptyRowContainerStyles', () => { - it('returns empty object when there are no epics available to render', done => { + it('returns empty object when there are no epics available to render', () => { wrapper.setProps({ epics: [], }); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.vm.getEmptyRowContainerStyles()).toEqual({}); - done(); }); }); it('returns object containing `height` when there epics available to render', () => { expect(wrapper.vm.getEmptyRowContainerStyles()).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ height: '0px', }), ); @@ -203,7 +215,7 @@ describe('EpicsListSectionComponent', () => { describe('getEpicItemProps', () => { it('returns an object containing props for EpicItem component', () => { expect(wrapper.vm.getEpicItemProps(1)).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ key: 1, props: { epic: wrapper.vm.epics[1], @@ -219,15 +231,14 @@ describe('EpicsListSectionComponent', () => { describe('template', () => { it('renders component container element with class `epics-list-section`', () => { - expect(wrapper.vm.$el.classList.contains('epics-list-section')).toBe(true); + expect(wrapper.classes('epics-list-section')).toBe(true); }); - it('renders virtual-list when roadmapBufferedRendering is `true` and `epics.length` is more than `bufferSize`', done => { + it('renders virtual-list when roadmapBufferedRendering is `true` and `epics.length` is more than `bufferSize`', () => { wrapper.vm.setBufferSize(5); - wrapper.vm.$nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.find(VirtualList).exists()).toBe(true); - done(); }); }); @@ -267,7 +278,6 @@ describe('EpicsListSectionComponent', () => { it('expands to show child epics when epic is toggled', done => { const epic = mockEpics[0]; - wrapper = createComponent(); expect(wrapper.findAll(EpicItem).length).toBe(mockEpics.length); diff --git a/ee/spec/frontend/roadmap/components/milestone_item_spec.js b/ee/spec/frontend/roadmap/components/milestone_item_spec.js index 17574581a1fb3ab1aeea5d82a1c8e445d7b95efc..ddb83f0722412e1eb9cdd06ebc5f34e1497b125b 100644 --- a/ee/spec/frontend/roadmap/components/milestone_item_spec.js +++ b/ee/spec/frontend/roadmap/components/milestone_item_spec.js @@ -7,7 +7,7 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; import { mount } from '@vue/test-utils'; -import { mockTimeframeInitialDate, mockMilestone2 } from '../../../javascripts/roadmap/mock_data'; +import { mockTimeframeInitialDate, mockMilestone2 } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -45,29 +45,25 @@ describe('MilestoneItemComponent', () => { describe('computed', () => { describe('startDateValues', () => { it('returns object containing date parts from milestone.startDate', () => { - expect(wrapper.vm.startDateValues).toEqual( - jasmine.objectContaining({ - day: mockMilestone2.startDate.getDay(), - date: mockMilestone2.startDate.getDate(), - month: mockMilestone2.startDate.getMonth(), - year: mockMilestone2.startDate.getFullYear(), - time: mockMilestone2.startDate.getTime(), - }), - ); + expect(wrapper.vm.startDateValues).toMatchObject({ + day: mockMilestone2.startDate.getDay(), + date: mockMilestone2.startDate.getDate(), + month: mockMilestone2.startDate.getMonth(), + year: mockMilestone2.startDate.getFullYear(), + time: mockMilestone2.startDate.getTime(), + }); }); }); describe('endDateValues', () => { it('returns object containing date parts from milestone.endDate', () => { - expect(wrapper.vm.endDateValues).toEqual( - jasmine.objectContaining({ - day: mockMilestone2.endDate.getDay(), - date: mockMilestone2.endDate.getDate(), - month: mockMilestone2.endDate.getMonth(), - year: mockMilestone2.endDate.getFullYear(), - time: mockMilestone2.endDate.getTime(), - }), - ); + expect(wrapper.vm.endDateValues).toMatchObject({ + day: mockMilestone2.endDate.getDay(), + date: mockMilestone2.endDate.getDate(), + month: mockMilestone2.endDate.getMonth(), + year: mockMilestone2.endDate.getFullYear(), + time: mockMilestone2.endDate.getTime(), + }); }); }); diff --git a/ee/spec/frontend/roadmap/components/milestone_timeline_spec.js b/ee/spec/frontend/roadmap/components/milestone_timeline_spec.js index 09644f71077747947cfe571c28cb4b64952ec5b6..bc39e3d5674a35c74fcbb3c5b9a3937fbb96e915 100644 --- a/ee/spec/frontend/roadmap/components/milestone_timeline_spec.js +++ b/ee/spec/frontend/roadmap/components/milestone_timeline_spec.js @@ -7,11 +7,7 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import { - mockTimeframeInitialDate, - mockMilestone2, - mockGroupId, -} from '../../../javascripts/roadmap/mock_data'; +import { mockTimeframeInitialDate, mockMilestone2, mockGroupId } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); diff --git a/ee/spec/frontend/roadmap/components/milestones_list_section_spec.js b/ee/spec/frontend/roadmap/components/milestones_list_section_spec.js index 561417f3fd401722fc0a57f0c3dcc1400f016b9c..5d9188ac2254f96661dfe8b3e86e00022943ba1b 100644 --- a/ee/spec/frontend/roadmap/components/milestones_list_section_spec.js +++ b/ee/spec/frontend/roadmap/components/milestones_list_section_spec.js @@ -8,11 +8,7 @@ import { EPIC_DETAILS_CELL_WIDTH, TIMELINE_CELL_MIN_WIDTH, } from 'ee/roadmap/constants'; -import { - mockTimeframeInitialDate, - mockGroupId, - rawMilestones, -} from '../../../javascripts/roadmap/mock_data'; +import { mockTimeframeInitialDate, mockGroupId, rawMilestones } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const store = createStore(); diff --git a/ee/spec/javascripts/roadmap/components/preset_months/months_header_item_spec.js b/ee/spec/frontend/roadmap/components/preset_months/months_header_item_spec.js similarity index 96% rename from ee/spec/javascripts/roadmap/components/preset_months/months_header_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_months/months_header_item_spec.js index 70ced7bac1f2e503bb2ceed2cf10d349db8dc9b3..49d529521f7e40afbd833b72c6ef33e44a77466f 100644 --- a/ee/spec/javascripts/roadmap/components/preset_months/months_header_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_months/months_header_item_spec.js @@ -3,8 +3,8 @@ import Vue from 'vue'; import MonthsHeaderItemComponent from 'ee/roadmap/components/preset_months/months_header_item.vue'; import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const mockTimeframeIndex = 0; diff --git a/ee/spec/javascripts/roadmap/components/preset_months/months_header_sub_item_spec.js b/ee/spec/frontend/roadmap/components/preset_months/months_header_sub_item_spec.js similarity index 95% rename from ee/spec/javascripts/roadmap/components/preset_months/months_header_sub_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_months/months_header_sub_item_spec.js index 3b6433cb77ca920e93a19a6c429bf9793049d747..d5fb785bfe5701cd111a8b33b4b17a1d01e6e491 100644 --- a/ee/spec/javascripts/roadmap/components/preset_months/months_header_sub_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_months/months_header_sub_item_spec.js @@ -4,8 +4,8 @@ import MonthsHeaderSubItemComponent from 'ee/roadmap/components/preset_months/mo import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_item_spec.js b/ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_item_spec.js similarity index 96% rename from ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_item_spec.js index eb1b9de4d01fb6d786d8ac6a711e2ecaa7388494..05fd74953565075149ec97688e5f123d5031ec7f 100644 --- a/ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_item_spec.js @@ -3,8 +3,8 @@ import Vue from 'vue'; import QuartersHeaderItemComponent from 'ee/roadmap/components/preset_quarters/quarters_header_item.vue'; import { getTimeframeForQuartersView } from 'ee/roadmap/utils/roadmap_utils'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeIndex = 0; const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js b/ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js similarity index 95% rename from ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js index 766a82cf2d73e5b949a29ec1f6a6e5ca0a69d08f..7210d4d17c9bc0386a4d5dfb0414040ba065e17d 100644 --- a/ee/spec/javascripts/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_quarters/quarters_header_sub_item_spec.js @@ -4,8 +4,8 @@ import QuartersHeaderSubItemComponent from 'ee/roadmap/components/preset_quarter import { getTimeframeForQuartersView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_item_spec.js b/ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_item_spec.js similarity index 96% rename from ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_item_spec.js index 1195c7489b1d26c79b62171220258e4429f6b9e3..67f42d7373aafacac437416e1a965eaabeff8a5d 100644 --- a/ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_item_spec.js @@ -3,8 +3,8 @@ import Vue from 'vue'; import WeeksHeaderItemComponent from 'ee/roadmap/components/preset_weeks/weeks_header_item.vue'; import { getTimeframeForWeeksView } from 'ee/roadmap/utils/roadmap_utils'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeIndex = 0; const mockTimeframeWeeks = getTimeframeForWeeksView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js b/ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js similarity index 95% rename from ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js rename to ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js index efda20cea2ae45533aecdec05bfa97c008932aa2..499e078397b18ef512b1e356ceaca70a0e98a283 100644 --- a/ee/spec/javascripts/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js +++ b/ee/spec/frontend/roadmap/components/preset_weeks/weeks_header_sub_item_spec.js @@ -4,8 +4,8 @@ import WeeksHeaderSubItemComponent from 'ee/roadmap/components/preset_weeks/week import { getTimeframeForWeeksView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate } from 'ee_spec/roadmap/mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate } from '../../mock_data'; const mockTimeframeWeeks = getTimeframeForWeeksView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/components/roadmap_app_spec.js b/ee/spec/frontend/roadmap/components/roadmap_app_spec.js similarity index 67% rename from ee/spec/javascripts/roadmap/components/roadmap_app_spec.js rename to ee/spec/frontend/roadmap/components/roadmap_app_spec.js index a903cd82420e88fb94a7b7a7bd20396971cf3416..9100c580050d37aef3239b7656617760ba0ead13 100644 --- a/ee/spec/javascripts/roadmap/components/roadmap_app_spec.js +++ b/ee/spec/frontend/roadmap/components/roadmap_app_spec.js @@ -8,7 +8,7 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES, EXTEND_AS } from 'ee/roadmap/constants'; -import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; +import { mountComponentWithStore } from 'helpers/vue_mount_component_helper'; import { mockTimeframeInitialDate, mockGroupId, @@ -18,7 +18,7 @@ import { mockSortedBy, basePath, epicsPath, -} from '../mock_data'; +} from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -115,50 +115,43 @@ describe('Roadmap AppComponent', () => { describe('methods', () => { describe('processExtendedTimeline', () => { - it('updates timeline by extending timeframe from the start when called with extendType as `prepend`', done => { + 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; - Vue.nextTick() - .then(() => { - const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section'); + return Vue.nextTick().then(() => { + const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section'); - spyOn(eventHub, '$emit'); - spyOn(roadmapTimelineEl.parentElement, 'scrollBy'); + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - vm.processExtendedTimeline({ - extendType: EXTEND_AS.PREPEND, - roadmapTimelineEl, - itemsCount: 0, - }); + vm.processExtendedTimeline({ + extendType: EXTEND_AS.PREPEND, + roadmapTimelineEl, + itemsCount: 0, + }); - expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', jasmine.any(Object)); - expect(roadmapTimelineEl.parentElement.scrollBy).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); + expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object)); + expect(roadmapTimelineEl.parentElement.scrollBy).toHaveBeenCalled(); + }); }); - it('updates timeline by extending timeframe from the end when called with extendType as `append`', done => { + 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; - Vue.nextTick() - .then(() => { - const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section'); + return Vue.nextTick().then(() => { + const roadmapTimelineEl = vm.$el.querySelector('.roadmap-timeline-section'); - spyOn(eventHub, '$emit'); + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - vm.processExtendedTimeline({ - extendType: EXTEND_AS.PREPEND, - roadmapTimelineEl, - itemsCount: 0, - }); + vm.processExtendedTimeline({ + extendType: EXTEND_AS.PREPEND, + roadmapTimelineEl, + itemsCount: 0, + }); - expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', jasmine.any(Object)); - }) - .then(done) - .catch(done.fail); + expect(eventHub.$emit).toHaveBeenCalledWith('refreshTimeline', expect.any(Object)); + }); }); }); @@ -172,10 +165,10 @@ describe('Roadmap AppComponent', () => { }); it('updates the store and refreshes roadmap with extended timeline based on provided extendType', () => { - spyOn(vm, 'extendTimeframe'); - spyOn(vm, 'refreshEpicDates'); - spyOn(vm, 'refreshMilestoneDates'); - spyOn(vm, 'fetchEpicsForTimeframe').and.callFake(() => new Promise(() => {})); + 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; @@ -186,26 +179,23 @@ describe('Roadmap AppComponent', () => { expect(vm.refreshMilestoneDates).toHaveBeenCalled(); }); - it('calls `fetchEpicsForTimeframe` with extended timeframe array', done => { - spyOn(vm, 'extendTimeframe').and.stub(); - spyOn(vm, 'refreshEpicDates').and.stub(); - spyOn(vm, 'refreshMilestoneDates').and.stub(); - spyOn(vm, 'fetchEpicsForTimeframe').and.callFake(() => new Promise(() => {})); + 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(); const extendType = EXTEND_AS.PREPEND; vm.handleScrollToExtend(roadmapTimelineEl, extendType); - vm.$nextTick() - .then(() => { - expect(vm.fetchEpicsForTimeframe).toHaveBeenCalledWith( - jasmine.objectContaining({ - timeframe: vm.extendedTimeframe, - }), - ); - }) - .then(done) - .catch(done.fail); + return vm.$nextTick().then(() => { + expect(vm.fetchEpicsForTimeframe).toHaveBeenCalledWith( + expect.objectContaining({ + timeframe: vm.extendedTimeframe, + }), + ); + }); }); }); }); @@ -215,15 +205,13 @@ describe('Roadmap AppComponent', () => { expect(vm.$el.classList.contains('roadmap-container')).toBe(true); }); - it('renders roadmap container with classes `roadmap-container overflow-reset` when isEpicsListEmpty prop is true', done => { + it('renders roadmap container with classes `roadmap-container overflow-reset` when isEpicsListEmpty prop is true', () => { vm.$store.state.epicsFetchResultEmpty = true; - Vue.nextTick() - .then(() => { - expect(vm.$el.classList.contains('roadmap-container')).toBe(true); - expect(vm.$el.classList.contains('overflow-reset')).toBe(true); - }) - .then(done) - .catch(done.fail); + + return Vue.nextTick().then(() => { + expect(vm.$el.classList.contains('roadmap-container')).toBe(true); + expect(vm.$el.classList.contains('overflow-reset')).toBe(true); + }); }); }); }); diff --git a/ee/spec/javascripts/roadmap/components/roadmap_shell_spec.js b/ee/spec/frontend/roadmap/components/roadmap_shell_spec.js similarity index 89% rename from ee/spec/javascripts/roadmap/components/roadmap_shell_spec.js rename to ee/spec/frontend/roadmap/components/roadmap_shell_spec.js index cde7e0136205bbc3550352280f09a0f33bcb8a04..8ed10c867ca0a06d2c5b9b2e4feedc25bb15e2eb 100644 --- a/ee/spec/javascripts/roadmap/components/roadmap_shell_spec.js +++ b/ee/spec/frontend/roadmap/components/roadmap_shell_spec.js @@ -7,8 +7,13 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { mockEpic, mockTimeframeInitialDate, mockGroupId, mockMilestone } from '../mock_data'; +import { mountComponentWithStore } from 'helpers/vue_mount_component_helper'; +import { + mockEpic, + mockTimeframeInitialDate, + mockGroupId, + mockMilestone, +} from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -73,13 +78,13 @@ describe('RoadmapShellComponent', () => { describe('handleScroll', () => { it('emits `epicsListScrolled` event via eventHub', done => { const vmWithParentEl = createComponent({}, document.getElementById('roadmap-shell')); - spyOn(eventHub, '$emit'); + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); Vue.nextTick() .then(() => { vmWithParentEl.handleScroll(); - expect(eventHub.$emit).toHaveBeenCalledWith('epicsListScrolled', jasmine.any(Object)); + expect(eventHub.$emit).toHaveBeenCalledWith('epicsListScrolled', expect.any(Object)); vmWithParentEl.$destroy(); }) diff --git a/ee/spec/javascripts/roadmap/components/roadmap_timeline_section_spec.js b/ee/spec/frontend/roadmap/components/roadmap_timeline_section_spec.js similarity index 88% rename from ee/spec/javascripts/roadmap/components/roadmap_timeline_section_spec.js rename to ee/spec/frontend/roadmap/components/roadmap_timeline_section_spec.js index 2b79348a8c536b47e291bd6c31e1b7dd25d936cb..5e1c9e24e525e7c728064a50167fe7d04e8556f7 100644 --- a/ee/spec/javascripts/roadmap/components/roadmap_timeline_section_spec.js +++ b/ee/spec/frontend/roadmap/components/roadmap_timeline_section_spec.js @@ -6,8 +6,8 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockEpic, mockTimeframeInitialDate } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockEpic, mockTimeframeInitialDate } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); @@ -46,7 +46,7 @@ describe('RoadmapTimelineSectionComponent', () => { describe('sectionContainerStyles', () => { it('returns object containing `width` with value based on epic details cell width, timeline cell width and timeframe length', () => { expect(vm.sectionContainerStyles).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ width: '1760px', }), ); @@ -73,21 +73,21 @@ describe('RoadmapTimelineSectionComponent', () => { describe('mounted', () => { it('binds `epicsListScrolled` event listener via eventHub', () => { - spyOn(eventHub, '$on'); + jest.spyOn(eventHub, '$on').mockImplementation(() => {}); const vmX = createComponent({}); - expect(eventHub.$on).toHaveBeenCalledWith('epicsListScrolled', jasmine.any(Function)); + expect(eventHub.$on).toHaveBeenCalledWith('epicsListScrolled', expect.any(Function)); vmX.$destroy(); }); }); describe('beforeDestroy', () => { it('unbinds `epicsListScrolled` event listener via eventHub', () => { - spyOn(eventHub, '$off'); + jest.spyOn(eventHub, '$off').mockImplementation(() => {}); const vmX = createComponent({}); vmX.$destroy(); - expect(eventHub.$off).toHaveBeenCalledWith('epicsListScrolled', jasmine.any(Function)); + expect(eventHub.$off).toHaveBeenCalledWith('epicsListScrolled', expect.any(Function)); }); }); diff --git a/ee/spec/javascripts/roadmap/mixins/months_preset_mixin_spec.js b/ee/spec/frontend/roadmap/mixins/months_preset_mixin_spec.js similarity index 97% rename from ee/spec/javascripts/roadmap/mixins/months_preset_mixin_spec.js rename to ee/spec/frontend/roadmap/mixins/months_preset_mixin_spec.js index 9c595a51e544f3543c62a105317aa745e41d9fd2..7e3855a2404fab500d9ded81a7b31058baaad900 100644 --- a/ee/spec/javascripts/roadmap/mixins/months_preset_mixin_spec.js +++ b/ee/spec/frontend/roadmap/mixins/months_preset_mixin_spec.js @@ -5,8 +5,8 @@ import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate, mockEpic } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate, mockEpic } from 'ee_jest/roadmap/mock_data'; const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/mixins/quarters_preset_mixin_spec.js b/ee/spec/frontend/roadmap/mixins/quarters_preset_mixin_spec.js similarity index 97% rename from ee/spec/javascripts/roadmap/mixins/quarters_preset_mixin_spec.js rename to ee/spec/frontend/roadmap/mixins/quarters_preset_mixin_spec.js index 9c53e63c084f1e2f9e540d4b2ce2dcd68fd5fae1..1f21a9dd1fa5d37e6a886cad1113ef290d98495b 100644 --- a/ee/spec/javascripts/roadmap/mixins/quarters_preset_mixin_spec.js +++ b/ee/spec/frontend/roadmap/mixins/quarters_preset_mixin_spec.js @@ -5,8 +5,8 @@ import { getTimeframeForQuartersView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate, mockEpic } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate, mockEpic } from 'ee_jest/roadmap/mock_data'; const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/mixins/weeks_preset_mixin_spec.js b/ee/spec/frontend/roadmap/mixins/weeks_preset_mixin_spec.js similarity index 97% rename from ee/spec/javascripts/roadmap/mixins/weeks_preset_mixin_spec.js rename to ee/spec/frontend/roadmap/mixins/weeks_preset_mixin_spec.js index c75aa62e5cd93a14ac1cae097e8bc67ffa9ede3f..c77a5a61954d9eb3dde9770610ea0554d722169f 100644 --- a/ee/spec/javascripts/roadmap/mixins/weeks_preset_mixin_spec.js +++ b/ee/spec/frontend/roadmap/mixins/weeks_preset_mixin_spec.js @@ -5,8 +5,8 @@ import { getTimeframeForWeeksView } from 'ee/roadmap/utils/roadmap_utils'; import { PRESET_TYPES } from 'ee/roadmap/constants'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { mockTimeframeInitialDate, mockEpic } from '../mock_data'; +import mountComponent from 'helpers/vue_mount_component_helper'; +import { mockTimeframeInitialDate, mockEpic } from 'ee_jest/roadmap/mock_data'; const mockTimeframeWeeks = getTimeframeForWeeksView(mockTimeframeInitialDate); diff --git a/ee/spec/javascripts/roadmap/mock_data.js b/ee/spec/frontend/roadmap/mock_data.js similarity index 100% rename from ee/spec/javascripts/roadmap/mock_data.js rename to ee/spec/frontend/roadmap/mock_data.js diff --git a/ee/spec/javascripts/roadmap/store/actions_spec.js b/ee/spec/frontend/roadmap/store/actions_spec.js similarity index 76% rename from ee/spec/javascripts/roadmap/store/actions_spec.js rename to ee/spec/frontend/roadmap/store/actions_spec.js index 938a3146f307a95714060f3c42e77899299bdb14..6e6f7337199713b646595550281b67503b921af7 100644 --- a/ee/spec/javascripts/roadmap/store/actions_spec.js +++ b/ee/spec/frontend/roadmap/store/actions_spec.js @@ -12,8 +12,9 @@ import groupEpics from 'ee/roadmap/queries/groupEpics.query.graphql'; import groupMilestones from 'ee/roadmap/queries/groupMilestones.query.graphql'; import epicChildEpics from 'ee/roadmap/queries/epicChildEpics.query.graphql'; -import testAction from 'spec/helpers/vuex_action_helper'; +import testAction from 'helpers/vuex_action_helper'; import axios from '~/lib/utils/axios_utils'; +import createFlash from '~/flash'; import { mockGroupId, @@ -35,6 +36,8 @@ import { mockFormattedMilestone, } from '../mock_data'; +jest.mock('~/flash'); + const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); describe('Roadmap Vuex Actions', () => { @@ -57,32 +60,30 @@ describe('Roadmap Vuex Actions', () => { }); describe('setInitialData', () => { - it('should set initial roadmap props', done => { + it('should set initial roadmap props', () => { const mockRoadmap = { foo: 'bar', bar: 'baz', }; - testAction( + return testAction( actions.setInitialData, mockRoadmap, {}, [{ type: types.SET_INITIAL_DATA, payload: mockRoadmap }], [], - done, ); }); }); describe('setWindowResizeInProgress', () => { - it('should set value of `state.windowResizeInProgress` based on provided value', done => { - testAction( + it('should set value of `state.windowResizeInProgress` based on provided value', () => { + return testAction( actions.setWindowResizeInProgress, true, state, [{ type: types.SET_WINDOW_RESIZE_IN_PROGRESS, payload: true }], [], - done, ); }); }); @@ -110,27 +111,23 @@ describe('Roadmap Vuex Actions', () => { }; }); - it('should fetch Group Epics using GraphQL client when epicIid is not present in state', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should fetch Group Epics using GraphQL client when epicIid is not present in state', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockGroupEpicsQueryResponse.data, }), ); - actions - .fetchGroupEpics(mockState) - .then(() => { - expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ - query: groupEpics, - variables: expectedVariables, - }); - }) - .then(done) - .catch(done.fail); + return actions.fetchGroupEpics(mockState).then(() => { + expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ + query: groupEpics, + variables: expectedVariables, + }); + }); }); - it('should fetch child Epics of an Epic using GraphQL client when epicIid is present in state', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should fetch child Epics of an Epic using GraphQL client when epicIid is present in state', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockEpicChildEpicsQueryResponse.data, }), @@ -138,44 +135,39 @@ describe('Roadmap Vuex Actions', () => { mockState.epicIid = '1'; - actions - .fetchGroupEpics(mockState) - .then(() => { - expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ - query: epicChildEpics, - variables: { - iid: '1', - ...expectedVariables, - }, - }); - }) - .then(done) - .catch(done.fail); + return actions.fetchGroupEpics(mockState).then(() => { + expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ + query: epicChildEpics, + variables: { + iid: '1', + ...expectedVariables, + }, + }); + }); }); }); describe('requestEpics', () => { - it('should set `epicsFetchInProgress` to true', done => { - testAction(actions.requestEpics, {}, state, [{ type: 'REQUEST_EPICS' }], [], done); + it('should set `epicsFetchInProgress` to true', () => { + return testAction(actions.requestEpics, {}, state, [{ type: 'REQUEST_EPICS' }], []); }); }); describe('requestEpicsForTimeframe', () => { - it('should set `epicsFetchForTimeframeInProgress` to true', done => { - testAction( + it('should set `epicsFetchForTimeframeInProgress` to true', () => { + return testAction( actions.requestEpicsForTimeframe, {}, state, [{ type: types.REQUEST_EPICS_FOR_TIMEFRAME }], [], - done, ); }); }); describe('receiveEpicsSuccess', () => { - it('should set formatted epics array and epicId to IDs array in state based on provided epics list', done => { - testAction( + it('should set formatted epics array and epicId to IDs array in state based on provided epics list', () => { + return testAction( actions.receiveEpicsSuccess, { rawEpics: [ @@ -207,12 +199,11 @@ describe('Roadmap Vuex Actions', () => { }, ], [], - done, ); }); - it('should set formatted epics array and epicId to IDs array in state based on provided epics list when timeframe was extended', done => { - testAction( + it('should set formatted epics array and epicId to IDs array in state based on provided epics list when timeframe was extended', () => { + return testAction( actions.receiveEpicsSuccess, { rawEpics: [ @@ -236,33 +227,25 @@ describe('Roadmap Vuex Actions', () => { }, ], [], - done, ); }); }); describe('receiveEpicsFailure', () => { - beforeEach(() => { - setFixtures('
'); - }); - - it('should set epicsFetchInProgress, epicsFetchForTimeframeInProgress to false and epicsFetchFailure to true', done => { - testAction( + it('should set epicsFetchInProgress, epicsFetchForTimeframeInProgress to false and epicsFetchFailure to true', () => { + return testAction( actions.receiveEpicsFailure, {}, state, [{ type: types.RECEIVE_EPICS_FAILURE }], [], - done, ); }); it('should show flash error', () => { actions.receiveEpicsFailure({ commit: () => {} }); - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - 'Something went wrong while fetching epics', - ); + expect(createFlash).toHaveBeenCalledWith('Something went wrong while fetching epics'); }); }); @@ -278,14 +261,14 @@ describe('Roadmap Vuex Actions', () => { }); describe('success', () => { - it('should dispatch requestEpics and receiveEpicsSuccess when request is successful', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should dispatch requestEpics and receiveEpicsSuccess when request is successful', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockGroupEpicsQueryResponse.data, }), ); - testAction( + return testAction( actions.fetchEpics, null, state, @@ -299,18 +282,15 @@ describe('Roadmap Vuex Actions', () => { payload: { rawEpics: mockGroupEpicsQueryResponseFormatted }, }, ], - done, ); }); }); describe('failure', () => { - it('should dispatch requestEpics and receiveEpicsFailure when request fails', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( - Promise.reject(new Error('error message')), - ); + it('should dispatch requestEpics and receiveEpicsFailure when request fails', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockRejectedValue(new Error('error message')); - testAction( + return testAction( actions.fetchEpics, null, state, @@ -323,34 +303,21 @@ describe('Roadmap Vuex Actions', () => { type: 'receiveEpicsFailure', }, ], - done, ); }); }); }); describe('fetchEpicsForTimeframe', () => { - const mockEpicsPath = - '/groups/gitlab-org/-/epics.json?state=&start_date=2017-11-1&end_date=2018-6-30'; - let mock; - - beforeEach(() => { - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - describe('success', () => { - it('should dispatch requestEpicsForTimeframe and receiveEpicsSuccess when request is successful', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should dispatch requestEpicsForTimeframe and receiveEpicsSuccess when request is successful', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockGroupEpicsQueryResponse.data, }), ); - testAction( + return testAction( actions.fetchEpicsForTimeframe, { timeframe: mockTimeframeMonths }, state, @@ -368,16 +335,15 @@ describe('Roadmap Vuex Actions', () => { }, }, ], - done, ); }); }); describe('failure', () => { - it('should dispatch requestEpicsForTimeframe and requestEpicsFailure when request fails', done => { - mock.onGet(mockEpicsPath).replyOnce(500, {}); + it('should dispatch requestEpicsForTimeframe and requestEpicsFailure when request fails', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockRejectedValue(); - testAction( + return testAction( actions.fetchEpicsForTimeframe, { timeframe: mockTimeframeMonths }, state, @@ -390,38 +356,35 @@ describe('Roadmap Vuex Actions', () => { type: 'receiveEpicsFailure', }, ], - done, ); }); }); }); describe('extendTimeframe', () => { - it('should prepend to timeframe when called with extend type prepend', done => { - testAction( + it('should prepend to timeframe when called with extend type prepend', () => { + return testAction( actions.extendTimeframe, { extendAs: EXTEND_AS.PREPEND }, state, [{ type: types.PREPEND_TIMEFRAME, payload: mockTimeframeMonthsPrepend }], [], - done, ); }); - it('should append to timeframe when called with extend type append', done => { - testAction( + it('should append to timeframe when called with extend type append', () => { + return testAction( actions.extendTimeframe, { extendAs: EXTEND_AS.APPEND }, state, [{ type: types.APPEND_TIMEFRAME, payload: mockTimeframeMonthsAppend }], [], - done, ); }); }); describe('refreshEpicDates', () => { - it('should update epics after refreshing epic dates to match with updated timeframe', done => { + it('should update epics after refreshing epic dates to match with updated timeframe', () => { const epics = rawEpics.map(epic => roadmapItemUtils.formatRoadmapItemDetails( epic, @@ -430,26 +393,24 @@ describe('Roadmap Vuex Actions', () => { ), ); - testAction( + return testAction( actions.refreshEpicDates, {}, { ...state, timeframe: mockTimeframeMonths.concat(mockTimeframeMonthsAppend), epics }, [{ type: types.SET_EPICS, payload: epics }], [], - done, ); }); }); describe('setBufferSize', () => { - it('should set bufferSize in store state', done => { - testAction( + it('should set bufferSize in store state', () => { + return testAction( actions.setBufferSize, 10, state, [{ type: types.SET_BUFFER_SIZE, payload: 10 }], [], - done, ); }); }); @@ -474,42 +435,38 @@ describe('Roadmap Vuex Actions', () => { }; }); - it('should fetch Group Milestones using GraphQL client when milestoneIid is not present in state', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should fetch Group Milestones using GraphQL client when milestoneIid is not present in state', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockGroupMilestonesQueryResponse.data, }), ); - actions - .fetchGroupMilestones(mockState) - .then(() => { - expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ - query: groupMilestones, - variables: expectedVariables, - }); - }) - .then(done) - .catch(done.fail); + return actions.fetchGroupMilestones(mockState).then(() => { + expect(epicUtils.gqClient.query).toHaveBeenCalledWith({ + query: groupMilestones, + variables: expectedVariables, + }); + }); }); }); describe('requestMilestones', () => { - it('should set `milestonesFetchInProgress` to true', done => { - testAction(actions.requestMilestones, {}, state, [{ type: 'REQUEST_MILESTONES' }], [], done); + it('should set `milestonesFetchInProgress` to true', () => { + return testAction(actions.requestMilestones, {}, state, [{ type: 'REQUEST_MILESTONES' }], []); }); }); describe('fetchMilestones', () => { describe('success', () => { - it('should dispatch requestMilestones and receiveMilestonesSuccess when request is successful', done => { - spyOn(epicUtils.gqClient, 'query').and.returnValue( + it('should dispatch requestMilestones and receiveMilestonesSuccess when request is successful', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue( Promise.resolve({ data: mockGroupMilestonesQueryResponse.data, }), ); - testAction( + return testAction( actions.fetchMilestones, null, state, @@ -523,14 +480,15 @@ describe('Roadmap Vuex Actions', () => { payload: { rawMilestones }, }, ], - done, ); }); }); describe('failure', () => { - it('should dispatch requestMilestones and receiveMilestonesFailure when request fails', done => { - testAction( + it('should dispatch requestMilestones and receiveMilestonesFailure when request fails', () => { + jest.spyOn(epicUtils.gqClient, 'query').mockReturnValue(Promise.reject()); + + return testAction( actions.fetchMilestones, null, state, @@ -543,15 +501,14 @@ describe('Roadmap Vuex Actions', () => { type: 'receiveMilestonesFailure', }, ], - done, ); }); }); }); describe('receiveMilestonesSuccess', () => { - it('should set formatted milestones array and milestoneId to IDs array in state based on provided milestones list', done => { - testAction( + it('should set formatted milestones array and milestoneId to IDs array in state based on provided milestones list', () => { + return testAction( actions.receiveMilestonesSuccess, { rawMilestones: [ @@ -579,38 +536,30 @@ describe('Roadmap Vuex Actions', () => { }, ], [], - done, ); }); }); describe('receiveMilestonesFailure', () => { - beforeEach(() => { - setFixtures('
'); - }); - - it('should set milestonesFetchInProgress to false and milestonesFetchFailure to true', done => { - testAction( + it('should set milestonesFetchInProgress to false and milestonesFetchFailure to true', () => { + return testAction( actions.receiveMilestonesFailure, {}, state, [{ type: types.RECEIVE_MILESTONES_FAILURE }], [], - done, ); }); it('should show flash error', () => { actions.receiveMilestonesFailure({ commit: () => {} }); - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - 'Something went wrong while fetching milestones', - ); + expect(createFlash).toHaveBeenCalledWith('Something went wrong while fetching milestones'); }); }); describe('refreshMilestoneDates', () => { - it('should update milestones after refreshing milestone dates to match with updated timeframe', done => { + it('should update milestones after refreshing milestone dates to match with updated timeframe', () => { const milestones = rawMilestones.map(milestone => roadmapItemUtils.formatRoadmapItemDetails( milestone, @@ -619,13 +568,12 @@ describe('Roadmap Vuex Actions', () => { ), ); - testAction( + return testAction( actions.refreshMilestoneDates, {}, { ...state, timeframe: mockTimeframeMonths.concat(mockTimeframeMonthsAppend), milestones }, [{ type: types.SET_MILESTONES, payload: milestones }], [], - done, ); }); }); diff --git a/ee/spec/javascripts/roadmap/store/mutations_spec.js b/ee/spec/frontend/roadmap/store/mutations_spec.js similarity index 98% rename from ee/spec/javascripts/roadmap/store/mutations_spec.js rename to ee/spec/frontend/roadmap/store/mutations_spec.js index ba1bdda723e4e4fcd115527680f5190a00372d7b..318565ab457a9bb7bb39e9e806c1cdf32b0e4f50 100644 --- a/ee/spec/javascripts/roadmap/store/mutations_spec.js +++ b/ee/spec/frontend/roadmap/store/mutations_spec.js @@ -3,7 +3,7 @@ import * as types from 'ee/roadmap/store/mutation_types'; import defaultState from 'ee/roadmap/store/state'; -import { mockGroupId, basePath, epicsPath, mockSortedBy } from '../mock_data'; +import { mockGroupId, basePath, epicsPath, mockSortedBy } from 'ee_jest/roadmap/mock_data'; const getEpic = (epicId, epics) => epics.find(e => e.id === epicId); @@ -36,7 +36,7 @@ describe('Roadmap Store Mutations', () => { mutations[types.SET_INITIAL_DATA](state, initialData); - expect(state).toEqual(jasmine.objectContaining(initialData)); + expect(state).toEqual(expect.objectContaining(initialData)); }); }); diff --git a/ee/spec/javascripts/roadmap/utils/epic_utils_spec.js b/ee/spec/frontend/roadmap/utils/epic_utils_spec.js similarity index 98% rename from ee/spec/javascripts/roadmap/utils/epic_utils_spec.js rename to ee/spec/frontend/roadmap/utils/epic_utils_spec.js index 0d82195bf598accb7ec51f84dd2341e7efdb0d9f..9bdadafbce8776bf873a55c6d6b5d4f91a7e7dc9 100644 --- a/ee/spec/javascripts/roadmap/utils/epic_utils_spec.js +++ b/ee/spec/frontend/roadmap/utils/epic_utils_spec.js @@ -9,7 +9,7 @@ describe('extractGroupEpics', () => { expect(extractedEpics.length).toBe(edges.length); expect(extractedEpics[0]).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ ...edges[0].node, groupName: edges[0].node.group.name, groupFullName: edges[0].node.group.fullName, diff --git a/ee/spec/javascripts/roadmap/utils/roadmap_item_utils_spec.js b/ee/spec/frontend/roadmap/utils/roadmap_item_utils_spec.js similarity index 100% rename from ee/spec/javascripts/roadmap/utils/roadmap_item_utils_spec.js rename to ee/spec/frontend/roadmap/utils/roadmap_item_utils_spec.js diff --git a/ee/spec/javascripts/roadmap/utils/roadmap_utils_spec.js b/ee/spec/frontend/roadmap/utils/roadmap_utils_spec.js similarity index 98% rename from ee/spec/javascripts/roadmap/utils/roadmap_utils_spec.js rename to ee/spec/frontend/roadmap/utils/roadmap_utils_spec.js index 2cfa7a39a8b262b8be4341444b44bd5140a3fdd4..57c260529d73c775c49d1e75354ef8ad03e8613a 100644 --- a/ee/spec/javascripts/roadmap/utils/roadmap_utils_spec.js +++ b/ee/spec/frontend/roadmap/utils/roadmap_utils_spec.js @@ -43,8 +43,8 @@ describe('getTimeframeForQuartersView', () => { it('each timeframe item has `quarterSequence`, `year` and `range` present', () => { const timeframeItem = timeframe[0]; - expect(timeframeItem.quarterSequence).toEqual(jasmine.any(Number)); - expect(timeframeItem.year).toEqual(jasmine.any(Number)); + expect(timeframeItem.quarterSequence).toEqual(expect.any(Number)); + expect(timeframeItem.year).toEqual(expect.any(Number)); expect(Array.isArray(timeframeItem.range)).toBe(true); }); @@ -307,7 +307,7 @@ describe('getEpicsTimeframeRange', () => { }); expect(range).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ startDate: '2017-7-1', dueDate: '2019-3-31', }), @@ -322,7 +322,7 @@ describe('getEpicsTimeframeRange', () => { }); expect(range).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ startDate: '2017-11-1', dueDate: '2018-6-30', }), @@ -337,7 +337,7 @@ describe('getEpicsTimeframeRange', () => { }); expect(range).toEqual( - jasmine.objectContaining({ + expect.objectContaining({ startDate: '2017-12-17', dueDate: '2018-2-3', }),