Skip to content
Snippets Groups Projects
Verified Commit 044509a7 authored by Coung Ngo's avatar Coung Ngo Committed by GitLab
Browse files

Merge branch 'akotte-add-iteration-quick-action' into 'master'

WorkItems: Add iteration quick action

See merge request !175556



Merged-by: default avatarCoung Ngo <cngo@gitlab.com>
Approved-by: Rajan Mistry's avatarRajan Mistry <rmistry@gitlab.com>
Approved-by: default avatarJay Montal <jmontal@gitlab.com>
Approved-by: Alex Buijs's avatarAlex Buijs <abuijs@gitlab.com>
Approved-by: default avatarMax Fan <mfan@gitlab.com>
Reviewed-by: default avatarJay Montal <jmontal@gitlab.com>
Reviewed-by: default avatarMax Fan <mfan@gitlab.com>
Co-authored-by: default avatarAbhilash Kotte <akotte@gitlab.com>
parents 7dd7beab 2f30bcbb
No related branches found
No related tags found
2 merge requests!181325Fix ambiguous `created_at` in project.rb,!175556WorkItems: Add iteration quick action
Pipeline #1594262807 failed
Pipeline: E2E Omnibus GitLab EE

#1594308095

    Pipeline: E2E CNG

    #1594308069

      Pipeline: E2E GDK

      #1594300589

        +31
        ......@@ -159,6 +159,13 @@ export const autocompleteDataSources = ({ fullPath, iid, workItemTypeId, isGroup
        workItemTypeId,
        isGroup,
        }),
        iterations: autocompleteSourcesPath({
        autocompleteType: 'iterations',
        fullPath,
        iid,
        workItemTypeId,
        isGroup,
        }),
        });
        export const markdownPreviewPath = ({ fullPath, iid, isGroup = false }) => {
        ......
        ......@@ -153,6 +153,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
        enable :admin_issue_board
        enable :admin_issue_board_list
        enable :admin_issue
        enable :admin_work_item
        enable :update_issue
        enable :destroy_issue
        enable :read_confidential_issues
        ......@@ -244,6 +245,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
        enable :admin_milestone
        enable :admin_issue_board_list
        enable :admin_issue
        enable :admin_work_item
        enable :update_issue
        enable :read_prometheus
        enable :read_package
        ......
        ......@@ -399,6 +399,7 @@ class ProjectPolicy < BasePolicy
        enable :update_issue
        enable :reopen_issue
        enable :admin_issue
        enable :admin_work_item
        enable :destroy_issue
        enable :read_confidential_issues
        enable :create_design
        ......@@ -440,6 +441,7 @@ class ProjectPolicy < BasePolicy
        enable :update_issue
        enable :reopen_issue
        enable :admin_issue
        enable :admin_work_item
        enable :admin_label
        enable :admin_milestone
        enable :admin_issue_board_list
        ......
        ......@@ -4,6 +4,14 @@ module WorkItems
        module Widgets
        class Iteration < Base
        delegate :iteration, to: :work_item
        def self.quick_action_commands
        [:iteration, :remove_iteration]
        end
        def self.quick_action_params
        [:iteration]
        end
        end
        end
        end
        # frozen_string_literal: true
        require 'spec_helper'
        RSpec.describe WorkItems::Widgets::Iteration, feature_category: :team_planning do
        let_it_be(:work_item) { create(:work_item, :issue) }
        describe '#iteration' do
        subject { described_class.new(work_item).iteration }
        it { is_expected.to eq(work_item.iteration) }
        end
        describe '.quick_action_params' do
        subject { described_class.quick_action_params }
        it { is_expected.to match_array([:iteration]) }
        end
        describe '.quick_action_commands' do
        subject { described_class.quick_action_commands }
        it { is_expected.to match_array([:iteration, :remove_iteration]) }
        end
        end
        ......@@ -428,6 +428,7 @@
        let_it_be(:root_group) { create(:group, :private) }
        let_it_be(:group) { create(:group, :private, parent: root_group) }
        let_it_be(:project) { create(:project, :private, :repository, group: group) }
        let_it_be_with_reload(:work_item_issue) { create(:work_item, project: project) }
        context 'when iterations are enabled' do
        before do
        ......@@ -451,35 +452,35 @@
        expect(message).to eq(_("Could not apply iteration command. Failed to find the referenced iteration."))
        end
        it 'assigns an iteration to an issue' do
        _, updates, message = service.execute(content, issue)
        expect(updates).to eq(iteration: iteration)
        expect(message).to eq("Set the iteration to #{iteration.to_reference}.")
        end
        context 'when iteration is started' do
        before do
        iteration.start!
        shared_examples 'assigns iteration' do |factory|
        let(:issuable) do
        factory == :issue ? issue : build(factory, project: project)
        end
        it 'assigns an iteration to an issue' do
        _, updates, message = service.execute(content, issue)
        it 'assigns an iteration' do
        _, updates, message = service.execute(content, issuable)
        expect(updates).to eq(iteration: iteration)
        expect(message).to eq("Set the iteration to #{iteration.to_reference}.")
        end
        end
        context 'when issuable is an incident' do
        let(:incident) { create(:incident, project: project) }
        it_behaves_like 'assigns iteration', :issue
        it 'assigns an iteration' do
        _, updates, message = service.execute(content, incident)
        context 'when issuable is a work item' do
        it_behaves_like 'assigns iteration', :work_item
        end
        expect(updates).to eq(iteration: iteration)
        expect(message).to eq("Set the iteration to #{iteration.to_reference}.")
        context 'when issuable is an incident' do
        it_behaves_like 'assigns iteration', :incident
        end
        context 'when iteration is started' do
        before do
        iteration.start!
        end
        it_behaves_like 'assigns iteration', :issue
        end
        end
        ......@@ -487,13 +488,16 @@
        before do
        allow(current_user).to receive(:can?).with(:use_quick_actions).and_return(true)
        allow(current_user).to receive(:can?).with(:admin_issue, project).and_return(false)
        allow(current_user).to receive(:can?).with(:admin_work_item, project).and_return(false)
        end
        it 'returns an error message' do
        _, updates, message = service.execute(content, issue)
        [issue, work_item_issue].each do |issuable|
        _, updates, message = service.execute(content, issuable)
        expect(updates).to be_empty
        expect(message).to eq('Could not apply iteration command.')
        expect(updates).to be_empty
        expect(message).to eq('Could not apply iteration command.')
        end
        end
        end
        end
        ......@@ -653,35 +657,43 @@
        issue.update!(iteration: iteration)
        end
        it 'removes an assigned iteration from an issue' do
        _, updates, message = service.execute(content, issue)
        expect(updates).to eq(iteration: nil)
        expect(message).to eq("Removed #{iteration.to_reference} iteration.")
        end
        context 'when issuable is an incident' do
        let(:incident) { create(:incident, project: project, iteration: iteration) }
        shared_examples 'removes iteration' do |factory|
        let(:issuable) { create(factory, project: project, iteration: iteration) }
        it 'removes an assigned iteration' do
        _, updates, message = service.execute(content, incident)
        _, updates, message = service.execute(content, issuable)
        expect(updates).to eq(iteration: nil)
        expect(message).to eq("Removed #{iteration.to_reference} iteration.")
        end
        end
        it_behaves_like 'removes iteration', :issue
        context 'when issuable is a work item' do
        it_behaves_like 'removes iteration', :work_item
        end
        context 'when issuable is an incident' do
        it_behaves_like 'removes iteration', :incident
        end
        context 'when the user does not have enough permissions' do
        before do
        allow(current_user).to receive(:can?).with(:use_quick_actions).and_return(true)
        allow(current_user).to receive(:can?).with(:admin_issue, project).and_return(false)
        allow(current_user).to receive(:can?).with(:admin_work_item, project).and_return(false)
        end
        let_it_be(:work_item_issue) { create(:work_item, :issue, project: project, iteration: iteration) }
        it 'returns an error message' do
        _, updates, message = service.execute(content, issue)
        [issue, work_item_issue].each do |issuable|
        _, updates, message = service.execute(content, issuable)
        expect(updates).to be_empty
        expect(message).to eq('Could not apply remove_iteration command.')
        expect(updates).to be_empty
        expect(message).to eq('Could not apply remove_iteration command.')
        end
        end
        end
        end
        ......
        ......@@ -48,6 +48,8 @@ describe('autocompleteDataSources', () => {
        epics: '/foobar/project/group/-/autocomplete_sources/epics?type=WorkItem&work_item_type_id=2',
        milestones:
        '/foobar/project/group/-/autocomplete_sources/milestones?type=WorkItem&work_item_type_id=2',
        iterations:
        '/foobar/project/group/-/autocomplete_sources/iterations?type=WorkItem&work_item_type_id=2',
        });
        });
        ......@@ -61,6 +63,7 @@ describe('autocompleteDataSources', () => {
        '/foobar/project/group/-/autocomplete_sources/merge_requests?type=WorkItem&type_id=2',
        epics: '/foobar/project/group/-/autocomplete_sources/epics?type=WorkItem&type_id=2',
        milestones: '/foobar/project/group/-/autocomplete_sources/milestones?type=WorkItem&type_id=2',
        iterations: '/foobar/project/group/-/autocomplete_sources/iterations?type=WorkItem&type_id=2',
        });
        });
        ......@@ -86,6 +89,8 @@ describe('autocompleteDataSources', () => {
        epics: '/foobar/groups/group/-/autocomplete_sources/epics?type=WorkItem&work_item_type_id=2',
        milestones:
        '/foobar/groups/group/-/autocomplete_sources/milestones?type=WorkItem&work_item_type_id=2',
        iterations:
        '/foobar/groups/group/-/autocomplete_sources/iterations?type=WorkItem&work_item_type_id=2',
        });
        });
        ......@@ -105,6 +110,7 @@ describe('autocompleteDataSources', () => {
        '/foobar/groups/group/-/autocomplete_sources/merge_requests?type=WorkItem&type_id=2',
        epics: '/foobar/groups/group/-/autocomplete_sources/epics?type=WorkItem&type_id=2',
        milestones: '/foobar/groups/group/-/autocomplete_sources/milestones?type=WorkItem&type_id=2',
        iterations: '/foobar/groups/group/-/autocomplete_sources/iterations?type=WorkItem&type_id=2',
        });
        });
        });
        ......
        ......@@ -39,7 +39,7 @@
        let(:planner_permissions) do
        guest_permissions + %i[
        admin_label admin_milestone admin_issue_board admin_issue_board_list
        admin_issue update_issue destroy_issue read_confidential_issues read_internal_note
        admin_issue admin_work_item update_issue destroy_issue read_confidential_issues read_internal_note
        read_crm_contact read_crm_organization
        ]
        end
        ......@@ -49,6 +49,7 @@
        admin_label
        admin_milestone
        admin_issue_board
        admin_work_item
        read_container_image
        read_harbor_registry
        read_prometheus
        ......
        ......@@ -37,7 +37,7 @@
        let(:planner_permissions) do
        base_guest_permissions +
        %i[
        admin_issue admin_issue_board admin_issue_board_list admin_label admin_milestone
        admin_issue admin_work_item admin_issue_board admin_issue_board_list admin_label admin_milestone
        read_confidential_issues update_issue reopen_issue destroy_issue read_internal_note
        download_wiki_code create_wiki admin_wiki export_work_items
        ]
        ......@@ -45,7 +45,7 @@
        let(:base_reporter_permissions) do
        %i[
        admin_issue admin_label admin_milestone admin_issue_board_list
        admin_issue admin_work_item admin_label admin_milestone admin_issue_board_list
        create_snippet create_incident daily_statistics create_merge_request_in download_code
        download_wiki_code fork_project metrics_dashboard read_build
        read_commit_status read_confidential_issues read_container_image
        ......
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment