Commit 71163894 authored by Fabio Pitino's avatar Fabio Pitino

Ensure OpenSource plan gets Ultimate features

OpenSource plan gets Ultimate features and is set as
a top tier plan.

Fix `GitlabSubscription#upgradable?` bug.
parent 6f8ad5c5
...@@ -13,11 +13,10 @@ module EE ...@@ -13,11 +13,10 @@ module EE
NAMESPACE_PLANS_TO_LICENSE_PLANS = { NAMESPACE_PLANS_TO_LICENSE_PLANS = {
::Plan::BRONZE => License::STARTER_PLAN, ::Plan::BRONZE => License::STARTER_PLAN,
[::Plan::SILVER, ::Plan::PREMIUM, ::Plan::PREMIUM_TRIAL] => License::PREMIUM_PLAN, [::Plan::SILVER, ::Plan::PREMIUM, ::Plan::PREMIUM_TRIAL] => License::PREMIUM_PLAN,
[::Plan::GOLD, ::Plan::ULTIMATE, ::Plan::ULTIMATE_TRIAL] => License::ULTIMATE_PLAN [::Plan::GOLD, ::Plan::ULTIMATE, ::Plan::ULTIMATE_TRIAL, ::Plan::OPEN_SOURCE] => License::ULTIMATE_PLAN
}.freeze }.freeze
LICENSE_PLANS_TO_NAMESPACE_PLANS = NAMESPACE_PLANS_TO_LICENSE_PLANS.invert.freeze LICENSE_PLANS_TO_NAMESPACE_PLANS = NAMESPACE_PLANS_TO_LICENSE_PLANS.invert.freeze
PLANS = (NAMESPACE_PLANS_TO_LICENSE_PLANS.keys + [Plan::FREE]).flatten.freeze
TEMPORARY_STORAGE_INCREASE_DAYS = 30 TEMPORARY_STORAGE_INCREASE_DAYS = 30
prepended do prepended do
...@@ -381,6 +380,10 @@ module EE ...@@ -381,6 +380,10 @@ module EE
feature_available?(:api_fuzzing) feature_available?(:api_fuzzing)
end end
def default_plan?
actual_plan_name == ::Plan::DEFAULT
end
def free_plan? def free_plan?
actual_plan_name == ::Plan::FREE actual_plan_name == ::Plan::FREE
end end
...@@ -413,6 +416,10 @@ module EE ...@@ -413,6 +416,10 @@ module EE
actual_plan_name == ::Plan::ULTIMATE_TRIAL actual_plan_name == ::Plan::ULTIMATE_TRIAL
end end
def opensource_plan?
actual_plan_name == ::Plan::OPEN_SOURCE
end
def plan_eligible_for_trial? def plan_eligible_for_trial?
::Plan::PLANS_ELIGIBLE_FOR_TRIAL.include?(actual_plan_name) ::Plan::PLANS_ELIGIBLE_FOR_TRIAL.include?(actual_plan_name)
end end
......
...@@ -20,6 +20,7 @@ module EE ...@@ -20,6 +20,7 @@ module EE
PAID_HOSTED_PLANS = [BRONZE, SILVER, PREMIUM, GOLD, ULTIMATE, ULTIMATE_TRIAL, PREMIUM_TRIAL, OPEN_SOURCE].freeze PAID_HOSTED_PLANS = [BRONZE, SILVER, PREMIUM, GOLD, ULTIMATE, ULTIMATE_TRIAL, PREMIUM_TRIAL, OPEN_SOURCE].freeze
EE_ALL_PLANS = (EE_DEFAULT_PLANS + PAID_HOSTED_PLANS).freeze EE_ALL_PLANS = (EE_DEFAULT_PLANS + PAID_HOSTED_PLANS).freeze
PLANS_ELIGIBLE_FOR_TRIAL = EE_DEFAULT_PLANS PLANS_ELIGIBLE_FOR_TRIAL = EE_DEFAULT_PLANS
TOP_PLANS = [GOLD, ULTIMATE, OPEN_SOURCE].freeze
has_many :hosted_subscriptions, class_name: 'GitlabSubscription', foreign_key: 'hosted_plan_id' has_many :hosted_subscriptions, class_name: 'GitlabSubscription', foreign_key: 'hosted_plan_id'
......
...@@ -90,11 +90,9 @@ class GitlabSubscription < ApplicationRecord ...@@ -90,11 +90,9 @@ class GitlabSubscription < ApplicationRecord
end end
def upgradable? def upgradable?
return false if [::Plan::GOLD, ::Plan::ULTIMATE].include?(plan_name) return false if ::Plan::TOP_PLANS.include?(plan_name)
has_a_paid_hosted_plan? && has_a_paid_hosted_plan? && !expired?
!expired? &&
plan_name != Plan::PAID_HOSTED_PLANS[-1]
end end
def plan_code=(code) def plan_code=(code)
......
...@@ -48,7 +48,7 @@ RSpec.describe Namespace do ...@@ -48,7 +48,7 @@ RSpec.describe Namespace do
end end
context "for a plan that isn't #{namespace_plan}" do context "for a plan that isn't #{namespace_plan}" do
where(plan_name: described_class::PLANS - [namespace_plan]) where(plan_name: ::Plan.all_plans - [namespace_plan])
with_them do with_them do
it { is_expected.to eq(false) } it { is_expected.to eq(false) }
...@@ -56,7 +56,7 @@ RSpec.describe Namespace do ...@@ -56,7 +56,7 @@ RSpec.describe Namespace do
end end
end end
described_class::PLANS.each do |namespace_plan| ::Plan.all_plans.each do |namespace_plan|
describe "#{namespace_plan}_plan?", :saas do describe "#{namespace_plan}_plan?", :saas do
it_behaves_like 'plan helper', namespace_plan it_behaves_like 'plan helper', namespace_plan
end end
...@@ -165,20 +165,66 @@ RSpec.describe Namespace do ...@@ -165,20 +165,66 @@ RSpec.describe Namespace do
context 'scopes' do context 'scopes' do
describe '.with_feature_available_in_plan', :saas do describe '.with_feature_available_in_plan', :saas do
let!(:namespace) { create(:namespace) } let(:starter_feature) { :audit_events }
let(:premium_feature) { :epics }
let(:ultimate_feature) { :dast }
context 'Bronze plan has Starter features' do
let!(:bronze_namespace) { create(:namespace_with_plan, plan: :bronze_plan) }
it 'returns namespaces with plan' do
create(:namespace_with_plan, plan: :free_plan)
expect(described_class.with_feature_available_in_plan(starter_feature)).to match_array([bronze_namespace])
end
context 'plan is nil' do it 'includes namespace from higher plans' do
it 'returns no namespace' do ultimate_namespace = create(:namespace_with_plan, plan: :ultimate_plan)
expect(described_class.with_feature_available_in_plan(:group_project_templates)).to be_empty
expect(described_class.with_feature_available_in_plan(starter_feature))
.to include(ultimate_namespace)
end end
end end
context 'plan is set' do context 'Silver, Premium and Premium_trial plans have Premium license features' do
it 'returns namespaces with plan' do let!(:silver_namespace) { create(:namespace_with_plan, plan: :silver_plan) }
let!(:premium_namespace) { create(:namespace_with_plan, plan: :premium_plan) }
let!(:premium_trial_namespace) { create(:namespace_with_plan, plan: :premium_trial_plan) }
let!(:not_included_namespace) { create(:namespace_with_plan, plan: :bronze_plan) }
it 'returns namespaces with matching plans' do
expect(described_class.with_feature_available_in_plan(premium_feature))
.to contain_exactly(silver_namespace, premium_namespace, premium_trial_namespace)
end
it 'includes namespace from higher plans' do
ultimate_namespace = create(:namespace_with_plan, plan: :ultimate_plan)
expect(described_class.with_feature_available_in_plan(premium_feature))
.to include(ultimate_namespace)
end
end
context 'Gold, Ultimate, Ultimate_trial and OpenSource plans have Ultimate license features' do
let!(:gold_namespace) { create(:namespace_with_plan, plan: :gold_plan) }
let!(:ultimate_namespace) { create(:namespace_with_plan, plan: :ultimate_plan) }
let!(:ultimate_trial_namespace) { create(:namespace_with_plan, plan: :ultimate_trial_plan) }
let!(:opensource_namespace) { create(:namespace_with_plan, plan: :opensource_plan) }
it 'returns namespaces with matching plans' do
create(:gitlab_subscription, :bronze, namespace: namespace) create(:gitlab_subscription, :bronze, namespace: namespace)
create(:namespace_with_plan, plan: :free_plan)
expect(described_class.with_feature_available_in_plan(:audit_events)).to eq([namespace]) expect(described_class.with_feature_available_in_plan(ultimate_feature))
.to contain_exactly(gold_namespace, ultimate_namespace, ultimate_trial_namespace, opensource_namespace)
end
end
context 'when no namespace matches the feature' do
let!(:bronze_namespace) { create(:namespace_with_plan, plan: :bronze_plan) }
let!(:silver_namespace) { create(:namespace_with_plan, plan: :silver_plan) }
it 'returns an empty list' do
expect(described_class.with_feature_available_in_plan(ultimate_feature)).to be_empty
end end
end end
end end
...@@ -761,6 +807,22 @@ RSpec.describe Namespace do ...@@ -761,6 +807,22 @@ RSpec.describe Namespace do
end end
end end
describe '#paid?', :saas do
it 'returns true for a root namespace with a paid plan' do
create(:gitlab_subscription, :ultimate, namespace: namespace)
expect(namespace.paid?).to eq(true)
end
it 'returns false for a subgroup of a group with a paid plan' do
group = create(:group)
subgroup = create(:group, parent: group)
create(:gitlab_subscription, :ultimate, namespace: group)
expect(subgroup.paid?).to eq(false)
end
end
describe '#actual_plan' do describe '#actual_plan' do
context 'when namespace does not have a subscription associated' do context 'when namespace does not have a subscription associated' do
it 'generates a subscription and returns default plan' do it 'generates a subscription and returns default plan' do
...@@ -850,22 +912,6 @@ RSpec.describe Namespace do ...@@ -850,22 +912,6 @@ RSpec.describe Namespace do
end end
end end
describe '#paid?', :saas do
it 'returns true for a root namespace with a paid plan' do
create(:gitlab_subscription, :ultimate, namespace: namespace)
expect(namespace.paid?).to eq(true)
end
it 'returns false for a subgroup of a group with a paid plan' do
group = create(:group)
subgroup = create(:group, parent: group)
create(:gitlab_subscription, :ultimate, namespace: group)
expect(subgroup.paid?).to eq(false)
end
end
describe '#actual_plan_name' do describe '#actual_plan_name' do
context 'when namespace does not have a subscription associated' do context 'when namespace does not have a subscription associated' do
it 'returns default plan' do it 'returns default plan' do
......
...@@ -309,25 +309,57 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -309,25 +309,57 @@ RSpec.describe GitlabSubscription, :saas do
let(:subscription) { build(:gitlab_subscription) } let(:subscription) { build(:gitlab_subscription) }
where(:plan_name, :paid_hosted_plan, :expired, :result) do shared_examples 'upgradable lower plan' do |plan_name|
'bronze' | true | false | true where(:has_a_paid_hosted_plan, :expired, :result) do
'bronze' | true | true | false false | false | false
'premium' | true | false | true true | false | true
'ultimate' | true | false | false true | true | false
false | true | false
end
with_them do
before do
plan = build(:plan, name: plan_name)
allow(subscription).to receive(:expired?) { expired }
allow(subscription).to receive(:has_a_paid_hosted_plan?) { has_a_paid_hosted_plan }
subscription.assign_attributes(hosted_plan: plan)
end
it 'returns true if subscription is upgradable' do
expect(subscription.upgradable?).to eq(result)
end
end
end end
with_them do shared_examples 'top plan' do |plan_name|
before do where(:has_a_paid_hosted_plan, :expired) do
plan = build(:plan, name: plan_name) false | false
allow(subscription).to receive(:expired?) { expired } true | false
allow(subscription).to receive(:has_a_paid_hosted_plan?) { paid_hosted_plan } true | true
subscription.assign_attributes(hosted_plan: plan) false | true
end end
it 'returns true if subscription is upgradable' do with_them do
expect(subscription.upgradable?).to eq(result) before do
plan = build(:plan, name: plan_name)
allow(subscription).to receive(:expired?) { expired }
allow(subscription).to receive(:has_a_paid_hosted_plan?) { has_a_paid_hosted_plan }
subscription.assign_attributes(hosted_plan: plan)
end
it 'returns false' do
expect(subscription.upgradable?).to eq(false)
end
end end
end end
(::Plan.all_plans - ::Plan::TOP_PLANS).each do |plan_name|
it_behaves_like 'upgradable lower plan', plan_name
end
::Plan::TOP_PLANS.each do |plan_name|
it_behaves_like 'top plan', plan_name
end
end end
describe 'callbacks' do describe 'callbacks' do
......
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