Commit f1702175 authored by David O'Regan's avatar David O'Regan

Merge branch '326701-move-ee-vsa-filter-components-to-ce' into 'master'

Moves the VSA filter EE to CE[RUN-AS-IF-FOSS]

See merge request gitlab-org/gitlab!65433
parents 99f5cbd3 50db70aa
...@@ -9,11 +9,11 @@ import { ...@@ -9,11 +9,11 @@ import {
GlSearchBoxByType, GlSearchBoxByType,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { filterBySearchTerm } from '~/analytics/shared/utils';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import { n__, s__, __ } from '~/locale'; import { n__, s__, __ } from '~/locale';
import { DATA_REFETCH_DELAY } from '../constants';
import getProjects from '../graphql/projects.query.graphql'; import getProjects from '../graphql/projects.query.graphql';
import { filterBySearchTerm } from '../utils';
export default { export default {
name: 'ProjectsDropdownFilter', name: 'ProjectsDropdownFilter',
...@@ -106,7 +106,7 @@ export default { ...@@ -106,7 +106,7 @@ export default {
methods: { methods: {
search: debounce(function debouncedSearch() { search: debounce(function debouncedSearch() {
this.fetchData(); this.fetchData();
}, DATA_REFETCH_DELAY), }, DEFAULT_DEBOUNCE_AND_THROTTLE_MS),
getSelectedProjects(selectedProject, isMarking) { getSelectedProjects(selectedProject, isMarking) {
return isMarking return isMarking
? this.selectedProjects.concat([selectedProject]) ? this.selectedProjects.concat([selectedProject])
......
export const DATE_RANGE_LIMIT = 180;
export const OFFSET_DATE_BY_ONE = 1;
export const PROJECTS_PER_PAGE = 50;
export const filterBySearchTerm = (data = [], searchTerm = '', filterByKey = 'name') => {
if (!searchTerm?.length) return data;
return data.filter((item) => item[filterByKey].toLowerCase().includes(searchTerm.toLowerCase()));
};
<script> <script>
import DateRange from '../../shared/components/daterange.vue'; import DateRange from '~/analytics/shared/components/daterange.vue';
import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue'; import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import { DATE_RANGE_LIMIT } from '../../shared/constants'; import { DATE_RANGE_LIMIT, PROJECTS_PER_PAGE } from '~/analytics/shared/constants';
import { PROJECTS_PER_PAGE } from '../constants';
import FilterBar from './filter_bar.vue'; import FilterBar from './filter_bar.vue';
export default { export default {
......
export const DEFAULT_DAYS_IN_PAST = 30;
export const DEFAULT_DAYS_TO_DISPLAY = 30; export const DEFAULT_DAYS_TO_DISPLAY = 30;
export const OVERVIEW_STAGE_ID = 'overview'; export const OVERVIEW_STAGE_ID = 'overview';
......
...@@ -92,6 +92,8 @@ const refetchData = (dispatch, commit) => { ...@@ -92,6 +92,8 @@ const refetchData = (dispatch, commit) => {
.finally(() => commit(types.SET_LOADING, false)); .finally(() => commit(types.SET_LOADING, false));
}; };
export const setFilters = ({ dispatch, commit }) => refetchData(dispatch, commit);
export const setDateRange = ({ dispatch, commit }, { startDate = DEFAULT_DAYS_TO_DISPLAY }) => { export const setDateRange = ({ dispatch, commit }, { startDate = DEFAULT_DAYS_TO_DISPLAY }) => {
commit(types.SET_DATE_RANGE, { startDate }); commit(types.SET_DATE_RANGE, { startDate });
return refetchData(dispatch, commit); return refetchData(dispatch, commit);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import filters from '~/vue_shared/components/filtered_search_bar/store/modules/filters';
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters'; import * as getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
...@@ -20,4 +21,5 @@ export default () => ...@@ -20,4 +21,5 @@ export default () =>
getters, getters,
mutations, mutations,
state, state,
modules: { filters },
}); });
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import { GlEmptyState } from '@gitlab/ui'; import { GlEmptyState } from '@gitlab/ui';
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue'; import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants'; import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
import UrlSync from '~/vue_shared/components/url_sync.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue';
import { toYmd } from '../../shared/utils'; import { toYmd } from '../../shared/utils';
...@@ -9,7 +10,6 @@ import DurationChart from './duration_chart.vue'; ...@@ -9,7 +10,6 @@ import DurationChart from './duration_chart.vue';
import Metrics from './metrics.vue'; import Metrics from './metrics.vue';
import StageTable from './stage_table.vue'; import StageTable from './stage_table.vue';
import TypeOfWorkCharts from './type_of_work_charts.vue'; import TypeOfWorkCharts from './type_of_work_charts.vue';
import ValueStreamFilters from './value_stream_filters.vue';
import ValueStreamSelect from './value_stream_select.vue'; import ValueStreamSelect from './value_stream_select.vue';
export default { export default {
......
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants'; import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
export const PROJECTS_PER_PAGE = 50;
export const DEFAULT_DAYS_IN_PAST = 30;
export const EVENTS_LIST_ITEM_LIMIT = 50; export const EVENTS_LIST_ITEM_LIMIT = 50;
export const TASKS_BY_TYPE_SUBJECT_ISSUE = 'Issue'; export const TASKS_BY_TYPE_SUBJECT_ISSUE = 'Issue';
......
<script> <script>
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import DateRange from '~/analytics/shared/components/daterange.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue';
import DateRange from '../../shared/components/daterange.vue';
import { dateFormats } from '../../shared/constants'; import { dateFormats } from '../../shared/constants';
import { DEFAULT_NUMBER_OF_DAYS } from '../constants'; import { DEFAULT_NUMBER_OF_DAYS } from '../constants';
import FilterBar from './filter_bar.vue'; import FilterBar from './filter_bar.vue';
......
<script> <script>
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue'; import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue';
import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue';
import { accessLevelReporter, projectsPerPage } from '../constants'; import { accessLevelReporter, projectsPerPage } from '../constants';
export default { export default {
......
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import DateRange from '~/analytics/shared/components/daterange.vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils'; import { parseBoolean } from '~/lib/utils/common_utils';
import DateRange from '../shared/components/daterange.vue';
import { buildGroupFromDataset, buildProjectFromDataset } from '../shared/utils'; import { buildGroupFromDataset, buildProjectFromDataset } from '../shared/utils';
import ProductivityAnalyticsApp from './components/app.vue'; import ProductivityAnalyticsApp from './components/app.vue';
import FilterDropdowns from './components/filter_dropdowns.vue'; import FilterDropdowns from './components/filter_dropdowns.vue';
......
...@@ -10,10 +10,10 @@ import { ...@@ -10,10 +10,10 @@ import {
GlSafeHtmlDirective as SafeHtml, GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { filterBySearchTerm } from '~/analytics/shared/utils';
import Api from '~/api'; import Api from '~/api';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import { DATA_REFETCH_DELAY } from '../constants'; import { DATA_REFETCH_DELAY } from '../constants';
import { filterBySearchTerm } from '../utils';
export default { export default {
name: 'GroupsDropdownFilter', name: 'GroupsDropdownFilter',
......
...@@ -19,10 +19,6 @@ export const scatterChartLineProps = { ...@@ -19,10 +19,6 @@ export const scatterChartLineProps = {
}, },
}; };
export const DATE_RANGE_LIMIT = 180;
export const OFFSET_DATE_BY_ONE = 1;
export const NO_DRAG_CLASS = 'no-drag'; export const NO_DRAG_CLASS = 'no-drag';
export const DATA_REFETCH_DELAY = DEFAULT_DEBOUNCE_AND_THROTTLE_MS; export const DATA_REFETCH_DELAY = DEFAULT_DEBOUNCE_AND_THROTTLE_MS;
...@@ -135,8 +135,3 @@ export const buildCycleAnalyticsInitialData = ({ ...@@ -135,8 +135,3 @@ export const buildCycleAnalyticsInitialData = ({
: [], : [],
stage: JSON.parse(stage), stage: JSON.parse(stage),
}); });
export const filterBySearchTerm = (data = [], searchTerm = '', filterByKey = 'name') => {
if (!searchTerm?.length) return data;
return data.filter((item) => item[filterByKey].toLowerCase().includes(searchTerm.toLowerCase()));
};
...@@ -8,25 +8,38 @@ import DurationChart from 'ee/analytics/cycle_analytics/components/duration_char ...@@ -8,25 +8,38 @@ import DurationChart from 'ee/analytics/cycle_analytics/components/duration_char
import Metrics from 'ee/analytics/cycle_analytics/components/metrics.vue'; import Metrics from 'ee/analytics/cycle_analytics/components/metrics.vue';
import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue'; import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue';
import TypeOfWorkCharts from 'ee/analytics/cycle_analytics/components/type_of_work_charts.vue'; import TypeOfWorkCharts from 'ee/analytics/cycle_analytics/components/type_of_work_charts.vue';
import ValueStreamFilters from 'ee/analytics/cycle_analytics/components/value_stream_filters.vue';
import ValueStreamSelect from 'ee/analytics/cycle_analytics/components/value_stream_select.vue'; import ValueStreamSelect from 'ee/analytics/cycle_analytics/components/value_stream_select.vue';
import createStore from 'ee/analytics/cycle_analytics/store'; import createStore from 'ee/analytics/cycle_analytics/store';
import { toYmd } from 'ee/analytics/shared/utils'; import { toYmd } from 'ee/analytics/shared/utils';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import {
currentGroup,
createdBefore,
createdAfter,
selectedProjects,
} from 'jest/cycle_analytics/mock_data';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue'; import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants'; import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import * as commonUtils from '~/lib/utils/common_utils'; import * as commonUtils from '~/lib/utils/common_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status'; import httpStatusCodes from '~/lib/utils/http_status';
import * as urlUtils from '~/lib/utils/url_utility'; import * as urlUtils from '~/lib/utils/url_utility';
import UrlSync from '~/vue_shared/components/url_sync.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue';
import * as mockData from '../mock_data'; import {
initialPaginationQuery,
valueStreams,
endpoints,
customizableStagesAndEvents,
issueStage,
issueEvents,
groupLabels,
tasksByTypeData,
} from '../mock_data';
const noDataSvgPath = 'path/to/no/data'; const noDataSvgPath = 'path/to/no/data';
const noAccessSvgPath = 'path/to/no/access'; const noAccessSvgPath = 'path/to/no/access';
const currentGroup = convertObjectPropsToCamelCase(mockData.group);
const emptyStateSvgPath = 'path/to/empty/state'; const emptyStateSvgPath = 'path/to/empty/state';
const stage = null; const stage = null;
...@@ -49,12 +62,12 @@ const defaultFeatureFlags = { ...@@ -49,12 +62,12 @@ const defaultFeatureFlags = {
hasDurationChart: true, hasDurationChart: true,
}; };
const [selectedValueStream] = mockData.valueStreams; const [selectedValueStream] = valueStreams;
const initialCycleAnalyticsState = { const initialCycleAnalyticsState = {
selectedValueStream, selectedValueStream,
createdAfter: mockData.createdAfter, createdAfter,
createdBefore: mockData.createdBefore, createdBefore,
group: currentGroup, group: currentGroup,
stage, stage,
}; };
...@@ -71,23 +84,17 @@ const mocks = { ...@@ -71,23 +84,17 @@ const mocks = {
}; };
function mockRequiredRoutes(mockAdapter) { function mockRequiredRoutes(mockAdapter) {
mockAdapter.onGet(mockData.endpoints.stageData).reply(httpStatusCodes.OK, mockData.issueEvents); mockAdapter.onGet(endpoints.stageData).reply(httpStatusCodes.OK, issueEvents);
mockAdapter.onGet(endpoints.tasksByTypeTopLabelsData).reply(httpStatusCodes.OK, groupLabels);
mockAdapter.onGet(endpoints.tasksByTypeData).reply(httpStatusCodes.OK, { ...tasksByTypeData });
mockAdapter mockAdapter
.onGet(mockData.endpoints.tasksByTypeTopLabelsData) .onGet(endpoints.baseStagesEndpoint)
.reply(httpStatusCodes.OK, mockData.groupLabels); .reply(httpStatusCodes.OK, { ...customizableStagesAndEvents });
mockAdapter mockAdapter
.onGet(mockData.endpoints.tasksByTypeData) .onGet(endpoints.durationData)
.reply(httpStatusCodes.OK, { ...mockData.tasksByTypeData }); .reply(httpStatusCodes.OK, customizableStagesAndEvents.stages);
mockAdapter mockAdapter.onGet(endpoints.stageMedian).reply(httpStatusCodes.OK, { value: null });
.onGet(mockData.endpoints.baseStagesEndpoint) mockAdapter.onGet(endpoints.valueStreamData).reply(httpStatusCodes.OK, valueStreams);
.reply(httpStatusCodes.OK, { ...mockData.customizableStagesAndEvents });
mockAdapter
.onGet(mockData.endpoints.durationData)
.reply(httpStatusCodes.OK, mockData.customizableStagesAndEvents.stages);
mockAdapter.onGet(mockData.endpoints.stageMedian).reply(httpStatusCodes.OK, { value: null });
mockAdapter
.onGet(mockData.endpoints.valueStreamData)
.reply(httpStatusCodes.OK, mockData.valueStreams);
} }
async function shouldMergeUrlParams(wrapper, result) { async function shouldMergeUrlParams(wrapper, result) {
...@@ -140,10 +147,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -140,10 +147,7 @@ describe('EE Value Stream Analytics component', () => {
}); });
if (withStageSelected || selectedStage) { if (withStageSelected || selectedStage) {
await store.dispatch( await store.dispatch('receiveGroupStagesSuccess', customizableStagesAndEvents.stages);
'receiveGroupStagesSuccess',
mockData.customizableStagesAndEvents.stages,
);
if (selectedStage) { if (selectedStage) {
await store.dispatch('setSelectedStage', selectedStage); await store.dispatch('setSelectedStage', selectedStage);
await store.dispatch('fetchStageData', selectedStage.slug); await store.dispatch('fetchStageData', selectedStage.slug);
...@@ -311,7 +315,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -311,7 +315,7 @@ describe('EE Value Stream Analytics component', () => {
beforeEach(async () => { beforeEach(async () => {
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
mockRequiredRoutes(mock); mockRequiredRoutes(mock);
wrapper = await createComponent({ selectedStage: mockData.issueStage }); wrapper = await createComponent({ selectedStage: issueStage });
}); });
it('displays the stage table', () => { it('displays the stage table', () => {
...@@ -340,7 +344,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -340,7 +344,7 @@ describe('EE Value Stream Analytics component', () => {
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
mock mock
.onGet(mockData.endpoints.baseStagesEndpoint) .onGet(endpoints.baseStagesEndpoint)
.reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } }); .reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } });
wrapper = await createComponent(); wrapper = await createComponent();
...@@ -353,10 +357,10 @@ describe('EE Value Stream Analytics component', () => { ...@@ -353,10 +357,10 @@ describe('EE Value Stream Analytics component', () => {
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
mock mock
.onGet(mockData.endpoints.stageData) .onGet(endpoints.stageData)
.reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } }); .reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } });
wrapper = await createComponent({ selectedStage: mockData.issueStage }); wrapper = await createComponent({ selectedStage: issueStage });
expect(createFlash).toHaveBeenCalledWith({ expect(createFlash).toHaveBeenCalledWith({
message: 'There was an error fetching data for the selected stage', message: 'There was an error fetching data for the selected stage',
...@@ -367,7 +371,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -367,7 +371,7 @@ describe('EE Value Stream Analytics component', () => {
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
mock mock
.onGet(mockData.endpoints.tasksByTypeTopLabelsData) .onGet(endpoints.tasksByTypeTopLabelsData)
.reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } }); .reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } });
wrapper = await createComponent(); wrapper = await createComponent();
await waitForPromises(); await waitForPromises();
...@@ -381,7 +385,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -381,7 +385,7 @@ describe('EE Value Stream Analytics component', () => {
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
mock mock
.onGet(mockData.endpoints.tasksByTypeData) .onGet(endpoints.tasksByTypeData)
.reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } }); .reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } });
wrapper = await createComponent(); wrapper = await createComponent();
await waitForPromises(); await waitForPromises();
...@@ -395,7 +399,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -395,7 +399,7 @@ describe('EE Value Stream Analytics component', () => {
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
mock mock
.onGet(mockData.endpoints.stageMedian) .onGet(endpoints.stageMedian)
.reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } }); .reply(httpStatusCodes.NOT_FOUND, { response: { status: httpStatusCodes.NOT_FOUND } });
wrapper = await createComponent(); wrapper = await createComponent();
...@@ -406,11 +410,9 @@ describe('EE Value Stream Analytics component', () => { ...@@ -406,11 +410,9 @@ describe('EE Value Stream Analytics component', () => {
it('will display an error if the fetchStageData request is successful but has an embedded error', async () => { it('will display an error if the fetchStageData request is successful but has an embedded error', async () => {
const tooMuchDataError = 'There is too much data to calculate. Please change your selection.'; const tooMuchDataError = 'There is too much data to calculate. Please change your selection.';
mock mock.onGet(endpoints.stageData).reply(httpStatusCodes.OK, { error: tooMuchDataError });
.onGet(mockData.endpoints.stageData)
.reply(httpStatusCodes.OK, { error: tooMuchDataError });
wrapper = await createComponent({ selectedStage: mockData.issueStage }); wrapper = await createComponent({ selectedStage: issueStage });
displaysStageTable(true); displaysStageTable(true);
expect(findStageTable().props('emptyStateMessage')).toBe(tooMuchDataError); expect(findStageTable().props('emptyStateMessage')).toBe(tooMuchDataError);
...@@ -447,7 +449,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -447,7 +449,7 @@ describe('EE Value Stream Analytics component', () => {
expect(actionSpies.setDefaultSelectedStage).not.toHaveBeenCalled(); expect(actionSpies.setDefaultSelectedStage).not.toHaveBeenCalled();
expect(actionSpies.setSelectedStage).toHaveBeenCalledWith(selectedStage); expect(actionSpies.setSelectedStage).toHaveBeenCalledWith(selectedStage);
expect(actionSpies.updateStageTablePagination).toHaveBeenCalledWith({ expect(actionSpies.updateStageTablePagination).toHaveBeenCalledWith({
...mockData.initialPaginationQuery, ...initialPaginationQuery,
page: 1, page: 1,
}); });
}); });
...@@ -464,8 +466,8 @@ describe('EE Value Stream Analytics component', () => { ...@@ -464,8 +466,8 @@ describe('EE Value Stream Analytics component', () => {
describe('Url parameters', () => { describe('Url parameters', () => {
const defaultParams = { const defaultParams = {
value_stream_id: selectedValueStream.id, value_stream_id: selectedValueStream.id,
created_after: toYmd(mockData.createdAfter), created_after: toYmd(createdAfter),
created_before: toYmd(mockData.createdBefore), created_before: toYmd(createdBefore),
stage_id: null, stage_id: null,
project_ids: null, project_ids: null,
sort: null, sort: null,
...@@ -473,7 +475,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -473,7 +475,7 @@ describe('EE Value Stream Analytics component', () => {
page: null, page: null,
}; };
const selectedProjectIds = mockData.selectedProjects.map(({ id }) => getIdFromGraphQLId(id)); const selectedProjectIds = selectedProjects.map(({ id }) => getIdFromGraphQLId(id));
const selectedStage = { title: 'Plan', id: 2 }; const selectedStage = { title: 'Plan', id: 2 };
beforeEach(async () => { beforeEach(async () => {
...@@ -515,8 +517,8 @@ describe('EE Value Stream Analytics component', () => { ...@@ -515,8 +517,8 @@ describe('EE Value Stream Analytics component', () => {
it('sets the value_stream_id url parameter', async () => { it('sets the value_stream_id url parameter', async () => {
await shouldMergeUrlParams(wrapper, { await shouldMergeUrlParams(wrapper, {
...defaultParams, ...defaultParams,
created_after: toYmd(mockData.createdAfter), created_after: toYmd(createdAfter),
created_before: toYmd(mockData.createdBefore), created_before: toYmd(createdBefore),
project_ids: null, project_ids: null,
}); });
}); });
...@@ -525,15 +527,15 @@ describe('EE Value Stream Analytics component', () => { ...@@ -525,15 +527,15 @@ describe('EE Value Stream Analytics component', () => {
describe('with selectedProjectIds set', () => { describe('with selectedProjectIds set', () => {
beforeEach(async () => { beforeEach(async () => {
wrapper = await createComponent(); wrapper = await createComponent();
await store.dispatch('setSelectedProjects', mockData.selectedProjects); await store.dispatch('setSelectedProjects', selectedProjects);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
}); });
it('sets the project_ids url parameter', async () => { it('sets the project_ids url parameter', async () => {
await shouldMergeUrlParams(wrapper, { await shouldMergeUrlParams(wrapper, {
...defaultParams, ...defaultParams,
created_after: toYmd(mockData.createdAfter), created_after: toYmd(createdAfter),
created_before: toYmd(mockData.createdBefore), created_before: toYmd(createdBefore),
project_ids: selectedProjectIds, project_ids: selectedProjectIds,
stage_id: null, stage_id: null,
}); });
...@@ -545,7 +547,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -545,7 +547,7 @@ describe('EE Value Stream Analytics component', () => {
wrapper = await createComponent({ wrapper = await createComponent({
initialState: { initialState: {
...initialCycleAnalyticsState, ...initialCycleAnalyticsState,
pagination: mockData.initialPaginationQuery, pagination: initialPaginationQuery,
}, },
selectedStage, selectedStage,
}); });
...@@ -554,7 +556,7 @@ describe('EE Value Stream Analytics component', () => { ...@@ -554,7 +556,7 @@ describe('EE Value Stream Analytics component', () => {
it('sets the stage, sort, direction and page parameters', async () => { it('sets the stage, sort, direction and page parameters', async () => {
await shouldMergeUrlParams(wrapper, { await shouldMergeUrlParams(wrapper, {
...defaultParams, ...defaultParams,
...mockData.initialPaginationQuery, ...initialPaginationQuery,
stage_id: selectedStage.id, stage_id: selectedStage.id,
}); });
}); });
......
...@@ -3,8 +3,9 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -3,8 +3,9 @@ import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import Metrics from 'ee/analytics/cycle_analytics/components/metrics.vue'; import Metrics from 'ee/analytics/cycle_analytics/components/metrics.vue';
import Api from 'ee/api'; import Api from 'ee/api';
import { group } from 'jest/cycle_analytics/mock_data';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { group, timeMetricsData, recentActivityData } from '../mock_data'; import { timeMetricsData, recentActivityData } from '../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
......
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { import {
DEFAULT_DAYS_IN_PAST,
TASKS_BY_TYPE_SUBJECT_ISSUE, TASKS_BY_TYPE_SUBJECT_ISSUE,
OVERVIEW_STAGE_CONFIG, OVERVIEW_STAGE_CONFIG,
PAGINATION_TYPE, PAGINATION_TYPE,
...@@ -15,11 +14,16 @@ import { ...@@ -15,11 +14,16 @@ import {
} from 'ee/analytics/cycle_analytics/utils'; } from 'ee/analytics/cycle_analytics/utils';
import { toYmd } from 'ee/analytics/shared/utils'; import { toYmd } from 'ee/analytics/shared/utils';
import { getJSONFixture } from 'helpers/fixtures'; import { getJSONFixture } from 'helpers/fixtures';
import { TEST_HOST } from 'helpers/test_constants'; import {
import { getStageByTitle, defaultStages, rawStageMedians } from 'jest/cycle_analytics/mock_data'; getStageByTitle,
defaultStages,
rawStageMedians,
createdBefore,
createdAfter,
} from 'jest/cycle_analytics/mock_data';
import { transformStagesForPathNavigation } from '~/cycle_analytics/utils'; import { transformStagesForPathNavigation } from '~/cycle_analytics/utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { getDateInPast, getDatesInRange } from '~/lib/utils/datetime_utility'; import { getDatesInRange } from '~/lib/utils/datetime_utility';
const fixtureEndpoints = { const fixtureEndpoints = {
customizableCycleAnalyticsStagesAndEvents: 'analytics/value_stream_analytics/stages.json', // customizable stages and events endpoint customizableCycleAnalyticsStagesAndEvents: 'analytics/value_stream_analytics/stages.json', // customizable stages and events endpoint
...@@ -54,16 +58,6 @@ export const groupLabels = getJSONFixture(fixtureEndpoints.groupLabels).map( ...@@ -54,16 +58,6 @@ export const groupLabels = getJSONFixture(fixtureEndpoints.groupLabels).map(
convertObjectPropsToCamelCase, convertObjectPropsToCamelCase,
); );
export const group = {
id: 1,
name: 'foo',
path: 'foo',
full_path: 'foo',
avatar_url: `${TEST_HOST}/images/home/nasa.svg`,
};
export const currentGroup = convertObjectPropsToCamelCase(group, { deep: true });
export const recentActivityData = getJSONFixture(fixtureEndpoints.recentActivityData); export const recentActivityData = getJSONFixture(fixtureEndpoints.recentActivityData);
export const timeMetricsData = getJSONFixture(fixtureEndpoints.timeMetricsData); export const timeMetricsData = getJSONFixture(fixtureEndpoints.timeMetricsData);
...@@ -158,9 +152,6 @@ export const stageCounts = rawStageMedians.reduce((acc, { id, value }) => { ...@@ -158,9 +152,6 @@ export const stageCounts = rawStageMedians.reduce((acc, { id, value }) => {
return { ...acc, [stageId]: value }; return { ...acc, [stageId]: value };
}, {}); }, {});
export const createdBefore = new Date(2019, 0, 14);
export const createdAfter = getDateInPast(createdBefore, DEFAULT_DAYS_IN_PAST);
export const issueEvents = deepCamelCase(stageFixtures.issue); export const issueEvents = deepCamelCase(stageFixtures.issue);
export const planEvents = deepCamelCase(stageFixtures.plan); export const planEvents = deepCamelCase(stageFixtures.plan);
export const reviewEvents = deepCamelCase(stageFixtures.review); export const reviewEvents = deepCamelCase(stageFixtures.review);
...@@ -299,21 +290,6 @@ export const rawDurationMedianData = [ ...@@ -299,21 +290,6 @@ export const rawDurationMedianData = [
}, },
]; ];
export const selectedProjects = [
{
id: 'gid://gitlab/Project/1',
name: 'cool project',
pathWithNamespace: 'group/cool-project',
avatarUrl: null,
},
{
id: 'gid://gitlab/Project/2',
name: 'another cool project',
pathWithNamespace: 'group/another-cool-project',
avatarUrl: null,
},
];
export const pathNavIssueMetric = 172800; export const pathNavIssueMetric = 172800;
export const initialPaginationQuery = { export const initialPaginationQuery = {
......
...@@ -5,13 +5,11 @@ import * as actions from 'ee/analytics/cycle_analytics/store/actions'; ...@@ -5,13 +5,11 @@ import * as actions from 'ee/analytics/cycle_analytics/store/actions';
import * as getters from 'ee/analytics/cycle_analytics/store/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/getters';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { createdAfter, createdBefore, currentGroup } from 'jest/cycle_analytics/mock_data';
import createFlash from '~/flash'; import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status'; import httpStatusCodes from '~/lib/utils/http_status';
import { import {
currentGroup,
allowedStages as stages, allowedStages as stages,
createdAfter,
createdBefore,
customizableStagesAndEvents, customizableStagesAndEvents,
endpoints, endpoints,
valueStreams, valueStreams,
......
import * as getters from 'ee/analytics/cycle_analytics/store/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/getters';
import { createdAfter, createdBefore, selectedProjects } from 'jest/cycle_analytics/mock_data';
import { import {
filterMilestones, filterMilestones,
filterUsers, filterUsers,
...@@ -9,10 +10,7 @@ import { ...@@ -9,10 +10,7 @@ import {
getFilterValues, getFilterValues,
} from 'jest/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper'; } from 'jest/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper';
import { import {
createdAfter,
createdBefore,
allowedStages, allowedStages,
selectedProjects,
issueStage, issueStage,
stageMedians, stageMedians,
stageCounts, stageCounts,
......
...@@ -5,13 +5,11 @@ import * as actions from 'ee/analytics/cycle_analytics/store/modules/duration_ch ...@@ -5,13 +5,11 @@ import * as actions from 'ee/analytics/cycle_analytics/store/modules/duration_ch
import * as getters from 'ee/analytics/cycle_analytics/store/modules/duration_chart/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/modules/duration_chart/getters';
import * as types from 'ee/analytics/cycle_analytics/store/modules/duration_chart/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/modules/duration_chart/mutation_types';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { createdAfter, createdBefore, group } from 'jest/cycle_analytics/mock_data';
import createFlash from '~/flash'; import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status'; import httpStatusCodes from '~/lib/utils/http_status';
import { import {
group,
allowedStages as stages, allowedStages as stages,
createdAfter,
createdBefore,
rawDurationData, rawDurationData,
transformedDurationData, transformedDurationData,
endpoints, endpoints,
......
import * as getters from 'ee/analytics/cycle_analytics/store/modules/duration_chart/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/modules/duration_chart/getters';
import { import { createdAfter, createdBefore } from 'jest/cycle_analytics/mock_data';
createdAfter, import { transformedDurationData, durationChartPlottableData } from '../../../mock_data';
createdBefore,
transformedDurationData,
durationChartPlottableData,
} from '../../../mock_data';
const rootState = { const rootState = {
createdAfter, createdAfter,
......
...@@ -9,15 +9,10 @@ import * as actions from 'ee/analytics/cycle_analytics/store/modules/type_of_wor ...@@ -9,15 +9,10 @@ import * as actions from 'ee/analytics/cycle_analytics/store/modules/type_of_wor
import * as getters from 'ee/analytics/cycle_analytics/store/modules/type_of_work/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/modules/type_of_work/getters';
import * as types from 'ee/analytics/cycle_analytics/store/modules/type_of_work/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/modules/type_of_work/mutation_types';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { createdAfter, createdBefore } from 'jest/cycle_analytics/mock_data';
import createFlash from '~/flash'; import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status'; import httpStatusCodes from '~/lib/utils/http_status';
import { import { groupLabels, endpoints, rawTasksByTypeData } from '../../../mock_data';
groupLabels,
endpoints,
createdAfter,
createdBefore,
rawTasksByTypeData,
} from '../../../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
......
import { tasksByTypeChartData } from 'ee/analytics/cycle_analytics/store/modules/type_of_work/getters'; import { tasksByTypeChartData } from 'ee/analytics/cycle_analytics/store/modules/type_of_work/getters';
import { import { createdAfter, createdBefore } from 'jest/cycle_analytics/mock_data';
rawTasksByTypeData, import { rawTasksByTypeData, transformedTasksByTypeData } from '../../../mock_data';
transformedTasksByTypeData,
createdAfter,
createdBefore,
} from '../../../mock_data';
describe('Type of work getters', () => { describe('Type of work getters', () => {
describe('tasksByTypeChartData', () => { describe('tasksByTypeChartData', () => {
......
...@@ -4,16 +4,13 @@ import { ...@@ -4,16 +4,13 @@ import {
} from 'ee/analytics/cycle_analytics/constants'; } from 'ee/analytics/cycle_analytics/constants';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types'; import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import mutations from 'ee/analytics/cycle_analytics/store/mutations'; import mutations from 'ee/analytics/cycle_analytics/store/mutations';
import { createdAfter, createdBefore, selectedProjects } from 'jest/cycle_analytics/mock_data';
import { import {
issueStage, issueStage,
planStage, planStage,
codeStage, codeStage,
stagingStage, stagingStage,
reviewStage, reviewStage,
createdAfter,
createdBefore,
selectedProjects,
customizableStagesAndEvents, customizableStagesAndEvents,
valueStreams, valueStreams,
rawCustomStageEvents, rawCustomStageEvents,
......
...@@ -19,7 +19,7 @@ import { ...@@ -19,7 +19,7 @@ import {
formatMedianValuesWithOverview, formatMedianValuesWithOverview,
} from 'ee/analytics/cycle_analytics/utils'; } from 'ee/analytics/cycle_analytics/utils';
import { toYmd } from 'ee/analytics/shared/utils'; import { toYmd } from 'ee/analytics/shared/utils';
import { rawStageMedians } from 'jest/cycle_analytics/mock_data'; import { createdAfter, createdBefore, rawStageMedians } from 'jest/cycle_analytics/mock_data';
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants'; import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
import { medianTimeToParsedSeconds } from '~/cycle_analytics/utils'; import { medianTimeToParsedSeconds } from '~/cycle_analytics/utils';
import { getDatesInRange } from '~/lib/utils/datetime_utility'; import { getDatesInRange } from '~/lib/utils/datetime_utility';
...@@ -32,8 +32,6 @@ import { ...@@ -32,8 +32,6 @@ import {
transformedDurationData, transformedDurationData,
flattenedDurationData, flattenedDurationData,
durationChartPlottableData, durationChartPlottableData,
createdAfter,
createdBefore,
issueStage, issueStage,
rawCustomStage, rawCustomStage,
rawTasksByTypeData, rawTasksByTypeData,
......
...@@ -3,7 +3,7 @@ import MergeRequestAnalyticsApp from 'ee/analytics/merge_request_analytics/compo ...@@ -3,7 +3,7 @@ import MergeRequestAnalyticsApp from 'ee/analytics/merge_request_analytics/compo
import FilterBar from 'ee/analytics/merge_request_analytics/components/filter_bar.vue'; import FilterBar from 'ee/analytics/merge_request_analytics/components/filter_bar.vue';
import ThroughputChart from 'ee/analytics/merge_request_analytics/components/throughput_chart.vue'; import ThroughputChart from 'ee/analytics/merge_request_analytics/components/throughput_chart.vue';
import ThroughputTable from 'ee/analytics/merge_request_analytics/components/throughput_table.vue'; import ThroughputTable from 'ee/analytics/merge_request_analytics/components/throughput_table.vue';
import DateRange from 'ee/analytics/shared/components/daterange.vue'; import DateRange from '~/analytics/shared/components/daterange.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue';
describe('MergeRequestAnalyticsApp', () => { describe('MergeRequestAnalyticsApp', () => {
......
...@@ -3,7 +3,7 @@ import Vuex from 'vuex'; ...@@ -3,7 +3,7 @@ import Vuex from 'vuex';
import FilterDropdowns from 'ee/analytics/productivity_analytics/components/filter_dropdowns.vue'; import FilterDropdowns from 'ee/analytics/productivity_analytics/components/filter_dropdowns.vue';
import { getStoreConfig } from 'ee/analytics/productivity_analytics/store'; import { getStoreConfig } from 'ee/analytics/productivity_analytics/store';
import GroupsDropdownFilter from 'ee/analytics/shared/components/groups_dropdown_filter.vue'; import GroupsDropdownFilter from 'ee/analytics/shared/components/groups_dropdown_filter.vue';
import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue'; import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import resetStore from '../helpers'; import resetStore from '../helpers';
const localVue = createLocalVue(); const localVue = createLocalVue();
......
...@@ -2,7 +2,6 @@ import { ...@@ -2,7 +2,6 @@ import {
buildGroupFromDataset, buildGroupFromDataset,
buildProjectFromDataset, buildProjectFromDataset,
buildCycleAnalyticsInitialData, buildCycleAnalyticsInitialData,
filterBySearchTerm,
} from 'ee/analytics/shared/utils'; } from 'ee/analytics/shared/utils';
const rawValueStream = `{ const rawValueStream = `{
...@@ -179,27 +178,4 @@ describe('buildCycleAnalyticsInitialData', () => { ...@@ -179,27 +178,4 @@ describe('buildCycleAnalyticsInitialData', () => {
expect(buildCycleAnalyticsInitialData()).toMatchObject({ [field]: null }); expect(buildCycleAnalyticsInitialData()).toMatchObject({ [field]: null });
}); });
}); });
describe('filterBySearchTerm', () => {
const data = [
{ name: 'eins', title: 'one' },
{ name: 'zwei', title: 'two' },
{ name: 'drei', title: 'three' },
];
const searchTerm = 'rei';
it('filters data by `name` for the provided search term', () => {
expect(filterBySearchTerm(data, searchTerm)).toEqual([data[2]]);
});
it('with no search term returns the data', () => {
['', null].forEach((search) => {
expect(filterBySearchTerm(data, search)).toEqual(data);
});
});
it('with a key, filters by the provided key', () => {
expect(filterBySearchTerm(data, 'ne', 'title')).toEqual([data[0]]);
});
});
}); });
import { GlDaterangePicker } from '@gitlab/ui'; import { GlDaterangePicker } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Daterange from 'ee/analytics/shared/components/daterange.vue';
import { useFakeDate } from 'helpers/fake_date'; import { useFakeDate } from 'helpers/fake_date';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import Daterange from '~/analytics/shared/components/daterange.vue';
const defaultProps = { const defaultProps = {
startDate: new Date(2019, 8, 1), startDate: new Date(2019, 8, 1),
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue';
import getProjects from 'ee/analytics/shared/graphql/projects.query.graphql';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import getProjects from '~/analytics/shared/graphql/projects.query.graphql';
const projects = [ const projects = [
{ {
......
import { filterBySearchTerm } from '~/analytics/shared/utils';
describe('filterBySearchTerm', () => {
const data = [
{ name: 'eins', title: 'one' },
{ name: 'zwei', title: 'two' },
{ name: 'drei', title: 'three' },
];
const searchTerm = 'rei';
it('filters data by `name` for the provided search term', () => {
expect(filterBySearchTerm(data, searchTerm)).toEqual([data[2]]);
});
it('with no search term returns the data', () => {
['', null].forEach((search) => {
expect(filterBySearchTerm(data, search)).toEqual(data);
});
});
it('with a key, filters by the provided key', () => {
expect(filterBySearchTerm(data, 'ne', 'title')).toEqual([data[0]]);
});
});
...@@ -2,12 +2,12 @@ import { createLocalVue, shallowMount } from '@vue/test-utils'; ...@@ -2,12 +2,12 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex'; import Vuex from 'vuex';
import FilterBar from 'ee/analytics/cycle_analytics/components/filter_bar.vue';
import storeConfig from 'ee/analytics/cycle_analytics/store';
import { import {
filterMilestones, filterMilestones,
filterLabels, filterLabels,
} from 'jest/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data'; } from 'jest/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data';
import FilterBar from '~/cycle_analytics/components/filter_bar.vue';
import storeConfig from '~/cycle_analytics/store';
import * as commonUtils from '~/lib/utils/common_utils'; import * as commonUtils from '~/lib/utils/common_utils';
import * as urlUtils from '~/lib/utils/url_utility'; import * as urlUtils from '~/lib/utils/url_utility';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue'; import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
......
import { DEFAULT_VALUE_STREAM } from '~/cycle_analytics/constants'; import { TEST_HOST } from 'helpers/test_constants';
import { DEFAULT_VALUE_STREAM, DEFAULT_DAYS_IN_PAST } from '~/cycle_analytics/constants';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { getDateInPast } from '~/lib/utils/datetime_utility';
export const createdBefore = new Date(2019, 0, 14);
export const createdAfter = getDateInPast(createdBefore, DEFAULT_DAYS_IN_PAST);
export const getStageByTitle = (stages, title) => export const getStageByTitle = (stages, title) =>
stages.find((stage) => stage.title && stage.title.toLowerCase().trim() === title) || {}; stages.find((stage) => stage.title && stage.title.toLowerCase().trim() === title) || {};
...@@ -212,6 +217,31 @@ export const transformedProjectStagePathData = [ ...@@ -212,6 +217,31 @@ export const transformedProjectStagePathData = [
export const selectedValueStream = DEFAULT_VALUE_STREAM; export const selectedValueStream = DEFAULT_VALUE_STREAM;
export const group = {
id: 1,
name: 'foo',
path: 'foo',
full_path: 'foo',
avatar_url: `${TEST_HOST}/images/home/nasa.svg`,
};
export const currentGroup = convertObjectPropsToCamelCase(group, { deep: true });
export const selectedProjects = [
{
id: 'gid://gitlab/Project/1',
name: 'cool project',
pathWithNamespace: 'group/cool-project',
avatarUrl: null,
},
{
id: 'gid://gitlab/Project/2',
name: 'another cool project',
pathWithNamespace: 'group/another-cool-project',
avatarUrl: null,
},
];
export const rawValueStreamStages = [ export const rawValueStreamStages = [
{ {
title: 'Issue', title: 'Issue',
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import FilterBar from 'ee/analytics/cycle_analytics/components/filter_bar.vue'; import Daterange from '~/analytics/shared/components/daterange.vue';
import ValueStreamFilters from 'ee/analytics/cycle_analytics/components/value_stream_filters.vue'; import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import Daterange from 'ee/analytics/shared/components/daterange.vue'; import FilterBar from '~/cycle_analytics/components/filter_bar.vue';
import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue'; import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
import { import {
createdAfter as startDate, createdAfter as startDate,
createdBefore as endDate, createdBefore as endDate,
currentGroup, currentGroup,
selectedProjects, selectedProjects,
} from '../mock_data'; } from './mock_data';
function createComponent(props = {}) { function createComponent(props = {}) {
return shallowMount(ValueStreamFilters, { return shallowMount(ValueStreamFilters, {
......
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