Commit 8db2630d authored by Jay Swain's avatar Jay Swain

Revert "Revert "Merge branch '3326-fix-license_helper-memoization-issue' into 'master'""

This reverts commit 14ebe68c.
parent abf209ef
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
.mobile-overlay .mobile-overlay
.alert-wrapper .alert-wrapper
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
= render_if_exists "layouts/header/ee_license_banner" = render_if_exists "layouts/header/ee_subscribable_banner"
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/header/read_only_banner" = render "layouts/header/read_only_banner"
= render "layouts/nav/classification_level_banner" = render "layouts/nav/classification_level_banner"
......
...@@ -8,4 +8,5 @@ ...@@ -8,4 +8,5 @@
- unless project.empty_repo? - unless project.empty_repo?
= render 'shared/auto_devops_implicitly_enabled_banner', project: project = render 'shared/auto_devops_implicitly_enabled_banner', project: project
= render_if_exists 'projects/above_size_limit_warning', project: project = render_if_exists 'projects/above_size_limit_warning', project: project
= render_if_exists "layouts/header/ee_subscribable_banner", subscription: true
= render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)] = render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)]
...@@ -28,7 +28,7 @@ module EE ...@@ -28,7 +28,7 @@ module EE
end end
def has_start_trial? def has_start_trial?
!current_license && current_user.admin? !current_user.has_current_license? && current_user.admin?
end end
def analytics_nav_url def analytics_nav_url
......
...@@ -42,6 +42,12 @@ module EE ...@@ -42,6 +42,12 @@ module EE
project_security_vulnerability_path(entity.project, entity, *args) project_security_vulnerability_path(entity.project, entity, *args)
end end
def upgrade_plan_path(group)
return profile_billings_path if group.blank?
group_billings_path(group)
end
def self.url_helper(route_name) def self.url_helper(route_name)
define_method("#{route_name}_url") do |*args| define_method("#{route_name}_url") do |*args|
path = public_send(:"#{route_name}_path", *args) # rubocop:disable GitlabSecurity/PublicSend path = public_send(:"#{route_name}_path", *args) # rubocop:disable GitlabSecurity/PublicSend
......
...@@ -180,6 +180,21 @@ module EE ...@@ -180,6 +180,21 @@ module EE
"The total size of this project's repository #{show_lfs} will be limited to this size. 0 for unlimited. Leave empty to inherit the group/global value." "The total size of this project's repository #{show_lfs} will be limited to this size. 0 for unlimited. Leave empty to inherit the group/global value."
end end
def subscription_message
return unless ::Gitlab.com?
::Gitlab::ExpiringSubscriptionMessage.new(
subscribable: decorated_subscription,
signed_in: signed_in?,
is_admin: can?(current_user, :owner_access, @project),
namespace: @project.namespace
).message
end
def decorated_subscription
SubscriptionPresenter.new(@project.gitlab_subscription)
end
override :membership_locked? override :membership_locked?
def membership_locked? def membership_locked?
group = @project.group group = @project.group
......
...@@ -18,35 +18,25 @@ module LicenseHelper ...@@ -18,35 +18,25 @@ module LicenseHelper
License.current&.maximum_user_count || 0 License.current&.maximum_user_count || 0
end end
def license_message(signed_in: signed_in?, is_admin: current_user&.admin?) def license_message(signed_in: signed_in?, is_admin: current_user&.admin?, license: License.current)
return unless current_license Gitlab::ExpiringSubscriptionMessage.new(
return unless signed_in subscribable: license,
return unless (is_admin && current_license.notify_admins?) || current_license.notify_users? signed_in: signed_in,
is_admin: is_admin
message = [] ).message
message << license_message_subject
message << expiration_blocking_message
message.reject {|string| string.blank? }.join(' ').html_safe
end end
def seats_calculation_message def seats_calculation_message(license)
if current_license&.exclude_guests_from_active_count? return unless license.present?
return unless license.exclude_guests_from_active_count?
content_tag :p do content_tag :p do
"Users with a Guest role or those who don't belong to a Project or Group will not use a seat from your license." "Users with a Guest role or those who don't belong to a Project or Group will not use a seat from your license."
end end
end end
end
def current_license
return @current_license if defined?(@current_license)
@current_license = License.current
end
def current_license_title def current_license_title
@current_license_title ||= License.current ? License.current.plan.titleize : 'Core' License.current&.plan&.titleize || 'Core'
end end
def new_trial_url def new_trial_url
...@@ -57,15 +47,6 @@ module LicenseHelper ...@@ -57,15 +47,6 @@ module LicenseHelper
uri.to_s uri.to_s
end end
def upgrade_plan_url
group = @project&.group || @group
if group
group_billings_path(group)
else
profile_billings_path
end
end
def show_promotions?(selected_user = current_user) def show_promotions?(selected_user = current_user)
return false unless selected_user return false unless selected_user
...@@ -105,44 +86,4 @@ module LicenseHelper ...@@ -105,44 +86,4 @@ module LicenseHelper
def active_user_count def active_user_count
User.active.count User.active.count
end end
def license_message_subject
if current_license.expired?
message = if current_license.block_changes?
_('Your subscription has been downgraded')
else
_('Your subscription expired!')
end
else
remaining_days = pluralize(current_license.remaining_days, 'day')
message = _('Your subscription will expire in %{remaining_days}') % { remaining_days: remaining_days }
end
message = content_tag(:strong, message)
content_tag(:p, message, class: 'mb-2')
end
def expiration_blocking_message
return '' unless current_license.will_block_changes?
plan_name = current_license.plan.titleize
strong = "<strong>".html_safe
strong_close = "</strong>".html_safe
if current_license.expired?
if current_license.block_changes?
message = _('You didn\'t renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan.') % { plan_name: plan_name, strong: strong, strong_close: strong_close }
else
remaining_days = pluralize((current_license.block_changes_at - Date.today).to_i, 'day')
message = _('No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription.') % { plan_name: plan_name, remaining_days: remaining_days, strong: strong, strong_close: strong_close }
end
else
message = _('Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features.') % { expires_on: current_license.expires_at.strftime("%Y-%m-%d"), plan_name: plan_name, strong: strong, strong_close: strong_close }
end
content_tag(:p, message.html_safe)
end
end end
...@@ -160,6 +160,7 @@ module EE ...@@ -160,6 +160,7 @@ module EE
delegate :merge_pipelines_enabled, :merge_pipelines_enabled=, :merge_pipelines_enabled?, :merge_pipelines_were_disabled?, to: :ci_cd_settings delegate :merge_pipelines_enabled, :merge_pipelines_enabled=, :merge_pipelines_enabled?, :merge_pipelines_were_disabled?, to: :ci_cd_settings
delegate :merge_trains_enabled?, to: :ci_cd_settings delegate :merge_trains_enabled?, to: :ci_cd_settings
delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true
delegate :gitlab_subscription, to: :namespace
validates :repository_size_limit, validates :repository_size_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0, allow_nil: true } numericality: { only_integer: true, greater_than_or_equal_to: 0, allow_nil: true }
......
# frozen_string_literal: true
class SubscriptionPresenter < Gitlab::View::Presenter::Delegated
presents :subscription
def block_changes?
expired?
end
def plan
namespace.try(:actual_plan_name)
end
def notify_admins?
remaining_days && remaining_days < 30
end
def notify_users?
false
end
def expires_at
end_date
end
alias_method :block_changes_at, :expires_at
def remaining_days
return unless end_date
(end_date - Date.today).to_i
end
def will_block_changes?
true
end
end
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
= _(' %{start} to %{end}') % { start: @license.starts_at, end: @license.expires_at } = _(' %{start} to %{end}') % { start: @license.starts_at, end: @license.expires_at }
\. \.
= _('The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal.').html_safe % { link_start: true_up_link_start, link_end: link_end } = _('The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal.').html_safe % { link_start: true_up_link_start, link_end: link_end }
= seats_calculation_message = seats_calculation_message(@license)
.col-sm-6.d-flex.pr-0 .col-sm-6.d-flex.pr-0
.info-well.dark-well .info-well.dark-well
.well-segment.well-centered .well-segment.well-centered
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- else - else
%h3.page-title %h3.page-title
Your License Your License
- if current_license.trial? - if @license.trial?
= render "upload_buy_license" = render "upload_buy_license"
- else - else
= link_to 'Upload New License', new_admin_license_path, class: "btn btn-success float-right" = link_to 'Upload New License', new_admin_license_path, class: "btn btn-success float-right"
......
- if license_message.present? - if local_assigns[:subscription]
- subscribable = decorated_subscription
- message = subscription_message
- else
- subscribable = License.current
- message = license_message(license: subscribable)
- if message.present?
.container-fluid.container-limited.pt-3 .container-fluid.container-limited.pt-3
.alert.alert-dismissible.gitlab-ee-license-banner.hidden.js-gitlab-ee-license-banner.pb-5.border-width-1px.border-style-solid.border-color-default.border-radius-default{ role: 'alert', data: { license_expiry: current_license.expires_at } } .alert.alert-dismissible.gitlab-ee-license-banner.hidden.js-gitlab-ee-license-banner.pb-5.border-width-1px.border-style-solid.border-color-default.border-radius-default{ role: 'alert', data: { license_expiry: subscribable.expires_at } }
%button.close.p-2{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' } %button.close.p-2{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' }
%span{ 'aria-hidden' => 'true' } %span{ 'aria-hidden' => 'true' }
= sprite_icon('merge-request-close-m', size: 24) = sprite_icon('merge-request-close-m', size: 24)
.d-flex.flex-row .d-flex.flex-row
.pr-4.pl-3.pt-2 .pr-4.pl-3.pt-2
- if current_license.expired? - if subscribable.expired?
- if current_license.block_changes? - if subscribable.block_changes?
= image_tag('illustrations/subscription-downgraded.svg') = image_tag('illustrations/subscription-downgraded.svg')
- else - else
= image_tag('illustrations/subscription-cancelled.svg') = image_tag('illustrations/subscription-cancelled.svg')
- else - else
= image_tag('illustrations/subscription-warning.svg') = image_tag('illustrations/subscription-warning.svg')
.text-left.pt-2 .text-left.pt-2
= license_message = message
- if current_license.block_changes? - if subscribable.block_changes?
= link_to 'Upgrade your plan', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary' = link_to 'Upgrade your plan', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary'
- else - else
= link_to 'Renew subscription', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary' = link_to 'Renew subscription', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary'
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
- if Gitlab::CurrentSettings.should_check_namespace_plan? - if Gitlab::CurrentSettings.should_check_namespace_plan?
- namespace = @project&.namespace || @group - namespace = @project&.namespace || @group
- if can?(current_user, :admin_namespace, namespace) - if can?(current_user, :admin_namespace, namespace)
= link_to _('Upgrade your plan'), upgrade_plan_url, class: 'btn btn-primary', target: target_blank ? '_blank' : '_self' - current_group = @project&.group || @group
= link_to _('Upgrade your plan'), upgrade_plan_path(current_group), class: 'btn btn-primary', target: target_blank ? '_blank' : '_self'
- elsif namespace.is_a?(Group) - elsif namespace.is_a?(Group)
%p= _('Contact an owner of group %{namespace_name} to upgrade the plan.') % { namespace_name: namespace.name } %p= _('Contact an owner of group %{namespace_name} to upgrade the plan.') % { namespace_name: namespace.name }
- else - else
......
---
title: ".com has a subscription expired banner"
merge_request: 28238
author:
type: added
# frozen_string_literal: true
module Gitlab
class ExpiringSubscriptionMessage
include ActionView::Helpers::TextHelper
attr_reader :subscribable, :signed_in, :is_admin, :namespace
def initialize(subscribable:, signed_in:, is_admin:, namespace: nil)
@subscribable = subscribable
@signed_in = signed_in
@is_admin = is_admin
@namespace = namespace
end
def message
return unless notifiable?
message = []
message << license_message_subject
message << expiration_blocking_message
message.reject { |string| string.blank? }.join(' ').html_safe
end
private
def license_message_subject
message = subscribable.expired? ? expired_subject : expiring_subject
message = content_tag(:strong, message)
content_tag(:p, message, class: 'mb-2')
end
def expired_subject
if subscribable.block_changes?
_('Your subscription has been downgraded')
else
_('Your subscription expired!')
end
end
def expiring_subject
remaining_days = pluralize(subscribable.remaining_days, 'day')
_('Your subscription will expire in %{remaining_days}') % { remaining_days: remaining_days }
end
def expiration_blocking_message
return '' unless subscribable.will_block_changes?
message = subscribable.expired? ? expired_message : expiring_message
content_tag(:p, message.html_safe)
end
def expired_message
if subscribable.block_changes?
if namespace
_('You didn\'t renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan.') % { plan_name: plan_name, strong: strong, strong_close: strong_close, namespace_name: namespace.name }
else
_('You didn\'t renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan.') % { plan_name: plan_name, strong: strong, strong_close: strong_close }
end
else
remaining_days = pluralize((subscribable.block_changes_at - Date.today).to_i, 'day')
_('No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription.') % { plan_name: plan_name, remaining_days: remaining_days, strong: strong, strong_close: strong_close }
end
end
def expiring_message
if namespace
_('Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features.') % { expires_on: subscribable.expires_at.strftime("%Y-%m-%d"), plan_name: plan_name, strong: strong, strong_close: strong_close, namespace_name: namespace.name }
else
_('Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features.') % { expires_on: subscribable.expires_at.strftime("%Y-%m-%d"), plan_name: plan_name, strong: strong, strong_close: strong_close }
end
end
def notifiable?
subscribable &&
signed_in &&
((is_admin && subscribable.notify_admins?) || subscribable.notify_users?) &&
expired_subscribable_within_notification_window?
end
def expired_subscribable_within_notification_window?
return true unless subscribable.expired?
expired_at = subscribable.expires_at
(expired_at..(expired_at + 30.days)).cover?(Date.today)
end
def plan_name
subscribable.plan.titleize
end
def strong
"<strong>".html_safe
end
def strong_close
"</strong>".html_safe
end
end
end
...@@ -208,7 +208,7 @@ describe DashboardHelper, type: :helper do ...@@ -208,7 +208,7 @@ describe DashboardHelper, type: :helper do
before do before do
allow(helper).to receive(:current_user).and_return(user) allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:current_license).and_return(license) allow(License).to receive(:current).and_return(license)
end end
it { is_expected.to eq(output) } it { is_expected.to eq(output) }
......
...@@ -114,4 +114,24 @@ describe EE::GitlabRoutingHelper do ...@@ -114,4 +114,24 @@ describe EE::GitlabRoutingHelper do
expect(subject).to start_with 'http://localhost/users/auth/group_saml/metadata?group_path=foo&token=' expect(subject).to start_with 'http://localhost/users/auth/group_saml/metadata?group_path=foo&token='
end end
end end
describe '#upgrade_plan_path' do
subject { upgrade_plan_path(group) }
context 'when the group is present' do
let(:group) { build_stubbed(:group) }
it "returns the group billing path" do
expect(subject).to eq(group_billings_path(group))
end
end
context 'when the group is blank' do
let(:group) { nil }
it "returns the profile billing path" do
expect(subject).to eq(profile_billings_path)
end
end
end
end end
...@@ -9,110 +9,23 @@ describe LicenseHelper do ...@@ -9,110 +9,23 @@ describe LicenseHelper do
end end
describe '#license_message' do describe '#license_message' do
subject { license_message(signed_in: signed_in, is_admin: is_admin) }
context 'license installed' do
let(:license) { double(:license) } let(:license) { double(:license) }
let(:expired_date) { Time.utc(2020, 3, 9, 10) } let(:message_mock) { double(:message_mock) }
let(:today) { Time.utc(2020, 3, 7, 10) }
before do before do
allow(License).to receive(:current).and_return(license) allow(License).to receive(:current).and_return(license)
allow(license).to receive(:plan).and_return('ultimate')
allow(license).to receive(:expires_at).and_return(expired_date)
end
context 'license is notify admins' do
before do
allow(license).to receive(:notify_admins?).and_return(true)
end end
context 'admin signed in' do it 'calls another class with args' do
let(:signed_in) { true } expect(Gitlab::ExpiringSubscriptionMessage).to receive(:new).with(
let(:is_admin) { true } subscribable: license,
signed_in: true,
is_admin: false
).and_return(message_mock)
context 'license expired' do expect(message_mock).to receive(:message)
let(:expired_date) { Time.utc(2020, 3, 9).to_date }
before do license_message(signed_in: true, is_admin: false)
allow(license).to receive(:expired?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
end
context 'and it will block changes when it expires' do
before do
allow(license).to receive(:will_block_changes?).and_return(true)
end
context 'and its currently blocking changes' do
before do
allow(license).to receive(:block_changes?).and_return(true)
allow(license).to receive(:block_changes_at).and_return(expired_date)
end
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
expect(subject).to have_text('Your subscription has been downgraded')
end
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to have_text("You didn't renew your Ultimate subscription so it was downgraded to the GitLab Core Plan")
end
end
end
context 'and its NOT currently blocking changes' do
before do
allow(license).to receive(:block_changes?).and_return(false)
end
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
expect(subject).to have_text('Your subscription expired!')
end
it 'has an expiration blocking message' do
allow(license).to receive(:block_changes_at).and_return(expired_date)
Timecop.freeze(today) do
expect(subject).to have_text('No worries, you can still use all the Ultimate features for now. You have 2 days to renew your subscription.')
end
end
end
end
end
context 'license NOT expired' do
before do
allow(license).to receive(:expired?).and_return(false)
allow(license).to receive(:remaining_days).and_return(4)
allow(license).to receive(:will_block_changes?).and_return(true)
allow(license).to receive(:block_changes_at).and_return(expired_date)
end
it 'has a nice subject' do
expect(subject).to have_text('Your subscription will expire in 4 days')
end
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to have_text('Your Ultimate subscription will expire on 2020-03-09. After that, you will not to be able to create issues or merge requests as well as many other features.')
end
end
end
end
end
end
context 'no license installed' do
let(:license) { nil }
let(:signed_in) { true }
let(:is_admin) { true }
it { is_expected.to be_blank }
end end
end end
...@@ -177,4 +90,67 @@ describe LicenseHelper do ...@@ -177,4 +90,67 @@ describe LicenseHelper do
end end
end end
end end
describe '#current_license_title' do
context 'when there is a current license' do
context 'and it has a plan associated to it' do
it 'returns the plan titleized' do
custom_plan = 'custom plan'
license = double('License', plan: custom_plan)
allow(License).to receive(:current).and_return(license)
expect(current_license_title).to eq(custom_plan.titleize)
end
end
context 'and it does not have a plan associated to it' do
it 'returns the default title' do
license = double('License', plan: nil)
allow(License).to receive(:current).and_return(license)
expect(current_license_title).to eq('Core')
end
end
end
context 'when there is NOT a current license' do
it 'returns the default title' do
allow(License).to receive(:current).and_return(nil)
expect(current_license_title).to eq('Core')
end
end
end
describe '#seats_calculation_message' do
subject { seats_calculation_message(license) }
context 'with a license' do
let(:license) { double("License", 'exclude_guests_from_active_count?' => exclude_guests) }
context 'and guest are excluded from the active count' do
let(:exclude_guests) { true }
it 'returns a tag with the message' do
expect(subject).to eq("<p>Users with a Guest role or those who don&#39;t belong to a Project or Group will not use a seat from your license.</p>")
end
end
context 'and guest are NOT excluded from the active count' do
let(:exclude_guests) { false }
it 'returns nil' do
expect(subject).to be_blank
end
end
end
context 'when the license is blank' do
let(:license) { nil }
it 'returns nil' do
expect(subject).to be_blank
end
end
end
end end
...@@ -224,4 +224,36 @@ describe ProjectsHelper do ...@@ -224,4 +224,36 @@ describe ProjectsHelper do
end end
end end
end end
describe '#subscription_message' do
let(:gitlab_subscription) { double(:gitlab_subscription) }
let(:decorated_mock) { double(:decorated_mock) }
let(:message_mock) { double(:message_mock) }
let(:user) { double(:user_mock) }
it 'if it is not Gitlab.com? it returns nil' do
allow(Gitlab).to receive(:com?).and_return(false)
expect(helper.subscription_message).to be_nil
end
it 'calls 2 classes if is Gitlab.com?' do
allow(Gitlab).to receive(:com?).and_return(true)
allow(helper).to receive(:signed_in?).and_return(true)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).with(user, :owner_access, project).and_return(true)
allow(project).to receive(:gitlab_subscription).and_return(gitlab_subscription)
expect(SubscriptionPresenter).to receive(:new).with(gitlab_subscription).and_return(decorated_mock)
expect(::Gitlab::ExpiringSubscriptionMessage).to receive(:new).with(
subscribable: decorated_mock,
signed_in: true,
is_admin: true,
namespace: project.namespace
).and_return(message_mock)
expect(message_mock).to receive(:message).and_return('hey yay yay yay')
expect(helper.subscription_message).to eq('hey yay yay yay')
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::ExpiringSubscriptionMessage do
include ActionView::Helpers::SanitizeHelper
describe 'message' do
subject { strip_tags(message) }
let(:subscribable) { double(:license) }
let(:namespace) { nil }
let(:message) do
described_class.new(
subscribable: subscribable,
signed_in: true,
is_admin: true,
namespace: namespace
).message
end
context 'subscribable installed' do
let(:expired_date) { Time.utc(2020, 3, 9, 10) }
let(:today) { Time.utc(2020, 3, 7, 10) }
before do
allow(subscribable).to receive(:plan).and_return('ultimate')
allow(subscribable).to receive(:expires_at).and_return(expired_date)
end
context 'subscribable should not notify admins' do
it 'returns nil' do
allow(subscribable).to receive(:notify_admins?).and_return(false)
allow(subscribable).to receive(:notify_users?).and_return(false)
expect(subject).to be nil
end
end
context 'subscribable should notify admins' do
before do
allow(subscribable).to receive(:notify_admins?).and_return(true)
end
context 'admin signed in' do
let(:signed_in) { true }
let(:is_admin) { true }
context 'subscribable expired' do
let(:expired_date) { Time.utc(2020, 3, 1, 10).to_date }
before do
allow(subscribable).to receive(:expired?).and_return(true)
allow(subscribable).to receive(:expires_at).and_return(expired_date)
end
context 'when it blocks changes' do
before do
allow(subscribable).to receive(:will_block_changes?).and_return(true)
end
context 'when it is currently blocking changes' do
before do
allow(subscribable).to receive(:block_changes?).and_return(true)
allow(subscribable).to receive(:block_changes_at).and_return(expired_date)
end
it 'has a nice subject' do
allow(subscribable).to receive(:will_block_changes?).and_return(false)
Timecop.freeze(today) do
expect(subject).to include('Your subscription has been downgraded')
end
end
context 'no namespace' do
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to include("You didn't renew your Ultimate subscription so it was downgraded to the GitLab Core Plan")
end
end
end
context 'with namespace' do
let(:namespace) { double(:namespace, name: 'No Limit Records') }
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to include("You didn't renew your Ultimate subscription for No Limit Records so it was downgraded to the free plan")
end
end
end
end
context 'when it is not currently blocking changes' do
before do
allow(subscribable).to receive(:block_changes?).and_return(false)
end
it 'has a nice subject' do
allow(subscribable).to receive(:will_block_changes?).and_return(false)
Timecop.freeze(today) do
expect(subject).to include('Your subscription expired!')
end
end
it 'has an expiration blocking message' do
allow(subscribable).to receive(:block_changes_at).and_return(Time.utc(2020, 3, 9, 10).to_date)
Timecop.freeze(today) do
expect(subject).to include('No worries, you can still use all the Ultimate features for now. You have 2 days to renew your subscription.')
end
end
end
end
end
context 'subscribable is expiring soon' do
before do
allow(subscribable).to receive(:expired?).and_return(false)
allow(subscribable).to receive(:remaining_days).and_return(4)
allow(subscribable).to receive(:will_block_changes?).and_return(true)
allow(subscribable).to receive(:block_changes_at).and_return(expired_date)
end
it 'has a nice subject' do
Timecop.freeze(today) do
expect(subject).to include('Your subscription will expire in 4 days')
end
end
context 'without namespace' do
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to include('Your Ultimate subscription will expire on 2020-03-09. After that, you will not to be able to create issues or merge requests as well as many other features.')
end
end
end
context 'with namespace' do
let(:namespace) { double(:namespace, name: 'No Limit Records') }
it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to include('Your Ultimate subscription for No Limit Records will expire on 2020-03-09. After that, you will not to be able to create issues or merge requests as well as many other features.')
end
end
end
end
end
end
end
context 'no subscribable installed' do
let(:subscribable) { nil }
it { is_expected.to be_blank }
end
end
end
...@@ -2590,4 +2590,23 @@ describe Project do ...@@ -2590,4 +2590,23 @@ describe Project do
end end
end end
end end
describe '#gitlab_subscription' do
subject { project.gitlab_subscription }
let(:project) { create(:project, namespace: namespace) }
context 'has a gitlab subscription' do
let(:namespace) { subscription.namespace }
let(:subscription) { create(:gitlab_subscription) }
it { is_expected.to eq(subscription) }
end
context 'does not have a gitlab subscription' do
let(:namespace) { create(:namespace) }
it { is_expected.to be_nil }
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe SubscriptionPresenter do
let(:subscription) { create(:gitlab_subscription) }
let(:presenter) { described_class.new(subscription, {}) }
describe '#plan' do
subject { presenter.plan }
it { is_expected.to eq('gold') }
end
describe '#notify_admins?' do
subject { presenter.notify_admins? }
let(:today) { Time.utc(2020, 3, 7, 10) }
it 'is false when remaining days is nil' do
expect(subject).to be false
end
it 'remaining days more than 30 is false' do
allow(subscription).to receive(:end_date).and_return(Time.utc(2020, 4, 9, 10).to_date)
Timecop.freeze(today) do
expect(subject).to be false
end
end
it 'remaining days less than 30 is true' do
allow(subscription).to receive(:end_date).and_return(Time.utc(2020, 3, 9, 10).to_date)
Timecop.freeze(today) do
expect(subject).to be true
end
end
end
describe '#notify_users?' do
subject { presenter.notify_users? }
it { is_expected.to be false }
end
describe '#block_changes_at' do
subject { presenter.block_changes_at }
it { is_expected.to eq(subscription.end_date) }
end
describe '#block_changes?' do
subject { presenter.block_changes? }
it { is_expected.to be false }
context 'is expired' do
before do
allow(subscription).to receive(:expired?).and_return(true)
end
it { is_expected.to be true }
end
end
describe '#will_block_changes?' do
subject { presenter.will_block_changes? }
it { is_expected.to be true }
end
describe '#remaining_days' do
subject { presenter.remaining_days }
let(:today) { Time.utc(2020, 3, 7, 10) }
it 'is nil when end_date is nil' do
allow(subscription).to receive(:end_date).and_return(nil)
expect(subject).to be nil
end
it 'returns the number of days between end_date and today' do
allow(subscription).to receive(:end_date).and_return(Time.utc(2020, 3, 9, 10).to_date)
Timecop.freeze(today) do
expect(subject).to eq(2)
end
end
end
end
...@@ -23539,6 +23539,9 @@ msgstr "" ...@@ -23539,6 +23539,9 @@ msgstr ""
msgid "You could not create a new trigger." msgid "You could not create a new trigger."
msgstr "" msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan." msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr "" msgstr ""
...@@ -23770,6 +23773,9 @@ msgstr "" ...@@ -23770,6 +23773,9 @@ msgstr ""
msgid "YouTube" msgid "YouTube"
msgstr "" msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features." msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
msgstr "" msgstr ""
......
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