Commit 88e4e3c2 authored by Stan Hu's avatar Stan Hu

Merge branch 'remove-current-user-in-ci-minutes-notification' into 'master'

Make Ci::Minutes::Notification user agnostic

See merge request gitlab-org/gitlab!33611
parents ff22031e bc401d36
...@@ -21,7 +21,7 @@ module EE ...@@ -21,7 +21,7 @@ module EE
strong_memoize(:show_out_of_ci_minutes_notification) do strong_memoize(:show_out_of_ci_minutes_notification) do
next unless project&.persisted? || namespace&.persisted? next unless project&.persisted? || namespace&.persisted?
::Ci::Minutes::Notification.new(current_user, project, namespace).show? ::Ci::Minutes::Notification.new(project, namespace).show?(current_user)
end end
end end
end end
......
...@@ -10,22 +10,17 @@ module Ci ...@@ -10,22 +10,17 @@ module Ci
delegate :last_ci_minutes_usage_notification_level, delegate :last_ci_minutes_usage_notification_level,
:shared_runners_remaining_minutes_percent, to: :namespace :shared_runners_remaining_minutes_percent, to: :namespace
def initialize(user, project, namespace) attr_reader :level
@user = user
def initialize(project, namespace)
@project = project @project = project
@namespace = project&.shared_runners_limit_namespace || namespace @namespace = project&.shared_runners_limit_namespace || namespace
@level = project || namespace @level = project || namespace
end end
def can_see_status?
return false unless level
Ability.allowed?(user, :read_ci_minutes_quota, level)
end
private private
attr_reader :project, :user, :level, :namespace attr_reader :project, :namespace
end end
end end
end end
...@@ -9,32 +9,35 @@ module Ci ...@@ -9,32 +9,35 @@ module Ci
exceeded: 0 exceeded: 0
}.freeze }.freeze
def initialize(user, project, namespace) def initialize(project, namespace)
@context = Ci::Minutes::Context.new(user, project, namespace) @context = Ci::Minutes::Context.new(project, namespace)
@level = calculate_level if eligible_for_notifications? @stage = calculate_notification_stage if eligible_for_notifications?
end end
def show? def show?(current_user)
level.present? return false unless @stage
return false unless @context.level
Ability.allowed?(current_user, :read_ci_minutes_quota, @context.level)
end end
def text def text
contextual_map.dig(level, :text) contextual_map.dig(stage, :text)
end end
def style def style
contextual_map.dig(level, :style) contextual_map.dig(stage, :style)
end end
private private
attr_reader :context, :level attr_reader :context, :stage
def eligible_for_notifications? def eligible_for_notifications?
context.shared_runners_minutes_limit_enabled? && context.can_see_status? context.shared_runners_minutes_limit_enabled?
end end
def calculate_level def calculate_notification_stage
percentage = context.shared_runners_remaining_minutes_percent.to_i percentage = context.shared_runners_remaining_minutes_percent.to_i
if percentage <= PERCENTAGES[:exceeded] if percentage <= PERCENTAGES[:exceeded]
...@@ -74,7 +77,7 @@ module Ci ...@@ -74,7 +77,7 @@ module Ci
" minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run.") % " minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run.") %
{ {
namespace_name: context.namespace_name, namespace_name: context.namespace_name,
percentage: PERCENTAGES[level] percentage: PERCENTAGES[stage]
} }
end end
end end
......
- notification = ::Ci::Minutes::Notification.new(current_user, local_assigns.dig(:project), local_assigns.dig(:namespace)) - notification = ::Ci::Minutes::Notification.new(local_assigns.dig(:project), local_assigns.dig(:namespace))
- return unless notification.show? - return unless notification.show?(current_user)
%div{ class: [(classes if defined? classes)] } %div{ class: [(classes if defined? classes)] }
.shared-runner-quota-message.gl-pt-5.gl-pb-3 .shared-runner-quota-message.gl-pt-5.gl-pb-3
......
...@@ -3,12 +3,11 @@ ...@@ -3,12 +3,11 @@
require 'spec_helper' require 'spec_helper'
describe Ci::Minutes::Context do describe Ci::Minutes::Context do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:project) { build(:project, namespace: group) } let(:project) { build(:project, namespace: group) }
describe 'delegation' do describe 'delegation' do
subject { described_class.new(user, project, group) } subject { described_class.new(project, group) }
it { is_expected.to delegate_method(:shared_runners_remaining_minutes_below_threshold?).to(:level) } it { is_expected.to delegate_method(:shared_runners_remaining_minutes_below_threshold?).to(:level) }
it { is_expected.to delegate_method(:shared_runners_minutes_used?).to(:level) } it { is_expected.to delegate_method(:shared_runners_minutes_used?).to(:level) }
...@@ -16,64 +15,4 @@ describe Ci::Minutes::Context do ...@@ -16,64 +15,4 @@ describe Ci::Minutes::Context do
it { is_expected.to delegate_method(:name).to(:namespace).with_prefix } it { is_expected.to delegate_method(:name).to(:namespace).with_prefix }
it { is_expected.to delegate_method(:last_ci_minutes_usage_notification_level).to(:namespace) } it { is_expected.to delegate_method(:last_ci_minutes_usage_notification_level).to(:namespace) }
end end
context 'when at project level' do
subject { described_class.new(user, project, nil) }
describe '#can_see_status' do
context 'when eligible to see status' do
before do
project.add_developer(user)
end
it 'can see status' do
expect(subject.can_see_status?).to be_truthy
end
end
context 'when not eligible to see status' do
it 'cannot see status' do
expect(subject.can_see_status?).to be_falsey
end
end
context 'when user is not authenticated' do
let(:user) { nil }
it 'cannot see status' do
expect(subject.can_see_status?).to be_falsey
end
end
end
end
context 'when at namespace level' do
subject { described_class.new(user, nil, group) }
describe '#can_see_status' do
context 'when eligible to see status' do
before do
group.add_developer(user)
end
it 'can see status' do
expect(subject.can_see_status?).to be_truthy
end
end
context 'when not eligible to see status' do
it 'cannot see status' do
expect(subject.can_see_status?).to be_falsey
end
end
context 'when user is not authenticated' do
let(:user) { nil }
it 'cannot see status' do
expect(subject.can_see_status?).to be_falsey
end
end
end
end
end end
...@@ -42,7 +42,7 @@ describe Ci::Minutes::Notification do ...@@ -42,7 +42,7 @@ describe Ci::Minutes::Notification do
end end
it 'has warning notification' do it 'has warning notification' do
expect(subject.show?).to be_truthy expect(subject.show?(user)).to be_truthy
expect(subject.text).to match(/.*\shas 30% or less Shared Runner Pipeline minutes remaining/) expect(subject.text).to match(/.*\shas 30% or less Shared Runner Pipeline minutes remaining/)
expect(subject.style).to eq :warning expect(subject.style).to eq :warning
end end
...@@ -54,7 +54,7 @@ describe Ci::Minutes::Notification do ...@@ -54,7 +54,7 @@ describe Ci::Minutes::Notification do
end end
it 'has danger notification' do it 'has danger notification' do
expect(subject.show?).to be_truthy expect(subject.show?(user)).to be_truthy
expect(subject.text).to match(/.*\shas 5% or less Shared Runner Pipeline minutes remaining/) expect(subject.text).to match(/.*\shas 5% or less Shared Runner Pipeline minutes remaining/)
expect(subject.style).to eq :danger expect(subject.style).to eq :danger
end end
...@@ -66,7 +66,7 @@ describe Ci::Minutes::Notification do ...@@ -66,7 +66,7 @@ describe Ci::Minutes::Notification do
end end
it 'has warning notification' do it 'has warning notification' do
expect(subject.show?).to be_truthy expect(subject.show?(user)).to be_truthy
expect(subject.text).to match(/.*\shas 30% or less Shared Runner Pipeline minutes remaining/) expect(subject.text).to match(/.*\shas 30% or less Shared Runner Pipeline minutes remaining/)
expect(subject.style).to eq :warning expect(subject.style).to eq :warning
end end
...@@ -76,7 +76,7 @@ describe Ci::Minutes::Notification do ...@@ -76,7 +76,7 @@ describe Ci::Minutes::Notification do
let(:group) { create(:group, :with_used_build_minutes_limit) } let(:group) { create(:group, :with_used_build_minutes_limit) }
it 'has exceeded notification' do it 'has exceeded notification' do
expect(subject.show?).to be_truthy expect(subject.show?(user)).to be_truthy
expect(subject.text).to match(/.*\shas exceeded its pipeline minutes quota/) expect(subject.text).to match(/.*\shas exceeded its pipeline minutes quota/)
expect(subject.style).to eq :danger expect(subject.style).to eq :danger
end end
...@@ -92,9 +92,7 @@ describe Ci::Minutes::Notification do ...@@ -92,9 +92,7 @@ describe Ci::Minutes::Notification do
context 'when not permitted to see notifications' do context 'when not permitted to see notifications' do
it 'has no notifications set' do it 'has no notifications set' do
expect(subject.show?).to be_falsey expect(subject.show?(user)).to be_falsey
expect(subject.text).to be_nil
expect(subject.style).to be_nil
end end
end end
end end
...@@ -108,18 +106,26 @@ describe Ci::Minutes::Notification do ...@@ -108,18 +106,26 @@ describe Ci::Minutes::Notification do
it_behaves_like 'queries for notifications' do it_behaves_like 'queries for notifications' do
subject do subject do
threshold = described_class.new(user, injected_project, nil) threshold = described_class.new(injected_project, nil)
threshold.show? threshold.show?(user)
end end
end end
it_behaves_like 'has notifications' do it_behaves_like 'has notifications' do
subject { described_class.new(user, injected_project, nil) } subject { described_class.new(injected_project, nil) }
end end
end end
it_behaves_like 'not eligible to see notifications' do it_behaves_like 'not eligible to see notifications' do
subject { described_class.new(user, injected_project, nil) } subject { described_class.new(injected_project, nil) }
end
context 'when user is not authenticated' do
let(:user) { nil }
it_behaves_like 'not eligible to see notifications' do
subject { described_class.new(injected_project, nil) }
end
end end
end end
end end
...@@ -134,26 +140,34 @@ describe Ci::Minutes::Notification do ...@@ -134,26 +140,34 @@ describe Ci::Minutes::Notification do
context 'with a project that has runners enabled inside namespace' do context 'with a project that has runners enabled inside namespace' do
it_behaves_like 'queries for notifications' do it_behaves_like 'queries for notifications' do
subject do subject do
threshold = described_class.new(user, nil, injected_group) threshold = described_class.new(nil, injected_group)
threshold.show? threshold.show?(user)
end end
end end
it_behaves_like 'has notifications' do it_behaves_like 'has notifications' do
subject { described_class.new(user, nil, injected_group) } subject { described_class.new(nil, injected_group) }
end end
end end
context 'with no projects that have runners enabled inside namespace' do context 'with no projects that have runners enabled inside namespace' do
it_behaves_like 'not eligible to see notifications' do it_behaves_like 'not eligible to see notifications' do
let(:shared_runners_enabled) { false } let(:shared_runners_enabled) { false }
subject { described_class.new(user, nil, injected_group) } subject { described_class.new(nil, injected_group) }
end end
end end
end end
it_behaves_like 'not eligible to see notifications' do it_behaves_like 'not eligible to see notifications' do
subject { described_class.new(user, nil, injected_group) } subject { described_class.new(nil, injected_group) }
end
context 'when user is not authenticated' do
let(:user) { nil }
it_behaves_like 'not eligible to see notifications' do
subject { described_class.new(injected_project, nil) }
end
end end
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