Commit 5b683957 authored by Mark Chao's avatar Mark Chao

Merge branch 'vij-max-seats-new-term' into 'master'

Reset GitlabSubscription seats when starting a new term

See merge request gitlab-org/gitlab!73078
parents 6749959d fc8902d2
...@@ -9,7 +9,10 @@ class GitlabSubscription < ApplicationRecord ...@@ -9,7 +9,10 @@ class GitlabSubscription < ApplicationRecord
enum trial_extension_type: { extended: 1, reactivated: 2 } enum trial_extension_type: { extended: 1, reactivated: 2 }
default_value_for(:start_date) { Date.today } default_value_for(:start_date) { Date.today }
before_update :log_previous_state_for_update before_update :log_previous_state_for_update
before_update :reset_seats_for_new_term
after_commit :index_namespace, on: [:create, :update] after_commit :index_namespace, on: [:create, :update]
after_destroy_commit :log_previous_state_for_destroy after_destroy_commit :log_previous_state_for_destroy
...@@ -175,4 +178,18 @@ class GitlabSubscription < ApplicationRecord ...@@ -175,4 +178,18 @@ class GitlabSubscription < ApplicationRecord
ElasticsearchIndexedNamespace.safe_find_or_create_by!(namespace_id: namespace_id) ElasticsearchIndexedNamespace.safe_find_or_create_by!(namespace_id: namespace_id)
end end
# If the subscription starts a new term, the dates will change. We reset max_seats_used
# and seats_owed so that we don't carry it over from the previous term
def reset_seats_for_new_term
return unless new_term?
self.max_seats_used = attributes['seats_in_use']
self.seats_owed = calculate_seats_owed
end
def new_term?
persisted? && start_date_changed? && end_date_changed? &&
(end_date_was.nil? || start_date >= end_date_was)
end
end end
...@@ -163,7 +163,7 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -163,7 +163,7 @@ RSpec.describe GitlabSubscription, :saas do
end end
describe '#refresh_seat_attributes!' do describe '#refresh_seat_attributes!' do
subject { create(:gitlab_subscription, seats: 3, max_seats_used: 2) } subject(:gitlab_subscription) { create(:gitlab_subscription, seats: 3, max_seats_used: 2) }
before do before do
expect(subject).to receive(:calculate_seats_in_use).and_return(calculate_seats_in_use) expect(subject).to receive(:calculate_seats_in_use).and_return(calculate_seats_in_use)
...@@ -174,10 +174,10 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -174,10 +174,10 @@ RSpec.describe GitlabSubscription, :saas do
it 'does not increase max_seats_used' do it 'does not increase max_seats_used' do
expect do expect do
subject.refresh_seat_attributes! gitlab_subscription.refresh_seat_attributes!
end.to change(subject, :seats_in_use).from(0).to(1) end.to change(gitlab_subscription, :seats_in_use).from(0).to(1)
.and not_change(subject, :max_seats_used) .and not_change(gitlab_subscription, :max_seats_used)
.and not_change(subject, :seats_owed) .and not_change(gitlab_subscription, :seats_owed)
end end
end end
...@@ -186,10 +186,10 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -186,10 +186,10 @@ RSpec.describe GitlabSubscription, :saas do
it 'increases seats and max_seats_used' do it 'increases seats and max_seats_used' do
expect do expect do
subject.refresh_seat_attributes! gitlab_subscription.refresh_seat_attributes!
end.to change(subject, :seats_in_use).from(0).to(4) end.to change(gitlab_subscription, :seats_in_use).from(0).to(4)
.and change(subject, :max_seats_used).from(2).to(4) .and change(gitlab_subscription, :max_seats_used).from(2).to(4)
.and change(subject, :seats_owed).from(0).to(1) .and change(gitlab_subscription, :seats_owed).from(0).to(1)
end end
end end
end end
...@@ -432,11 +432,13 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -432,11 +432,13 @@ RSpec.describe GitlabSubscription, :saas do
expect(GitlabSubscriptionHistory.attribute_names - described_class.attribute_names).to eq(diff_attrs) expect(GitlabSubscriptionHistory.attribute_names - described_class.attribute_names).to eq(diff_attrs)
end end
context 'before_update' do context 'before_update', :freeze_time do
it 'logs previous state to gitlab subscription history' do let(:gitlab_subscription) do
gitlab_subscription = create(:gitlab_subscription, max_seats_used: 42, seats: 13, namespace: create(:namespace)) create(:gitlab_subscription, seats_in_use: 20, max_seats_used: 42, seats: 13, seats_owed: 29, start_date: Date.today - 1.year)
end
gitlab_subscription.update! max_seats_used: 32 it 'logs previous state to gitlab subscription history' do
gitlab_subscription.update!(max_seats_used: 32)
expect(GitlabSubscriptionHistory.count).to eq(1) expect(GitlabSubscriptionHistory.count).to eq(1)
expect(GitlabSubscriptionHistory.last.attributes).to include( expect(GitlabSubscriptionHistory.last.attributes).to include(
...@@ -446,6 +448,73 @@ RSpec.describe GitlabSubscription, :saas do ...@@ -446,6 +448,73 @@ RSpec.describe GitlabSubscription, :saas do
'seats' => 13 'seats' => 13
) )
end end
context 'when start and end dates change' do
context 'when start_date is after the old end_date' do
it 'resets seats attributes' do
new_start = gitlab_subscription.end_date + 1.year
new_end = new_start + 1.year
expect do
gitlab_subscription.update!(start_date: new_start, end_date: new_end)
end.to change(gitlab_subscription, :start_date).to(new_start)
.and change(gitlab_subscription, :end_date).to(new_end)
.and change(gitlab_subscription, :max_seats_used).from(42).to(20)
.and change(gitlab_subscription, :seats_owed).from(29).to(7)
.and not_change(gitlab_subscription, :seats_in_use)
end
end
context 'when the end_date was nil' do
it 'resets seats attributes' do
gitlab_subscription.update!(end_date: nil)
new_start = Date.today + 1.year
new_end = new_start + 1.year
expect do
gitlab_subscription.update!(start_date: new_start, end_date: new_end)
end.to change(gitlab_subscription, :start_date).to(new_start)
.and change(gitlab_subscription, :end_date).to(new_end)
.and change(gitlab_subscription, :max_seats_used).from(42).to(20)
.and change(gitlab_subscription, :seats_owed).from(29).to(7)
.and not_change(gitlab_subscription, :seats_in_use)
end
end
context 'when start_date is not after the old end_date' do
it 'does not reset seats attributes' do
new_start = gitlab_subscription.end_date - 1.month
new_end = new_start + 1.year
expect do
gitlab_subscription.update!(start_date: new_start, end_date: new_end)
end.to change(gitlab_subscription, :start_date).to(new_start)
.and change(gitlab_subscription, :end_date).to(new_end)
.and not_change(gitlab_subscription, :max_seats_used)
.and not_change(gitlab_subscription, :seats_owed)
end
end
end
context 'when only one date is changed' do
it 'does not reset seats attributes' do
expect do
gitlab_subscription.update!(start_date: Date.today)
end.to change(gitlab_subscription, :start_date).to(Date.today)
.and not_change(gitlab_subscription, :max_seats_used)
.and not_change(gitlab_subscription, :seats_owed)
end
end
context 'when no dates are changed' do
it 'does not reset seats attributes' do
expect do
gitlab_subscription.update!(seats_in_use: 99)
end.to not_change(gitlab_subscription, :max_seats_used)
.and not_change(gitlab_subscription, :seats_owed)
end
end
end end
context 'after_destroy_commit' do context 'after_destroy_commit' do
......
...@@ -590,14 +590,14 @@ RSpec.describe API::Namespaces do ...@@ -590,14 +590,14 @@ RSpec.describe API::Namespaces do
let_it_be(:premium_plan) { create(:premium_plan) } let_it_be(:premium_plan) { create(:premium_plan) }
let_it_be(:namespace) { create(:group, name: 'test.test-group.22') } let_it_be(:namespace) { create(:group, name: 'test.test-group.22') }
let_it_be(:gitlab_subscription) { create(:gitlab_subscription, namespace: namespace) } let_it_be(:gitlab_subscription) { create(:gitlab_subscription, namespace: namespace, start_date: '2018/01/01', end_date: '2019/01/01') }
let(:params) do let(:params) do
{ {
seats: 150, seats: 150,
plan_code: 'premium', plan_code: 'premium',
start_date: '01/01/2018', start_date: '2018/01/01',
end_date: '01/01/2019' end_date: '2019/01/01'
} }
end end
...@@ -679,6 +679,26 @@ RSpec.describe API::Namespaces do ...@@ -679,6 +679,26 @@ RSpec.describe API::Namespaces do
do_put(namespace.id, admin, gitlab_subscription.attributes) do_put(namespace.id, admin, gitlab_subscription.attributes)
end.to change { gitlab_subscription.reload.updated_at } end.to change { gitlab_subscription.reload.updated_at }
end end
context 'when starting a new term' do
it 'resets the seat attributes for the subscription' do
gitlab_subscription.update!(seats: 20, max_seats_used: 42, seats_owed: 22)
new_start = gitlab_subscription.end_date + 1.year
new_end = new_start + 1.year
new_term_params = params.merge(start_date: new_start, end_date: new_end)
expect(gitlab_subscription.seats_in_use).to eq 0
do_put(namespace.id, admin, new_term_params)
expect(response).to have_gitlab_http_status(:ok)
expect(gitlab_subscription.reload).to have_attributes(
max_seats_used: 0,
seats_owed: 0
)
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