Commit 123bcddf authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge branch '48-add-company-question-to-profile-information' into 'master'

Add company question to profile information

See merge request gitlab-org/gitlab!17999
parents 529bf9aa b77dc957
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
.signup-heading h2 { .signup-heading h2 {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
padding: 0 10px; padding: 0 $gl-padding;
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
font-size: $gl-font-size-large; font-size: $gl-font-size-large;
......
...@@ -30,7 +30,7 @@ class ApplicationController < ActionController::Base ...@@ -30,7 +30,7 @@ class ApplicationController < ActionController::Base
before_action :active_user_check, unless: :devise_controller? before_action :active_user_check, unless: :devise_controller?
before_action :set_usage_stats_consent_flag before_action :set_usage_stats_consent_flag
before_action :check_impersonation_availability before_action :check_impersonation_availability
before_action :require_role before_action :required_signup_info
around_action :set_locale around_action :set_locale
around_action :set_session_storage around_action :set_session_storage
...@@ -538,10 +538,13 @@ class ApplicationController < ActionController::Base ...@@ -538,10 +538,13 @@ class ApplicationController < ActionController::Base
@current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user) @current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user)
end end
# A user requires a role when they are part of the experimental signup flow (executed by the Growth team). Users # A user requires a role and have the setup_for_company attribute set when they are part of the experimental signup
# are redirected to the welcome page when their role is required and the experiment is enabled for the current user. # flow (executed by the Growth team). Users are redirected to the welcome page when their role is required and the
def require_role # experiment is enabled for the current user.
return unless current_user && current_user.role_required? && experiment_enabled?(:signup_flow) def required_signup_info
return unless current_user
return unless current_user.role_required?
return unless experiment_enabled?(:signup_flow)
store_location_for :user, request.fullpath store_location_for :user, request.fullpath
......
...@@ -8,7 +8,7 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -8,7 +8,7 @@ class RegistrationsController < Devise::RegistrationsController
layout :choose_layout layout :choose_layout
skip_before_action :require_role, only: [:welcome, :update_role] skip_before_action :required_signup_info, only: [:welcome, :update_registration]
prepend_before_action :check_captcha, only: :create prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, only: [:destroy] before_action :whitelist_query_limiting, only: [:destroy]
before_action :ensure_terms_accepted, before_action :ensure_terms_accepted,
...@@ -53,22 +53,22 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -53,22 +53,22 @@ class RegistrationsController < Devise::RegistrationsController
def welcome def welcome
return redirect_to new_user_registration_path unless current_user return redirect_to new_user_registration_path unless current_user
return redirect_to stored_location_or_dashboard_or_almost_there_path(current_user) if current_user.role.present? return redirect_to stored_location_or_dashboard_or_almost_there_path(current_user) if current_user.role.present? && !current_user.setup_for_company.nil?
current_user.name = nil current_user.name = nil if current_user.name == current_user.username
render layout: 'devise_experimental_separate_sign_up_flow' render layout: 'devise_experimental_separate_sign_up_flow'
end end
def update_role def update_registration
user_params = params.require(:user).permit(:name, :role) user_params = params.require(:user).permit(:name, :role, :setup_for_company)
result = ::Users::UpdateService.new(current_user, user_params.merge(user: current_user)).execute result = ::Users::SignupService.new(current_user, user_params).execute
if result[:status] == :success if result[:status] == :success
track_experiment_event(:signup_flow, 'end') # We want this event to be tracked when the user is _in_ the experimental group track_experiment_event(:signup_flow, 'end') # We want this event to be tracked when the user is _in_ the experimental group
set_flash_message! :notice, :signed_up set_flash_message! :notice, :signed_up
redirect_to stored_location_or_dashboard_or_almost_there_path(current_user) redirect_to stored_location_or_dashboard_or_almost_there_path(current_user)
else else
redirect_to users_sign_up_welcome_path, alert: result[:message] render :welcome, layout: 'devise_experimental_separate_sign_up_flow'
end end
end end
......
...@@ -240,6 +240,7 @@ class User < ApplicationRecord ...@@ -240,6 +240,7 @@ class User < ApplicationRecord
delegate :time_display_relative, :time_display_relative=, to: :user_preference delegate :time_display_relative, :time_display_relative=, to: :user_preference
delegate :time_format_in_24h, :time_format_in_24h=, to: :user_preference delegate :time_format_in_24h, :time_format_in_24h=, to: :user_preference
delegate :show_whitespace_in_diffs, :show_whitespace_in_diffs=, to: :user_preference delegate :show_whitespace_in_diffs, :show_whitespace_in_diffs=, to: :user_preference
delegate :setup_for_company, :setup_for_company=, to: :user_preference
accepts_nested_attributes_for :user_preference, update_only: true accepts_nested_attributes_for :user_preference, update_only: true
......
# frozen_string_literal: true
module Users
class SignupService < BaseService
def initialize(current_user, params = {})
@user = current_user
@params = params.dup
end
def execute
assign_attributes
inject_validators
if @user.save
success
else
error(@user.errors.full_messages.join('. '))
end
end
private
def assign_attributes
@user.assign_attributes(params) unless params.empty?
end
def inject_validators
class << @user
validates :role, presence: true
validates :setup_for_company, inclusion: { in: [true, false], message: :blank }
end
end
end
end
- content_for(:page_title, _('Welcome to GitLab %{username}!') % { username: current_user.username }) - content_for(:page_title, _('Welcome to GitLab @%{username}!') % { username: current_user.username })
- max_name_length = 128 - max_name_length = 128
.text-center.mb-3 .text-center.mb-3
= _('In order to tailor your experience with GitLab<br>we would like to know a bit more about you.').html_safe = _('In order to tailor your experience with GitLab we<br>would like to know a bit more about you.').html_safe
.signup-box.p-3.mb-2 .signup-box.p-3.mb-2
.signup-body .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| = form_for(current_user, url: users_sign_up_update_registration_path, html: { class: 'new_new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
.devise-errors.mt-0 .devise-errors.mt-0
= render 'devise/shared/error_messages', resource: current_user = render 'devise/shared/error_messages', resource: current_user
.name.form-group .name.form-group
...@@ -13,5 +13,14 @@ ...@@ -13,5 +13,14 @@
.form-group .form-group
= f.label :role, _('Role'), class: 'label-bold' = f.label :role, _('Role'), class: 'label-bold'
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control' = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control'
.form-group
= f.label :setup_for_company, _('Are you setting up GitLab for a company?'), class: 'label-bold'
.d-flex.justify-content-center
.w-25
= f.radio_button :setup_for_company, true
= f.label :setup_for_company, _('Yes'), value: 'true'
.w-25
= f.radio_button :setup_for_company, false
= f.label :setup_for_company, _('No'), value: 'false'
.submit-container.mt-3 .submit-container.mt-3
= f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2' = f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2'
---
title: Ask if the user is setting up GitLab for a company during signup
merge_request: 17999
author:
type: changed
...@@ -57,7 +57,7 @@ Rails.application.routes.draw do ...@@ -57,7 +57,7 @@ Rails.application.routes.draw do
# Sign up # Sign up
get 'users/sign_up/welcome' => 'registrations#welcome' get 'users/sign_up/welcome' => 'registrations#welcome'
patch 'users/sign_up/update_role' => 'registrations#update_role' patch 'users/sign_up/update_registration' => 'registrations#update_registration'
# Search # Search
get 'search' => 'search#show' get 'search' => 'search#show'
......
# frozen_string_literal: true
class AddSetupForCompanyToUserPreferences < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_column :user_preferences, :setup_for_company, :boolean
end
end
...@@ -3754,6 +3754,7 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do ...@@ -3754,6 +3754,7 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do
t.boolean "time_format_in_24h" t.boolean "time_format_in_24h"
t.string "projects_sort", limit: 64 t.string "projects_sort", limit: 64
t.boolean "show_whitespace_in_diffs", default: true, null: false t.boolean "show_whitespace_in_diffs", default: true, null: false
t.boolean "setup_for_company"
t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true
end end
......
...@@ -1947,6 +1947,9 @@ msgstr "" ...@@ -1947,6 +1947,9 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. <strong>The repository cannot be committed to, and no issues, comments or other entities can be created.</strong>" msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. <strong>The repository cannot be committed to, and no issues, comments or other entities can be created.</strong>"
msgstr "" msgstr ""
msgid "Are you setting up GitLab for a company?"
msgstr ""
msgid "Are you sure that you want to archive this project?" msgid "Are you sure that you want to archive this project?"
msgstr "" msgstr ""
...@@ -9143,7 +9146,7 @@ msgstr "" ...@@ -9143,7 +9146,7 @@ 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." msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
msgstr "" 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."
...@@ -19090,7 +19093,7 @@ msgstr "" ...@@ -19090,7 +19093,7 @@ msgstr ""
msgid "Welcome to GitLab" msgid "Welcome to GitLab"
msgstr "" msgstr ""
msgid "Welcome to GitLab %{username}!" msgid "Welcome to GitLab @%{username}!"
msgstr "" msgstr ""
msgid "Welcome to the Guided GitLab Tour" msgid "Welcome to the Guided GitLab Tour"
......
...@@ -827,7 +827,7 @@ describe ApplicationController do ...@@ -827,7 +827,7 @@ describe ApplicationController do
end end
end end
describe '#require_role' do describe '#required_signup_info' do
controller(described_class) do controller(described_class) do
def index; end def index; end
end end
...@@ -849,7 +849,7 @@ describe ApplicationController do ...@@ -849,7 +849,7 @@ describe ApplicationController do
it { is_expected.to redirect_to users_sign_up_welcome_path } it { is_expected.to redirect_to users_sign_up_welcome_path }
end end
context 'experiment enabled and user without a role' do context 'experiment enabled and user without a required role' do
before do before do
sign_in(user) sign_in(user)
get :index get :index
...@@ -858,7 +858,7 @@ describe ApplicationController do ...@@ -858,7 +858,7 @@ describe ApplicationController do
it { is_expected.not_to redirect_to users_sign_up_welcome_path } it { is_expected.not_to redirect_to users_sign_up_welcome_path }
end end
context 'experiment disabled and user with required role' do context 'experiment disabled' do
let(:experiment_enabled) { false } let(:experiment_enabled) { false }
before do before do
......
...@@ -381,7 +381,7 @@ describe RegistrationsController do ...@@ -381,7 +381,7 @@ describe RegistrationsController do
end end
end end
describe '#update_role' do describe '#update_registration' do
before do before do
stub_experiment(signup_flow: true) stub_experiment(signup_flow: true)
stub_experiment_for_user(signup_flow: true) stub_experiment_for_user(signup_flow: true)
...@@ -395,7 +395,7 @@ describe RegistrationsController do ...@@ -395,7 +395,7 @@ describe RegistrationsController do
label: anything, label: anything,
property: 'experimental_group' property: 'experimental_group'
) )
patch :update_role, params: { user: { name: 'New name', role: 'software_developer' } } patch :update_registration, params: { user: { name: 'New name', role: 'software_developer', setup_for_company: 'false' } }
end end
end end
end end
...@@ -441,11 +441,13 @@ describe 'With experimental flow' do ...@@ -441,11 +441,13 @@ describe 'With experimental flow' do
fill_in 'user_name', with: 'New name' fill_in 'user_name', with: 'New name'
select 'Software Developer', from: 'user_role' select 'Software Developer', from: 'user_role'
choose 'user_setup_for_company_true'
click_button 'Get started!' click_button 'Get started!'
new_user = User.find_by_username(new_user.username) new_user = User.find_by_username(new_user.username)
expect(new_user.name).to eq 'New name' expect(new_user.name).to eq 'New name'
expect(new_user.software_developer_role?).to be_truthy expect(new_user.software_developer_role?).to be_truthy
expect(new_user.setup_for_company).to be_truthy
expect(page).to have_current_path(new_project_path) expect(page).to have_current_path(new_project_path)
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe Users::SignupService do
let(:user) { create(:user, setup_for_company: true) }
describe '#execute' do
context 'when updating name' do
it 'updates the name attribute' do
result = update_user(user, name: 'New Name')
expect(result).to eq(status: :success)
expect(user.reload.name).to eq('New Name')
end
it 'returns an error result when name is missing' do
result = update_user(user, name: '')
expect(user.reload.name).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to include("Name can't be blank")
end
end
context 'when updating role' do
it 'updates the role attribute' do
result = update_user(user, role: 'development_team_lead')
expect(result).to eq(status: :success)
expect(user.reload.role).to eq('development_team_lead')
end
it 'returns an error result when role is missing' do
result = update_user(user, role: '')
expect(user.reload.role).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to eq("Role can't be blank")
end
end
context 'when updating setup_for_company' do
it 'updates the setup_for_company attribute' do
result = update_user(user, setup_for_company: 'false')
expect(result).to eq(status: :success)
expect(user.reload.setup_for_company).to be(false)
end
it 'returns an error result when setup_for_company is missing' do
result = update_user(user, setup_for_company: '')
expect(user.reload.setup_for_company).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to eq("Setup for company can't be blank")
end
end
def update_user(user, opts)
described_class.new(user, opts).execute
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