Commit 75c3ace5 authored by Jay Swain's avatar Jay Swain

Internationalize the renewal banner

I'll be working in this area and decided to backfill the test suite so
it'd be more easily refactorable for the feature I'm working on. In the
process I also added I18n suport.

At first glance one could argue this has duplicate language and could be
more concise, but I found it difficult to follow the GitLab best
practices for externalization (particularly "splitting sentences")
in it's previous implementation.

I also felt like although the code was more concise before, it was
fairly difficult to parse, and more difficult to extend.

* backfill license_helper_spec
* refactor license_helper

I've followed the best practices outlined here:
https://docs.gitlab.com/ee/development/i18n/externalization.html#best-practices

This is part of:
https://gitlab.com/gitlab-org/growth/product/-/issues/102
parent 89e07cc6
...@@ -23,48 +23,16 @@ module LicenseHelper ...@@ -23,48 +23,16 @@ module LicenseHelper
return unless signed_in return unless signed_in
return unless (is_admin && current_license.notify_admins?) || current_license.notify_users? return unless (is_admin && current_license.notify_admins?) || current_license.notify_users?
is_trial = current_license.trial? message = []
message = ["Your #{'trial ' if is_trial}license"]
message << expiration_message
message << link_to('Buy now!', ::EE::SUBSCRIPTIONS_PLANS_URL, target: '_blank') if is_trial
if current_license.expired? && current_license.will_block_changes?
message << 'Pushing code and creation of issues and merge requests'
message << block_changes_message
message << if is_admin
'Upload a new license in the admin area'
else
'Ask an admin to upload a new license'
end
message << 'to' is_trial = current_license.trial?
message << (current_license.block_changes? ? 'restore' : 'ensure uninterrupted')
message << 'service.'
end
message << license_message_subject(is_trial: is_trial)
message << trial_purchase_message if is_trial
message << expiration_blocking_message(is_admin: is_admin)
message << renewal_instructions_message unless is_trial message << renewal_instructions_message unless is_trial
message.join(' ').html_safe message.reject {|string| string.blank? }.join(' ').html_safe
end
def expiration_message
if current_license.expired?
"expired on #{current_license.expires_at}."
else
"will expire in #{pluralize(current_license.remaining_days, 'day')}."
end
end
def block_changes_message
if current_license.block_changes?
'has been disabled.'
else
"will be disabled on #{current_license.block_changes_at}."
end
end end
def seats_calculation_message def seats_calculation_message
...@@ -142,10 +110,71 @@ module LicenseHelper ...@@ -142,10 +110,71 @@ module LicenseHelper
User.active.count User.active.count
end end
def license_message_subject(is_trial:)
message = []
if current_license.expired?
expires_at = current_license.expires_at
message << if is_trial
_('Your trial license expired on %{expires_at}.') % { expires_at: expires_at }
else
_('Your license expired on %{expires_at}.') % { expires_at: expires_at }
end
else
remaining_days = pluralize(current_license.remaining_days, 'day')
message << if is_trial
_('Your trial license will expire in %{remaining_days}.') % { remaining_days: remaining_days }
else
_('Your license will expire in %{remaining_days}.') % { remaining_days: remaining_days }
end
end
message.join(' ')
end
def trial_purchase_message
buy_now_url = ::EE::SUBSCRIPTIONS_PLANS_URL
buy_now_link_start = "<a href='#{buy_now_url}' target='_blank' rel='noopener'>".html_safe
link_end = '</a>'.html_safe
_('%{buy_now_link_start}Buy now!%{link_end}') % { buy_now_link_start: buy_now_link_start, link_end: link_end }
end
def expiration_blocking_message(is_admin:)
return '' unless current_license.expired? && current_license.will_block_changes?
message = []
message << if current_license.block_changes?
_('Pushing code and creation of issues and merge requests has been disabled.')
else
_('Pushing code and creation of issues and merge requests will be disabled on %{disabled_on}.') % { disabled_on: current_license.block_changes_at }
end
message << if is_admin
if current_license.block_changes?
_('Upload a new license in the admin area to restore service.')
else
_('Upload a new license in the admin area to ensure uninterrupted service.')
end
else
if current_license.block_changes?
_('Ask an admin to upload a new license to restore service.')
else
_('Ask an admin to upload a new license to ensure uninterrupted service.')
end
end
message.join(' ')
end
def renewal_instructions_message def renewal_instructions_message
renewal_faq_url = 'https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription' renewal_faq_url = 'https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription'
renewal_faq_link_start = "<a href='#{renewal_faq_url}' target='_blank'>".html_safe renewal_faq_link_start = "<a href='#{renewal_faq_url}' target='_blank' rel='noopener'>".html_safe
link_end = '</a>'.html_safe link_end = '</a>'.html_safe
_('For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}') % { link_start: renewal_faq_link_start, link_end: link_end } _('For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}') % { link_start: renewal_faq_link_start, link_end: link_end }
......
...@@ -9,66 +9,138 @@ describe LicenseHelper do ...@@ -9,66 +9,138 @@ describe LicenseHelper do
end end
describe '#license_message' do describe '#license_message' do
context 'license installed' do subject { license_message(signed_in: signed_in, is_admin: is_admin) }
subject { license_message(signed_in: true, is_admin: false) }
let(:license) { double('License') } context 'license installed' do
let(:faq_link_regex) { /For renewal instructions <a href.*>view our Licensing FAQ\.<\/a>/ } let(:license) { double(:license) }
before do before do
allow(License).to receive(:current).and_return(license) allow(License).to receive(:current).and_return(license)
allow(license).to receive(:notify_users?).and_return(true)
allow(license).to receive(:expired?).and_return(false)
allow(license).to receive(:remaining_days).and_return(4)
end
it 'does NOT have a license faq link if license is a trial' do
allow(license).to receive(:trial?).and_return(true)
expect(subject).not_to match(faq_link_regex)
end
it 'has license faq link if license is not a trial' do
allow(license).to receive(:trial?).and_return(false)
expect(subject).to match(faq_link_regex)
end end
end
context 'no license installed' do context 'license is notify admins' do
before do before do
allow(License).to receive(:current).and_return(nil) allow(license).to receive(:notify_admins?).and_return(true)
end
context 'admin user' do
let(:is_admin) { true }
it 'displays correct error message for admin user' do
expect(license_message(signed_in: true, is_admin: is_admin)).to be_blank
end end
end
context 'normal user' do context 'admin signed in' do
let(:is_admin) { false } let(:signed_in) { true }
let(:is_admin) { true }
it 'displays correct error message for normal user' do context 'license is trial' do
expect(license_message(signed_in: true, is_admin: is_admin)).to be_blank before do
allow(license).to receive(:trial?).and_return(true)
end
context 'license expired' do
let(:expired_date) { Date.parse('2020-03-09') }
before do
allow(license).to receive(:expired?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
end
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
regex = /Your trial license expired on 2020-03-09\. <a href=\'https?:\/\/.*\/plans\' target=\'_blank\' rel=\'noopener\'>Buy now!<\/a>/
expect(subject).to match(regex)
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)
end
it 'has an expiration blocking message' do
regex = <<~HEREDOC.chomp
Pushing code and creation of issues and merge requests has been disabled. Upload a new license in the admin area to restore service.
HEREDOC
expect(subject).to match(regex)
end
context 'not admin' do
let(:is_admin) { false }
it 'has an expiration blocking message' do
allow(license).to receive(:notify_users?).and_return(true)
regex = <<~HEREDOC.chomp
Pushing code and creation of issues and merge requests has been disabled. Ask an admin to upload a new license to restore service.
HEREDOC
expect(subject).to match(regex)
end
end
end
context 'and its NOT currently blocking changes' do
it 'has an expiration blocking message' do
allow(license).to receive(:block_changes?).and_return(false)
allow(license).to receive(:block_changes_at).and_return(expired_date)
regex = <<~HEREDOC.chomp
Pushing code and creation of issues and merge requests will be disabled on 2020-03-09. Upload a new license in the admin area to ensure uninterrupted service.
HEREDOC
expect(subject).to match(regex)
end
end
end
end
context 'license NOT expired' do
it 'has a nice subject' 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(false)
regex = /Your trial license will expire in 4 days\. <a href=\'https?:\/\/.*\/plans\' target=\'_blank\' rel=\'noopener\'>Buy now!<\/a>/
expect(subject).to match(regex)
end
end
end
context 'license is NOT trial' do
let(:expired_date) { Date.parse('2020-03-09') }
before do
allow(license).to receive(:trial?).and_return(false)
allow(license).to receive(:expired?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
allow(license).to receive(:will_block_changes?).and_return(false)
end
it 'has a nice subject' do
regex = <<~HEREDOC.chomp
Your license expired on 2020-03-09. For renewal instructions <a href='https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription' target='_blank' rel='noopener'>view our Licensing FAQ.</a>
HEREDOC
expect(subject).to match(regex)
end
it 'does not have buy now link' do
expect(subject).not_to include('Buy now!')
end
end
end end
end end
end end
end
describe '#api_licenses_url' do context 'no license installed' do
it 'returns licenses API url' do let(:license) { nil }
stub_default_url_options let(:signed_in) { true }
let(:is_admin) { true }
expect(api_licenses_url).to eq('http://localhost/api/v4/licenses')
end
it 'returns licenses API url with relative url' do
stub_default_url_options(script_name: '/gitlab')
expect(api_licenses_url).to eq('http://localhost/gitlab/api/v4/licenses') it { is_expected.to be_blank }
end end
end end
......
...@@ -217,6 +217,9 @@ msgstr "" ...@@ -217,6 +217,9 @@ msgstr ""
msgid "%{authorsName}'s thread" msgid "%{authorsName}'s thread"
msgstr "" msgstr ""
msgid "%{buy_now_link_start}Buy now!%{link_end}"
msgstr ""
msgid "%{commit_author_link} authored %{commit_timeago}" msgid "%{commit_author_link} authored %{commit_timeago}"
msgstr "" msgstr ""
...@@ -2385,6 +2388,12 @@ msgstr "" ...@@ -2385,6 +2388,12 @@ msgstr ""
msgid "Ascending" msgid "Ascending"
msgstr "" msgstr ""
msgid "Ask an admin to upload a new license to ensure uninterrupted service."
msgstr ""
msgid "Ask an admin to upload a new license to restore service."
msgstr ""
msgid "Ask your group maintainer to set up a group Runner." msgid "Ask your group maintainer to set up a group Runner."
msgstr "" msgstr ""
...@@ -15962,6 +15971,12 @@ msgstr "" ...@@ -15962,6 +15971,12 @@ msgstr ""
msgid "Pushes" msgid "Pushes"
msgstr "" msgstr ""
msgid "Pushing code and creation of issues and merge requests has been disabled."
msgstr ""
msgid "Pushing code and creation of issues and merge requests will be disabled on %{disabled_on}."
msgstr ""
msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"." msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
msgstr "" msgstr ""
...@@ -21314,6 +21329,12 @@ msgstr "" ...@@ -21314,6 +21329,12 @@ msgstr ""
msgid "Upload a certificate for your domain with all intermediates" msgid "Upload a certificate for your domain with all intermediates"
msgstr "" msgstr ""
msgid "Upload a new license in the admin area to ensure uninterrupted service."
msgstr ""
msgid "Upload a new license in the admin area to restore service."
msgstr ""
msgid "Upload a private key for your certificate" msgid "Upload a private key for your certificate"
msgstr "" msgstr ""
...@@ -23028,9 +23049,15 @@ msgstr "" ...@@ -23028,9 +23049,15 @@ msgstr ""
msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email." msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
msgstr "" msgstr ""
msgid "Your license expired on %{expires_at}."
msgstr ""
msgid "Your license is valid from" msgid "Your license is valid from"
msgstr "" msgstr ""
msgid "Your license will expire in %{remaining_days}."
msgstr ""
msgid "Your message here" msgid "Your message here"
msgstr "" msgstr ""
...@@ -23061,6 +23088,12 @@ msgstr "" ...@@ -23061,6 +23088,12 @@ msgstr ""
msgid "Your request for access has been queued for review." msgid "Your request for access has been queued for review."
msgstr "" msgstr ""
msgid "Your trial license expired on %{expires_at}."
msgstr ""
msgid "Your trial license will expire in %{remaining_days}."
msgstr ""
msgid "Zoom meeting added" msgid "Zoom meeting added"
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