Commit 290004ef authored by Mark Florian's avatar Mark Florian Committed by Rémy Coutable
Browse files

Add/document alpha_feature_available? method

This adds and documents an `alpha_feature_available?` method to groups
and projects, and also documents the existing `beta_feature_available?`
method.
parent b4eeb72a
...@@ -38,7 +38,7 @@ Feature.enabled?(:feature_flag, project, default_enabled: true) ...@@ -38,7 +38,7 @@ Feature.enabled?(:feature_flag, project, default_enabled: true)
The [`Project#feature_available?`][project-fa], The [`Project#feature_available?`][project-fa],
[`Namespace#feature_available?`][namespace-fa] (EE), and [`Namespace#feature_available?`][namespace-fa] (EE), and
[`License.feature_available?`][license-fa] (EE) methods all implicitly check for [`License.feature_available?`][license-fa] (EE) methods all implicitly check for
a feature flag by the same name as the provided argument. a by default enabled feature flag with the same name as the provided argument.
   
For example if a feature is license-gated, there's no need to add an additional For example if a feature is license-gated, there's no need to add an additional
explicit feature flag check since the flag will be checked as part of the explicit feature flag check since the flag will be checked as part of the
...@@ -56,12 +56,19 @@ isn't gated by a License or Plan. ...@@ -56,12 +56,19 @@ isn't gated by a License or Plan.
unless the feature is explicitly disabled or limited to a percentage of users, unless the feature is explicitly disabled or limited to a percentage of users,
the feature flag check will default to `true`.** the feature flag check will default to `true`.**
   
As an example, if you were to ship the backend half of a feature behind a flag, This is relevant when developing the feature using
you'd want to explicitly disable that flag until the frontend half is also ready [several smaller merge requests](https://about.gitlab.com/handbook/values/#make-small-merge-requests), or when the feature is considered to be an
to be shipped. To make sure this feature is disabled for both GitLab.com and [alpha or beta](https://about.gitlab.com/handbook/product/#alpha-beta-ga), and
self-managed instances you'd need to explicitly call `Feature.enabled?` method should not be available by default.
before the `feature_available` method. This ensures the feature_flag is defaulting
to `false`. As an example, if you were to ship the frontend half of a feature without the
backend, you'd want to disable the feature entirely until the backend half is
also ready to be shipped. To make sure this feature is disabled for both
GitLab.com and self-managed instances, you should use the
[`Namespace#alpha_feature_available?`](https://gitlab.com/gitlab-org/gitlab/blob/458749872f4a8f27abe8add930dbb958044cb926/ee/app/models/ee/namespace.rb#L113) or
[`Namespace#beta_feature_available?`](https://gitlab.com/gitlab-org/gitlab/blob/458749872f4a8f27abe8add930dbb958044cb926/ee/app/models/ee/namespace.rb#L100-112)
method, according to our [definitions](https://about.gitlab.com/handbook/product/#alpha-beta-ga). This ensures the feature is disabled unless the feature flag is
_explicitly_ enabled.
   
## Feature groups ## Feature groups
   
......
...@@ -112,6 +112,7 @@ module EE ...@@ -112,6 +112,7 @@ module EE
::Feature.enabled?(feature, self) || ::Feature.enabled?(feature, self) ||
(::Feature.enabled?(feature) && feature_available?(feature)) (::Feature.enabled?(feature) && feature_available?(feature))
end end
alias_method :alpha_feature_available?, :beta_feature_available?
   
# Checks features (i.e. https://about.gitlab.com/pricing/) availabily # Checks features (i.e. https://about.gitlab.com/pricing/) availabily
# for a given Namespace plan. This method should consider ancestor groups # for a given Namespace plan. This method should consider ancestor groups
......
...@@ -297,6 +297,7 @@ module EE ...@@ -297,6 +297,7 @@ module EE
::Feature.enabled?(feature, self) || ::Feature.enabled?(feature, self) ||
(::Feature.enabled?(feature) && feature_available?(feature)) (::Feature.enabled?(feature) && feature_available?(feature))
end end
alias_method :alpha_feature_available?, :beta_feature_available?
   
def push_audit_events_enabled? def push_audit_events_enabled?
::Feature.enabled?(:repository_push_audit_event, self) ::Feature.enabled?(:repository_push_audit_event, self)
......
...@@ -607,8 +607,8 @@ describe Group do ...@@ -607,8 +607,8 @@ describe Group do
end end
end end
   
describe '#beta_feature_available?' do describe '#alpha/beta_feature_available?' do
it_behaves_like 'an entity with beta feature support' do it_behaves_like 'an entity with alpha/beta feature support' do
let(:entity) { group } let(:entity) { group }
end end
end end
......
...@@ -545,8 +545,8 @@ describe Project do ...@@ -545,8 +545,8 @@ describe Project do
end end
end end
   
describe '#beta_feature_available?' do describe '#alpha/beta_feature_available?' do
it_behaves_like 'an entity with beta feature support' do it_behaves_like 'an entity with alpha/beta feature support' do
let(:entity) { create(:project) } let(:entity) { create(:project) }
end end
end end
......
# frozen_string_literal: true
# This needs an `entity` object: Project or Group.
RSpec.shared_examples 'an entity with alpha/beta feature support' do
where(level: %w[alpha beta])
with_them do
let(:method_name) { "#{level}_feature_available?" }
context 'when license does not allow it' do
before do
stub_licensed_features(insights: false)
end
context 'when the feature flag is disabled globally' do
before do
stub_feature_flags(insights: false)
end
it { expect(entity.public_send(method_name, :insights)).to be_falsy }
end
context 'when the feature flag is enabled globally' do
before do
stub_feature_flags(insights: true)
end
it { expect(entity.public_send(method_name, :insights)).to be_truthy }
end
context 'when the feature flag is enabled for the entity' do
before do
stub_feature_flags(insights: { enabled: true, thing: entity })
end
it { expect(entity.public_send(method_name, :insights)).to be_truthy }
end
end
context 'when license allows it' do
before do
stub_licensed_features(insights: true)
end
context 'when the feature flag is disabled globally' do
before do
stub_feature_flags(insights: false)
end
it { expect(entity.public_send(method_name, :insights)).to be_falsy }
end
context 'when the feature flag is enabled globally' do
before do
stub_feature_flags(insights: true)
end
it { expect(entity.public_send(method_name, :insights)).to be_truthy }
end
context 'when the feature flag is enabled for the entity' do
before do
stub_feature_flags(insights: { enabled: true, thing: entity })
end
it { expect(entity.public_send(method_name, :insights)).to be_truthy }
end
end
end
end
# frozen_string_literal: true
# This needs an `entity` object: Project or Group.
RSpec.shared_examples 'an entity with beta feature support' do
context 'when license does not allow it' do
before do
stub_licensed_features(insights: false)
end
context 'when the feature flag is disabled globally' do
before do
stub_feature_flags(insights: false)
end
it { expect(entity.beta_feature_available?(:insights)).to be_falsy }
end
context 'when the feature flag is enabled globally' do
before do
stub_feature_flags(insights: true)
end
it { expect(entity.beta_feature_available?(:insights)).to be_truthy }
end
context 'when the feature flag is enabled for the entity' do
before do
stub_feature_flags(insights: { enabled: true, thing: entity })
end
it { expect(entity.beta_feature_available?(:insights)).to be_truthy }
end
end
context 'when license allows it' do
before do
stub_licensed_features(insights: true)
end
context 'when the feature flag is disabled globally' do
before do
stub_feature_flags(insights: false)
end
it { expect(entity.beta_feature_available?(:insights)).to be_falsy }
end
context 'when the feature flag is enabled globally' do
before do
stub_feature_flags(insights: true)
end
it { expect(entity.beta_feature_available?(:insights)).to be_truthy }
end
context 'when the feature flag is enabled for the entity' do
before do
stub_feature_flags(insights: { enabled: true, thing: entity })
end
it { expect(entity.beta_feature_available?(:insights)).to be_truthy }
end
end
end
Supports Markdown
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