Commit 4801dbdd authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch 'automatically-position-vsa-stages' into 'master'

Automatically set position for VSA stages

See merge request gitlab-org/gitlab!55108
parents 2e35142c 0dcb3a95
......@@ -67,8 +67,7 @@ export default {
state.stages = [];
},
[types.RECEIVE_GROUP_STAGES_SUCCESS](state, stages) {
const transformedStages = transformRawStages(stages);
state.stages = transformedStages.sort((a, b) => a?.id > b?.id);
state.stages = transformRawStages(stages);
},
[types.REQUEST_UPDATE_STAGE](state) {
state.isLoading = true;
......
......@@ -3,7 +3,7 @@
class Analytics::CycleAnalytics::GroupValueStream < ApplicationRecord
belongs_to :group
has_many :stages, class_name: 'Analytics::CycleAnalytics::GroupStage', index_errors: true
has_many :stages, -> { ordered }, class_name: 'Analytics::CycleAnalytics::GroupStage', index_errors: true
validates :group, :name, presence: true
validates :name, length: { minimum: 3, maximum: 100, allow_nil: false }, uniqueness: { scope: :group_id }
......
......@@ -37,6 +37,8 @@ module Analytics
raw_params[:stages_attributes] = raw_params.delete(:stages) || []
raw_params[:stages_attributes].map! { |attrs| build_stage_attributes(attrs) }
set_relative_positions!(raw_params[:stages_attributes])
raw_params
end
......@@ -62,6 +64,13 @@ module Analytics
ServiceResponse.error(message: 'Forbidden', http_status: :forbidden, payload: { errors: nil })
end
end
def set_relative_positions!(stages_attributes)
increment = (Gitlab::RelativePositioning::MAX_POSITION - Gitlab::RelativePositioning::START_POSITION).fdiv(stages_attributes.size + 1).floor
stages_attributes.each_with_index do |stage_attribute, i|
stage_attribute[:relative_position] = increment * i
end
end
end
end
end
......
......@@ -23,4 +23,26 @@ RSpec.describe Analytics::CycleAnalytics::GroupValueStream, type: :model do
expect(value_stream.errors.messages).to eq(name: [I18n.t('errors.messages.taken')])
end
end
describe 'ordering of stages' do
let(:group) { create(:group) }
let(:value_stream) do
create(:cycle_analytics_group_value_stream, group: group, stages: [
create(:cycle_analytics_group_stage, group: group, name: "stage 1", relative_position: 5),
create(:cycle_analytics_group_stage, group: group, name: "stage 2", relative_position: nil),
create(:cycle_analytics_group_stage, group: group, name: "stage 3", relative_position: 1)
])
end
before do
value_stream.reload
end
describe 'stages attribute' do
it 'sorts stages by relative position' do
names = value_stream.stages.map(&:name)
expect(names).to eq(['stage 3', 'stage 1', 'stage 2'])
end
end
end
end
......@@ -49,6 +49,15 @@ RSpec.describe Analytics::CycleAnalytics::ValueStreams::CreateService do
expect(value_stream.stages.size).to eq(2)
end
it 'calculates and sets relative_position for the stages based on the incoming stages array' do
incoming_stage_names = params[:stages].map { |stage| stage[:name] }
value_stream = subject.payload[:value_stream]
persisted_stages_sorted_by_relative_position = value_stream.stages.sort_by(&:relative_position).map(&:name)
expect(persisted_stages_sorted_by_relative_position).to eq(incoming_stage_names)
end
context 'when the stage is invalid' do
it 'propagates validation errors' do
params[:stages].first[:name] = ''
......
......@@ -53,6 +53,21 @@ RSpec.describe Analytics::CycleAnalytics::ValueStreams::UpdateService do
expect(last_stage.reload.name).to eq('updated')
end
context 'relative positioning' do
before do
params[:stages].reverse!
end
it 'calculates and sets relative_position for the stages based on the incoming stages array' do
incoming_stage_names = params[:stages].map { |stage| stage[:name] }
value_stream = subject.payload[:value_stream]
persisted_stages_sorted_by_relative_position = value_stream.stages.sort_by(&:relative_position).map(&:name)
expect(persisted_stages_sorted_by_relative_position).to eq(incoming_stage_names)
end
end
context 'when the params are invalid' do
before do
params[:stages].last[:name] = ''
......
......@@ -8,10 +8,12 @@ module Gitlab
# Issue: < 100
# MergeRequest: >= 100 && < 1000
# Custom events for default stages: >= 1000 (legacy)
#
# To avoid duplications, verify that the value does not exist in ee/lib/ee/gitlab/analytics/cycle_analytics/stage_events.rb
ENUM_MAPPING = {
StageEvents::IssueCreated => 1,
StageEvents::IssueFirstMentionedInCommit => 2,
StageEvents::IssueDeployedToProduction => 3,
StageEvents::IssueDeployedToProduction => 10,
StageEvents::MergeRequestCreated => 100,
StageEvents::MergeRequestFirstDeployedToProduction => 101,
StageEvents::MergeRequestLastBuildFinished => 102,
......
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