Commit e2d16634 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Simon Knox

Minor VSA i18n and create value stream form components refactor

parent 7e079330
......@@ -3,8 +3,8 @@ import { __, s__, sprintf } from '~/locale';
export const NAME_MAX_LENGTH = 100;
export const i18n = {
FORM_TITLE: s__('CreateValueStreamForm|Create Value Stream'),
EDIT_FORM_TITLE: s__('CreateValueStreamForm|Edit Value Stream'),
FORM_TITLE: s__('CreateValueStreamForm|Create value stream'),
EDIT_FORM_TITLE: s__('CreateValueStreamForm|Edit value stream'),
EDIT_FORM_ACTION: s__('CreateValueStreamForm|Save value stream'),
FORM_CREATED: s__("CreateValueStreamForm|'%{name}' Value Stream created"),
FORM_EDITED: s__("CreateValueStreamForm|'%{name}' Value Stream saved"),
......
<script>
import { GlFormGroup, GlDropdown, GlDropdownItem } from '@gitlab/ui';
export default {
name: 'CustomStageEventField',
components: {
GlFormGroup,
GlDropdown,
GlDropdownItem,
},
props: {
index: {
type: Number,
required: true,
},
eventType: {
type: String,
required: true,
},
eventsList: {
type: Array,
required: true,
},
fieldLabel: {
type: String,
required: true,
},
selectedEventName: {
type: String,
required: true,
},
disabled: {
type: Boolean,
required: false,
default: false,
},
hasIdentifierError: {
type: Boolean,
required: false,
default: false,
},
identifierError: {
type: String,
required: false,
default: '',
},
},
computed: {
fieldName() {
const { eventType, index } = this;
return `custom-stage-${eventType}-${index}`;
},
},
};
</script>
<template>
<gl-form-group
class="gl-w-half gl-mr-2"
:data-testid="fieldName"
:label="fieldLabel"
:state="hasIdentifierError"
:invalid-feedback="identifierError"
>
<gl-dropdown
toggle-class="gl-mb-0"
:text="selectedEventName"
:name="fieldName"
:disabled="disabled"
menu-class="gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for="{ text, value } in eventsList"
:key="`${eventType}-${value}`"
:value="value"
@click="$emit('update-identifier', value)"
>{{ text }}</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
</template>
<script>
import { GlFormGroup } from '@gitlab/ui';
import LabelsSelector from '../labels_selector.vue';
export default {
name: 'CustomStageEventLabelField',
components: {
GlFormGroup,
LabelsSelector,
},
props: {
index: {
type: Number,
required: true,
},
eventType: {
type: String,
required: true,
},
fieldLabel: {
type: String,
required: true,
},
requiresLabel: {
type: Boolean,
required: true,
},
initialGroupLabels: {
type: Array,
required: true,
},
hasLabelError: {
type: Boolean,
required: false,
default: false,
},
labelError: {
type: String,
required: false,
default: '',
},
selectedLabelIds: {
type: Array,
required: false,
default: () => [],
},
},
computed: {
fieldName() {
const { eventType, index } = this;
return `custom-stage-${eventType}-label-${index}`;
},
},
};
</script>
<template>
<div class="gl-w-half gl-ml-2">
<transition name="fade">
<gl-form-group
v-if="requiresLabel"
:data-testid="fieldName"
:label="fieldLabel"
:state="hasLabelError"
:invalid-feedback="labelError"
>
<labels-selector
:initial-data="initialGroupLabels"
:selected-label-ids="selectedLabelIds"
:name="fieldName"
@select-label="$emit('update-label', $event)"
/>
</gl-form-group>
</transition>
</div>
</template>
<script>
import { GlFormGroup, GlFormInput, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { GlFormGroup, GlFormInput } from '@gitlab/ui';
import { isLabelEvent, getLabelEventsIdentifiers, uniqById } from '../../utils';
import LabelsSelector from '../labels_selector.vue';
import { i18n } from './constants';
import CustomStageEventField from './custom_stage_event_field.vue';
import CustomStageEventLabelField from './custom_stage_event_label_field.vue';
import StageFieldActions from './stage_field_actions.vue';
import { startEventOptions, endEventOptions } from './utils';
......@@ -11,9 +12,8 @@ export default {
components: {
GlFormGroup,
GlFormInput,
GlDropdown,
GlDropdownItem,
LabelsSelector,
CustomStageEventField,
CustomStageEventLabelField,
StageFieldActions,
},
props: {
......@@ -21,6 +21,10 @@ export default {
type: Number,
required: true,
},
stageLabel: {
type: String,
required: true,
},
totalStages: {
type: Number,
required: true,
......@@ -107,6 +111,7 @@ export default {
<div class="gl-display-flex">
<gl-form-group
class="gl-flex-grow-1"
:label="stageLabel"
:state="hasFieldErrors('name')"
:invalid-feedback="fieldErrorMessage('name')"
:data-testid="`custom-stage-name-${index}`"
......@@ -123,6 +128,7 @@ export default {
</gl-form-group>
<stage-field-actions
v-if="hasMultipleStages"
class="gl-mt-6"
:index="index"
:stage-count="totalStages"
:can-remove="true"
......@@ -131,91 +137,51 @@ export default {
/>
</div>
<div class="gl-display-flex gl-justify-content-between">
<gl-form-group
:data-testid="`custom-stage-start-event-${index}`"
class="gl-w-half gl-mr-2"
:label="$options.i18n.FORM_FIELD_START_EVENT"
:state="hasFieldErrors('startEventIdentifier')"
:invalid-feedback="fieldErrorMessage('startEventIdentifier')"
>
<gl-dropdown
toggle-class="gl-mb-0"
:text="selectedStartEventName"
:name="`custom-stage-start-id-${index}`"
menu-class="gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for="{ text, value } in startEvents"
:key="`start-event-${value}`"
:value="value"
@click="$emit('input', { field: 'startEventIdentifier', value })"
>{{ text }}</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
<div class="gl-w-half gl-ml-2">
<transition name="fade">
<gl-form-group
v-if="startEventRequiresLabel"
:data-testid="`custom-stage-start-event-label-${index}`"
:label="$options.i18n.FORM_FIELD_START_EVENT_LABEL"
:state="hasFieldErrors('startEventLabelId')"
:invalid-feedback="fieldErrorMessage('startEventLabelId')"
>
<labels-selector
:initial-data="initialGroupLabels"
:selected-label-ids="[stage.startEventLabelId]"
:name="`custom-stage-start-label-${index}`"
@select-label="$emit('input', { field: 'startEventLabelId', value: $event })"
/>
</gl-form-group>
</transition>
</div>
<custom-stage-event-field
event-type="start-event"
:index="index"
:field-label="$options.i18n.FORM_FIELD_START_EVENT"
:selected-event-name="selectedStartEventName"
:events-list="startEvents"
:identifier-error="fieldErrorMessage('startEventIdentifier')"
:has-identifier-error="hasFieldErrors('startEventIdentifier')"
@update-identifier="$emit('input', { field: 'startEventIdentifier', value: $event })"
/>
<custom-stage-event-label-field
event-type="start-event"
:index="index"
:field-label="$options.i18n.FORM_FIELD_START_EVENT_LABEL"
:initial-group-labels="initialGroupLabels"
:requires-label="startEventRequiresLabel"
:label-error="fieldErrorMessage('startEventLabelId')"
:has-label-error="hasFieldErrors('startEventLabelId')"
:selected-label-ids="[stage.startEventLabelId]"
@update-label="$emit('input', { field: 'startEventLabelId', value: $event })"
/>
</div>
<div class="gl-display-flex gl-justify-content-between">
<gl-form-group
:data-testid="`custom-stage-end-event-${index}`"
class="gl-w-half gl-mr-2"
:label="$options.i18n.FORM_FIELD_END_EVENT"
:state="hasFieldErrors('endEventIdentifier')"
:invalid-feedback="fieldErrorMessage('endEventIdentifier')"
>
<gl-dropdown
toggle-class="gl-mb-0"
:text="selectedEndEventName"
:name="`custom-stage-end-id-${index}`"
:disabled="!hasStartEvent"
menu-class="gl-overflow-hidden!"
block
>
<gl-dropdown-item
v-for="{ text, value } in endEvents"
:key="`end-event-${value}`"
:value="value"
@click="$emit('input', { field: 'endEventIdentifier', value })"
>{{ text }}</gl-dropdown-item
>
</gl-dropdown>
</gl-form-group>
<div class="gl-w-half gl-ml-2">
<transition name="fade">
<gl-form-group
v-if="endEventRequiresLabel"
:data-testid="`custom-stage-end-event-label-${index}`"
:label="$options.i18n.FORM_FIELD_END_EVENT_LABEL"
:state="hasFieldErrors('endEventLabelId')"
:invalid-feedback="fieldErrorMessage('endEventLabelId')"
>
<labels-selector
:initial-data="initialGroupLabels"
:selected-label-ids="[stage.endEventLabelId]"
:name="`custom-stage-end-label-${index}`"
@select-label="$emit('input', { field: 'endEventLabelId', value: $event })"
/>
</gl-form-group>
</transition>
</div>
<custom-stage-event-field
event-type="end-event"
:index="index"
:disabled="!hasStartEvent"
:field-label="$options.i18n.FORM_FIELD_END_EVENT"
:selected-event-name="selectedEndEventName"
:events-list="endEvents"
:identifier-error="fieldErrorMessage('endEventIdentifier')"
:has-identifier-error="hasFieldErrors('endEventIdentifier')"
@update-identifier="$emit('input', { field: 'endEventIdentifier', value: $event })"
/>
<custom-stage-event-label-field
event-type="end-event"
:index="index"
:field-label="$options.i18n.FORM_FIELD_END_EVENT_LABEL"
:initial-group-labels="initialGroupLabels"
:requires-label="endEventRequiresLabel"
:label-error="fieldErrorMessage('endEventLabelId')"
:has-label-error="hasFieldErrors('endEventLabelId')"
:selected-label-ids="[stage.endEventLabelId]"
@update-label="$emit('input', { field: 'endEventLabelId', value: $event })"
/>
</div>
</div>
</template>
......@@ -26,6 +26,10 @@ export default {
type: Number,
required: true,
},
stageLabel: {
type: String,
required: true,
},
totalStages: {
type: Number,
required: true,
......@@ -63,6 +67,7 @@ export default {
<div class="gl-display-flex">
<gl-form-group
class="gl-flex-grow-1 gl-mb-0"
:label="stageLabel"
:state="isValid('name')"
:invalid-feedback="renderError('name')"
:data-testid="`default-stage-name-${index}`"
......@@ -79,6 +84,7 @@ export default {
<!-- eslint-enable vue/no-mutating-props -->
</gl-form-group>
<stage-field-actions
class="gl-mt-6"
:index="index"
:stage-count="totalStages"
@move="$emit('move', $event)"
......
......@@ -388,12 +388,9 @@ export default {
:key="stage.id || stage.transitionKey"
>
<hr class="gl-my-3" />
<span
class="gl-display-flex gl-m-0 gl-vertical-align-middle gl-mr-2 gl-font-weight-bold gl-display-flex gl-pb-3"
>{{ stageGroupLabel(activeStageIndex) }}</span
>
<custom-stage-fields
v-if="stage.custom"
:stage-label="stageGroupLabel(activeStageIndex)"
:stage="stage"
:stage-events="formEvents"
:index="activeStageIndex"
......@@ -406,6 +403,7 @@ export default {
/>
<default-stage-fields
v-else
:stage-label="stageGroupLabel(activeStageIndex)"
:stage="stage"
:stage-events="formEvents"
:index="activeStageIndex"
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
i18n,
ERRORS,
} from 'ee/analytics/cycle_analytics/components/create_value_stream_form/constants';
import CustomStageEventField from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue';
import { customStageEvents as stageEvents } from '../../mock_data';
const formatStartEventOpts = (_events) => [
{ text: 'Select start event', value: null },
..._events
.filter((ev) => ev.canBeStartEvent)
.map(({ name: text, identifier: value }) => ({ text, value })),
];
const index = 0;
const eventType = 'stage-start-event';
const fieldLabel = i18n.FORM_FIELD_START_EVENT;
const selectedEventName = i18n.SELECT_START_EVENT;
const eventsList = formatStartEventOpts(stageEvents);
const selectedEventIndex = 1; // index `0` is the default select text
const firstEvent = eventsList[selectedEventIndex];
const identifierError = ERRORS.START_EVENT_REQUIRED;
const defaultProps = {
index,
eventType,
eventsList,
fieldLabel,
selectedEventName,
};
describe('CustomStageEventField', () => {
function createComponent(props = {}) {
return shallowMountExtended(CustomStageEventField, {
propsData: {
...defaultProps,
...props,
},
});
}
let wrapper = null;
const findEventField = () => wrapper.findByTestId(`custom-stage-${eventType}-${index}`);
const findEventDropdown = () => findEventField().findComponent(GlDropdown);
const findEventDropdownItems = () => findEventField().findAllComponents(GlDropdownItem);
const findEventDropdownItem = (itemIndex = 0) => findEventDropdownItems().at(itemIndex);
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('Event dropdown', () => {
it('renders the event dropdown', () => {
expect(findEventField().exists()).toBe(true);
expect(findEventField().attributes('label')).toBe(fieldLabel);
expect(findEventDropdown().attributes('disabled')).toBeUndefined();
expect(findEventDropdown().attributes('text')).toBe(selectedEventName);
});
it('renders each item in the event list', () => {
const ev = findEventDropdownItems().wrappers.map((d) => d.text());
const eventsListText = eventsList.map(({ text }) => text);
expect(eventsListText).toEqual(ev);
});
it('emits the `update-identifier` event when an event is selected', () => {
expect(wrapper.emitted('update-identifier')).toBeUndefined();
findEventDropdownItem(selectedEventIndex).vm.$emit('click');
expect(wrapper.emitted('update-identifier')[0]).toEqual([firstEvent.value]);
});
it('sets disables the dropdown when the disabled prop is set', async () => {
expect(findEventDropdown().attributes('disabled')).toBeUndefined();
wrapper = await createComponent({ disabled: true });
expect(findEventDropdown().attributes('disabled')).toBe('true');
});
});
describe('with an event field error', () => {
beforeEach(() => {
wrapper = createComponent({
hasIdentifierError: true,
identifierError,
});
});
it('sets the form group error state', () => {
expect(findEventField().attributes('state')).toBe('true');
expect(findEventField().attributes('invalid-feedback')).toBe(identifierError);
});
});
});
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
i18n,
ERRORS,
} from 'ee/analytics/cycle_analytics/components/create_value_stream_form/constants';
import CustomStageEventLabelField from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue';
import LabelsSelector from 'ee/analytics/cycle_analytics/components/labels_selector.vue';
import { groupLabels as initialGroupLabels } from '../../mock_data';
const index = 0;
const eventType = 'start-event';
const fieldLabel = i18n.FORM_FIELD_START_EVENT_LABEL;
const labelError = ERRORS.INVALID_EVENT_PAIRS;
const [selectedLabel, secondLabel] = initialGroupLabels;
const selectedLabelIds = [selectedLabel.id, secondLabel.id];
const defaultProps = {
index,
eventType,
fieldLabel,
requiresLabel: true,
initialGroupLabels,
labelError,
selectedLabelIds: [],
};
describe('CustomStageEventLabelField', () => {
function createComponent(props = {}) {
return shallowMountExtended(CustomStageEventLabelField, {
propsData: {
...defaultProps,
...props,
},
});
}
let wrapper = null;
const findEventLabelField = () =>
wrapper.findByTestId(`custom-stage-${eventType}-label-${index}`);
const findEventLabelDropdown = () => findEventLabelField().findComponent(LabelsSelector);
const findEventLabelDropdownProp = (prop) => findEventLabelDropdown().props(prop);
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('Label dropdown', () => {
it('renders the event dropdown', () => {
expect(findEventLabelField().exists()).toBe(true);
expect(findEventLabelField().attributes('label')).toBe(fieldLabel);
});
it('renders each item in the labels list', () => {
const lt = findEventLabelDropdownProp('initialData').map((d) => d.name);
const labelsText = initialGroupLabels.map(({ name }) => name);
expect(labelsText).toEqual(lt);
});
it('has no selected labels', () => {
const selected = findEventLabelDropdownProp('selectedLabelIds');
expect(selected).toEqual([]);
});
it('emits the `update-label` event when a label is selected', () => {
expect(wrapper.emitted('update-label')).toBeUndefined();
findEventLabelDropdown().vm.$emit('select-label', selectedLabel.id);
expect(wrapper.emitted('update-label')[0]).toEqual([selectedLabel.id]);
});
});
describe('with selected labels', () => {
beforeEach(() => {
wrapper = createComponent({ selectedLabelIds });
});
it('sets the selected labels', () => {
const selected = findEventLabelDropdownProp('selectedLabelIds');
expect(selected).toEqual(selectedLabelIds);
});
});
describe('with `requiresLabel=false`', () => {
beforeEach(() => {
wrapper = createComponent({ requiresLabel: false });
});
it('sets the form group error state', () => {
expect(findEventLabelField().exists()).toBe(false);
});
});
describe('with an event field error', () => {
beforeEach(() => {
wrapper = createComponent({
hasLabelError: true,
labelError,
});
});
it('sets the form group error state', () => {
expect(findEventLabelField().attributes('state')).toBe('true');
expect(findEventLabelField().attributes('invalid-feedback')).toBe(labelError);
});
});
});
import { GlDropdown, GlFormInput } from '@gitlab/ui';
import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CustomStageFields from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue';
import CustomStageEventField from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue';
import CustomStageEventLabelField from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_label_field.vue';
import StageFieldActions from 'ee/analytics/cycle_analytics/components/create_value_stream_form/stage_field_actions.vue';
import LabelsSelector from 'ee/analytics/cycle_analytics/components/labels_selector.vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import {
customStageEvents as stageEvents,
labelStartEvent,
labelEndEvent,
customStageEndEvents as endEvents,
groupLabels as defaultGroupLabels,
} from '../../mock_data';
import { emptyState, emptyErrorsState, firstLabel } from './mock_data';
......@@ -39,11 +41,13 @@ describe('CustomStageFields', () => {
return extendedWrapper(
shallowMount(CustomStageFields, {
propsData: {
defaultGroupLabels,
stage,
errors,
stageEvents,
index: 0,
totalStages: 3,
stageLabel: 'Stage 1',
...props,
},
stubs: {
......@@ -56,21 +60,17 @@ describe('CustomStageFields', () => {
let wrapper = null;
const getDropdown = (dropdownEl) => dropdownEl.findComponent(GlDropdown);
const getLabelSelect = (dropdownEl) => dropdownEl.findComponent(LabelsSelector);
const findName = (index = 0) => wrapper.findByTestId(`custom-stage-name-${index}`);
const findStartEvent = (index = 0) => wrapper.findByTestId(`custom-stage-start-event-${index}`);
const findEndEvent = (index = 0) => wrapper.findByTestId(`custom-stage-end-event-${index}`);
const findStartEventLabel = (index = 0) =>
wrapper.findByTestId(`custom-stage-start-event-label-${index}`);
const findEndEventLabel = (index = 0) =>
wrapper.findByTestId(`custom-stage-end-event-label-${index}`);
const findNameField = () => findName().findComponent(GlFormInput);
const findStartEventField = () => getDropdown(findStartEvent());
const findEndEventField = () => getDropdown(findEndEvent());
const findStartEventLabelField = () => getLabelSelect(findStartEventLabel());
const findEndEventLabelField = () => getLabelSelect(findEndEventLabel());
const findStartEventField = () => wrapper.findAllComponents(CustomStageEventField).at(0);
const findEndEventField = () => wrapper.findAllComponents(CustomStageEventField).at(1);
const findStartEventLabelField = () =>
wrapper.findAllComponents(CustomStageEventLabelField).at(0);
const findEndEventLabelField = () => wrapper.findAllComponents(CustomStageEventLabelField).at(1);
const findStageFieldActions = () => wrapper.findComponent(StageFieldActions);
beforeEach(() => {
......@@ -135,13 +135,13 @@ describe('CustomStageFields', () => {
});
it('will display the start event label field if a label event is selected', () => {
expect(findStartEventLabel().exists()).toEqual(true);
expect(findStartEventLabelField().exists()).toEqual(true);
});
it('will emit the `input` event when the start event label field when selected', async () => {
expect(wrapper.emitted('input')).toBeUndefined();
findStartEventLabelField().vm.$emit('select-label', firstLabel.id);
findStartEventLabelField().vm.$emit('update-label', firstLabel.id);
expect(wrapper.emitted('input')[0]).toEqual([
{ field: 'startEventLabelId', value: firstLabel.id },
......@@ -180,13 +180,13 @@ describe('CustomStageFields', () => {
});
it('will display the end event label field if a label event is selected', () => {
expect(findEndEventLabel().exists()).toEqual(true);
expect(findEndEventLabelField().exists()).toEqual(true);
});
it('will emit the `input` event when the start event label field when selected', async () => {
expect(wrapper.emitted('input')).toBeUndefined();
findEndEventLabelField().vm.$emit('select-label', firstLabel.id);
findEndEventLabelField().vm.$emit('update-label', firstLabel.id);
expect(wrapper.emitted('input')[0]).toEqual([
{ field: 'endEventLabelId', value: firstLabel.id },
......
......@@ -28,6 +28,7 @@ describe('DefaultStageFields', () => {
stage,
errors,
stageEvents,
stageLabel: 'Stage 1',
},
stubs: {
'labels-selector': false,
......
......@@ -3,10 +3,12 @@ import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import {
i18n,
PRESET_OPTIONS_BLANK,
PRESET_OPTIONS_DEFAULT,
} from 'ee/analytics/cycle_analytics/components/create_value_stream_form/constants';
import CustomStageFields from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_fields.vue';
import CustomStageEventField from 'ee/analytics/cycle_analytics/components/create_value_stream_form/custom_stage_event_field.vue';
import DefaultStageFields from 'ee/analytics/cycle_analytics/components/create_value_stream_form/default_stage_fields.vue';
import ValueStreamForm from 'ee/analytics/cycle_analytics/components/value_stream_form.vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
......@@ -15,7 +17,12 @@ import {
convertObjectPropsToCamelCase,
convertObjectPropsToSnakeCase,
} from '~/lib/utils/common_utils';
import { customStageEvents as formEvents, defaultStageConfig, rawCustomStage } from '../mock_data';
import {
customStageEvents as formEvents,
defaultStageConfig,
rawCustomStage,
groupLabels as defaultGroupLabels,
} from '../mock_data';
const scrollIntoViewMock = jest.fn();
HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
......@@ -55,7 +62,7 @@ describe('ValueStreamForm', () => {
state: {
isCreatingValueStream: false,
formEvents,
defaultGroupLabels: null,
defaultGroupLabels,
...state,
},
actions: {
......@@ -96,12 +103,16 @@ describe('ValueStreamForm', () => {
const findRestoreStageButton = (index) => wrapper.findByTestId(`stage-action-restore-${index}`);
const findHiddenStages = () => wrapper.findAllByTestId('vsa-hidden-stage').wrappers;
const findBtn = (btn) => findModal().props(btn);
const findCustomStageEventField = (index = 0) =>
wrapper.findAllComponents(CustomStageEventField).at(index);
const clickSubmit = () => findModal().vm.$emit('primary', mockEvent);
const clickAddStage = () => findModal().vm.$emit('secondary', mockEvent);
const clickRestoreStageAtIndex = (index) => findRestoreStageButton(index).vm.$emit('click');
const expectFieldError = (testId, error = '') =>
expect(wrapper.findByTestId(testId).attributes('invalid-feedback')).toBe(error);
const expectCustomFieldError = (index, attr, error = '') =>
expect(findCustomStageEventField(index).attributes(attr)).toBe(error);
const expectStageTransitionKeys = (stages) =>
stages.forEach((stage) => expect(stage.transitionKey).toContain('stage-'));
......@@ -112,7 +123,7 @@ describe('ValueStreamForm', () => {
describe('default state', () => {
beforeEach(() => {
wrapper = createComponent();
wrapper = createComponent({ state: { defaultGroupLabels: null } });
});
it('has the extended fields', () => {
......@@ -120,7 +131,7 @@ describe('ValueStreamForm', () => {
});
it('sets the submit action text to "Create Value Stream"', () => {
expect(findBtn('actionPrimary').text).toBe('Create Value Stream');
expect(findBtn('actionPrimary').text).toBe(i18n.FORM_TITLE);
});
describe('Preset selector', () => {
......@@ -223,8 +234,9 @@ describe('ValueStreamForm', () => {
});
expectFieldError('custom-stage-name-0', initialFormStageErrors.stages[0].name[0]);
expectFieldError(
'custom-stage-end-event-0',
expectCustomFieldError(
1,
'identifiererror',
initialFormStageErrors.stages[0].endEventIdentifier[0],
);
});
......@@ -247,7 +259,7 @@ describe('ValueStreamForm', () => {
});
it('sets the submit action text to "Save value stream"', () => {
expect(findBtn('actionPrimary').text).toBe('Save value stream');
expect(findBtn('actionPrimary').text).toBe(i18n.EDIT_FORM_ACTION);
});
it('does not display any hidden stages', () => {
......@@ -324,7 +336,7 @@ describe('ValueStreamForm', () => {
});
it('has the add stage button', () => {
expect(findBtn('actionSecondary')).toMatchObject({ text: 'Add another stage' });
expect(findBtn('actionSecondary')).toMatchObject({ text: i18n.BTN_ADD_ANOTHER_STAGE });
});
it('adds a blank custom stage when clicked', async () => {
......
......@@ -10126,9 +10126,6 @@ msgstr ""
msgid "CreateValueStreamForm|Code stage start"
msgstr ""
msgid "CreateValueStreamForm|Create Value Stream"
msgstr ""
msgid "CreateValueStreamForm|Create from default template"
msgstr ""
......@@ -10138,13 +10135,16 @@ msgstr ""
msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
msgid "CreateValueStreamForm|Create value stream"
msgstr ""
msgid "CreateValueStreamForm|Default stages"
msgstr ""
msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
msgid "CreateValueStreamForm|Edit Value Stream"
msgid "CreateValueStreamForm|Edit value stream"
msgstr ""
msgid "CreateValueStreamForm|Editing stage"
......
......@@ -59,7 +59,7 @@ module CycleAnalyticsHelpers
def save_value_stream(custom_value_stream_name)
fill_in 'create-value-stream-name', with: custom_value_stream_name
page.find_button(s_('CreateValueStreamForm|Create Value Stream')).click
page.find_button(s_('CreateValueStreamForm|Create value stream')).click
wait_for_requests
end
......
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