Commit 4682f501 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 6d59e989
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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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!
......
# 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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
- 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 @@ ...@@ -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?
......
- 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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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")
......
- 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'
---
title: Add step 2 of the experimental signup flow
merge_request: 16583
author:
type: changed
...@@ -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
......
# 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 ...@@ -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. ...@@ -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 ...@@ -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 ...@@ -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 "" ...@@ -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 "" ...@@ -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 "" ...@@ -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 "" ...@@ -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 "" ...@@ -14092,6 +14101,9 @@ msgstr ""
msgid "Roadmap" msgid "Roadmap"
msgstr "" msgstr ""
msgid "Role"
msgstr ""
msgid "Rollback" msgid "Rollback"
msgstr "" msgstr ""
......
...@@ -842,4 +842,48 @@ describe ApplicationController do ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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)
......
This diff is collapsed.
...@@ -634,40 +634,21 @@ describe API::Users do ...@@ -634,40 +634,21 @@ 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 end
context 'on gitlab.com' do it "shows sign up page" do
before do get "/users/sign_up"
allow(::Gitlab).to receive(:com?).and_return(true) expect(response).to have_gitlab_http_status(200)
end expect(response).to render_template(:new)
it "shows sign up page" do
get "/users/sign_up"
expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:new)
end
end
context 'not on gitlab.com' do
before do
allow(::Gitlab).to receive(:com?).and_return(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
end end
context 'when experimental_separate_sign_up_flow is not active' do context 'when experimental signup_flow is not active' do
before do before do
allow(::Gitlab).to receive(:com?).and_return(true) stub_experiment(signup_flow: false)
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| ...@@ -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 ...@@ -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
# 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 ...@@ -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 ...@@ -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 @@ ...@@ -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"
......
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