Commit 25536b04 authored by Brandon Labuschagne's avatar Brandon Labuschagne Committed by charlie ablett

Group devops adoption controller and nav

This commit introduces the group level devops
adoption controller and navigation. It does so
behind the group_devops_adoption_flag feature.
parent 772b9df8
---
name: group_devops_adoption
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55039
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323159
milestone: '13.10'
type: development
group: group::optimize
default_enabled: false
# frozen_string_literal: true
class Groups::Analytics::DevopsAdoptionController < Groups::Analytics::ApplicationController
layout 'group'
before_action :load_group
before_action -> { authorize_view_by_action!(:view_group_devops_adoption) }
def show
end
end
...@@ -19,6 +19,7 @@ module EE ...@@ -19,6 +19,7 @@ module EE
def group_analytics_navbar_links(group, current_user) def group_analytics_navbar_links(group, current_user)
super + [ super + [
group_ci_cd_analytics_navbar_link(group, current_user), group_ci_cd_analytics_navbar_link(group, current_user),
group_devops_adoption_navbar_link(group, current_user),
group_repository_analytics_navbar_link(group, current_user), group_repository_analytics_navbar_link(group, current_user),
contribution_analytics_navbar_link(group, current_user), contribution_analytics_navbar_link(group, current_user),
group_insights_navbar_link(group, current_user), group_insights_navbar_link(group, current_user),
...@@ -74,6 +75,16 @@ module EE ...@@ -74,6 +75,16 @@ module EE
) )
end end
def group_devops_adoption_navbar_link(group, current_user)
return unless group_sidebar_link?(:group_devops_adoption)
navbar_sub_item(
title: _('DevOps Adoption'),
path: 'groups/analytics/devops_adoption#show',
link: group_analytics_devops_adoption_path(group)
)
end
def productivity_analytics_navbar_link(group, current_user) def productivity_analytics_navbar_link(group, current_user)
return unless group_sidebar_link?(:productivity_analytics) return unless group_sidebar_link?(:productivity_analytics)
......
...@@ -151,6 +151,10 @@ module EE ...@@ -151,6 +151,10 @@ module EE
links << :group_ci_cd_analytics links << :group_ci_cd_analytics
end end
if can?(current_user, :view_group_devops_adoption, @group)
links << :group_devops_adoption
end
links links
end end
end end
......
...@@ -24,6 +24,7 @@ class License < ApplicationRecord ...@@ -24,6 +24,7 @@ class License < ApplicationRecord
group_activity_analytics group_activity_analytics
group_bulk_edit group_bulk_edit
group_webhooks group_webhooks
group_level_devops_adoption
instance_level_devops_adoption instance_level_devops_adoption
issuable_default_templates issuable_default_templates
issue_weights issue_weights
......
...@@ -37,6 +37,11 @@ module EE ...@@ -37,6 +37,11 @@ module EE
@subject.feature_available?(:group_activity_analytics) @subject.feature_available?(:group_activity_analytics)
end end
condition(:group_devops_adoption_available) do
::Feature.enabled?(:group_devops_adoption, @subject, default_enabled: :yaml) &&
@subject.feature_available?(:group_level_devops_adoption)
end
condition(:dora4_analytics_available) do condition(:dora4_analytics_available) do
@subject.feature_available?(:dora4_analytics) @subject.feature_available?(:dora4_analytics)
end end
...@@ -191,6 +196,10 @@ module EE ...@@ -191,6 +196,10 @@ module EE
enable :view_group_ci_cd_analytics enable :view_group_ci_cd_analytics
end end
rule { reporter & group_devops_adoption_available }.policy do
enable :view_group_devops_adoption
end
rule { owner & ~has_parent & prevent_group_forking_available }.policy do rule { owner & ~has_parent & prevent_group_forking_available }.policy do
enable :change_prevent_group_forking enable :change_prevent_group_forking
end end
......
...@@ -18,6 +18,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do ...@@ -18,6 +18,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
namespace :analytics do namespace :analytics do
resource :ci_cd_analytics, only: :show, path: 'ci_cd' resource :ci_cd_analytics, only: :show, path: 'ci_cd'
resource :devops_adoption, controller: :devops_adoption, only: :show
resource :productivity_analytics, only: :show resource :productivity_analytics, only: :show
resources :coverage_reports, only: :index resources :coverage_reports, only: :index
resource :merge_request_analytics, only: :show resource :merge_request_analytics, only: :show
......
...@@ -26,7 +26,7 @@ RSpec.describe 'Group navbar' do ...@@ -26,7 +26,7 @@ RSpec.describe 'Group navbar' do
stub_licensed_features(productivity_analytics: true) stub_licensed_features(productivity_analytics: true)
insert_after_sub_nav_item( insert_after_sub_nav_item(
_('Contribution'), _('DevOps Adoption'),
within: _('Analytics'), within: _('Analytics'),
new_sub_nav_item_name: _('Productivity') new_sub_nav_item_name: _('Productivity')
) )
...@@ -42,7 +42,7 @@ RSpec.describe 'Group navbar' do ...@@ -42,7 +42,7 @@ RSpec.describe 'Group navbar' do
stub_licensed_features(cycle_analytics_for_groups: true) stub_licensed_features(cycle_analytics_for_groups: true)
insert_after_sub_nav_item( insert_after_sub_nav_item(
_('Contribution'), _('DevOps Adoption'),
within: _('Analytics'), within: _('Analytics'),
new_sub_nav_item_name: _('Value Stream') new_sub_nav_item_name: _('Value Stream')
) )
......
...@@ -1497,4 +1497,51 @@ RSpec.describe GroupPolicy do ...@@ -1497,4 +1497,51 @@ RSpec.describe GroupPolicy do
include_context 'compliance framework permissions' include_context 'compliance framework permissions'
end end
end end
describe 'view_devops_adoption' do
let(:current_user) { owner }
let(:policy) { :view_group_devops_adoption }
context 'when feature is disabled' do
before do
stub_feature_flags(group_devops_adoption: false)
end
it { is_expected.to be_disallowed(policy) }
end
context 'when license does not include the feature' do
before do
stub_feature_flags(group_devops_adoption: true)
stub_licensed_features(group_level_devops_adoption: false)
end
it { is_expected.to be_disallowed(policy) }
end
context 'when feature is enabled and license include the feature' do
using RSpec::Parameterized::TableSyntax
where(:role, :allowed) do
:admin | true
:owner | true
:maintainer | true
:developer | true
:reporter | true
:guest | false
:non_group_member | false
end
before do
stub_feature_flags(group_devops_adoption: true)
stub_licensed_features(group_level_devops_adoption: true)
end
with_them do
let(:current_user) { public_send(role) }
it { is_expected.to(allowed ? be_allowed(policy) : be_disallowed(policy)) }
end
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Groups::Analytics::DevopsAdoptionController do
let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create :group }
before do
sign_in(current_user)
stub_licensed_features(group_level_devops_adoption: true)
stub_feature_flags(group_devops_adoption: true)
end
describe 'GET show' do
subject do
get group_analytics_devops_adoption_path(group)
end
before do
group.add_maintainer(current_user)
end
it 'renders the devops adoption page' do
subject
expect(response).to render_template :show
end
context 'when the feature flag is false' do
before do
stub_feature_flags(group_devops_adoption: false)
end
it 'renders forbidden' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when the feature is not available' do
before do
stub_licensed_features(group_level_devops_adoption: false)
end
it 'renders forbidden' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
end
...@@ -46,6 +46,64 @@ RSpec.describe 'layouts/nav/sidebar/_group' do ...@@ -46,6 +46,64 @@ RSpec.describe 'layouts/nav/sidebar/_group' do
end end
end end
describe 'DevOps adoption link' do
let!(:current_user) { create(:user) }
before do
group.add_maintainer(current_user)
allow(view).to receive(:current_user).and_return(current_user)
end
context 'DevOps adoption feature is available' do
before do
stub_licensed_features(group_level_devops_adoption: true)
end
it 'is visible' do
render
expect(rendered).to have_text 'DevOps Adoption'
end
context 'feature flag is disabled' do
before do
stub_feature_flags(group_devops_adoption: false)
end
it 'is not visible' do
render
expect(rendered).not_to have_text 'DevOps Adoption'
end
end
end
context 'DevOps apoption feature is not available' do
before do
stub_licensed_features(group_level_devops_adoption: false)
end
it 'is not visible' do
render
expect(rendered).not_to have_text 'DevOps Adoption'
end
context 'feature flag is disabled' do
before do
stub_feature_flags(group_devops_adoption: false)
end
it 'is not visible' do
render
expect(rendered).not_to have_text 'DevOps Adoption'
end
end
end
end
describe 'contribution analytics tab' do describe 'contribution analytics tab' do
let!(:current_user) { create(:user) } let!(:current_user) { create(:user) }
......
...@@ -10479,6 +10479,9 @@ msgstr "" ...@@ -10479,6 +10479,9 @@ msgstr ""
msgid "Detect host keys" msgid "Detect host keys"
msgstr "" msgstr ""
msgid "DevOps Adoption"
msgstr ""
msgid "DevOps Report" msgid "DevOps Report"
msgstr "" msgstr ""
......
...@@ -124,7 +124,8 @@ RSpec.shared_context 'group navbar structure' do ...@@ -124,7 +124,8 @@ RSpec.shared_context 'group navbar structure' do
{ {
nav_item: _('Analytics'), nav_item: _('Analytics'),
nav_sub_items: [ nav_sub_items: [
_('Contribution') _('Contribution'),
_('DevOps Adoption')
] ]
} }
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