Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6d59e98918
commit
4682f5015a
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
||||||
|
});
|
|
@ -29,6 +29,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
|
||||||
|
|
||||||
around_action :set_locale
|
around_action :set_locale
|
||||||
around_action :set_session_storage
|
around_action :set_session_storage
|
||||||
|
@ -547,6 +548,16 @@ class ApplicationController < ActionController::Base
|
||||||
def current_user_mode
|
def current_user_mode
|
||||||
@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
|
||||||
|
# are redirected to the welcome page when their role is required and the experiment is enabled for the current user.
|
||||||
|
def require_role
|
||||||
|
return unless current_user && current_user.role_required? && experiment_enabled?(:signup_flow)
|
||||||
|
|
||||||
|
store_location_for :user, request.fullpath
|
||||||
|
|
||||||
|
redirect_to users_sign_up_welcome_path
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ApplicationController.prepend_if_ee('EE::ApplicationController')
|
ApplicationController.prepend_if_ee('EE::ApplicationController')
|
||||||
|
|
|
@ -8,7 +8,7 @@ module InvisibleCaptcha
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_honeypot_spam_callback
|
def on_honeypot_spam_callback
|
||||||
return unless Feature.enabled?(:invisible_captcha)
|
return unless Feature.enabled?(:invisible_captcha) || experiment_enabled?(:signup_flow)
|
||||||
|
|
||||||
invisible_captcha_honeypot_counter.increment
|
invisible_captcha_honeypot_counter.increment
|
||||||
log_request('Invisible_Captcha_Honeypot_Request')
|
log_request('Invisible_Captcha_Honeypot_Request')
|
||||||
|
@ -17,7 +17,7 @@ module InvisibleCaptcha
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_timestamp_spam_callback
|
def on_timestamp_spam_callback
|
||||||
return unless Feature.enabled?(:invisible_captcha)
|
return unless Feature.enabled?(:invisible_captcha) || experiment_enabled?(:signup_flow)
|
||||||
|
|
||||||
invisible_captcha_timestamp_counter.increment
|
invisible_captcha_timestamp_counter.increment
|
||||||
log_request('Invisible_Captcha_Timestamp_Request')
|
log_request('Invisible_Captcha_Timestamp_Request')
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
|
||||||
include Gitlab::Allowable
|
include Gitlab::Allowable
|
||||||
include PageLayoutHelper
|
include PageLayoutHelper
|
||||||
include OauthApplications
|
include OauthApplications
|
||||||
|
include Gitlab::Experimentation::ControllerConcern
|
||||||
|
|
||||||
before_action :verify_user_oauth_applications_enabled, except: :index
|
before_action :verify_user_oauth_applications_enabled, except: :index
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||||
|
include Gitlab::Experimentation::ControllerConcern
|
||||||
layout 'profile'
|
layout 'profile'
|
||||||
|
|
||||||
# Overridden from Doorkeeper::AuthorizationsController to
|
# Overridden from Doorkeeper::AuthorizationsController to
|
||||||
|
|
|
@ -100,6 +100,7 @@ class ProfilesController < Profiles::ApplicationController
|
||||||
:avatar,
|
:avatar,
|
||||||
:bio,
|
:bio,
|
||||||
:email,
|
:email,
|
||||||
|
:role,
|
||||||
:hide_no_password,
|
:hide_no_password,
|
||||||
:hide_no_ssh_key,
|
:hide_no_ssh_key,
|
||||||
:hide_project_limit,
|
:hide_project_limit,
|
||||||
|
|
|
@ -8,13 +8,14 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
|
|
||||||
layout :choose_layout
|
layout :choose_layout
|
||||||
|
|
||||||
|
skip_before_action :require_role, only: [:welcome, :update_role]
|
||||||
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,
|
||||||
if: -> { action_name == 'create' && Gitlab::CurrentSettings.current_application_settings.enforce_terms? }
|
if: -> { action_name == 'create' && Gitlab::CurrentSettings.current_application_settings.enforce_terms? }
|
||||||
|
|
||||||
def new
|
def new
|
||||||
if helpers.use_experimental_separate_sign_up_flow?
|
if experiment_enabled?(:signup_flow)
|
||||||
@resource = build_resource
|
@resource = build_resource
|
||||||
else
|
else
|
||||||
redirect_to new_user_session_path(anchor: 'register-pane')
|
redirect_to new_user_session_path(anchor: 'register-pane')
|
||||||
|
@ -26,8 +27,13 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
|
|
||||||
super do |new_user|
|
super do |new_user|
|
||||||
persist_accepted_terms_if_required(new_user)
|
persist_accepted_terms_if_required(new_user)
|
||||||
|
set_role_required(new_user)
|
||||||
yield new_user if block_given?
|
yield new_user if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Do not show the signed_up notice message when the signup_flow experiment is enabled.
|
||||||
|
# Instead, show it after succesfully updating the role.
|
||||||
|
flash[:notice] = nil if experiment_enabled?(:signup_flow)
|
||||||
rescue Gitlab::Access::AccessDeniedError
|
rescue Gitlab::Access::AccessDeniedError
|
||||||
redirect_to(new_user_session_path)
|
redirect_to(new_user_session_path)
|
||||||
end
|
end
|
||||||
|
@ -42,6 +48,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_or_almost_there_path(current_user) if current_user.role.present?
|
||||||
|
|
||||||
|
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
|
||||||
|
set_flash_message! :notice, :signed_up
|
||||||
|
redirect_to stored_location_or_dashboard_or_almost_there_path(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)
|
||||||
|
@ -54,6 +80,10 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_role_required(new_user)
|
||||||
|
new_user.set_role_required! if new_user.persisted? && experiment_enabled?(:signup_flow)
|
||||||
|
end
|
||||||
|
|
||||||
def destroy_confirmation_valid?
|
def destroy_confirmation_valid?
|
||||||
if current_user.confirm_deletion_with_password?
|
if current_user.confirm_deletion_with_password?
|
||||||
current_user.valid_password?(params[:password])
|
current_user.valid_password?(params[:password])
|
||||||
|
@ -76,7 +106,10 @@ 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?))
|
||||||
confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path
|
|
||||||
|
return users_sign_up_welcome_path if experiment_enabled?(:signup_flow)
|
||||||
|
|
||||||
|
stored_location_or_dashboard_or_almost_there_path(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_inactive_sign_up_path_for(resource)
|
def after_inactive_sign_up_path_for(resource)
|
||||||
|
@ -103,6 +136,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
ensure_correct_params!
|
ensure_correct_params!
|
||||||
|
|
||||||
return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true) # reCAPTCHA on the UI will still display however
|
return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true) # reCAPTCHA on the UI will still display however
|
||||||
|
return if experiment_enabled?(:signup_flow) # when the experimental signup flow is enabled for the current user, disable the reCAPTCHA check
|
||||||
return unless show_recaptcha_sign_up?
|
return unless show_recaptcha_sign_up?
|
||||||
return unless Gitlab::Recaptcha.load_configurations!
|
return unless Gitlab::Recaptcha.load_configurations!
|
||||||
|
|
||||||
|
@ -114,7 +148,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 experiment_enabled?(:signup_flow)
|
||||||
|
clean_params[:name] = clean_params[:username]
|
||||||
|
end
|
||||||
|
|
||||||
|
clean_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_name
|
def resource_name
|
||||||
|
@ -144,17 +184,21 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def confirmed_or_unconfirmed_access_allowed(user)
|
def confirmed_or_unconfirmed_access_allowed(user)
|
||||||
user.confirmed? || Feature.enabled?(:soft_email_confirmation)
|
user.confirmed? || Feature.enabled?(:soft_email_confirmation) || experiment_enabled?(:signup_flow)
|
||||||
end
|
end
|
||||||
|
|
||||||
def stored_location_or_dashboard(user)
|
def stored_location_or_dashboard(user)
|
||||||
stored_location_for(user) || dashboard_projects_path
|
stored_location_for(user) || dashboard_projects_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stored_location_or_dashboard_or_almost_there_path(user)
|
||||||
|
confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path
|
||||||
|
end
|
||||||
|
|
||||||
# Part of an experiment to build a new sign up flow. Will be resolved
|
# Part of an experiment to build a new sign up flow. Will be resolved
|
||||||
# with https://gitlab.com/gitlab-org/growth/engineering/issues/64
|
# with https://gitlab.com/gitlab-org/growth/engineering/issues/64
|
||||||
def choose_layout
|
def choose_layout
|
||||||
if helpers.use_experimental_separate_sign_up_flow?
|
if experiment_enabled?(:signup_flow)
|
||||||
'devise_experimental_separate_sign_up_flow'
|
'devise_experimental_separate_sign_up_flow'
|
||||||
else
|
else
|
||||||
'devise'
|
'devise'
|
||||||
|
|
|
@ -4,8 +4,4 @@ module SessionsHelper
|
||||||
def unconfirmed_email?
|
def unconfirmed_email?
|
||||||
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
|
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
|
||||||
end
|
end
|
||||||
|
|
||||||
def use_experimental_separate_sign_up_flow?
|
|
||||||
::Gitlab.dev_env_or_com? && Feature.enabled?(:experimental_separate_sign_up_flow)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -231,6 +231,10 @@ class User < ApplicationRecord
|
||||||
# Note: When adding an option, it MUST go on the end of the array.
|
# Note: When adding an option, it MUST go on the end of the array.
|
||||||
enum project_view: [:readme, :activity, :files]
|
enum project_view: [:readme, :activity, :files]
|
||||||
|
|
||||||
|
# User's role
|
||||||
|
# Note: When adding an option, it MUST go on the end of the array.
|
||||||
|
enum role: [:software_developer, :development_team_lead, :devops_engineer, :systems_administrator, :security_analyst, :data_analyst, :product_manager, :product_designer, :other], _suffix: true
|
||||||
|
|
||||||
delegate :path, to: :namespace, allow_nil: true, prefix: true
|
delegate :path, to: :namespace, allow_nil: true, prefix: true
|
||||||
delegate :notes_filter_for, to: :user_preference
|
delegate :notes_filter_for, to: :user_preference
|
||||||
delegate :set_notes_filter, to: :user_preference
|
delegate :set_notes_filter, to: :user_preference
|
||||||
|
@ -1571,6 +1575,20 @@ class User < ApplicationRecord
|
||||||
[last_activity, last_sign_in].compact.max
|
[last_activity, last_sign_in].compact.max
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Below is used for the signup_flow experiment. Should be removed
|
||||||
|
# when experiment finishes.
|
||||||
|
# See https://gitlab.com/gitlab-org/growth/engineering/issues/64
|
||||||
|
REQUIRES_ROLE_VALUE = 99
|
||||||
|
|
||||||
|
def role_required?
|
||||||
|
role_before_type_cast == REQUIRES_ROLE_VALUE
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_role_required!
|
||||||
|
update_column(:role, REQUIRES_ROLE_VALUE)
|
||||||
|
end
|
||||||
|
# End of signup_flow experiment methods
|
||||||
|
|
||||||
# @deprecated
|
# @deprecated
|
||||||
alias_method :owned_or_masters_groups, :owned_or_maintainers_groups
|
alias_method :owned_or_masters_groups, :owned_or_maintainers_groups
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- page_title "Sign up"
|
- page_title "Sign up"
|
||||||
- if use_experimental_separate_sign_up_flow?
|
- if experiment_enabled?(:signup_flow)
|
||||||
= render 'devise/shared/experimental_separate_sign_up_flow_box'
|
= render 'devise/shared/experimental_separate_sign_up_flow_box'
|
||||||
- else
|
- else
|
||||||
= render 'devise/shared/signup_box'
|
= render 'devise/shared/signup_box'
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
- if form_based_providers.any?
|
- if form_based_providers.any?
|
||||||
= render 'devise/shared/tabs_ldap'
|
= render 'devise/shared/tabs_ldap'
|
||||||
- else
|
- else
|
||||||
- unless use_experimental_separate_sign_up_flow?
|
- unless experiment_enabled?(:signup_flow)
|
||||||
= render 'devise/shared/tabs_normal'
|
= render 'devise/shared/tabs_normal'
|
||||||
.tab-content
|
.tab-content
|
||||||
- if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
|
- if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- max_name_length = 128
|
- content_for(:page_title, _('Register for GitLab'))
|
||||||
- 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 @@
|
||||||
.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.")
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
.login-body
|
.login-body
|
||||||
= render 'devise/sessions/new_base'
|
= render 'devise/sessions/new_base'
|
||||||
|
|
||||||
- if use_experimental_separate_sign_up_flow?
|
- if experiment_enabled?(:signup_flow)
|
||||||
%p.light.mt-2
|
%p.light.mt-2
|
||||||
= _("Don't have an account yet?")
|
= _("Don't have an account yet?")
|
||||||
= link_to _("Register now"), new_registration_path(:user)
|
= link_to _("Register now"), new_registration_path(:user)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
-# anything from this page beforehand.
|
-# anything from this page beforehand.
|
||||||
-# Part of an experiment to build a new sign up flow. Will be removed again with
|
-# Part of an experiment to build a new sign up flow. Will be removed again with
|
||||||
-# https://gitlab.com/gitlab-org/growth/engineering/issues/64
|
-# https://gitlab.com/gitlab-org/growth/engineering/issues/64
|
||||||
- if use_experimental_separate_sign_up_flow? && current_path?("sessions#new")
|
- if experiment_enabled?(:signup_flow) && current_path?("sessions#new")
|
||||||
= javascript_tag nonce: true do
|
= javascript_tag nonce: true do
|
||||||
:plain
|
:plain
|
||||||
if (window.location.hash === '#register-pane') {
|
if (window.location.hash === '#register-pane') {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
- else
|
- else
|
||||||
= f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
|
= f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
|
||||||
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
|
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
|
||||||
|
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'input-md'
|
||||||
|
|
||||||
= render_if_exists 'profiles/email_settings', form: f
|
= render_if_exists 'profiles/email_settings', form: f
|
||||||
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
|
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
- content_for(:page_title, _('Welcome to GitLab<br>%{username}!' % { username: html_escape(current_user.username) }).html_safe)
|
||||||
|
- max_name_length = 128
|
||||||
|
.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
|
||||||
|
.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
|
||||||
|
.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_('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'
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add step 2 of the experimental signup flow
|
||||||
|
merge_request: 16583
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||||
|
# for more information on how to write migrations for GitLab.
|
||||||
|
|
||||||
|
class AddRoleToUsers < ActiveRecord::Migration[5.2]
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :users, :role, :smallint
|
||||||
|
end
|
||||||
|
end
|
|
@ -3780,6 +3780,7 @@ ActiveRecord::Schema.define(version: 2019_10_16_220135) do
|
||||||
t.string "first_name", limit: 255
|
t.string "first_name", limit: 255
|
||||||
t.string "last_name", limit: 255
|
t.string "last_name", limit: 255
|
||||||
t.string "static_object_token", limit: 255
|
t.string "static_object_token", limit: 255
|
||||||
|
t.integer "role", limit: 2
|
||||||
t.index "lower((name)::text)", name: "index_on_users_name_lower"
|
t.index "lower((name)::text)", name: "index_on_users_name_lower"
|
||||||
t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id"
|
t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id"
|
||||||
t.index ["admin"], name: "index_users_on_admin"
|
t.index ["admin"], name: "index_users_on_admin"
|
||||||
|
|
|
@ -234,14 +234,21 @@ future based on additional testing and iteration.
|
||||||
|
|
||||||
- **Supported Users (approximate):** 25,000
|
- **Supported Users (approximate):** 25,000
|
||||||
- **RPS:** 500 requests per second
|
- **RPS:** 500 requests per second
|
||||||
- **Status:** Work-in-progress
|
- **Known Issues:** The slow API endpoints that were discovered during testing
|
||||||
- **Related Issue:** See the [related issue](https://gitlab.com/gitlab-org/quality/performance/issues/57) for more information.
|
the 10,000 user architecture also affect the 25,000 user architecture. For
|
||||||
|
details, see the related issues list in
|
||||||
|
[this issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/64335).
|
||||||
|
|
||||||
The Support and Quality teams are in the process of building and performance
|
The GitLab Support and Quality teams built, performance tested, and validated an
|
||||||
testing an environment that will support around 25,000 users. The specifications
|
environment that supports around 25,000 users. The specifications below are a
|
||||||
below are a work-in-progress representation of the work so far. The Quality team
|
representation of the work so far. The specifications may be adjusted in the
|
||||||
will be certifying this environment in late 2019. The specifications may be
|
future based on additional testing and iteration.
|
||||||
adjusted prior to certification based on performance testing.
|
|
||||||
|
NOTE: **Note:** The specifications here were performance tested against a
|
||||||
|
specific coded workload. Your exact needs may be more, depending on your
|
||||||
|
workload. Your workload is influenced by factors such as - but not limited to -
|
||||||
|
how active your users are, how much automation you use, mirroring, and
|
||||||
|
repo/change size.
|
||||||
|
|
||||||
| Service | Configuration | GCP type |
|
| Service | Configuration | GCP type |
|
||||||
| ------------------------------|-------------------------|----------------|
|
| ------------------------------|-------------------------|----------------|
|
||||||
|
|
|
@ -40,8 +40,8 @@ module Gitlab
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def experiment_enabled?(experiment)
|
def experiment_enabled?(experiment_key)
|
||||||
Experimentation.enabled?(experiment, experimentation_subject_index)
|
Experimentation.enabled?(experiment_key, experimentation_subject_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -55,10 +55,14 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def experiment(key)
|
||||||
|
Experiment.new(EXPERIMENTS[key].merge(key: key))
|
||||||
|
end
|
||||||
|
|
||||||
def enabled?(experiment_key, experimentation_subject_index)
|
def enabled?(experiment_key, experimentation_subject_index)
|
||||||
return false unless EXPERIMENTS.key?(experiment_key)
|
return false unless EXPERIMENTS.key?(experiment_key)
|
||||||
|
|
||||||
experiment = Experiment.new(EXPERIMENTS[experiment_key].merge(key: experiment_key))
|
experiment = experiment(experiment_key)
|
||||||
|
|
||||||
experiment.feature_toggle_enabled? &&
|
experiment.feature_toggle_enabled? &&
|
||||||
experiment.enabled_for_environment? &&
|
experiment.enabled_for_environment? &&
|
||||||
|
|
|
@ -7841,6 +7841,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 ""
|
||||||
|
|
||||||
|
@ -8917,6 +8920,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 ""
|
||||||
|
|
||||||
|
@ -10708,6 +10714,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 ""
|
||||||
|
|
||||||
|
@ -13513,7 +13522,7 @@ msgstr ""
|
||||||
msgid "Register and see your runners for this project."
|
msgid "Register and see your runners for this project."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Register for GitLab.com"
|
msgid "Register for GitLab"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Register now"
|
msgid "Register now"
|
||||||
|
@ -14092,6 +14101,9 @@ msgstr ""
|
||||||
msgid "Roadmap"
|
msgid "Roadmap"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Role"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Rollback"
|
msgid "Rollback"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||||
"@babel/preset-env": "^7.6.2",
|
"@babel/preset-env": "^7.6.2",
|
||||||
"@gitlab/svgs": "^1.78.0",
|
"@gitlab/svgs": "^1.78.0",
|
||||||
"@gitlab/ui": "5.35.0",
|
"@gitlab/ui": "5.36.0",
|
||||||
"@gitlab/visual-review-tools": "1.0.3",
|
"@gitlab/visual-review-tools": "1.0.3",
|
||||||
"apollo-cache-inmemory": "^1.5.1",
|
"apollo-cache-inmemory": "^1.5.1",
|
||||||
"apollo-client": "^2.5.1",
|
"apollo-client": "^2.5.1",
|
||||||
|
|
|
@ -842,4 +842,48 @@ describe ApplicationController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#require_role' do
|
||||||
|
controller(described_class) do
|
||||||
|
def index; end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:experiment_enabled) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_experiment(signup_flow: experiment_enabled)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'experiment enabled and user with required role' do
|
||||||
|
before do
|
||||||
|
user.set_role_required!
|
||||||
|
sign_in(user)
|
||||||
|
get :index
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to redirect_to users_sign_up_welcome_path }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'experiment enabled and user without a role' do
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
get :index
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.not_to redirect_to users_sign_up_welcome_path }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'experiment disabled and user with required role' do
|
||||||
|
let(:experiment_enabled) { false }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user.set_role_required!
|
||||||
|
sign_in(user)
|
||||||
|
get :index
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.not_to redirect_to users_sign_up_welcome_path }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -114,9 +114,14 @@ describe RegistrationsController do
|
||||||
context 'when invisible captcha is enabled' do
|
context 'when invisible captcha is enabled' do
|
||||||
before do
|
before do
|
||||||
stub_feature_flags(invisible_captcha: true)
|
stub_feature_flags(invisible_captcha: true)
|
||||||
|
InvisibleCaptcha.timestamp_enabled = true
|
||||||
InvisibleCaptcha.timestamp_threshold = treshold
|
InvisibleCaptcha.timestamp_threshold = treshold
|
||||||
end
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
InvisibleCaptcha.timestamp_enabled = false
|
||||||
|
end
|
||||||
|
|
||||||
let(:treshold) { 4 }
|
let(:treshold) { 4 }
|
||||||
let(:session_params) { { invisible_captcha_timestamp: form_rendered_time.iso8601 } }
|
let(:session_params) { { invisible_captcha_timestamp: form_rendered_time.iso8601 } }
|
||||||
let(:form_rendered_time) { Time.current }
|
let(:form_rendered_time) { Time.current }
|
||||||
|
|
|
@ -6,6 +6,7 @@ FactoryBot.define do
|
||||||
name { generate(:name) }
|
name { generate(:name) }
|
||||||
username { generate(:username) }
|
username { generate(:username) }
|
||||||
password { "12345678" }
|
password { "12345678" }
|
||||||
|
role { 'software_developer' }
|
||||||
confirmed_at { Time.now }
|
confirmed_at { Time.now }
|
||||||
confirmation_token { nil }
|
confirmation_token { nil }
|
||||||
can_create_group { true }
|
can_create_group { true }
|
||||||
|
|
|
@ -10,7 +10,6 @@ describe 'Invites' do
|
||||||
let(:group_invite) { group.group_members.invite.last }
|
let(:group_invite) { group.group_members.invite.last }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_feature_flags(invisible_captcha: false)
|
|
||||||
project.add_maintainer(owner)
|
project.add_maintainer(owner)
|
||||||
group.add_user(owner, Gitlab::Access::OWNER)
|
group.add_user(owner, Gitlab::Access::OWNER)
|
||||||
group.add_developer('user@example.com', owner)
|
group.add_developer('user@example.com', owner)
|
||||||
|
|
|
@ -5,10 +5,6 @@ require 'spec_helper'
|
||||||
shared_examples 'Signup' do
|
shared_examples 'Signup' do
|
||||||
include TermsHelper
|
include TermsHelper
|
||||||
|
|
||||||
before do
|
|
||||||
stub_feature_flags(invisible_captcha: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:new_user) { build_stubbed(:user) }
|
let(:new_user) { build_stubbed(:user) }
|
||||||
|
|
||||||
describe 'username validation', :js do
|
describe 'username validation', :js do
|
||||||
|
@ -129,35 +125,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
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_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
|
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 +181,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 Gitlab::Experimentation.enabled?(:signup_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 +206,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 Gitlab::Experimentation.enabled?(:signup_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,31 +218,39 @@ shared_examples 'Signup' do
|
||||||
|
|
||||||
expect { click_button 'Register' }.to change { User.count }.by(1)
|
expect { click_button 'Register' }.to change { User.count }.by(1)
|
||||||
|
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
expect(current_path).to eq users_sign_up_welcome_path
|
||||||
|
else
|
||||||
expect(current_path).to eq dashboard_projects_path
|
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.")
|
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
|
||||||
|
|
||||||
context "when sigining up with different cased emails" do
|
context "when sigining up with different cased emails" 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 Gitlab::Experimentation.enabled?(:signup_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"
|
||||||
|
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
expect(current_path).to eq users_sign_up_welcome_path
|
||||||
|
else
|
||||||
expect(current_path).to eq dashboard_projects_path
|
expect(current_path).to eq dashboard_projects_path
|
||||||
expect(page).to have_content("Welcome! You have signed up successfully.")
|
expect(page).to have_content("Welcome! You have signed up successfully.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when not sending confirmation email" do
|
context "when not sending confirmation email" do
|
||||||
before do
|
before do
|
||||||
|
@ -248,22 +260,26 @@ 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 Gitlab::Experimentation.enabled?(:signup_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"
|
||||||
|
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
expect(current_path).to eq users_sign_up_welcome_path
|
||||||
|
else
|
||||||
expect(current_path).to eq dashboard_projects_path
|
expect(current_path).to eq dashboard_projects_path
|
||||||
expect(page).to have_content("Welcome! You have signed up successfully.")
|
expect(page).to have_content("Welcome! You have signed up successfully.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with errors' do
|
context 'with errors' do
|
||||||
it "displays the errors" do
|
it "displays the errors" do
|
||||||
|
@ -271,7 +287,10 @@ shared_examples 'Signup' do
|
||||||
|
|
||||||
visit new_user_registration_path
|
visit new_user_registration_path
|
||||||
|
|
||||||
|
unless Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
fill_in 'new_user_name', with: new_user.name
|
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
|
||||||
|
@ -279,14 +298,14 @@ shared_examples 'Signup' do
|
||||||
|
|
||||||
expect(current_path).to eq user_registration_path
|
expect(current_path).to eq user_registration_path
|
||||||
|
|
||||||
if Feature.enabled?(:experimental_separate_sign_up_flow)
|
if Gitlab::Experimentation.enabled?(:signup_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 +313,10 @@ shared_examples 'Signup' do
|
||||||
|
|
||||||
visit new_user_registration_path
|
visit new_user_registration_path
|
||||||
|
|
||||||
|
unless Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
fill_in 'new_user_name', with: new_user.name
|
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 +335,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 Gitlab::Experimentation.enabled?(:signup_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 +354,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 Gitlab::Experimentation.enabled?(:signup_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 +367,84 @@ shared_examples 'Signup' do
|
||||||
|
|
||||||
click_button "Register"
|
click_button "Register"
|
||||||
|
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
expect(current_path).to eq users_sign_up_welcome_path
|
||||||
|
else
|
||||||
expect(current_path).to eq dashboard_projects_path
|
expect(current_path).to eq dashboard_projects_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when reCAPTCHA and invisible captcha are enabled' do
|
||||||
|
before do
|
||||||
|
InvisibleCaptcha.timestamp_enabled = true
|
||||||
|
stub_application_setting(recaptcha_enabled: true)
|
||||||
|
allow_any_instance_of(RegistrationsController).to receive(:verify_recaptcha).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
InvisibleCaptcha.timestamp_enabled = false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prevents from signing up' do
|
||||||
|
visit new_user_registration_path
|
||||||
|
|
||||||
|
fill_in 'new_user_username', with: new_user.username
|
||||||
|
fill_in 'new_user_email', with: new_user.email
|
||||||
|
|
||||||
|
unless Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
fill_in 'new_user_name', with: new_user.name
|
||||||
|
fill_in 'new_user_email_confirmation', with: new_user.email
|
||||||
|
end
|
||||||
|
|
||||||
|
fill_in 'new_user_password', with: new_user.password
|
||||||
|
|
||||||
|
expect { click_button 'Register' }.not_to change { User.count }
|
||||||
|
|
||||||
|
if Gitlab::Experimentation.enabled?(:signup_flow)
|
||||||
|
expect(page).to have_content('That was a bit too quick! Please resubmit.')
|
||||||
|
else
|
||||||
|
expect(page).to have_content('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
|
||||||
|
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_experiment(signup_flow: false)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'Signup'
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'With experimental flow on GitLab.com' do
|
describe 'With experimental flow' do
|
||||||
it_behaves_like 'Signup' do
|
|
||||||
before do
|
before do
|
||||||
expect(Gitlab).to receive(:com?).and_return(true).at_least(:once)
|
stub_experiment(signup_flow: true)
|
||||||
stub_feature_flags(experimental_separate_sign_up_flow: true)
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'Signup'
|
||||||
|
|
||||||
|
describe 'when role is required' do
|
||||||
|
it 'after registering, it redirects to step 2 of the signup process, sets the name and role and then redirects to the original requested url' do
|
||||||
|
new_user = build_stubbed(:user)
|
||||||
|
visit new_user_registration_path
|
||||||
|
fill_in 'new_user_username', with: new_user.username
|
||||||
|
fill_in 'new_user_email', with: new_user.email
|
||||||
|
fill_in 'new_user_password', with: new_user.password
|
||||||
|
click_button 'Register'
|
||||||
|
visit new_project_path
|
||||||
|
|
||||||
|
expect(page).to have_current_path(users_sign_up_welcome_path)
|
||||||
|
|
||||||
|
fill_in 'user_name', with: 'New name'
|
||||||
|
select 'Software Developer', from: 'user_role'
|
||||||
|
click_button 'Get started!'
|
||||||
|
new_user = User.find_by_username(new_user.username)
|
||||||
|
|
||||||
|
expect(new_user.name).to eq 'New name'
|
||||||
|
expect(new_user.software_developer_role?).to be_truthy
|
||||||
|
expect(page).to have_current_path(new_project_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -634,14 +634,9 @@ describe API::Users do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /users/sign_up" do
|
describe "GET /users/sign_up" do
|
||||||
context 'when experimental_separate_sign_up_flow is active' do
|
context 'when experimental signup_flow is active' do
|
||||||
before do
|
before do
|
||||||
stub_feature_flags(experimental_separate_sign_up_flow: true)
|
stub_experiment(signup_flow: true)
|
||||||
end
|
|
||||||
|
|
||||||
context 'on gitlab.com' do
|
|
||||||
before do
|
|
||||||
allow(::Gitlab).to receive(:com?).and_return(true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "shows sign up page" do
|
it "shows sign up page" do
|
||||||
|
@ -651,23 +646,9 @@ describe API::Users do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'not on gitlab.com' do
|
context 'when experimental signup_flow is not active' do
|
||||||
before do
|
before do
|
||||||
allow(::Gitlab).to receive(:com?).and_return(false)
|
stub_experiment(signup_flow: false)
|
||||||
end
|
|
||||||
|
|
||||||
it "redirects to sign in page" do
|
|
||||||
get "/users/sign_up"
|
|
||||||
expect(response).to have_gitlab_http_status(302)
|
|
||||||
expect(response).to redirect_to(new_user_session_path(anchor: 'register-pane'))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when experimental_separate_sign_up_flow is not active' do
|
|
||||||
before do
|
|
||||||
allow(::Gitlab).to receive(:com?).and_return(true)
|
|
||||||
stub_feature_flags(experimental_separate_sign_up_flow: false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "redirects to sign in page" do
|
it "redirects to sign in page" do
|
||||||
|
|
|
@ -88,6 +88,7 @@ RSpec.configure do |config|
|
||||||
config.include FixtureHelpers
|
config.include FixtureHelpers
|
||||||
config.include GitlabRoutingHelper
|
config.include GitlabRoutingHelper
|
||||||
config.include StubFeatureFlags
|
config.include StubFeatureFlags
|
||||||
|
config.include StubExperiments
|
||||||
config.include StubGitlabCalls
|
config.include StubGitlabCalls
|
||||||
config.include StubGitlabData
|
config.include StubGitlabData
|
||||||
config.include NextInstanceOf
|
config.include NextInstanceOf
|
||||||
|
@ -378,3 +379,6 @@ end
|
||||||
|
|
||||||
# Prevent Rugged from picking up local developer gitconfig.
|
# Prevent Rugged from picking up local developer gitconfig.
|
||||||
Rugged::Settings['search_path_global'] = Rails.root.join('tmp/tests').to_s
|
Rugged::Settings['search_path_global'] = Rails.root.join('tmp/tests').to_s
|
||||||
|
|
||||||
|
# Disable timestamp checks for invisible_captcha
|
||||||
|
InvisibleCaptcha.timestamp_enabled = false
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module StubExperiments
|
||||||
|
# Stub Experiment with `key: true/false`
|
||||||
|
#
|
||||||
|
# @param [Hash] experiment where key is feature name and value is boolean whether enabled or not.
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
# - `stub_experiment(signup_flow: false)` ... Disable `signup_flow` experiment globally.
|
||||||
|
def stub_experiment(experiments)
|
||||||
|
experiments.each do |experiment_key, enabled|
|
||||||
|
allow(Gitlab::Experimentation).to receive(:enabled?).with(experiment_key, any_args) { enabled }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,6 +10,7 @@ describe 'devise/shared/_signin_box' do
|
||||||
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
|
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
|
||||||
allow(view).to receive(:captcha_enabled?).and_return(false)
|
allow(view).to receive(:captcha_enabled?).and_return(false)
|
||||||
allow(view).to receive(:captcha_on_login_required?).and_return(false)
|
allow(view).to receive(:captcha_on_login_required?).and_return(false)
|
||||||
|
allow(view).to receive(:experiment_enabled?).and_return(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is shown when Crowd is enabled' do
|
it 'is shown when Crowd is enabled' do
|
||||||
|
|
|
@ -7,6 +7,7 @@ describe 'layouts/_head' do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
|
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
|
||||||
|
allow(view).to receive(:experiment_enabled?).and_return(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'escapes HTML-safe strings in page_title' do
|
it 'escapes HTML-safe strings in page_title' do
|
||||||
|
|
|
@ -995,10 +995,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.78.0.tgz#469493bd6cdd254eb5d1271edeab22bbbee2f4c4"
|
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.78.0.tgz#469493bd6cdd254eb5d1271edeab22bbbee2f4c4"
|
||||||
integrity sha512-dBgEB/Q4FRD0NapmNrD86DF1FsV0uSgTx0UOJloHnGE2DNR2P1HQrCmLW2fX+QgN4P9CDAzdi2buVHuholofWw==
|
integrity sha512-dBgEB/Q4FRD0NapmNrD86DF1FsV0uSgTx0UOJloHnGE2DNR2P1HQrCmLW2fX+QgN4P9CDAzdi2buVHuholofWw==
|
||||||
|
|
||||||
"@gitlab/ui@5.35.0":
|
"@gitlab/ui@5.36.0":
|
||||||
version "5.35.0"
|
version "5.36.0"
|
||||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.35.0.tgz#843e9febf1d4ef9b846dc3280e32e3e626c6f9b1"
|
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.36.0.tgz#3087b23c138ad1c222f6b047e533f253371bc618"
|
||||||
integrity sha512-PD9hqVlRhwYRPbL+u/gcHew8NfPXbphZ0CQqfIXaWUYdEOMksUtP6DnLToG6S321WjrCMD+IBHnVQxf2juZBxg==
|
integrity sha512-XXWUYZbRItKh9N92Vxql04BJ05uW5HlOuTCkD+lMbUgneqYTgVoKGH8d9kD++Jy7q8l5+AfzjboUn2n9sbQMZA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/standalone" "^7.0.0"
|
"@babel/standalone" "^7.0.0"
|
||||||
"@gitlab/vue-toasted" "^1.2.1"
|
"@gitlab/vue-toasted" "^1.2.1"
|
||||||
|
|
Loading…
Reference in New Issue