Commit 381ce090 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch 'jswain_force_company_trial' into 'master'

Auto-check trial toggle for company signups

See merge request gitlab-org/gitlab!65287
parents 6c1f7a2e caf5cef9
......@@ -16,7 +16,7 @@ module Registrations
result = ::Users::SignupService.new(current_user, update_params).execute
if result[:status] == :success
return redirect_to new_users_sign_up_group_path if show_signup_onboarding?
return redirect_to new_users_sign_up_group_path(trial_params) if show_signup_onboarding?
members = current_user.members
......@@ -67,6 +67,10 @@ module Registrations
def show_signup_onboarding?
false
end
def trial_params
nil
end
end
end
......
# frozen_string_literal: true
class ForceCompanyTrialExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
exclude :setup_for_personal
private
def setup_for_personal
!context.user.setup_for_company
end
end
---
name: force_company_trial
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65287
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335050
milestone: '14.1'
type: experiment
group: group::adoption
default_enabled: false
......@@ -62,6 +62,14 @@ module EE
helpers.signup_onboarding_enabled?
end
override :trial_params
def trial_params
experiment(:force_company_trial, user: current_user) do |e|
e.try { { trial: true } }
e.run
end
end
def authorized_for_trial_onboarding!
access_denied! unless can?(current_user, :owner_access, learn_gitlab_project)
end
......
......@@ -15,6 +15,8 @@ module Registrations
def create
Members::CreateService.new(current_user, invite_params).execute
experiment(:force_company_trial, user: current_user).track(:create_invite, namespace: group, user: current_user)
redirect_to new_users_sign_up_project_path(namespace_id: group.id,
trial: helpers.in_trial_during_signup_flow?,
trial_onboarding_flow: helpers.in_trial_onboarding_flow?,
......
......@@ -23,6 +23,9 @@ module Registrations
if @group.persisted?
experiment(:jobs_to_be_done, user: current_user)
.track(:create_group, namespace: @group)
force_company_trial_experiment.track(:create_group, namespace: @group, user: current_user)
create_successful_flow
else
render action: :new
......@@ -37,6 +40,11 @@ module Registrations
private
def force_company_trial_experiment
@force_company_trial_experiment ||=
experiment(:force_company_trial, user: current_user)
end
def create_successful_flow
if helpers.in_trial_onboarding_flow?
apply_trial_for_trial_onboarding_flow
......@@ -123,7 +131,11 @@ module Registrations
result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params)
flash[:alert] = result&.dig(:errors) unless result&.dig(:success)
result&.dig(:success)
success = result&.dig(:success)
force_company_trial_experiment.track(:create_trial, namespace: @group, user: current_user, label: 'registrations_groups_controller') if success
success
end
def learn_gitlab_context
......
......@@ -34,6 +34,9 @@ module Registrations
experiment(:jobs_to_be_done, user: current_user)
.track(:create_project, project: @project)
experiment(:force_company_trial, user: current_user)
.track(:create_project, namespace: @project.namespace, project: @project, user: current_user)
if helpers.in_trial_onboarding_flow?
record_experiment_user(:trial_onboarding_issues, onboarding_context)
record_experiment_conversion_event(:trial_onboarding_issues)
......
......@@ -69,6 +69,8 @@ class SubscriptionsController < ApplicationController
edit_subscriptions_group_path(group.path, plan_id: plan_id, quantity: quantity, new_user: params[:new_user])
end
experiment(:force_company_trial, user: current_user).track(:create_subscription, namespace: group, user: current_user)
response[:data] = { location: redirect_location }
end
......
......@@ -45,6 +45,8 @@ class TrialsController < ApplicationController
record_experiment_conversion_event(:remove_known_trial_form_fields)
record_experiment_conversion_event(:trial_onboarding_issues)
experiment(:force_company_trial, user: current_user).track(:create_trial, namespace: @namespace, user: current_user, label: 'trials_controller') if @namespace.created_at > 24.hours.ago
if discover_group_security_flow?
redirect_trial_user_to_feature_experiment_flow
else
......
......@@ -273,6 +273,16 @@ RSpec.describe Registrations::GroupsController do
context 'with separate invite page' do
it { is_expected.to redirect_to(new_users_sign_up_group_invite_path(group_id: group.id, trial: true)) }
end
it 'tracks for the force_company_trial experiment', :experiment do
wrapped_experiment(experiment(:force_company_trial)) do |e|
expect(e.context.value).to include(user: user)
expect(e).to receive(:track).with(:create_group, namespace: an_instance_of(Group), user: user)
expect(e).to receive(:track).with(:create_trial, namespace: an_instance_of(Group), user: user, label: 'registrations_groups_controller')
end
subject
end
end
context 'when failing to create a lead and apply trial' do
......@@ -306,6 +316,16 @@ RSpec.describe Registrations::GroupsController do
subject
end
it 'selectivly tracks for the force_company_trial experiment', :experiment do
wrapped_experiment(experiment(:force_company_trial)) do |e|
expect(e.context.value).to include(user: user)
expect(e).to receive(:track).with(:create_group, namespace: an_instance_of(Group))
expect(e).not_to receive(:track).with(:create_trial, namespace: an_instance_of(Group))
end
subject
end
end
end
end
......
......@@ -97,6 +97,14 @@ RSpec.describe Registrations::ProjectsController do
subject
end
it 'tracks an event for the force_company_trial experiment', :experiment do
expect(experiment(:force_company_trial)).to track(:create_project, namespace: namespace, project: an_instance_of(Project), user: user)
.with_context(user: user)
.on_next_instance
subject
end
it 'tracks learn gitlab experiments' do
allow_next_instance_of(::Projects::CreateService) do |service|
allow(service).to receive(:execute).and_return(first_project)
......
......@@ -229,6 +229,16 @@ RSpec.describe Registrations::WelcomeController do
allow(controller.helpers).to receive(:signup_onboarding_enabled?).and_return(true)
end
context 'and force_company_trial experiment is candidate' do
let(:setup_for_company) { 'true' }
before do
stub_experiments(force_company_trial: :candidate)
end
it { is_expected.to redirect_to new_users_sign_up_group_path(trial: true) }
end
it { is_expected.to redirect_to new_users_sign_up_group_path }
context 'when in subscription flow' do
......
......@@ -305,6 +305,12 @@ RSpec.describe SubscriptionsController do
expect(response.body).to eq({ location: "/#{selected_group.path}?plan_id=#{plan_id}&purchased_quantity=#{quantity}" }.to_json)
end
it 'tracks for the force_company_trial experiment', :experiment do
expect(experiment(:force_company_trial)).to track(:create_subscription, namespace: selected_group, user: user).with_context(user: user).on_next_instance
subject
end
end
context 'when the selected group is ineligible for a new subscription' do
......
......@@ -185,7 +185,7 @@ RSpec.describe TrialsController do
it_behaves_like 'an authenticated endpoint'
it_behaves_like 'a dot-com only feature'
context 'on success' do
context 'on success', :experiment do
let(:apply_trial_result) { true }
it { is_expected.to redirect_to("/#{namespace.path}?trial=true") }
......@@ -194,6 +194,7 @@ RSpec.describe TrialsController do
expect(controller).to receive(:record_experiment_user).with(:trial_onboarding_issues, namespace_id: namespace.id)
expect(controller).to receive(:record_experiment_conversion_event).with(:remove_known_trial_form_fields)
expect(controller).to receive(:record_experiment_conversion_event).with(:trial_onboarding_issues)
expect(experiment(:force_company_trial)).to track(:create_trial, namespace: namespace, user: user, label: 'trials_controller').with_context(user: user).on_next_instance
subject
end
......@@ -235,6 +236,16 @@ RSpec.describe TrialsController do
expect { subject }.to change { Group.count }.by(1)
end
end
context 'with an old namespace' do
it 'does not track for the force_company_trial experiment' do
namespace.update!(created_at: 2.days.ago)
expect(controller).not_to receive(:experiment).with(:force_company_trial, user: user)
subject
end
end
end
context 'on failure' do
......
......@@ -5,8 +5,12 @@ require 'spec_helper'
RSpec.describe 'User sees new onboarding flow', :js do
include Select2Helper
let_it_be(:user) { create(:user) }
let_it_be(:trial_fields) { ['Company name', 'Number of employees', 'How many employees will use Gitlab?', 'Telephone number', 'Country'] }
let(:experiments) { {} }
before do
stub_experiments(experiments)
allow(Gitlab).to receive(:com?).and_return(true)
sign_in(user)
visit users_sign_up_welcome_path
......@@ -19,6 +23,14 @@ RSpec.describe 'User sees new onboarding flow', :js do
expect(page).to have_content('GitLab Ultimate trial (optional)')
end
context 'when force_company_trial experiment is candidate' do
let(:experiments) { { force_company_trial: :candidate } }
it 'shows the trial fields' do
trial_fields.each { |field| expect(page).to have_content(field) }
end
end
it 'shows the expected behavior with no trial chosen', :aggregate_failures do
fill_in 'group_name', with: 'test'
......@@ -29,16 +41,15 @@ RSpec.describe 'User sees new onboarding flow', :js do
end
it 'shows the expected behavior with trial chosen' do
fields = ['Company name', 'Number of employees', 'How many employees will use Gitlab?', 'Telephone number', 'Country']
fill_in 'group_name', with: 'test'
# fields initially invisible
fields.each { |field| expect(page).not_to have_content(field) }
trial_fields.each { |field| expect(page).not_to have_content(field) }
# fields become visible with trial toggle
click_button class: 'gl-toggle'
fields.each { |field| expect(page).to have_content(field) }
trial_fields.each { |field| expect(page).to have_content(field) }
# fields are required
click_on 'Create group'
......@@ -48,12 +59,12 @@ RSpec.describe 'User sees new onboarding flow', :js do
# make fields invisible again
click_button class: 'gl-toggle'
fields.each { |field| expect(page).not_to have_content(field) }
trial_fields.each { |field| expect(page).not_to have_content(field) }
# make fields visible again
click_button class: 'gl-toggle'
fields.each { |field| expect(page).to have_content(field) }
trial_fields.each { |field| expect(page).to have_content(field) }
# submit the trial form
fill_in 'company_name', with: 'GitLab'
......
......@@ -65,7 +65,15 @@ RSpec.describe 'view group invites' do
hide_trial_activation_banner: true))
end
context 'when inviting members' do
context 'when inviting members', :experiment do
it 'tracks for the force_company_trial experiment' do
expect(experiment(:force_company_trial)).to track(:create_invite, namespace: group, user: user)
.with_context(user: user)
.on_next_instance
post_request
end
context 'without valid emails in the params' do
it 'no invites generated by default' do
post_request
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ForceCompanyTrialExperiment, :experiment do
subject { described_class.new(current_user: user) }
let(:user) { create(:user, setup_for_company: setup_for_company) }
let(:setup_for_company) { true }
context 'when a user is setup_for_company' do
it 'is not excluded' do
expect(subject).not_to exclude(user: user)
end
end
context 'when a user is not setup_for_company' do
let(:setup_for_company) { nil }
it 'is excluded' do
expect(subject).to exclude(user: user)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment