Commit eb2d5760 authored by Matthias Käppler's avatar Matthias Käppler

Merge branch 'add-incident-escalations-initial-data' into 'master'

Add elements to incident page to render escalation info

See merge request gitlab-org/gitlab!78926
parents 54ade9d7 a937d1c0
...@@ -14,7 +14,7 @@ module Mutations ...@@ -14,7 +14,7 @@ module Mutations
project = issue.project project = issue.project
authorize_escalation_status!(project) authorize_escalation_status!(project)
check_feature_availability!(project, issue) check_feature_availability!(issue)
::Issues::UpdateService.new( ::Issues::UpdateService.new(
project: project, project: project,
...@@ -36,8 +36,8 @@ module Mutations ...@@ -36,8 +36,8 @@ module Mutations
raise_resource_not_available_error! raise_resource_not_available_error!
end end
def check_feature_availability!(project, issue) def check_feature_availability!(issue)
return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation? return if issue.supports_escalation?
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue' raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
end end
......
...@@ -173,9 +173,7 @@ module Types ...@@ -173,9 +173,7 @@ module Types
end end
def escalation_status def escalation_status
return unless Feature.enabled?(:incident_escalations, object.project) && object.supports_escalation? object.supports_escalation? ? object.escalation_status&.status_name : nil
object.escalation_status&.status_name
end end
end end
end end
......
...@@ -194,6 +194,8 @@ module Issuable ...@@ -194,6 +194,8 @@ module Issuable
end end
def supports_escalation? def supports_escalation?
return false unless ::Feature.enabled?(:incident_escalations, project)
incident? incident?
end end
......
...@@ -110,6 +110,7 @@ class IssuableSidebarBasicEntity < Grape::Entity ...@@ -110,6 +110,7 @@ class IssuableSidebarBasicEntity < Grape::Entity
expose :supports_time_tracking?, as: :supports_time_tracking expose :supports_time_tracking?, as: :supports_time_tracking
expose :supports_milestone?, as: :supports_milestone expose :supports_milestone?, as: :supports_milestone
expose :supports_severity?, as: :supports_severity expose :supports_severity?, as: :supports_severity
expose :supports_escalation?, as: :supports_escalation
private private
......
...@@ -4,6 +4,12 @@ class IssueSidebarBasicEntity < IssuableSidebarBasicEntity ...@@ -4,6 +4,12 @@ class IssueSidebarBasicEntity < IssuableSidebarBasicEntity
expose :due_date expose :due_date
expose :confidential expose :confidential
expose :severity expose :severity
expose :current_user, merge: true do
expose :can_update_escalation_status, if: -> (issue, _) { issue.supports_escalation? } do |issue|
can?(current_user, :update_escalation_status, issue.project)
end
end
end end
IssueSidebarBasicEntity.prepend_mod_with('IssueSidebarBasicEntity') IssueSidebarBasicEntity.prepend_mod_with('IssueSidebarBasicEntity')
...@@ -155,7 +155,6 @@ module AlertManagement ...@@ -155,7 +155,6 @@ module AlertManagement
end end
def should_sync_to_incident? def should_sync_to_incident?
Feature.enabled?(:incident_escalations, project) &&
alert.issue && alert.issue &&
alert.issue.supports_escalation? && alert.issue.supports_escalation? &&
alert.issue.escalation_status && alert.issue.escalation_status &&
......
...@@ -33,9 +33,8 @@ module IncidentManagement ...@@ -33,9 +33,8 @@ module IncidentManagement
attr_reader :issuable, :current_user, :params, :project attr_reader :issuable, :current_user, :params, :project
def available? def available?
Feature.enabled?(:incident_escalations, project) &&
user_has_permissions? &&
issuable.supports_escalation? && issuable.supports_escalation? &&
user_has_permissions? &&
escalation_status.present? escalation_status.present?
end end
......
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
.block.reviewer.qa-reviewer-block .block.reviewer.qa-reviewer-block
= render "shared/issuable/sidebar_reviewers", issuable_sidebar: issuable_sidebar, reviewers: reviewers, signed_in: signed_in = render "shared/issuable/sidebar_reviewers", issuable_sidebar: issuable_sidebar, reviewers: reviewers, signed_in: signed_in
- if issuable_sidebar[:supports_escalation]
.block.escalation-status{ data: { testid: 'escalation_status_container' } }
#js-escalation-status{ data: { can_edit: issuable_sidebar.dig(:current_user, :can_update_escalation_status).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
= render_if_exists 'shared/issuable/sidebar_escalation_policy', issuable_sidebar: issuable_sidebar
- if @project.group.present? - if @project.group.present?
= render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
......
...@@ -17,7 +17,7 @@ module Mutations ...@@ -17,7 +17,7 @@ module Mutations
project = issue.project project = issue.project
authorize_escalation_status!(project) authorize_escalation_status!(project)
check_feature_availability!(project, issue) check_feature_availability!(issue)
::Issues::UpdateService.new( ::Issues::UpdateService.new(
project: project, project: project,
...@@ -39,8 +39,8 @@ module Mutations ...@@ -39,8 +39,8 @@ module Mutations
raise_resource_not_available_error! raise_resource_not_available_error!
end end
def check_feature_availability!(project, issue) def check_feature_availability!(issue)
return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation? return if issue.supports_escalation? && issue.alert_management_alert.blank?
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue' raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
end end
......
...@@ -28,7 +28,6 @@ module EE ...@@ -28,7 +28,6 @@ module EE
end end
def escalation_policies_available? def escalation_policies_available?
return false unless ::Feature.enabled?(:incident_escalations, project)
return false unless ::Gitlab::IncidentManagement.escalation_policies_available?(project) return false unless ::Gitlab::IncidentManagement.escalation_policies_available?(project)
supports_escalation? supports_escalation?
......
...@@ -11,6 +11,7 @@ module EE ...@@ -11,6 +11,7 @@ module EE
expose :supports_weight?, as: :supports_weight expose :supports_weight?, as: :supports_weight
expose :supports_iterations?, as: :supports_iterations expose :supports_iterations?, as: :supports_iterations
expose :escalation_policies_available?, as: :supports_escalation_policies
end end
end end
end end
...@@ -25,6 +25,13 @@ module EE ...@@ -25,6 +25,13 @@ module EE
&& issue.project.public? \ && issue.project.public? \
&& issue.project.project_setting.cve_id_request_enabled? && issue.project.project_setting.cve_id_request_enabled?
end end
expose :current_user, merge: true do
expose :can_update_escalation_policy, if: -> (issue, _) { issue.escalation_policies_available? } do |issue|
can?(current_user, :update_escalation_status, issue.project) &&
issue.alert_management_alert.blank?
end
end
end end
end end
end end
- if issuable_sidebar[:supports_escalation_policies]
.block.escalation-policy{ data: { testid: 'escalation_policy_container' } }
#js-escalation-policy{ data: { can_edit: issuable_sidebar.dig(:current_user, :can_update_escalation_policy).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
...@@ -3,14 +3,31 @@ ...@@ -3,14 +3,31 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe EE::IssueSidebarBasicEntity do RSpec.describe EE::IssueSidebarBasicEntity do
let(:admin) { create(:admin) } let_it_be(:admin) { create(:admin) }
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, assignees: [user]) } let_it_be(:issue, reload: true) { create(:issue, project: project, assignees: [user]) }
let(:subject) { IssueSerializer.new(current_user: user, project: project) }
let(:serializer) { IssueSerializer.new(current_user: user, project: project) }
context "When serializing" do
context "with the cve_id_request_button" do subject(:entity) { serializer.represent(issue, serializer: 'sidebar') }
it 'contains keys related to issuables' do
expect(entity).to include(
:scoped_labels_available, :supports_weight, :supports_iterations,
:supports_escalation_policies
)
end
it 'contains attributes related to the issue' do
expect(entity).to include(:supports_epic, :features_available, :request_cve_enabled_for_user)
end
it 'contains attributes related to the available features' do
expect(entity[:features_available]).to include(:health_status, :issue_weights, :epics)
end
describe 'request_cve_enabled_for_user' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:is_gitlab_com, :is_public, :is_admin, :expected_value) do where(:is_gitlab_com, :is_public, :is_admin, :expected_value) do
...@@ -28,9 +45,56 @@ RSpec.describe EE::IssueSidebarBasicEntity do ...@@ -28,9 +45,56 @@ RSpec.describe EE::IssueSidebarBasicEntity do
end end
it 'uses the value from request_cve_enabled_for_user' do it 'uses the value from request_cve_enabled_for_user' do
data = subject.represent(issue, serializer: 'sidebar') expect(entity[:request_cve_enabled_for_user]).to eq(expected_value)
expect(data[:request_cve_enabled_for_user]).to eq(expected_value) end
end
end
describe 'can_update_escalation_policy' do
before do
issue.update!(issue_type: Issue.issue_types[:incident])
stub_licensed_features(oncall_schedules: true, escalation_policies: true)
project.add_developer(user)
end
it 'is present and true' do
expect(entity[:current_user][:can_update_escalation_policy]).to be(true)
end
context 'for a standard issue' do
subject(:entity) { serializer.represent(create(:issue, project: project), serializer: 'sidebar') }
it 'is not present' do
expect(entity[:current_user]).not_to have_key(:can_update_escalation_policy)
end
end
context 'with escalations policies disabled' do
before do
stub_licensed_features(escalation_policies: false)
end
it 'is not present' do
expect(entity[:current_user]).not_to have_key(:can_update_escalation_policy)
end
end end
context 'without permissions' do
let(:serializer) { IssueSerializer.new(current_user: create(:user), project: project) }
it 'is present and false' do
expect(entity[:current_user]).to have_key(:can_update_escalation_policy)
expect(entity[:current_user][:can_update_escalation_policy]).to be(false)
end
end
context 'with :incident_escalations feature flag disabled' do
before do
stub_feature_flags(incident_escalations: false)
end
it 'is not present' do
expect(entity[:current_user]).not_to include(:can_update_escalation_policy)
end end
end end
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do RSpec.describe 'shared/issuable/_sidebar.html.haml' do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
subject(:rendered) do subject(:rendered) do
...@@ -13,13 +13,15 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do ...@@ -13,13 +13,15 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do
context 'project in a group' do context 'project in a group' do
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) } let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:incident) { create(:incident, project: project) }
before do before do
assign(:project, project) assign(:project, project)
end end
context 'issuable that supports iterations' do context 'issuable that supports iterations' do
let(:issuable) { create(:issue, project: project) } let(:issuable) { issue }
it 'shows iteration dropdown' do it 'shows iteration dropdown' do
expect(rendered).to have_css('[data-testid="iteration_container"]') expect(rendered).to have_css('[data-testid="iteration_container"]')
...@@ -27,12 +29,32 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do ...@@ -27,12 +29,32 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do
end end
context 'issuable does not support iterations' do context 'issuable does not support iterations' do
let(:issuable) { create(:incident, project: project) } let(:issuable) { incident }
it 'does not show iteration dropdown' do it 'does not show iteration dropdown' do
expect(rendered).not_to have_css('[data-testid="iteration_container"]') expect(rendered).not_to have_css('[data-testid="iteration_container"]')
end end
end end
context 'issuable that does not support escalation policies' do
let(:issuable) { incident }
before do
stub_licensed_features(oncall_schedules: true, escalation_policies: true)
end
it 'shows escalation policy dropdown' do
expect(rendered).to have_css('[data-testid="escalation_policy_container"]')
end
end
context 'issuable that supports escalation policies' do
let(:issuable) { issue }
it 'does not show escalation policy dropdown' do
expect(rendered).not_to have_css('[data-testid="escalation_policy_container"]')
end
end
end end
context 'non-group project' do context 'non-group project' do
......
...@@ -935,6 +935,14 @@ RSpec.describe Issuable do ...@@ -935,6 +935,14 @@ RSpec.describe Issuable do
subject { issuable.supports_escalation? } subject { issuable.supports_escalation? }
it { is_expected.to eq(supports_escalation) } it { is_expected.to eq(supports_escalation) }
context 'with feature disabled' do
before do
stub_feature_flags(incident_escalations: false)
end
it { is_expected.to eq(false) }
end
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe IssueSidebarBasicEntity do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user, developer_projects: [project]) }
let_it_be(:issue) { create(:issue, project: project, assignees: [user]) }
let(:serializer) { IssueSerializer.new(current_user: user, project: project) }
subject(:entity) { serializer.represent(issue, serializer: 'sidebar') }
it 'contains keys related to issuables' do
expect(entity).to include(
:id, :iid, :type, :author_id, :project_id, :discussion_locked, :reference, :milestone,
:labels, :current_user, :issuable_json_path, :namespace_path, :project_path,
:project_full_path, :project_issuables_path, :create_todo_path, :project_milestones_path,
:project_labels_path, :toggle_subscription_path, :move_issue_path, :projects_autocomplete_path,
:project_emails_disabled, :create_note_email, :supports_time_tracking, :supports_milestone,
:supports_severity, :supports_escalation
)
end
it 'contains attributes related to the issue' do
expect(entity).to include(:due_date, :confidential, :severity)
end
describe 'current_user' do
it 'contains attributes related to the current user' do
expect(entity[:current_user]).to include(
:id, :name, :username, :state, :avatar_url, :web_url, :todo,
:can_edit, :can_move, :can_admin_label
)
end
describe 'can_update_escalation_status' do
context 'for a standard issue' do
it 'is not present' do
expect(entity[:current_user]).not_to have_key(:can_update_escalation_status)
end
end
context 'for an incident issue' do
before do
issue.update!(issue_type: Issue.issue_types[:incident])
end
it 'is present and true' do
expect(entity[:current_user][:can_update_escalation_status]).to be(true)
end
context 'without permissions' do
let(:serializer) { IssueSerializer.new(current_user: create(:user), project: project) }
it 'is present and false' do
expect(entity[:current_user]).to have_key(:can_update_escalation_status)
expect(entity[:current_user][:can_update_escalation_status]).to be(false)
end
end
context 'with :incident_escalations feature flag disabled' do
before do
stub_feature_flags(incident_escalations: false)
end
it 'is not present' do
expect(entity[:current_user]).not_to include(:can_update_escalation_status)
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'shared/issuable/_sidebar.html.haml' do
let_it_be(:user) { create(:user) }
subject(:rendered) do
render 'shared/issuable/sidebar', issuable_sidebar: IssueSerializer.new(current_user: user)
.represent(issuable, serializer: 'sidebar'), assignees: []
end
context 'project in a group' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:incident) { create(:incident, project: project) }
before do
assign(:project, project)
end
context 'issuable that does not support escalations' do
let(:issuable) { incident }
it 'shows escalation policy dropdown' do
expect(rendered).to have_css('[data-testid="escalation_status_container"]')
end
end
context 'issuable that supports escalations' do
let(:issuable) { issue }
it 'does not show escalation policy dropdown' do
expect(rendered).not_to have_css('[data-testid="escalation_status_container"]')
end
end
end
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