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
project = issue.project
authorize_escalation_status!(project)
check_feature_availability!(project, issue)
check_feature_availability!(issue)
::Issues::UpdateService.new(
project: project,
......@@ -36,8 +36,8 @@ module Mutations
raise_resource_not_available_error!
end
def check_feature_availability!(project, issue)
return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation?
def check_feature_availability!(issue)
return if issue.supports_escalation?
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
end
......
......@@ -173,9 +173,7 @@ module Types
end
def escalation_status
return unless Feature.enabled?(:incident_escalations, object.project) && object.supports_escalation?
object.escalation_status&.status_name
object.supports_escalation? ? object.escalation_status&.status_name : nil
end
end
end
......
......@@ -194,6 +194,8 @@ module Issuable
end
def supports_escalation?
return false unless ::Feature.enabled?(:incident_escalations, project)
incident?
end
......
......@@ -110,6 +110,7 @@ class IssuableSidebarBasicEntity < Grape::Entity
expose :supports_time_tracking?, as: :supports_time_tracking
expose :supports_milestone?, as: :supports_milestone
expose :supports_severity?, as: :supports_severity
expose :supports_escalation?, as: :supports_escalation
private
......
......@@ -4,6 +4,12 @@ class IssueSidebarBasicEntity < IssuableSidebarBasicEntity
expose :due_date
expose :confidential
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
IssueSidebarBasicEntity.prepend_mod_with('IssueSidebarBasicEntity')
......@@ -155,8 +155,7 @@ module AlertManagement
end
def should_sync_to_incident?
Feature.enabled?(:incident_escalations, project) &&
alert.issue &&
alert.issue &&
alert.issue.supports_escalation? &&
alert.issue.escalation_status &&
alert.issue.escalation_status.status != alert.status
......
......@@ -33,9 +33,8 @@ module IncidentManagement
attr_reader :issuable, :current_user, :params, :project
def available?
Feature.enabled?(:incident_escalations, project) &&
issuable.supports_escalation? &&
user_has_permissions? &&
issuable.supports_escalation? &&
escalation_status.present?
end
......
......@@ -25,6 +25,11 @@
.block.reviewer.qa-reviewer-block
= 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?
= 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
project = issue.project
authorize_escalation_status!(project)
check_feature_availability!(project, issue)
check_feature_availability!(issue)
::Issues::UpdateService.new(
project: project,
......@@ -39,8 +39,8 @@ module Mutations
raise_resource_not_available_error!
end
def check_feature_availability!(project, issue)
return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation?
def check_feature_availability!(issue)
return if issue.supports_escalation? && issue.alert_management_alert.blank?
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
end
......
......@@ -28,7 +28,6 @@ module EE
end
def escalation_policies_available?
return false unless ::Feature.enabled?(:incident_escalations, project)
return false unless ::Gitlab::IncidentManagement.escalation_policies_available?(project)
supports_escalation?
......
......@@ -11,6 +11,7 @@ module EE
expose :supports_weight?, as: :supports_weight
expose :supports_iterations?, as: :supports_iterations
expose :escalation_policies_available?, as: :supports_escalation_policies
end
end
end
......@@ -25,6 +25,13 @@ module EE
&& issue.project.public? \
&& issue.project.project_setting.cve_id_request_enabled?
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
- 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 @@
require 'spec_helper'
RSpec.describe EE::IssueSidebarBasicEntity do
let(:admin) { create(:admin) }
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, assignees: [user]) }
let(:subject) { IssueSerializer.new(current_user: user, project: project) }
context "When serializing" do
context "with the cve_id_request_button" do
using RSpec::Parameterized::TableSyntax
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
data = subject.represent(issue, serializer: 'sidebar')
expect(data[:request_cve_enabled_for_user]).to eq(expected_value)
end
let_it_be(:admin) { create(:admin) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:issue, reload: true) { 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(
: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
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
......
......@@ -2,7 +2,7 @@
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) }
subject(:rendered) do
......@@ -13,13 +13,15 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do
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 supports iterations' do
let(:issuable) { create(:issue, project: project) }
let(:issuable) { issue }
it 'shows iteration dropdown' do
expect(rendered).to have_css('[data-testid="iteration_container"]')
......@@ -27,12 +29,32 @@ RSpec.describe 'shared/issuable/_iterations_dropdown.html.haml' do
end
context 'issuable does not support iterations' do
let(:issuable) { create(:incident, project: project) }
let(:issuable) { incident }
it 'does not show iteration dropdown' do
expect(rendered).not_to have_css('[data-testid="iteration_container"]')
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
context 'non-group project' do
......
......@@ -935,6 +935,14 @@ RSpec.describe Issuable do
subject { issuable.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
......
# 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