Commit de49a547 authored by Dallas Reedy's avatar Dallas Reedy

Complete experience-level page functionality

- Add new controller for ExperienceLevels
- Use that controller’s #show & #update actions
- Save user’s experience level selection
- Progress user to their group page afterward
parent 99aa9c9d
# frozen_string_literal: true
module Registrations
class ExperienceLevelsController < DeviseController
# This will need to be changed to simply 'devise' as part of
# https://gitlab.com/gitlab-org/growth/engineering/issues/64
layout 'devise_experimental_separate_sign_up_flow'
before_action :authenticate_user!
before_action :check_experiment_enabled
def update
current_user.experience_level = params[:experience_level]
if current_user.save
set_flash_message! :notice, :signed_up
redirect_to group_path(params[:namespace_path] || current_user)
else
render :show
end
end
private
def check_experiment_enabled
access_denied! unless experiment_enabled?(:onboarding_issues)
end
# Override the default translation scope of "devise.#{controller_name}" to
# reuse existing translations from the RegistrationsController. Also, this
# way we're much more likely to catch problems early if that controller is
# ever renamed.
def translation_scope
"devise.#{RegistrationsController.controller_name}"
end
end
end
...@@ -14,7 +14,6 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -14,7 +14,6 @@ class RegistrationsController < Devise::RegistrationsController
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? }
before_action :load_recaptcha, only: :new before_action :load_recaptcha, only: :new
before_action :authenticate_user!, only: :experience_level
def new def new
if experiment_enabled?(:signup_flow) if experiment_enabled?(:signup_flow)
...@@ -58,10 +57,6 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -58,10 +57,6 @@ class RegistrationsController < Devise::RegistrationsController
return redirect_to path_for_signed_in_user(current_user) if current_user.role.present? && !current_user.setup_for_company.nil? return redirect_to path_for_signed_in_user(current_user) if current_user.role.present? && !current_user.setup_for_company.nil?
end end
def experience_level
return access_denied! unless experiment_enabled?(:onboarding_issues)
end
def update_registration def update_registration
user_params = params.require(:user).permit(:role, :setup_for_company) user_params = params.require(:user).permit(:role, :setup_for_company)
result = ::Users::SignupService.new(current_user, user_params).execute result = ::Users::SignupService.new(current_user, user_params).execute
......
...@@ -276,6 +276,7 @@ class User < ApplicationRecord ...@@ -276,6 +276,7 @@ class User < ApplicationRecord
:sourcegraph_enabled, :sourcegraph_enabled=, :sourcegraph_enabled, :sourcegraph_enabled=,
:setup_for_company, :setup_for_company=, :setup_for_company, :setup_for_company=,
:render_whitespace_in_code, :render_whitespace_in_code=, :render_whitespace_in_code, :render_whitespace_in_code=,
:experience_level, :experience_level=,
to: :user_preference to: :user_preference
delegate :path, to: :namespace, allow_nil: true, prefix: true delegate :path, to: :namespace, allow_nil: true, prefix: true
......
- content_for(:page_title, _('What’s your experience level?')) - page_title _('What’s your experience level?')
%h3= _('Hello there') %h3= _('Hello there')
%p= _('Welcome to the guided GitLab tour') %p= _('Welcome to the guided GitLab tour')
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
%b= _('Novice') %b= _('Novice')
%p= _('I’m not very familiar with the basics of project management and DevOps.') %p= _('I’m not very familiar with the basics of project management and DevOps.')
%p %p
%a{ href: '#novice' }= _('Show me everything') = link_to _('Show me everything'), users_sign_up_experience_level_path(experience_level: :novice, namespace_path: params[:namespace_path]), method: :patch
%hr %hr
...@@ -23,4 +23,4 @@ ...@@ -23,4 +23,4 @@
%b= _('Experienced') %b= _('Experienced')
%p= _('I’m familiar with the basics of project management and DevOps.') %p= _('I’m familiar with the basics of project management and DevOps.')
%p %p
%a{ href: '#experienced' }= _('Show me more advanced stuff') = link_to _('Show me more advanced stuff'), users_sign_up_experience_level_path(experience_level: :experienced, namespace_path: params[:namespace_path]), method: :patch
...@@ -48,7 +48,9 @@ Rails.application.routes.draw do ...@@ -48,7 +48,9 @@ Rails.application.routes.draw do
scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do
get :welcome get :welcome
patch :update_registration patch :update_registration
get :experience_level devise_scope :user do
resource :experience_level, only: [:show, :update]
end
Gitlab.ee do Gitlab.ee do
resources :groups, only: [:new, :create] resources :groups, only: [:new, :create]
......
...@@ -16,7 +16,7 @@ module Registrations ...@@ -16,7 +16,7 @@ module Registrations
if @project.saved? if @project.saved?
create_learn_gitlab_project create_learn_gitlab_project
redirect_to users_sign_up_experience_level_path redirect_to users_sign_up_experience_level_path(namespace_path: @project.namespace.to_param)
else else
render :new render :new
end end
......
...@@ -70,7 +70,7 @@ RSpec.describe Registrations::ProjectsController do ...@@ -70,7 +70,7 @@ RSpec.describe Registrations::ProjectsController do
Sidekiq::Worker.drain_all Sidekiq::Worker.drain_all
expect(subject).to have_gitlab_http_status(:redirect) expect(subject).to have_gitlab_http_status(:redirect)
expect(subject).to redirect_to(users_sign_up_experience_level_path) expect(subject).to redirect_to(users_sign_up_experience_level_path(namespace_path: namespace.to_param))
expect(namespace.projects.find_by_name(s_('Learn GitLab'))).to be_import_finished expect(namespace.projects.find_by_name(s_('Learn GitLab'))).to be_import_finished
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe Registrations::ExperienceLevelsController do
let_it_be(:user) { create(:user) }
before do
@request.env['devise.mapping'] = Devise.mappings[:user]
end
describe 'GET #show' do
subject { get :show }
# I don't understand why these specs are failing. It's like we never
# actually hit the `authenticate_user!` hook, or that it doesn't really do
# what I expect it to do based on other tests.
xcontext 'with an unauthenticated user' do
it { is_expected.to have_gitlab_http_status(:redirect) }
it { is_expected.to redirect_to(new_user_session_path) }
end
context 'with an authenticated user' do
before do
sign_in(user)
stub_experiment_for_user(onboarding_issues: true)
end
it { is_expected.to have_gitlab_http_status(:ok) }
it { is_expected.to render_template(:show) }
context 'when not part of the onboarding issues experiment' do
before do
stub_experiment_for_user(onboarding_issues: false)
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
end
describe 'PUT/PATCH #update' do
subject { patch :update, params: params }
let_it_be(:namespace) { create(:group, path: 'group-path' ) }
let(:params) { {} }
# I don't understand why these specs are failing. It's like we never
# actually hit the `authenticate_user!` hook, or that it doesn't really do
# what I expect it to do based on other tests.
xcontext 'with an unauthenticated user' do
it { is_expected.to have_gitlab_http_status(:redirect) }
it { is_expected.to redirect_to(new_user_session_path) }
end
context 'with an authenticated user' do
before do
sign_in(user)
stub_experiment_for_user(onboarding_issues: true)
end
context 'when no experience_level is sent' do
before do
user.user_preference.update_attribute(:experience_level, :novice)
end
it 'will unset the user’s experience level' do
expect { subject }.to change { user.reload.experience_level }.to(nil)
end
end
context 'when an expected experience level is sent' do
let(:params) { { experience_level: :novice } }
it 'sets the user’s experience level' do
expect { subject }.to change { user.reload.experience_level }
end
end
context 'when an unexpected experience level is sent' do
let(:params) { { experience_level: :nonexistent } }
it 'raises an exception' do
expect { subject }.to raise_error(ArgumentError, "'nonexistent' is not a valid experience_level")
end
end
context 'when a namespace_path is sent' do
let(:params) { { namespace_path: namespace.to_param } }
it { is_expected.to have_gitlab_http_status(:redirect) }
it { is_expected.to redirect_to(group_path(namespace)) }
end
context 'when no namespace_path is sent' do
it { is_expected.to have_gitlab_http_status(:redirect) }
it { is_expected.to redirect_to(user_path(user)) }
end
end
end
end
...@@ -445,27 +445,4 @@ RSpec.describe RegistrationsController do ...@@ -445,27 +445,4 @@ RSpec.describe RegistrationsController do
end end
end end
end end
describe '#experience_level' do
subject { get :experience_level }
let_it_be(:user) { create(:user) }
let(:part_of_onboarding_issues_experiment) { false }
before do
stub_experiment_for_user(onboarding_issues: part_of_onboarding_issues_experiment)
sign_in(user)
end
context 'when not part of the onboarding issues experiment' do
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context 'when part of the onboarding issues experiment' do
let(:part_of_onboarding_issues_experiment) { true }
it { is_expected.to render_template(:experience_level) }
end
end
end end
...@@ -53,6 +53,9 @@ describe User do ...@@ -53,6 +53,9 @@ describe User do
it { is_expected.to delegate_method(:render_whitespace_in_code).to(:user_preference) } it { is_expected.to delegate_method(:render_whitespace_in_code).to(:user_preference) }
it { is_expected.to delegate_method(:render_whitespace_in_code=).to(:user_preference).with_arguments(:args) } it { is_expected.to delegate_method(:render_whitespace_in_code=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:experience_level).to(:user_preference) }
it { is_expected.to delegate_method(:experience_level=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil } it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil } it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil }
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