Commit 710b3c9d authored by Avielle Wolfe's avatar Avielle Wolfe Committed by Mark Chao

Refactor minutes UI methods

Some of the logic in `Ci::Minutes::Quota` is only used to determine
whether or not to show CI minutes information in the UI. This commit
refactors and renames that logic to make it more clear that it is being
used only for UI purposes.
parent f08c1f7a
......@@ -16,9 +16,7 @@ module Ci
end
def enabled?
strong_memoize(:enabled) do
namespace_eligible? && total_minutes.nonzero?
end
namespace_root? && total_minutes.nonzero?
end
# Status of the monthly allowance being used.
......@@ -50,28 +48,34 @@ module Ci
enabled? && total_minutes_used >= total_minutes
end
def total_minutes
@total_minutes ||= monthly_minutes + purchased_minutes
def percent_total_minutes_remaining
return 0 if total_minutes == 0
100 * total_minutes_remaining.to_i / total_minutes
end
def total_minutes_used
@total_minutes_used ||= namespace.shared_runners_seconds.to_i / 60
def current_balance
total_minutes.to_i - total_minutes_used
end
def percent_total_minutes_remaining
return 0 if total_minutes == 0
def display_shared_runners_data?
namespace_root? && any_project_enabled?
end
100 * total_minutes_remaining.to_i / total_minutes
def display_minutes_available_data?
display_shared_runners_data? && total_minutes.nonzero?
end
def namespace_eligible?
strong_memoize(:namespace_eligible) do
namespace.root?
def total_minutes
strong_memoize(:total_minutes) do
monthly_minutes + purchased_minutes
end
end
def current_balance
total_minutes.to_i - total_minutes_used
def total_minutes_used
strong_memoize(:total_minutes_used) do
namespace.shared_runners_seconds.to_i / 60
end
end
def any_project_enabled?
......@@ -82,13 +86,15 @@ module Ci
private
attr_reader :namespace
def minutes_limit
return monthly_minutes if enabled? && any_project_enabled?
return _('Not supported') unless display_shared_runners_data?
if namespace_eligible? && any_project_enabled?
_('Unlimited')
if display_minutes_available_data?
monthly_minutes
else
_('Not supported')
_('Unlimited')
end
end
......@@ -137,14 +143,22 @@ module Ci
end
def monthly_minutes
@monthly_minutes ||= (namespace.shared_runners_minutes_limit || ::Gitlab::CurrentSettings.shared_runners_minutes).to_i
strong_memoize(:monthly_minutes) do
(namespace.shared_runners_minutes_limit || ::Gitlab::CurrentSettings.shared_runners_minutes).to_i
end
end
def purchased_minutes
@purchased_minutes ||= namespace.extra_shared_runners_minutes_limit.to_i
strong_memoize(:purchased_minutes) do
namespace.extra_shared_runners_minutes_limit.to_i
end
end
attr_reader :namespace
def namespace_root?
strong_memoize(:namespace_root) do
namespace.root?
end
end
end
end
end
......@@ -5,7 +5,7 @@
- return unless minutes_quota.enabled?
- if minutes_quota.namespace_eligible? && minutes_quota.any_project_enabled?
- if minutes_quota.display_shared_runners_data?
%li
%span.light= _('Additional minutes:')
%strong
......
- namespace = local_assigns.fetch(:namespace)
- minutes_quota = namespace.ci_minutes_quota
- if minutes_quota.namespace_eligible? && minutes_quota.any_project_enabled?
- if minutes_quota.display_shared_runners_data?
%li
%span.light= _('Pipeline minutes quota:')
%strong
......
- return unless Gitlab.com?
- minutes_quota = namespace.ci_minutes_quota
- return unless minutes_quota.enabled? && minutes_quota.purchased_minutes_report.limit > 0 && minutes_quota.any_project_enabled?
- return unless minutes_quota.display_minutes_available_data? && minutes_quota.purchased_minutes_report.limit > 0
.row
.col-sm-6
......
......@@ -26,7 +26,7 @@
= link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'shared-runners-pipeline-minutes-quota'), target: '_blank', 'aria-label': _('Shared runners help link')
.col-sm-6.right
- if minutes_quota.enabled? && minutes_quota.any_project_enabled?
- if minutes_quota.display_minutes_available_data?
#{minutes_quota.monthly_percent_used}% used
- elsif !minutes_quota.any_project_enabled?
0% used
......
......@@ -5,7 +5,7 @@ RSpec.describe Ci::Minutes::Quota do
using RSpec::Parameterized::TableSyntax
let_it_be_with_reload(:namespace) do
create(:namespace, namespace_statistics: create(:namespace_statistics))
create(:group, namespace_statistics: create(:namespace_statistics))
end
let(:quota) { described_class.new(namespace) }
......@@ -67,7 +67,7 @@ RSpec.describe Ci::Minutes::Quota do
context 'when the quota is not enabled' do
before do
allow(quota).to receive(:enabled?).and_return(false)
allow(quota).to receive(:namespace_eligible?).and_return(namespace_eligible)
allow(namespace).to receive(:root?).and_return(namespace_eligible)
allow(namespace).to receive(:any_project_with_shared_runners_enabled?).and_return(true)
end
......@@ -394,69 +394,101 @@ RSpec.describe Ci::Minutes::Quota do
end
end
describe '#namespace_eligible?' do
subject { quota.namespace_eligible? }
describe '#any_project_enabled?' do
let_it_be(:project) { create(:project, namespace: namespace) }
context 'when namespace is a subgroup' do
it 'is false' do
allow(namespace).to receive(:root?).and_return(false)
context 'when namespace has any project with shared runners enabled' do
before do
project.update!(shared_runners_enabled: true)
end
expect(subject).to be_falsey
it 'returns true' do
expect(quota.any_project_enabled?).to be_truthy
end
end
context 'when namespace is root' do
it 'is true' do
expect(subject).to be_truthy
context 'when namespace has no projects with shared runners enabled' do
before do
project.update!(shared_runners_enabled: false)
end
it 'returns false' do
expect(quota.any_project_enabled?).to be_falsey
end
end
it 'does not trigger additional queries when called multiple times' do
# memoizes the result
quota.namespace_eligible?
quota.any_project_enabled?
# count
actual = ActiveRecord::QueryRecorder.new do
quota.namespace_eligible?
quota.any_project_enabled?
end
expect(actual.count).to eq(0)
end
end
describe '#any_project_enabled?' do
let_it_be(:project) { create(:project, namespace: namespace) }
describe '#display_shared_runners_data?' do
let_it_be(:project) { create(:project, namespace: namespace, shared_runners_enabled: true) }
context 'when namespace has any project with shared runners enabled' do
subject { quota.display_shared_runners_data? }
context 'when the namespace is root and it has a project with shared runners enabled' do
it { is_expected.to be_truthy }
end
context 'when the namespace is not root' do
let(:namespace) { create(:group, :nested) }
it { is_expected.to be_falsey }
end
context 'when the namespaces has no project with shared runners enabled' do
before do
project.update!(shared_runners_enabled: true)
project.update!(shared_runners_enabled: false)
end
it 'returns true' do
expect(quota.any_project_enabled?).to be_truthy
it { is_expected.to be_falsey }
end
end
context 'when namespace has no projects with shared runners enabled' do
describe '#display_minutes_available_data?' do
let_it_be(:project) { create(:project, namespace: namespace, shared_runners_enabled: true) }
subject { quota.display_minutes_available_data? }
context 'when the namespace is root and it has a project with shared runners enabled' do
context 'when there is a minutes limit' do
before do
project.update!(shared_runners_enabled: false)
namespace.update!(shared_runners_minutes_limit: 200)
end
it 'returns false' do
expect(quota.any_project_enabled?).to be_falsey
it { is_expected.to be_truthy }
end
context 'when there is no minutes limit' do
before do
namespace.update!(shared_runners_minutes_limit: 0)
end
it 'does not trigger additional queries when called multiple times' do
# memoizes the result
quota.any_project_enabled?
it { is_expected.to be_falsey }
end
end
# count
actual = ActiveRecord::QueryRecorder.new do
quota.any_project_enabled?
context 'when the namespace is not root' do
let(:namespace) { create(:group, :nested) }
it { is_expected.to be_falsey }
end
expect(actual.count).to eq(0)
context 'when the namespaces has no project with shared runners enabled' do
before do
project.update!(shared_runners_enabled: false)
end
it { is_expected.to be_falsey }
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