Commit b349f475 authored by Dmytro Zaporozhets (DZ)'s avatar Dmytro Zaporozhets (DZ)

Merge branch 'nicolasdular/marketing-opt-in' into 'master'

Move marketing opt in to welcome page

See merge request gitlab-org/gitlab!46446
parents 0acf8815 9d247f72
...@@ -60,8 +60,7 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -60,8 +60,7 @@ class RegistrationsController < Devise::RegistrationsController
def update_registration def update_registration
return redirect_to new_user_registration_path unless current_user return redirect_to new_user_registration_path unless current_user
user_params = params.require(:user).permit(:role, :setup_for_company) result = ::Users::SignupService.new(current_user, update_registration_params).execute
result = ::Users::SignupService.new(current_user, user_params).execute
if result[:status] == :success if result[:status] == :success
if ::Gitlab.com? && show_onboarding_issues_experiment? if ::Gitlab.com? && show_onboarding_issues_experiment?
...@@ -164,6 +163,10 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -164,6 +163,10 @@ class RegistrationsController < Devise::RegistrationsController
params.require(:user).permit(:username, :email, :name, :first_name, :last_name, :password) params.require(:user).permit(:username, :email, :name, :first_name, :last_name, :password)
end end
def update_registration_params
params.require(:user).permit(:role, :setup_for_company)
end
def resource_name def resource_name
:user :user
end end
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
= f.label :password, class: 'label-bold' = f.label :password, class: 'label-bold'
= f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length } %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'devise/shared/email_opted_in', f: f
%div %div
- if show_recaptcha_sign_up? - if show_recaptcha_sign_up?
= recaptcha_tags = recaptcha_tags
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
= f.label :password, class: 'label-bold' = f.label :password, class: 'label-bold'
= f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length } %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'devise/shared/email_opted_in', f: f
%div %div
- if show_recaptcha_sign_up? - if show_recaptcha_sign_up?
= recaptcha_tags = recaptcha_tags
......
...@@ -2,4 +2,16 @@ import mountProgressBar from 'ee/registrations/welcome'; ...@@ -2,4 +2,16 @@ import mountProgressBar from 'ee/registrations/welcome';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
mountProgressBar(); mountProgressBar();
const emailUpdatesForm = document.querySelector('.js-email-opt-in');
const setupForCompany = document.querySelector('.js-setup-for-company');
const setupForMe = document.querySelector('.js-setup-for-me');
setupForCompany.addEventListener('change', () => {
emailUpdatesForm.classList.add('hidden');
});
setupForMe.addEventListener('change', () => {
emailUpdatesForm.classList.remove('hidden');
});
}); });
...@@ -14,9 +14,11 @@ module EE ...@@ -14,9 +14,11 @@ module EE
super(confirmed: confirmed) + ", experiments:#{experiments}" super(confirmed: confirmed) + ", experiments:#{experiments}"
end end
def sign_up_params def update_registration_params
clean_params = super.merge(params.require(:user).permit(:email_opted_in)) clean_params = super.merge(params.require(:user).permit(:email_opted_in))
clean_params[:email_opted_in] = '1' if clean_params[:setup_for_company] == 'true'
if clean_params[:email_opted_in] == '1' if clean_params[:email_opted_in] == '1'
clean_params[:email_opted_in_ip] = request.remote_ip clean_params[:email_opted_in_ip] = request.remote_ip
clean_params[:email_opted_in_source_id] = User::EMAIL_OPT_IN_SOURCE_ID_GITLAB_COM clean_params[:email_opted_in_source_id] = User::EMAIL_OPT_IN_SOURCE_ID_GITLAB_COM
......
- if Gitlab.com? - return unless Gitlab.dev_env_or_com?
.form-group - is_hidden = local_assigns.fetch(:hidden, false)
= f.check_box :email_opted_in
= f.label :email_opted_in, "I'd like to receive updates via email about GitLab." .js-email-opt-in{ class: is_hidden ? 'hidden' : '' }
.gl-font-weight-bold.gl-mb-3.gl-mt-3
= _('Email updates (optional)')
= f.check_box :email_opted_in
= f.label :email_opted_in, _("I'd like to receive updates about GitLab via email"), class: 'gl-font-weight-normal'
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
= f.label :setup_for_company, setup_for_company_label_text, class: 'label-bold' = f.label :setup_for_company, setup_for_company_label_text, class: 'label-bold'
.d-flex.flex-column.flex-lg-row .d-flex.flex-column.flex-lg-row
.flex-grow-1 .flex-grow-1
= f.radio_button :setup_for_company, true = f.radio_button :setup_for_company, true, class: 'js-setup-for-company'
= f.label :setup_for_company, _('My company or team'), class: 'normal', value: 'true' = f.label :setup_for_company, _('My company or team'), class: 'normal', value: 'true'
.flex-grow-1 .flex-grow-1
= f.radio_button :setup_for_company, false = f.radio_button :setup_for_company, false, class: 'js-setup-for-me'
= f.label :setup_for_company, _('Just me'), class: 'normal', value: 'false' = f.label :setup_for_company, _('Just me'), class: 'normal', value: 'false'
= render_if_exists 'devise/shared/email_opted_in', f: f, hidden: true
...@@ -27,9 +27,6 @@ ...@@ -27,9 +27,6 @@
= f.label :password, for: 'new_user_password', class: 'label-bold' = f.label :password, for: 'new_user_password', class: 'label-bold'
= f.password_field :password, class: 'form-control bottom', data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } = f.password_field :password, class: 'form-control bottom', data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length } %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
.form-group
= f.check_box :email_opted_in, data: { qa_selector: 'new_user_email_opted_in_checkbox' }
= f.label :email_opted_in, _("I'd like to receive updates via email about GitLab"), class: 'form-check-label'
%div %div
- if show_recaptcha_sign_up? - if show_recaptcha_sign_up?
= recaptcha_tags = recaptcha_tags
......
---
title: Move marketing opt in to welcome page and opt in by default when setting up for a company
merge_request: 46446
author:
type: changed
...@@ -9,32 +9,6 @@ RSpec.describe RegistrationsController do ...@@ -9,32 +9,6 @@ RSpec.describe RegistrationsController do
let(:base_user_params) { build_stubbed(:user).slice(:first_name, :last_name, :username, :email, :password) } let(:base_user_params) { build_stubbed(:user).slice(:first_name, :last_name, :username, :email, :password) }
let(:user_params) { { user: base_user_params } } let(:user_params) { { user: base_user_params } }
context 'when the user opted-in' do
let(:user_params) { { user: base_user_params.merge(email_opted_in: '1') } }
it 'sets the rest of the email_opted_in fields' do
post :create, params: user_params
user = User.find_by_username!(user_params[:user][:username])
expect(user.email_opted_in).to be_truthy
expect(user.email_opted_in_ip).to be_present
expect(user.email_opted_in_source).to eq('GitLab.com')
expect(user.email_opted_in_at).not_to be_nil
end
end
context 'when the user opted-out' do
let(:user_params) { { user: base_user_params.merge(email_opted_in: '0') } }
it 'does not set the rest of the email_opted_in fields' do
post :create, params: user_params
user = User.find_by_username!(user_params[:user][:username])
expect(user.email_opted_in).to be_falsey
expect(user.email_opted_in_ip).to be_blank
expect(user.email_opted_in_source).to be_blank
expect(user.email_opted_in_at).to be_nil
end
end
context 'when reCAPTCHA experiment enabled' do context 'when reCAPTCHA experiment enabled' do
it "logs a 'User Created' message including the experiment state" do it "logs a 'User Created' message including the experiment state" do
allow_any_instance_of(EE::RecaptchaExperimentHelper).to receive(:show_recaptcha_sign_up?).and_return(true) allow_any_instance_of(EE::RecaptchaExperimentHelper).to receive(:show_recaptcha_sign_up?).and_return(true)
...@@ -59,7 +33,18 @@ RSpec.describe RegistrationsController do ...@@ -59,7 +33,18 @@ RSpec.describe RegistrationsController do
end end
describe '#update_registration' do describe '#update_registration' do
subject(:update_registration) { patch :update_registration, params: { user: { role: 'software_developer', setup_for_company: 'false' } } } let(:setup_for_company) { 'false' }
let(:email_opted_in) { '0' }
subject(:update_registration) do
patch :update_registration, params: {
user: {
role: 'software_developer',
setup_for_company: setup_for_company,
email_opted_in: email_opted_in
}
}
end
context 'without a signed in user' do context 'without a signed in user' do
it { is_expected.to redirect_to new_user_registration_path } it { is_expected.to redirect_to new_user_registration_path }
...@@ -70,6 +55,49 @@ RSpec.describe RegistrationsController do ...@@ -70,6 +55,49 @@ RSpec.describe RegistrationsController do
sign_in(user) sign_in(user)
end end
context 'email updates' do
context 'when setup for company is false' do
context 'when the user opted in' do
let(:email_opted_in) { '1' }
it 'sets the email_opted_in fields' do
subject
expect(controller.current_user.email_opted_in).to be_truthy
expect(controller.current_user.email_opted_in_ip).to be_present
expect(controller.current_user.email_opted_in_source).to eq('GitLab.com')
expect(controller.current_user.email_opted_in_at).not_to be_nil
end
end
context 'when user opted out' do
let(:email_opted_in) { '0' }
it 'does not set the rest of the email_opted_in fields' do
subject
expect(controller.current_user.email_opted_in).to be_falsey
expect(controller.current_user.email_opted_in_ip).to be_blank
expect(controller.current_user.email_opted_in_source).to be_blank
expect(controller.current_user.email_opted_in_at).to be_nil
end
end
end
context 'when setup for company is true' do
let(:setup_for_company) { 'true' }
it 'sets email_opted_in fields' do
subject
expect(controller.current_user.email_opted_in).to be_truthy
expect(controller.current_user.email_opted_in_ip).to be_present
expect(controller.current_user.email_opted_in_source).to eq('GitLab.com')
expect(controller.current_user.email_opted_in_at).not_to be_nil
end
end
end
describe 'redirection' do describe 'redirection' do
it { is_expected.to redirect_to dashboard_projects_path } it { is_expected.to redirect_to dashboard_projects_path }
......
...@@ -18,14 +18,37 @@ RSpec.describe 'Signup on EE' do ...@@ -18,14 +18,37 @@ RSpec.describe 'Signup on EE' do
expect(Gitlab).to receive(:com?).and_return(true).at_least(:once) expect(Gitlab).to receive(:com?).and_return(true).at_least(:once)
end end
context 'when the user sets it up for the company' do
it 'creates the user and sets the email_opted_in field truthy' do
visit root_path
fill_in_signup_form
click_button "Register"
select 'Software Developer', from: 'user_role'
choose 'user_setup_for_company_true'
click_button 'Get started!'
user = User.find_by_username!(new_user[:username])
expect(user.email_opted_in).to be_truthy
expect(user.email_opted_in_ip).to be_present
expect(user.email_opted_in_source).to eq('GitLab.com')
expect(user.email_opted_in_at).not_to be_nil
end
end
context 'when the user checks the opt-in to email updates box' do context 'when the user checks the opt-in to email updates box' do
it 'creates the user and sets the email_opted_in field truthy' do it 'creates the user and sets the email_opted_in field truthy' do
visit root_path visit root_path
fill_in_signup_form fill_in_signup_form
check 'new_user_email_opted_in'
click_button "Register" click_button "Register"
select 'Software Developer', from: 'user_role'
choose 'user_setup_for_company_false'
check 'user_email_opted_in'
click_button 'Get started!'
user = User.find_by_username!(new_user[:username]) user = User.find_by_username!(new_user[:username])
expect(user.email_opted_in).to be_truthy expect(user.email_opted_in).to be_truthy
expect(user.email_opted_in_ip).to be_present expect(user.email_opted_in_ip).to be_present
...@@ -41,6 +64,10 @@ RSpec.describe 'Signup on EE' do ...@@ -41,6 +64,10 @@ RSpec.describe 'Signup on EE' do
fill_in_signup_form fill_in_signup_form
click_button "Register" click_button "Register"
select 'Software Developer', from: 'user_role'
choose 'user_setup_for_company_false'
click_button 'Get started!'
user = User.find_by_username!(new_user[:username]) user = User.find_by_username!(new_user[:username])
expect(user.email_opted_in).to be_falsey expect(user.email_opted_in).to be_falsey
expect(user.email_opted_in_ip).to be_blank expect(user.email_opted_in_ip).to be_blank
......
...@@ -9818,6 +9818,9 @@ msgstr "" ...@@ -9818,6 +9818,9 @@ msgstr ""
msgid "Email the pipelines status to a list of recipients." msgid "Email the pipelines status to a list of recipients."
msgstr "" msgstr ""
msgid "Email updates (optional)"
msgstr ""
msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies." msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies."
msgstr "" msgstr ""
...@@ -13631,7 +13634,7 @@ msgstr "" ...@@ -13631,7 +13634,7 @@ msgstr ""
msgid "I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)" msgid "I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)"
msgstr "" msgstr ""
msgid "I'd like to receive updates via email about GitLab" msgid "I'd like to receive updates about GitLab via email"
msgstr "" msgstr ""
msgid "ID" msgid "ID"
......
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