Commit 1d399264 authored by Andreas Brandl's avatar Andreas Brandl

Merge branch '250479-iteration-lists-creation' into 'master'

Add iteration_id column to lists

See merge request gitlab-org/gitlab!48103
parents 66d9c55d dda8f64e
......@@ -7,7 +7,7 @@ class List < ApplicationRecord
belongs_to :label
has_many :list_user_preferences
enum list_type: { backlog: 0, label: 1, closed: 2, assignee: 3, milestone: 4 }
enum list_type: { backlog: 0, label: 1, closed: 2, assignee: 3, milestone: 4, iteration: 5 }
validates :board, :list_type, presence: true, unless: :importing?
validates :label, :position, presence: true, if: :label?
......
---
title: Add iteration_id column to lists
merge_request: 48103
author:
type: added
# frozen_string_literal: true
class AddIterationIdToLists < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :lists, :iteration_id, :bigint
end
end
# frozen_string_literal: true
class AddIterationListsForeignKey < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_lists_on_iteration_id'
disable_ddl_transaction!
def up
add_concurrent_index :lists, :iteration_id, name: INDEX_NAME
add_concurrent_foreign_key :lists, :sprints, column: :iteration_id, on_delete: :cascade
end
def down
remove_foreign_key_if_exists :lists, :sprints, column: :iteration_id
remove_concurrent_index_by_name :lists, INDEX_NAME
end
end
6d2e6937c9e41975b1fd402bf2985796792a1e5f8e4f4f98bc76b65ff73c4e02
\ No newline at end of file
c7567489156bbc047cf9f7827f060ad507fd5d328179f2796566a7dc54806e3e
\ No newline at end of file
......@@ -13652,7 +13652,8 @@ CREATE TABLE lists (
milestone_id integer,
max_issue_count integer DEFAULT 0 NOT NULL,
max_issue_weight integer DEFAULT 0 NOT NULL,
limit_metric character varying(20)
limit_metric character varying(20),
iteration_id bigint
);
CREATE SEQUENCE lists_id_seq
......@@ -21617,6 +21618,8 @@ CREATE UNIQUE INDEX index_list_user_preferences_on_user_id_and_list_id ON list_u
CREATE UNIQUE INDEX index_lists_on_board_id_and_label_id ON lists USING btree (board_id, label_id);
CREATE INDEX index_lists_on_iteration_id ON lists USING btree (iteration_id);
CREATE INDEX index_lists_on_label_id ON lists USING btree (label_id);
CREATE INDEX index_lists_on_list_type ON lists USING btree (list_type);
......@@ -23263,6 +23266,9 @@ ALTER TABLE ONLY notes
ALTER TABLE ONLY members
ADD CONSTRAINT fk_2e88fb7ce9 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY lists
ADD CONSTRAINT fk_30f2a831f4 FOREIGN KEY (iteration_id) REFERENCES sprints(id) ON DELETE CASCADE;
ALTER TABLE ONLY approvals
ADD CONSTRAINT fk_310d714958 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
......
......@@ -19,11 +19,14 @@ module EE
base.belongs_to :user
base.belongs_to :milestone
base.belongs_to :iteration
base.validates :user, presence: true, if: :assignee?
base.validates :milestone, presence: true, if: :milestone?
base.validates :iteration, presence: true, if: :iteration?
base.validates :user_id, uniqueness: { scope: :board_id }, if: :assignee?
base.validates :milestone_id, uniqueness: { scope: :board_id }, if: :milestone?
base.validates :iteration_id, uniqueness: { scope: :board_id }, if: :iteration?
base.validates :max_issue_count, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
base.validates :max_issue_weight, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
base.validates :limit_metric, inclusion: {
......@@ -32,11 +35,14 @@ module EE
allow_nil: true
}
base.validates :list_type,
exclusion: { in: %w[assignee], message: _('Assignee lists not available with your current license') },
exclusion: { in: %w[assignee], message: -> (_object, _data) { _('Assignee lists not available with your current license') } },
unless: -> { board&.resource_parent&.feature_available?(:board_assignee_lists) }
base.validates :list_type,
exclusion: { in: %w[milestone], message: _('Milestone lists not available with your current license') },
exclusion: { in: %w[milestone], message: -> (_object, _data) { _('Milestone lists not available with your current license') } },
unless: -> { board&.resource_parent&.feature_available?(:board_milestone_lists) }
base.validates :list_type,
exclusion: { in: %w[iteration], message: -> (_object, _data) { _('Iteration lists not available with your current license') } },
unless: -> { board&.resource_parent&.feature_available?(:iterations) }
base.scope :without_types, ->(list_types) { where.not(list_type: list_types) }
end
......@@ -58,6 +64,8 @@ module EE
user.to_reference
when 'milestone'
milestone.title
when 'iteration'
iteration.title
else
super
end
......@@ -78,11 +86,11 @@ module EE
module ClassMethods
def destroyable_types
super + [:assignee, :milestone]
super + [:assignee, :milestone, :iteration]
end
def movable_types
super + [:assignee, :milestone]
super + [:assignee, :milestone, :iteration]
end
end
end
......
......@@ -8,6 +8,7 @@ RSpec.describe List do
describe 'relationships' do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:milestone) }
it { is_expected.to belong_to(:iteration) }
end
describe 'validations' do
......@@ -75,6 +76,33 @@ RSpec.describe List do
end
end
context 'when it is an iteration type' do
let(:iteration) { build(:iteration, title: 'awesome-iteration') }
subject { described_class.new(list_type: :iteration, iteration: iteration, board: board) }
it { is_expected.to be_destroyable }
it { is_expected.to be_movable }
describe 'validations' do
it { is_expected.to validate_presence_of(:iteration) }
it 'is invalid when feature is not available' do
stub_licensed_features(iterations: false)
expect(subject).to be_invalid
expect(subject.errors[:list_type])
.to contain_exactly('Iteration lists not available with your current license')
end
end
describe '#title' do
it 'returns the iteration title' do
expect(subject.title).to eq('awesome-iteration')
end
end
end
describe '#wip_limits_available?' do
let!(:project) { create(:project) }
let!(:group) { create(:group) }
......
......@@ -347,6 +347,7 @@ excluded_attributes:
- :board_id
- :label_id
- :milestone_id
- :iteration_id
epic:
- :start_date_sourcing_milestone_id
- :due_date_sourcing_milestone_id
......
......@@ -15417,6 +15417,9 @@ msgstr ""
msgid "Iteration changed to"
msgstr ""
msgid "Iteration lists not available with your current license"
msgstr ""
msgid "Iteration removed"
msgstr ""
......
......@@ -656,6 +656,7 @@ boards:
lists:
- user
- milestone
- iteration
- board
- label
- list_user_preferences
......
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