Commit 68f8c586 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Fix missing custom flag from transformed stages

Added basic tests for transformRawStages, to
ensure all stage properties are retained.

Minor review feedback
parent cf091d83
......@@ -703,7 +703,9 @@ export const convertObjectPropsToCamelCase = (obj = {}, options = {}) => {
* @param {Object} obj Object to transform
* @returns {Object}
*/
export const convertObjectKeysToSnakeCase = (obj = {}) =>
// Follow up to add additional options param:
// https://gitlab.com/gitlab-org/gitlab/issues/39173
export const convertObjectPropsToSnakeCase = (obj = {}) =>
obj
? Object.entries(obj).reduce(
(acc, [key, value]) => ({ ...acc, [convertToSnakeCase(key)]: value }),
......
......@@ -59,7 +59,7 @@ export default {
'isCreatingCustomStage',
'isEditingCustomStage',
'selectedGroup',
'selectedStageId',
'selectedStage',
'stages',
'summary',
'labels',
......@@ -72,7 +72,7 @@ export default {
]),
...mapGetters(['hasNoAccessError', 'currentGroupPath', 'durationChartPlottableData']),
shouldRenderEmptyState() {
return !this.selectedGroup;g
return !this.selectedGroup;
},
hasCustomizableCycleAnalytics() {
return Boolean(this.glFeatures.customizableCycleAnalytics);
......@@ -108,7 +108,7 @@ export default {
'fetchStageData',
'setSelectedGroup',
'setSelectedProjects',
'setSelectedStageId',
'setSelectedStage',
'hideCustomStageForm',
'showCustomStageForm',
'setDateRange',
......
......@@ -2,7 +2,7 @@
import { isEqual } from 'underscore';
import { GlButton, GlFormGroup, GlFormInput, GlFormSelect, GlLoadingIcon } from '@gitlab/ui';
import { s__ } from '~/locale';
import { convertObjectKeysToSnakeCase } from '~/lib/utils/common_utils';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import LabelsSelector from './labels_selector.vue';
import { STAGE_ACTIONS } from '../constants';
import {
......@@ -152,7 +152,7 @@ export default {
this.$emit('cancel');
},
handleSave() {
const data = convertObjectKeysToSnakeCase(this.fields);
const data = convertObjectPropsToSnakeCase(this.fields);
if (this.isEditingCustomStage) {
const { id } = this.initialFields;
this.$emit(STAGE_ACTIONS.UPDATE, { ...data, id });
......
......@@ -121,20 +121,6 @@ export default {
return this.isEditingCustomStage ? this.currentStage : {};
},
},
methods: {
selectStage(stage) {
this.$emit(STAGE_ACTIONS.SELECT, stage);
},
editStage(stage) {
this.$emit(STAGE_ACTIONS.EDIT, stage);
},
hideStage(stageId) {
this.$emit(STAGE_ACTIONS.HIDE, { id: stageId, hidden: true });
},
removeStage(stageId) {
this.$emit(STAGE_ACTIONS.REMOVE, stageId);
},
},
STAGE_ACTIONS,
};
</script>
......@@ -166,10 +152,10 @@ export default {
:is-active="!isCreatingCustomStage && stage.id === currentStage.id"
:can-edit="canEditStages"
:is-default-stage="!stage.custom"
@remove="removeStage(stage.id)"
@hide="hideStage(stage.id)"
@select="selectStage(stage)"
@edit="editStage(stage)"
@remove="$emit($options.STAGE_ACTIONS.REMOVE, stage.id)"
@hide="$emit($options.STAGE_ACTIONS.HIDE, { id: stage.id, hidden: true })"
@select="$emit($options.STAGE_ACTIONS.SELECT, stage)"
@edit="$emit($options.STAGE_ACTIONS.EDIT, stage)"
/>
<add-stage-button
v-if="canEditStages"
......
......@@ -53,6 +53,8 @@ export const transformRawStages = (stages = []) =>
id,
title,
slug: custom ? id : convertToSnakeCase(title),
custom,
name: title, // editing a stage takes 'name' as a parameter, but the api returns title
}))
.sort((a, b) => a.id > b.id);
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Cycle analytics utils transformRawStages retains all the stage properties 1`] = `
Array [
Object {
"custom": false,
"description": "Time before an issue gets scheduled",
"hidden": false,
"id": "issue",
"legend": "",
"name": "Issue",
"slug": "issue",
"title": "Issue",
},
Object {
"custom": true,
"description": "",
"endEventIdentifier": "issue_first_added_to_board",
"hidden": false,
"id": 18,
"legend": "",
"name": "Coolest beans stage",
"slug": 18,
"startEventIdentifier": "issue_first_mentioned_in_commit",
"title": "Coolest beans stage",
},
]
`;
......@@ -75,6 +75,16 @@ export const codeEvents = stageFixtures.code;
export const testEvents = stageFixtures.test;
export const stagingEvents = stageFixtures.staging;
export const productionEvents = stageFixtures.production;
export const rawCustomStage = {
title: 'Coolest beans stage',
hidden: false,
legend: '',
description: '',
id: 18,
custom: true,
start_event_identifier: 'issue_first_mentioned_in_commit',
end_event_identifier: 'issue_first_added_to_board',
};
const { events: rawCustomStageEvents } = customizableStagesAndEvents;
const camelCasedStageEvents = rawCustomStageEvents.map(deepCamelCase);
......
......@@ -8,6 +8,7 @@ import {
nestQueryStringKeys,
flattenDurationChartData,
getDurationChartData,
transformRawStages,
} from 'ee/analytics/cycle_analytics/utils';
import {
customStageEvents as events,
......@@ -19,6 +20,8 @@ import {
durationChartPlottableData,
startDate,
endDate,
issueStage,
rawCustomStage,
} from './mock_data';
const labelEvents = [labelStartEvent, labelStopEvent].map(i => i.identifier);
......@@ -153,4 +156,26 @@ describe('Cycle analytics utils', () => {
expect(plottableData).toStrictEqual(durationChartPlottableData);
});
});
describe('transformRawStages', () => {
it('retains all the stage properties', () => {
const transformed = transformRawStages([issueStage, rawCustomStage]);
expect(transformed).toMatchSnapshot();
});
it('converts object properties from snake_case to camelCase', () => {
const [transformedCustomStage] = transformRawStages([rawCustomStage]);
expect(transformedCustomStage).toMatchObject({
endEventIdentifier: 'issue_first_added_to_board',
startEventIdentifier: 'issue_first_mentioned_in_commit',
});
});
it('sets the slug to the value of the stage id', () => {
const transformed = transformRawStages([issueStage, rawCustomStage]);
transformed.forEach(t => {
expect(t.slug).toEqual(t.id);
});
});
});
});
......@@ -721,7 +721,7 @@ describe('common_utils', () => {
});
});
describe('convertObjectKeysToSnakeCase', () => {
describe('convertObjectPropsToSnakeCase', () => {
it('converts each object key to snake case', () => {
const obj = {
some: 'some',
......@@ -729,7 +729,7 @@ describe('common_utils', () => {
likeThisLongOne: 'likeThisLongOne',
};
expect(commonUtils.convertObjectKeysToSnakeCase(obj)).toEqual({
expect(commonUtils.convertObjectPropsToSnakeCase(obj)).toEqual({
some: 'some',
cool_object: 'cool object',
like_this_long_one: 'likeThisLongOne',
......@@ -738,7 +738,7 @@ describe('common_utils', () => {
it('returns an empty object if there are no keys', () => {
['', {}, [], null].forEach(badObj => {
expect(commonUtils.convertObjectKeysToSnakeCase(badObj)).toEqual({});
expect(commonUtils.convertObjectPropsToSnakeCase(badObj)).toEqual({});
});
});
});
......
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