Commit bc8266dc authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Ensure the stage name is not reserved

Checks if the stage name specified
is one of the default names and displays
an error
parent 5943cfe2
......@@ -13,7 +13,7 @@ import {
import { s__ } from '~/locale';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import LabelsSelector from './labels_selector.vue';
import { STAGE_ACTIONS } from '../constants';
import { STAGE_ACTIONS, DEFAULT_STAGE_NAMES } from '../constants';
import {
isStartEvent,
isLabelEvent,
......@@ -127,8 +127,14 @@ export default {
endEventRequiresLabel() {
return isLabelEvent(this.labelEvents, this.fields.endEventIdentifier);
},
hasErrors() {
return (
this.eventMismatchError ||
Object.values(this.fieldErrors).some(errArray => errArray && errArray.length)
);
},
isComplete() {
if (this.eventMismatchError) {
if (this.hasErrors) {
return false;
}
const {
......@@ -194,10 +200,14 @@ export default {
},
methods: {
handleCancel() {
this.fields = {
...defaultFields,
...this.initialFields,
};
const { initialFields = {}, errors = null } = this;
const formData = initializeFormData({
emptyFieldState: defaultFields,
initialFields,
errors,
});
this.$set(this, 'fields', formData.fields);
this.$set(this, 'fieldErrors', formData.fieldErrors);
this.$emit('cancel');
},
handleSave() {
......@@ -221,6 +231,15 @@ export default {
fieldErrorMessage(key) {
return this.fieldErrors[key]?.join('\n');
},
onUpdateNameField() {
if (DEFAULT_STAGE_NAMES.includes(this.fields.name.toLowerCase())) {
this.$set(this.fieldErrors, 'name', [
s__('CustomCycleAnalytics|Stage name already exists'),
]);
} else {
this.$set(this.fieldErrors, 'name', []);
}
},
onUpdateStartEventField() {
const initVal = this.initialFields?.endEventIdentifier
? this.initialFields.endEventIdentifier
......@@ -262,6 +281,7 @@ export default {
:label="s__('CustomCycleAnalytics|Name')"
:state="!hasFieldErrors('name')"
:invalid-feedback="fieldErrorMessage('name')"
@change.native="onUpdateNameField"
>
<gl-form-input
v-model="fields.name"
......
......@@ -30,6 +30,8 @@ export const EMPTY_STAGE_TEXT = {
),
};
export const DEFAULT_STAGE_NAMES = [...Object.keys(EMPTY_STAGE_TEXT), 'total'];
export const TASKS_BY_TYPE_SUBJECT_ISSUE = 'Issue';
export const TASKS_BY_TYPE_SUBJECT_MERGE_REQUEST = 'MergeRequest';
......
......@@ -488,11 +488,10 @@ describe 'Group Value Stream Analytics', :js do
end
it 'with a default name' do
name = 'issue'
fill_in 'custom-stage-name', with: name
fill_in 'custom-stage-name', with: 'issue'
click_button 'Add stage'
expect(page.find('.flash-alert')).to have_text("'#{name}' stage already exists")
expect(page).to have_button('Add stage', disabled: true)
end
end
......@@ -616,11 +615,10 @@ describe 'Group Value Stream Analytics', :js do
end
it 'with a default name' do
name = 'issue'
fill_in name_field, with: name
fill_in name_field, with: 'issue'
page.find(stage_save_button).click
expect(page.find('.flash-alert')).to have_text("'#{name}' stage already exists")
expect(page.find(stage_form_class)).to have_text("Stage name already exists")
end
end
end
......
......@@ -7,7 +7,7 @@ exports[`CustomStageForm Editing a custom stage isSavingCustomStage=true display
`;
exports[`CustomStageForm Start event with events does not select events with canBeStartEvent=false for the start events dropdown 1`] = `
"<select name=\\"custom-stage-start-event\\" required=\\"required\\" aria-required=\\"true\\" class=\\"gl-form-select custom-select\\" id=\\"__BVID__177\\">
"<select name=\\"custom-stage-start-event\\" required=\\"required\\" aria-required=\\"true\\" class=\\"gl-form-select custom-select\\" id=\\"__BVID__257\\">
<option value=\\"\\">Select start event</option>
<option value=\\"issue_created\\">Issue created</option>
<option value=\\"issue_first_mentioned_in_commit\\">Issue first mentioned in a commit</option>
......@@ -30,7 +30,7 @@ exports[`CustomStageForm Start event with events does not select events with can
`;
exports[`CustomStageForm Start event with events selects events with canBeStartEvent=true for the start events dropdown 1`] = `
"<select name=\\"custom-stage-start-event\\" required=\\"required\\" aria-required=\\"true\\" class=\\"gl-form-select custom-select\\" id=\\"__BVID__137\\">
"<select name=\\"custom-stage-start-event\\" required=\\"required\\" aria-required=\\"true\\" class=\\"gl-form-select custom-select\\" id=\\"__BVID__217\\">
<option value=\\"\\">Select start event</option>
<option value=\\"issue_created\\">Issue created</option>
<option value=\\"issue_first_mentioned_in_commit\\">Issue first mentioned in a commit</option>
......
......@@ -79,6 +79,15 @@ describe('CustomStageForm', () => {
});
}
const findNameField = _wrapper => _wrapper.find({ ref: 'name' });
const findNameFieldInput = _wrapper => _wrapper.find(sel.name);
function setNameField(_wrapper, value = '') {
findNameFieldInput(_wrapper).setValue(value);
findNameFieldInput(_wrapper).trigger('change');
return _wrapper.vm.$nextTick();
}
beforeEach(() => {
wrapper = createComponent({});
});
......@@ -106,6 +115,25 @@ describe('CustomStageForm', () => {
});
});
describe('Name', () => {
describe('with a reserved name', () => {
beforeEach(() => {
wrapper = createComponent({});
return setNameField(wrapper, 'issue');
});
it('displays an error', () => {
expect(findNameField(wrapper).text()).toContain('Stage name already exists');
});
it('clears the error when the field changes', () => {
return setNameField(wrapper, 'not an issue').then(() => {
expect(findNameField(wrapper).text()).not.toContain('Stage name already exists');
});
});
});
});
describe('Start event', () => {
describe('with events', () => {
beforeEach(() => {
......@@ -165,7 +193,6 @@ describe('CustomStageForm', () => {
expect(wrapper.vm.fields.startEventLabelId).toEqual(null);
wrapper.find(sel.startEvent).setValue(labelStartEvent.identifier);
// TODO: make func for setting single field
return Vue.nextTick()
.then(() => {
wrapper
......
......@@ -5848,6 +5848,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Select stop event"
msgstr ""
msgid "CustomCycleAnalytics|Stage name already exists"
msgstr ""
msgid "CustomCycleAnalytics|Start event"
msgstr ""
......
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