Commit 1e58a809 authored by Alex Buijs's avatar Alex Buijs

Add step 2 of the experimental signup flow

The welcome page is the second page of the
experimental signup flow
parent faef0d1c
import LengthValidator from '~/pages/sessions/new/length_validator';
import NoEmojiValidator from '~/emoji/no_emoji_validator';
document.addEventListener('DOMContentLoaded', () => {
new LengthValidator(); // eslint-disable-line no-new
new NoEmojiValidator(); // eslint-disable-line no-new
});
...@@ -42,6 +42,26 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -42,6 +42,26 @@ class RegistrationsController < Devise::RegistrationsController
end end
end end
def welcome
return redirect_to new_user_registration_path unless current_user
return redirect_to stored_location_or_dashboard(current_user) if current_user.role.present?
flash[:notice] = nil
current_user.name = nil
render layout: 'devise_experimental_separate_sign_up_flow'
end
def update_role
user_params = params.require(:user).permit(:name, :role)
result = ::Users::UpdateService.new(current_user, user_params.merge(user: current_user)).execute
if result[:status] == :success
redirect_to stored_location_or_dashboard(current_user)
else
redirect_to users_sign_up_welcome_path, alert: result[:message]
end
end
protected protected
def persist_accepted_terms_if_required(new_user) def persist_accepted_terms_if_required(new_user)
...@@ -76,6 +96,9 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -76,6 +96,9 @@ class RegistrationsController < Devise::RegistrationsController
def after_sign_up_path_for(user) def after_sign_up_path_for(user)
Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?)) Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?))
return users_sign_up_welcome_path if helpers.use_experimental_separate_sign_up_flow?
confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path
end end
...@@ -114,7 +137,13 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -114,7 +137,13 @@ class RegistrationsController < Devise::RegistrationsController
end end
def sign_up_params def sign_up_params
params.require(:user).permit(:username, :email, :email_confirmation, :name, :password) clean_params = params.require(:user).permit(:username, :email, :email_confirmation, :name, :password)
if helpers.use_experimental_separate_sign_up_flow?
clean_params[:name] = clean_params[:username]
end
clean_params
end end
def resource_name def resource_name
......
- max_name_length = 128 - content_for(:page_title, _('Register for GitLab.com'))
- max_username_length = 255 - max_username_length = 255
.signup-box.p-3.mb-2 .signup-box.p-3.mb-2
.signup-body .signup-body
...@@ -6,9 +6,6 @@ ...@@ -6,9 +6,6 @@
.devise-errors.mt-0 .devise-errors.mt-0
= render "devise/shared/error_messages", resource: resource = render "devise/shared/error_messages", resource: resource
= invisible_captcha = invisible_captcha
.name.form-group
= f.label :name, _('Full name'), class: 'label-bold'
= f.text_field :name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _("This field is required.")
.username.form-group .username.form-group
= f.label :username, class: 'label-bold' = f.label :username, class: 'label-bold'
= f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.") = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
......
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
= render_if_exists 'layouts/devise_help_text' = render_if_exists 'layouts/devise_help_text'
.text-center.signup-heading.mt-3.mb-3 .text-center.signup-heading.mt-3.mb-3
= image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo') = image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo')
%h2= _('Register for GitLab.com') - if content_for?(:page_title)
%h2= yield :page_title
= yield = yield
%hr.footer-fixed %hr.footer-fixed
.footer-container .footer-container
......
- content_for(:page_title, _('Welcome to GitLab.com<br>%{username}!' % { username: current_user.username }).html_safe)
- max_name_length = 128
.text-center.mb-2
= _('In order to tailor your experience with GitLab<br>we would like to know a bit more about you.').html_safe
.signup-box.p-3.mb-2
.signup-body
= form_for(current_user, url: users_sign_up_update_role_path, html: { class: 'new_new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
.devise-errors.mt-0
= render 'devise/shared/error_messages', resource: current_user
.form-group
= f.label :name, _('Full name'), class: 'label-bold'
= f.text_field :name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_name_length, :max_length_message => s_('Name is too long (maximum is %{max_length} characters).') % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _('This field is required.')
.form-group
= f.label :role, _('Role'), class: 'label-bold'
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control'
.submit-container.mt-3
= f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2'
...@@ -55,6 +55,10 @@ Rails.application.routes.draw do ...@@ -55,6 +55,10 @@ Rails.application.routes.draw do
get '/autocomplete/project_groups' => 'autocomplete#project_groups' get '/autocomplete/project_groups' => 'autocomplete#project_groups'
end end
# Sign up
get 'users/sign_up/welcome' => 'registrations#welcome'
patch 'users/sign_up/update_role' => 'registrations#update_role'
# Search # Search
get 'search' => 'search#show' get 'search' => 'search#show'
get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
......
...@@ -23,6 +23,10 @@ module EE ...@@ -23,6 +23,10 @@ module EE
clean_params[:email_opted_in_at] = Time.zone.now clean_params[:email_opted_in_at] = Time.zone.now
end end
if helpers.use_experimental_separate_sign_up_flow?
clean_params[:name] = clean_params[:username]
end
clean_params clean_params
end end
end end
......
...@@ -7793,6 +7793,9 @@ msgstr "" ...@@ -7793,6 +7793,9 @@ msgstr ""
msgid "Get started with performance monitoring" msgid "Get started with performance monitoring"
msgstr "" msgstr ""
msgid "Get started!"
msgstr ""
msgid "Getting started with releases" msgid "Getting started with releases"
msgstr "" msgstr ""
...@@ -8869,6 +8872,9 @@ msgstr "" ...@@ -8869,6 +8872,9 @@ msgstr ""
msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index." msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index."
msgstr "" msgstr ""
msgid "In order to tailor your experience with GitLab<br>we would like to know a bit more about you."
msgstr ""
msgid "In the next step, you'll be able to select the projects you want to import." msgid "In the next step, you'll be able to select the projects you want to import."
msgstr "" msgstr ""
...@@ -10657,6 +10663,9 @@ msgstr "" ...@@ -10657,6 +10663,9 @@ msgstr ""
msgid "Name has already been taken" msgid "Name has already been taken"
msgstr "" msgstr ""
msgid "Name is too long (maximum is %{max_length} characters)."
msgstr ""
msgid "Name new label" msgid "Name new label"
msgstr "" msgstr ""
...@@ -14017,6 +14026,9 @@ msgstr "" ...@@ -14017,6 +14026,9 @@ msgstr ""
msgid "Roadmap" msgid "Roadmap"
msgstr "" msgstr ""
msgid "Role"
msgstr ""
msgid "Rollback" msgid "Rollback"
msgstr "" msgstr ""
......
...@@ -129,35 +129,43 @@ shared_examples 'Signup' do ...@@ -129,35 +129,43 @@ shared_examples 'Signup' do
describe 'user\'s full name validation', :js do describe 'user\'s full name validation', :js do
before do before do
visit new_user_registration_path if Feature.enabled?(:experimental_separate_sign_up_flow)
user = create(:user, role: nil)
sign_in(user)
visit users_sign_up_welcome_path
@user_name_field = 'user_name'
else
visit new_user_registration_path
@user_name_field = 'new_user_name'
end
end end
it 'does not show an error border if the user\'s fullname length is not longer than 128 characters' do it 'does not show an error border if the user\'s fullname length is not longer than 128 characters' do
fill_in 'new_user_name', with: 'u' * 128 fill_in @user_name_field, with: 'u' * 128
expect(find('.name')).not_to have_css '.gl-field-error-outline' expect(find('.name')).not_to have_css '.gl-field-error-outline'
end end
it 'shows an error border if the user\'s fullname contains an emoji' do it 'shows an error border if the user\'s fullname contains an emoji' do
simulate_input('#new_user_name', 'Ehsan 🦋') simulate_input("##{@user_name_field}", 'Ehsan 🦋')
expect(find('.name')).to have_css '.gl-field-error-outline' expect(find('.name')).to have_css '.gl-field-error-outline'
end end
it 'shows an error border if the user\'s fullname is longer than 128 characters' do it 'shows an error border if the user\'s fullname is longer than 128 characters' do
fill_in 'new_user_name', with: 'n' * 129 fill_in @user_name_field, with: 'n' * 129
expect(find('.name')).to have_css '.gl-field-error-outline' expect(find('.name')).to have_css '.gl-field-error-outline'
end end
it 'shows an error message if the user\'s fullname is longer than 128 characters' do it 'shows an error message if the user\'s fullname is longer than 128 characters' do
fill_in 'new_user_name', with: 'n' * 129 fill_in @user_name_field, with: 'n' * 129
expect(page).to have_content("Name is too long (maximum is 128 characters).") expect(page).to have_content("Name is too long (maximum is 128 characters).")
end end
it 'shows an error message if the username contains emojis' do it 'shows an error message if the username contains emojis' do
simulate_input('#new_user_name', 'Ehsan 🦋') simulate_input("##{@user_name_field}", 'Ehsan 🦋')
expect(page).to have_content("Invalid input, please avoid emojis") expect(page).to have_content("Invalid input, please avoid emojis")
end end
...@@ -177,11 +185,11 @@ shared_examples 'Signup' do ...@@ -177,11 +185,11 @@ shared_examples 'Signup' do
it 'creates the user account and sends a confirmation email' do it 'creates the user account and sends a confirmation email' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email fill_in 'new_user_email_confirmation', with: new_user.email
end end
...@@ -202,11 +210,11 @@ shared_examples 'Signup' do ...@@ -202,11 +210,11 @@ shared_examples 'Signup' do
it 'creates the user account and sends a confirmation email' do it 'creates the user account and sends a confirmation email' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email fill_in 'new_user_email_confirmation', with: new_user.email
end end
...@@ -214,8 +222,12 @@ shared_examples 'Signup' do ...@@ -214,8 +222,12 @@ shared_examples 'Signup' do
expect { click_button 'Register' }.to change { User.count }.by(1) expect { click_button 'Register' }.to change { User.count }.by(1)
expect(current_path).to eq dashboard_projects_path if Feature.enabled?(:experimental_separate_sign_up_flow)
expect(page).to have_content("Please check your email (#{new_user.email}) to verify that you own this address.") expect(current_path).to eq users_sign_up_welcome_path
else
expect(current_path).to eq dashboard_projects_path
expect(page).to have_content("Please check your email (#{new_user.email}) to verify that you own this address.")
end
end end
end end
end end
...@@ -224,19 +236,23 @@ shared_examples 'Signup' do ...@@ -224,19 +236,23 @@ shared_examples 'Signup' do
it "creates the user successfully" do it "creates the user successfully" do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email.capitalize fill_in 'new_user_email_confirmation', with: new_user.email.capitalize
end end
fill_in 'new_user_password', with: new_user.password fill_in 'new_user_password', with: new_user.password
click_button "Register" click_button "Register"
expect(current_path).to eq dashboard_projects_path if Feature.enabled?(:experimental_separate_sign_up_flow)
expect(page).to have_content("Welcome! You have signed up successfully.") expect(current_path).to eq users_sign_up_welcome_path
else
expect(current_path).to eq dashboard_projects_path
expect(page).to have_content("Welcome! You have signed up successfully.")
end
end end
end end
...@@ -248,19 +264,23 @@ shared_examples 'Signup' do ...@@ -248,19 +264,23 @@ shared_examples 'Signup' do
it 'creates the user account and goes to dashboard' do it 'creates the user account and goes to dashboard' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email fill_in 'new_user_email_confirmation', with: new_user.email
end end
fill_in 'new_user_password', with: new_user.password fill_in 'new_user_password', with: new_user.password
click_button "Register" click_button "Register"
expect(current_path).to eq dashboard_projects_path if Feature.enabled?(:experimental_separate_sign_up_flow)
expect(page).to have_content("Welcome! You have signed up successfully.") expect(current_path).to eq users_sign_up_welcome_path
else
expect(current_path).to eq dashboard_projects_path
expect(page).to have_content("Welcome! You have signed up successfully.")
end
end end
end end
end end
...@@ -271,7 +291,10 @@ shared_examples 'Signup' do ...@@ -271,7 +291,10 @@ shared_examples 'Signup' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
end
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: existing_user.email fill_in 'new_user_email', with: existing_user.email
fill_in 'new_user_password', with: new_user.password fill_in 'new_user_password', with: new_user.password
...@@ -281,12 +304,12 @@ shared_examples 'Signup' do ...@@ -281,12 +304,12 @@ shared_examples 'Signup' do
if Feature.enabled?(:experimental_separate_sign_up_flow) if Feature.enabled?(:experimental_separate_sign_up_flow)
expect(page).to have_content("error prohibited this user from being saved") expect(page).to have_content("error prohibited this user from being saved")
expect(page).to have_content("Email has already been taken")
else else
expect(page).to have_content("errors prohibited this user from being saved") expect(page).to have_content("errors prohibited this user from being saved")
expect(page).to have_content("Email has already been taken")
expect(page).to have_content("Email confirmation doesn't match") expect(page).to have_content("Email confirmation doesn't match")
end end
expect(page).to have_content("Email has already been taken")
end end
it 'does not redisplay the password' do it 'does not redisplay the password' do
...@@ -294,7 +317,10 @@ shared_examples 'Signup' do ...@@ -294,7 +317,10 @@ shared_examples 'Signup' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
end
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: existing_user.email fill_in 'new_user_email', with: existing_user.email
fill_in 'new_user_password', with: new_user.password fill_in 'new_user_password', with: new_user.password
...@@ -313,11 +339,11 @@ shared_examples 'Signup' do ...@@ -313,11 +339,11 @@ shared_examples 'Signup' do
it 'requires the user to check the checkbox' do it 'requires the user to check the checkbox' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email fill_in 'new_user_email_confirmation', with: new_user.email
end end
...@@ -332,11 +358,11 @@ shared_examples 'Signup' do ...@@ -332,11 +358,11 @@ shared_examples 'Signup' do
it 'asks the user to accept terms before going to the dashboard' do it 'asks the user to accept terms before going to the dashboard' do
visit new_user_registration_path visit new_user_registration_path
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_username', with: new_user.username fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email fill_in 'new_user_email', with: new_user.email
unless Feature.enabled?(:experimental_separate_sign_up_flow) unless Feature.enabled?(:experimental_separate_sign_up_flow)
fill_in 'new_user_name', with: new_user.name
fill_in 'new_user_email_confirmation', with: new_user.email fill_in 'new_user_email_confirmation', with: new_user.email
end end
...@@ -345,24 +371,51 @@ shared_examples 'Signup' do ...@@ -345,24 +371,51 @@ shared_examples 'Signup' do
click_button "Register" click_button "Register"
expect(current_path).to eq dashboard_projects_path if Feature.enabled?(:experimental_separate_sign_up_flow)
expect(current_path).to eq users_sign_up_welcome_path
else
expect(current_path).to eq dashboard_projects_path
end
end end
end end
end end
describe 'With original flow' do describe 'With original flow' do
it_behaves_like 'Signup' do before do
before do stub_feature_flags(experimental_separate_sign_up_flow: false)
stub_feature_flags(experimental_separate_sign_up_flow: false)
end
end end
it_behaves_like 'Signup'
end end
describe 'With experimental flow on GitLab.com' do describe 'With experimental flow on GitLab.com' do
it_behaves_like 'Signup' do before do
allow(::Gitlab).to receive(:com?).and_return(true)
stub_feature_flags(experimental_separate_sign_up_flow: true)
end
it_behaves_like 'Signup'
describe 'user without role' do
let(:user) { create(:user, role: nil) }
before do before do
expect(Gitlab).to receive(:com?).and_return(true).at_least(:once) sign_in(user)
stub_feature_flags(experimental_separate_sign_up_flow: true) visit users_sign_up_welcome_path
end
it 'is shows step 2 of the signup process' do
expect(page).to have_text("Welcome to GitLab.com#{user.username}!")
end
it 'updates the user and sets the name and role' do
fill_in 'user_name', with: 'New name'
select 'Software Developer', from: 'user_role'
click_button 'Get started!'
user.reload
expect(user.name).to eq 'New name'
expect(user.role).to eq 'software_developer'
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