Commit a937d1c0 authored by Sarah Yasonik's avatar Sarah Yasonik Committed by Matthias Käppler

Add elements to incident page to render escalation info

Adds elements to html served by backend for frontend to
render incident status and escaltion policy. Includes
exposing permissions.

Moves feature flag check from EE to CE, to ensure the
page does not contain new elements if the feature is
disabled.
parent 9bdf73a5
...@@ -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,8 +155,7 @@ module AlertManagement ...@@ -155,8 +155,7 @@ 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 &&
alert.issue.escalation_status.status != alert.status alert.issue.escalation_status.status != alert.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) && issuable.supports_escalation? &&
user_has_permissions? && user_has_permissions? &&
issuable.supports_escalation? &&
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,34 +3,98 @@ ...@@ -3,34 +3,98 @@
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') }
using RSpec::Parameterized::TableSyntax
it 'contains keys related to issuables' do
where(:is_gitlab_com, :is_public, :is_admin, :expected_value) do expect(entity).to include(
true | true | true | true :scoped_labels_available, :supports_weight, :supports_iterations,
true | false | true | false :supports_escalation_policies
true | false | false | false )
false | false | true | false end
false | false | false | false
end it 'contains attributes related to the issue' do
with_them do expect(entity).to include(:supports_epic, :features_available, :request_cve_enabled_for_user)
before do end
allow(issue.project).to receive(:public?).and_return(is_public)
issue.project.add_maintainer(user) if is_admin it 'contains attributes related to the available features' do
allow(Gitlab).to receive(:com?).and_return(is_gitlab_com) expect(entity[:features_available]).to include(:health_status, :issue_weights, :epics)
end end
it 'uses the value from request_cve_enabled_for_user' do describe 'request_cve_enabled_for_user' do
data = subject.represent(issue, serializer: 'sidebar') using RSpec::Parameterized::TableSyntax
expect(data[:request_cve_enabled_for_user]).to eq(expected_value)
end where(:is_gitlab_com, :is_public, :is_admin, :expected_value) do
true | true | true | true
true | false | true | false
true | false | false | false
false | false | true | false
false | false | false | false
end
with_them do
before do
allow(issue.project).to receive(:public?).and_return(is_public)
issue.project.add_maintainer(user) if is_admin
allow(Gitlab).to receive(:com?).and_return(is_gitlab_com)
end
it 'uses the value from request_cve_enabled_for_user' do
expect(entity[: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
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