Commit 8d8555f1 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Brandon Labuschagne

Added specs for the duration chart

Adds jest tests for basic rendering of
the duration chart. Removes duplicate
tests from base_spec
parent 9c7433e9
...@@ -32,11 +32,14 @@ export default { ...@@ -32,11 +32,14 @@ export default {
}, },
computed: { computed: {
hasData() { hasData() {
// TODO: check if we want to display when only the median data is available return Boolean(this.scatterData.length);
return Boolean(this.scatterData.length || this.medianLineData.length); },
},
methods: {
onSelectStage(selectedStages) {
this.$emit('stageSelected', selectedStages);
}, },
}, },
methods: {},
durationChartTooltipDateFormat: dateFormats.defaultDate, durationChartTooltipDateFormat: dateFormats.defaultDate,
}; };
</script> </script>
...@@ -50,7 +53,7 @@ export default { ...@@ -50,7 +53,7 @@ export default {
v-if="stages.length" v-if="stages.length"
class="ml-auto" class="ml-auto"
:stages="stages" :stages="stages"
@selected="$emit('stageSelected')" @selected="onSelectStage"
/> />
</div> </div>
<scatterplot <scatterplot
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DurationChart renders the duration chart 1`] = `
"<div>
<div class=\\"d-flex\\">
<h4 class=\\"mt-0\\">Days to completion</h4>
<stagedropdownfilter-stub stages=\\"[object Object],[object Object],[object Object]\\" label=\\"stage dropdown\\" class=\\"ml-auto\\"></stagedropdownfilter-stub>
</div>
<scatterplot-stub xaxistitle=\\"Date\\" yaxistitle=\\"Total days to completion\\" scatterdata=\\"2019-01-01,29,2019-01-01,2019-01-02,100,2019-01-02\\" medianlinedata=\\"2018-12-31,29,2019-01-01,100\\" tooltipdateformat=\\"mmm d, yyyy\\"></scatterplot-stub>
</div>"
`;
...@@ -13,7 +13,6 @@ import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue' ...@@ -13,7 +13,6 @@ import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue'
import 'bootstrap'; import 'bootstrap';
import '~/gl_dropdown'; import '~/gl_dropdown';
import DurationChart from 'ee/analytics/cycle_analytics/components/duration_chart.vue'; import DurationChart from 'ee/analytics/cycle_analytics/components/duration_chart.vue';
import Scatterplot from 'ee/analytics/shared/components/scatterplot.vue';
import Daterange from 'ee/analytics/shared/components/daterange.vue'; import Daterange from 'ee/analytics/shared/components/daterange.vue';
import TasksByTypeChart from 'ee/analytics/cycle_analytics/components/tasks_by_type_chart.vue'; import TasksByTypeChart from 'ee/analytics/cycle_analytics/components/tasks_by_type_chart.vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -40,8 +39,6 @@ const defaultStubs = { ...@@ -40,8 +39,6 @@ const defaultStubs = {
'stage-nav-item': true, 'stage-nav-item': true,
'tasks-by-type-chart': true, 'tasks-by-type-chart': true,
'labels-selector': true, 'labels-selector': true,
'stage-dropdown-filter': true,
Scatterplot: true,
DurationChart: true, DurationChart: true,
}; };
...@@ -131,8 +128,8 @@ describe('Cycle Analytics component', () => { ...@@ -131,8 +128,8 @@ describe('Cycle Analytics component', () => {
expect(wrapper.find(StageTable).exists()).toBe(flag); expect(wrapper.find(StageTable).exists()).toBe(flag);
}; };
const displaysDurationScatterPlot = flag => { const displaysDurationChart = flag => {
expect(wrapper.find(Scatterplot).exists()).toBe(flag); expect(wrapper.find(DurationChart).exists()).toBe(flag);
}; };
const displaysTasksByType = flag => { const displaysTasksByType = flag => {
...@@ -187,8 +184,8 @@ describe('Cycle Analytics component', () => { ...@@ -187,8 +184,8 @@ describe('Cycle Analytics component', () => {
displaysStageTable(false); displaysStageTable(false);
}); });
it('does not display the duration scatter plot', () => { it('does not display the duration chart', () => {
displaysDurationScatterPlot(false); displaysDurationChart(false);
}); });
describe('hideGroupDropDown = true', () => { describe('hideGroupDropDown = true', () => {
...@@ -213,13 +210,6 @@ describe('Cycle Analytics component', () => { ...@@ -213,13 +210,6 @@ describe('Cycle Analytics component', () => {
wrapper = createComponent({ wrapper = createComponent({
withStageSelected: true, withStageSelected: true,
tasksByTypeChartEnabled: false, tasksByTypeChartEnabled: false,
opts: {
stubs: {
...defaultStubs,
'duration-chart': false,
},
},
}); });
}); });
...@@ -257,16 +247,7 @@ describe('Cycle Analytics component', () => { ...@@ -257,16 +247,7 @@ describe('Cycle Analytics component', () => {
describe('with no durationData', () => { describe('with no durationData', () => {
it('displays the duration chart', () => { it('displays the duration chart', () => {
expect(wrapper.find(Scatterplot).exists()).toBe(false); displaysDurationChart(true);
});
it('displays the no data message', () => {
const element = wrapper.find({ ref: 'duration-chart-no-data' });
expect(element.exists()).toBe(true);
expect(element.text()).toBe(
'There is no data available. Please change your selection.',
);
}); });
}); });
...@@ -371,7 +352,7 @@ describe('Cycle Analytics component', () => { ...@@ -371,7 +352,7 @@ describe('Cycle Analytics component', () => {
}); });
it('does not display the duration chart', () => { it('does not display the duration chart', () => {
displaysDurationScatterPlot(false); displaysDurationChart(false);
}); });
}); });
......
import { shallowMount, mount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
import $ from 'jquery';
import 'bootstrap';
import '~/gl_dropdown';
import Scatterplot from 'ee/analytics/shared/components/scatterplot.vue';
import DurationChart from 'ee/analytics/cycle_analytics/components/duration_chart.vue';
import StageDropdownFilter from 'ee/analytics/cycle_analytics/components/stage_dropdown_filter.vue';
import {
allowedStages as stages,
durationChartPlottableData as scatterData,
durationChartPlottableMedianData as medianLineData,
} from '../mock_data';
function createComponent({ mountFn = shallowMount, props = {}, stubs = {} } = {}) {
return mountFn(DurationChart, {
propsData: {
isLoading: false,
stages,
scatterData,
medianLineData,
...props,
},
stubs: {
GlLoadingIcon: true,
Scatterplot: true,
StageDropdownFilter: true,
...stubs,
},
});
}
describe('DurationChart', () => {
let wrapper;
const findNoDataContainer = _wrapper => _wrapper.find({ ref: 'duration-chart-no-data' });
const findScatterPlot = _wrapper => _wrapper.find(Scatterplot);
const findStageDropdown = _wrapper => _wrapper.find(StageDropdownFilter);
const findLoader = _wrapper => _wrapper.find(GlLoadingIcon);
const openStageDropdown = _wrapper => {
$(findStageDropdown(_wrapper).element).trigger('shown.bs.dropdown');
return _wrapper.vm.$nextTick();
};
const selectStage = (_wrapper, index = 0) => {
findStageDropdown(_wrapper)
.findAll('a')
.at(index)
.trigger('click');
return _wrapper.vm.$nextTick();
};
beforeEach(() => {
wrapper = createComponent({});
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders the duration chart', () => {
expect(wrapper.html()).toMatchSnapshot();
});
it('renders the scatter plot', () => {
expect(findScatterPlot(wrapper).exists()).toBe(true);
});
it('renders the stage dropdown', () => {
expect(findStageDropdown(wrapper).exists()).toBe(true);
});
describe('when a stage is selected', () => {
const selectedIndex = 1;
const selectedStages = stages.filter((_, index) => index !== selectedIndex);
beforeEach(() => {
wrapper = createComponent({ mountFn: mount, stubs: { StageDropdownFilter: false } });
return openStageDropdown(wrapper).then(() => selectStage(wrapper, selectedIndex));
});
it('emits the stageSelected event', () => {
expect(wrapper.emitted().stageSelected).toBeTruthy();
});
it('toggles the selected stage', () => {
expect(wrapper.emitted('stageSelected')[0]).toEqual([selectedStages]);
return selectStage(wrapper, selectedIndex).then(() => {
const [updatedStages] = wrapper.emitted('stageSelected')[1];
stages.forEach(stage => {
expect(updatedStages).toContain(stage);
});
});
});
});
describe('with no chart data', () => {
beforeEach(() => {
wrapper = createComponent({ props: { scatterData: [], medianLineData: [] } });
});
it('renders the no data available message', () => {
expect(findNoDataContainer(wrapper).text()).toEqual(
'There is no data available. Please change your selection.',
);
});
});
describe('while loading', () => {
beforeEach(() => {
wrapper = createComponent({ props: { isLoading: true } });
});
it('renders loading icon', () => {
expect(findLoader(wrapper).exists()).toBe(true);
});
});
});
...@@ -111,7 +111,7 @@ describe('Cycle analytics getters', () => { ...@@ -111,7 +111,7 @@ describe('Cycle analytics getters', () => {
); );
}); });
it('returns null if there is no plottable data for the selected stages', () => { it('returns an empty array if there is no plottable data for the selected stages', () => {
const stateWithDurationData = { const stateWithDurationData = {
startDate, startDate,
endDate, endDate,
......
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