From 95c16a23b5fe6601341c619b735a623802c6903d Mon Sep 17 00:00:00 2001 From: Doug Stull <dstull@gitlab.com> Date: Thu, 1 Sep 2022 21:53:34 +0000 Subject: [PATCH] Conclude the combined registration experiment - make part of product Changelog: changed EE: true --- .rubocop_todo/layout/line_length.yml | 9 - .rubocop_todo/rspec/context_wording.yml | 4 - .rubocop_todo/rspec/expect_change.yml | 3 - .rubocop_todo/rspec/expect_in_hook.yml | 4 - .../style/class_and_module_children.yml | 3 - .../javascripts/google_tag_manager/index.js | 11 - .../components/visibility_level_dropdown.vue | 48 ---- .../javascripts/groups/visibility_level.js | 24 -- .../combined_registration_experiment.rb | 16 -- app/services/projects/create_service.rb | 2 +- .../shared/groups/_visibility_level.html.haml | 3 - .../experiment/combined_registration.yml | 8 - config/routes.rb | 7 +- .../pages/registrations/groups/new/index.js | 13 - .../pages/registrations/projects/new/index.js | 9 - .../components/registration_trial_toggle.vue | 45 ---- .../registrations/groups/new/index.js | 47 ---- .../javascripts/trials/country_select.js | 29 --- .../concerns/registrations/apply_trial.rb | 25 -- .../concerns/registrations/create_group.rb | 33 --- .../concerns/registrations/create_project.rb | 40 --- .../ee/registrations/welcome_controller.rb | 14 +- .../registrations/groups_controller.rb | 92 ------- .../groups_projects_controller.rb | 80 +++++- .../registrations/projects_controller.rb | 76 ------ ee/app/controllers/trials_controller.rb | 5 +- ee/app/helpers/ee/welcome_helper.rb | 8 - .../views/registrations/groups/new.html.haml | 55 ---- .../registrations/projects/new.html.haml | 62 ----- .../_country_or_region_selector.html.haml | 2 - .../views/shared/groups/_trial_form.html.haml | 26 -- ee/app/views/trials/_select_country.html.haml | 2 - .../registrations/groups_controller_spec.rb | 244 ------------------ .../groups_projects_controller_spec.rb | 207 +++++++++------ .../registrations/projects_controller_spec.rb | 58 ----- .../registrations/welcome_controller_spec.rb | 26 +- ee/spec/controllers/trials_controller_spec.rb | 40 ++- .../combined_registration_experiment_spec.rb | 32 --- .../google_analytics_datalayer_spec.rb | 39 --- .../combined_registration_spec.rb | 106 ++++---- .../features/registrations/one_trust_spec.rb | 17 -- .../saas_user_registration_spec.rb | 45 +++- .../trial_during_signup_flow_spec.rb | 78 ------ .../user_sees_new_onboarding_flow_spec.rb | 46 ---- .../registration_trial_toggle_spec.js | 51 ---- ee/spec/helpers/ee/welcome_helper_spec.rb | 19 -- .../registrations/project_creation_spec.rb | 2 +- .../groups_controller_shared_examples.rb | 59 +---- .../projects_controller_shared_examples.rb | 140 ---------- .../groups/new.html.haml_spec.rb | 54 ---- .../groups_projects/new.html.haml_spec.rb | 6 +- .../projects/new.html.haml_spec.rb | 45 ---- locale/gitlab.pot | 45 ---- .../frontend/google_tag_manager/index_spec.js | 16 +- .../visibility_level_dropdown_spec.js | 70 ----- spec/services/projects/create_service_spec.rb | 6 +- spec/support/rspec_order_todo.yml | 1 - 57 files changed, 335 insertions(+), 1922 deletions(-) delete mode 100644 app/assets/javascripts/groups/components/visibility_level_dropdown.vue delete mode 100644 app/assets/javascripts/groups/visibility_level.js delete mode 100644 app/experiments/combined_registration_experiment.rb delete mode 100644 app/views/shared/groups/_visibility_level.html.haml delete mode 100644 config/feature_flags/experiment/combined_registration.yml delete mode 100644 ee/app/assets/javascripts/pages/registrations/groups/new/index.js delete mode 100644 ee/app/assets/javascripts/pages/registrations/projects/new/index.js delete mode 100644 ee/app/assets/javascripts/registrations/components/registration_trial_toggle.vue delete mode 100644 ee/app/assets/javascripts/registrations/groups/new/index.js delete mode 100644 ee/app/assets/javascripts/trials/country_select.js delete mode 100644 ee/app/controllers/concerns/registrations/apply_trial.rb delete mode 100644 ee/app/controllers/concerns/registrations/create_group.rb delete mode 100644 ee/app/controllers/concerns/registrations/create_project.rb delete mode 100644 ee/app/controllers/registrations/groups_controller.rb delete mode 100644 ee/app/controllers/registrations/projects_controller.rb delete mode 100644 ee/app/views/registrations/groups/new.html.haml delete mode 100644 ee/app/views/registrations/projects/new.html.haml delete mode 100644 ee/app/views/shared/groups/_country_or_region_selector.html.haml delete mode 100644 ee/app/views/shared/groups/_trial_form.html.haml delete mode 100644 ee/app/views/trials/_select_country.html.haml delete mode 100644 ee/spec/controllers/registrations/groups_controller_spec.rb delete mode 100644 ee/spec/controllers/registrations/projects_controller_spec.rb delete mode 100644 ee/spec/experiments/combined_registration_experiment_spec.rb delete mode 100644 ee/spec/features/registrations/trial_during_signup_flow_spec.rb delete mode 100644 ee/spec/features/registrations/user_sees_new_onboarding_flow_spec.rb delete mode 100644 ee/spec/frontend/groups/components/registration_trial_toggle_spec.js delete mode 100644 ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb delete mode 100644 ee/spec/views/registrations/groups/new.html.haml_spec.rb delete mode 100644 ee/spec/views/registrations/projects/new.html.haml_spec.rb delete mode 100644 spec/frontend/groups/components/visibility_level_dropdown_spec.js diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index 80c0f98655272..7424ab7ea2602 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -1123,7 +1123,6 @@ Layout/LineLength: - 'ee/app/controllers/concerns/ee/issuable_collections.rb' - 'ee/app/controllers/concerns/group_invite_members.rb' - 'ee/app/controllers/concerns/insights_actions.rb' - - 'ee/app/controllers/concerns/registrations/create_project.rb' - 'ee/app/controllers/ee/admin/dev_ops_report_controller.rb' - 'ee/app/controllers/ee/admin/users_controller.rb' - 'ee/app/controllers/ee/application_controller.rb' @@ -1160,8 +1159,6 @@ Layout/LineLength: - 'ee/app/controllers/projects/requirements_management/requirements_controller.rb' - 'ee/app/controllers/projects/security/policies_controller.rb' - 'ee/app/controllers/projects/security/vulnerabilities/notes_controller.rb' - - 'ee/app/controllers/registrations/groups_controller.rb' - - 'ee/app/controllers/registrations/groups_projects_controller.rb' - 'ee/app/controllers/subscriptions_controller.rb' - 'ee/app/controllers/trial_registrations_controller.rb' - 'ee/app/controllers/trials_controller.rb' @@ -1862,8 +1859,6 @@ Layout/LineLength: - 'ee/spec/controllers/projects/subscriptions_controller_spec.rb' - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb' - 'ee/spec/controllers/projects_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_projects_controller_spec.rb' - 'ee/spec/controllers/registrations/welcome_controller_spec.rb' - 'ee/spec/controllers/subscriptions/groups_controller_spec.rb' - 'ee/spec/controllers/subscriptions_controller_spec.rb' @@ -1979,7 +1974,6 @@ Layout/LineLength: - 'ee/spec/features/projects_spec.rb' - 'ee/spec/features/promotion_spec.rb' - 'ee/spec/features/read_only_spec.rb' - - 'ee/spec/features/registrations/combined_registration_spec.rb' - 'ee/spec/features/search/elastic/global_search_spec.rb' - 'ee/spec/features/search/elastic/project_search_spec.rb' - 'ee/spec/features/search/elastic/snippet_search_spec.rb' @@ -2960,8 +2954,6 @@ Layout/LineLength: - 'ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_shared_examples.rb' - 'ee/spec/support/shared_examples/controllers/concerns/description_diff_actions_shared_examples.rb' - 'ee/spec/support/shared_examples/controllers/projects/license_scanning_report_comparison_shared_examples.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb' - 'ee/spec/support/shared_examples/features/epics_filtered_search_shared_examples.rb' - 'ee/spec/support/shared_examples/features/over_free_user_limit_shared_examples.rb' - 'ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb' @@ -3017,7 +3009,6 @@ Layout/LineLength: - 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb' - 'ee/spec/views/operations/environments.html.haml_spec.rb' - 'ee/spec/views/projects/security/discover/show.html.haml_spec.rb' - - 'ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb' - 'ee/spec/views/registrations/welcome/show.html.haml_spec.rb' - 'ee/spec/views/shared/_mirror_status.html.haml_spec.rb' - 'ee/spec/views/shared/_namespace_user_cap_reached_alert.html.haml_spec.rb' diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml index 163533621a6b4..98fd3c52fd94c 100644 --- a/.rubocop_todo/rspec/context_wording.yml +++ b/.rubocop_todo/rspec/context_wording.yml @@ -64,7 +64,6 @@ RSpec/ContextWording: - 'ee/spec/controllers/projects/settings/repository_controller_spec.rb' - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb' - 'ee/spec/controllers/projects_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_projects_controller_spec.rb' - 'ee/spec/controllers/registrations/welcome_controller_spec.rb' - 'ee/spec/controllers/repositories/git_http_controller_spec.rb' - 'ee/spec/controllers/security/dashboard_controller_spec.rb' @@ -921,8 +920,6 @@ RSpec/ContextWording: - 'ee/spec/support/shared_examples/controllers/boards_actions_shared_examples.rb' - 'ee/spec/support/shared_examples/controllers/cluster_metrics_shared_examples.rb' - 'ee/spec/support/shared_examples/controllers/concerns/description_diff_actions_shared_examples.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb' - 'ee/spec/support/shared_examples/features/insights_shared_examples.rb' - 'ee/spec/support/shared_examples/features/password_complexity_shared_examples.rb' - 'ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb' @@ -968,7 +965,6 @@ RSpec/ContextWording: - 'ee/spec/views/profiles/preferences/show.html.haml_spec.rb' - 'ee/spec/views/projects/edit.html.haml_spec.rb' - 'ee/spec/views/projects/security/discover/show.html.haml_spec.rb' - - 'ee/spec/views/registrations/groups/new.html.haml_spec.rb' - 'ee/spec/views/registrations/welcome/show.html.haml_spec.rb' - 'ee/spec/views/search/_category.html.haml_spec.rb' - 'ee/spec/views/shared/_clone_panel.html.haml_spec.rb' diff --git a/.rubocop_todo/rspec/expect_change.yml b/.rubocop_todo/rspec/expect_change.yml index 0306662688327..3d771b0ecef81 100644 --- a/.rubocop_todo/rspec/expect_change.yml +++ b/.rubocop_todo/rspec/expect_change.yml @@ -22,8 +22,6 @@ RSpec/ExpectChange: - 'ee/spec/controllers/projects/repositories_controller_spec.rb' - 'ee/spec/controllers/projects/security/vulnerabilities/notes_controller_spec.rb' - 'ee/spec/controllers/projects_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_projects_controller_spec.rb' - 'ee/spec/controllers/trials_controller_spec.rb' - 'ee/spec/elastic/migrate/20220119120500_populate_commit_permissions_in_main_index_spec.rb' - 'ee/spec/features/groups/group_settings_spec.rb' @@ -245,7 +243,6 @@ RSpec/ExpectChange: - 'ee/spec/services/vulnerability_feedback/create_service_spec.rb' - 'ee/spec/services/vulnerability_feedback/destroy_service_spec.rb' - 'ee/spec/support/shared_contexts/audit_event_not_licensed_shared_context.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb' - 'ee/spec/support/shared_examples/graphql/mutations/update_health_status_shared_examples.rb' - 'ee/spec/support/shared_examples/models/concerns/replicable_model_with_separate_table_shared_examples.rb' - 'ee/spec/support/shared_examples/models/geo_verifiable_registry_shared_examples.rb' diff --git a/.rubocop_todo/rspec/expect_in_hook.yml b/.rubocop_todo/rspec/expect_in_hook.yml index d138ea806f80d..8ab50ede1ba09 100644 --- a/.rubocop_todo/rspec/expect_in_hook.yml +++ b/.rubocop_todo/rspec/expect_in_hook.yml @@ -6,8 +6,6 @@ RSpec/ExpectInHook: - 'ee/spec/controllers/groups/seat_usage_controller_spec.rb' - 'ee/spec/controllers/projects/boards_controller_spec.rb' - 'ee/spec/controllers/projects/settings/slacks_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_controller_spec.rb' - - 'ee/spec/controllers/registrations/groups_projects_controller_spec.rb' - 'ee/spec/controllers/subscriptions_controller_spec.rb' - 'ee/spec/controllers/trials_controller_spec.rb' - 'ee/spec/elastic/migrate/20220118150500_delete_orphaned_commits_spec.rb' @@ -17,7 +15,6 @@ RSpec/ExpectInHook: - 'ee/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb' - 'ee/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb' - 'ee/spec/features/projects/settings/ee/service_desk_setting_spec.rb' - - 'ee/spec/features/registrations/combined_registration_spec.rb' - 'ee/spec/features/registrations/saas_user_registration_spec.rb' - 'ee/spec/features/registrations/trial_during_signup_flow_spec.rb' - 'ee/spec/features/signup_spec.rb' @@ -103,7 +100,6 @@ RSpec/ExpectInHook: - 'ee/spec/services/projects/update_mirror_service_spec.rb' - 'ee/spec/services/security/findings/cleanup_service_spec.rb' - 'ee/spec/services/upcoming_reconciliations/update_service_spec.rb' - - 'ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb' - 'ee/spec/support/shared_examples/lib/gitlab/graphql/issuables_lazy_links_aggregate_shared_examples.rb' - 'ee/spec/support/shared_examples/models/concerns/elastic/cannot_read_cross_project_shared_examples.rb' - 'ee/spec/support/shared_examples/models/concerns/verifiable_replicator_shared_examples.rb' diff --git a/.rubocop_todo/style/class_and_module_children.yml b/.rubocop_todo/style/class_and_module_children.yml index e0747f232a1a8..2674902c7eed8 100644 --- a/.rubocop_todo/style/class_and_module_children.yml +++ b/.rubocop_todo/style/class_and_module_children.yml @@ -384,9 +384,6 @@ Style/ClassAndModuleChildren: - 'ee/app/controllers/admin/push_rules_controller.rb' - 'ee/app/controllers/admin/subscriptions_controller.rb' - 'ee/app/controllers/admin/user_permission_exports_controller.rb' - - 'ee/app/controllers/concerns/registrations/apply_trial.rb' - - 'ee/app/controllers/concerns/registrations/create_group.rb' - - 'ee/app/controllers/concerns/registrations/create_project.rb' - 'ee/app/controllers/concerns/registrations/verification.rb' - 'ee/app/controllers/ee/profiles/accounts_controller.rb' - 'ee/app/controllers/ee/profiles/preferences_controller.rb' diff --git a/app/assets/javascripts/google_tag_manager/index.js b/app/assets/javascripts/google_tag_manager/index.js index ca5a1b29b6ded..5b0bcfa963be4 100644 --- a/app/assets/javascripts/google_tag_manager/index.js +++ b/app/assets/javascripts/google_tag_manager/index.js @@ -140,17 +140,6 @@ export const trackSaasTrialGroup = () => { }); }; -export const trackSaasTrialProject = () => { - if (!isSupported()) { - return; - } - - const form = document.getElementById('new_project'); - form.addEventListener('submit', () => { - pushEvent('saasTrialProject'); - }); -}; - export const trackProjectImport = () => { if (!isSupported()) { return; diff --git a/app/assets/javascripts/groups/components/visibility_level_dropdown.vue b/app/assets/javascripts/groups/components/visibility_level_dropdown.vue deleted file mode 100644 index 0933045fc387b..0000000000000 --- a/app/assets/javascripts/groups/components/visibility_level_dropdown.vue +++ /dev/null @@ -1,48 +0,0 @@ -<script> -import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; - -export default { - components: { - GlDropdown, - GlDropdownItem, - }, - props: { - visibilityLevelOptions: { - type: Array, - required: true, - }, - defaultLevel: { - type: Number, - required: true, - }, - }, - data() { - return { - selectedOption: this.getDefaultOption(), - }; - }, - methods: { - getDefaultOption() { - return this.visibilityLevelOptions.find((option) => option.level === this.defaultLevel); - }, - onClick(option) { - this.selectedOption = option; - }, - }, -}; -</script> -<template> - <div> - <input type="hidden" name="group[visibility_level]" :value="selectedOption.level" /> - <gl-dropdown :text="selectedOption.label" class="gl-w-full" menu-class="gl-w-full! gl-mb-0"> - <gl-dropdown-item - v-for="option in visibilityLevelOptions" - :key="option.level" - :secondary-text="option.description" - @click="onClick(option)" - > - <div class="gl-font-weight-bold gl-mb-1">{{ option.label }}</div> - </gl-dropdown-item> - </gl-dropdown> - </div> -</template> diff --git a/app/assets/javascripts/groups/visibility_level.js b/app/assets/javascripts/groups/visibility_level.js deleted file mode 100644 index d570b5e65ac25..0000000000000 --- a/app/assets/javascripts/groups/visibility_level.js +++ /dev/null @@ -1,24 +0,0 @@ -import Vue from 'vue'; -import VisibilityLevelDropdown from './components/visibility_level_dropdown.vue'; - -export default () => { - const el = document.querySelector('.js-visibility-level-dropdown'); - - if (!el) { - return null; - } - - const { visibilityLevelOptions, defaultLevel } = el.dataset; - - return new Vue({ - el, - render(createElement) { - return createElement(VisibilityLevelDropdown, { - props: { - visibilityLevelOptions: JSON.parse(visibilityLevelOptions), - defaultLevel: Number(defaultLevel), - }, - }); - }, - }); -}; diff --git a/app/experiments/combined_registration_experiment.rb b/app/experiments/combined_registration_experiment.rb deleted file mode 100644 index 38295cec0d330..0000000000000 --- a/app/experiments/combined_registration_experiment.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -class CombinedRegistrationExperiment < ApplicationExperiment - include Rails.application.routes.url_helpers - - control { new_users_sign_up_group_path } - candidate { new_users_sign_up_groups_project_path } - - def key_for(source, _ = nil) - super(source, 'force_company_trial') - end - - def redirect_path - run - end -end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 6381ee67ce750..9f52dd89ff2b0 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -96,7 +96,7 @@ def after_create_actions log_info("#{current_user.name} created a new project \"#{@project.full_name}\"") if @project.import? - experiment(:combined_registration, user: current_user).track(:import_project) + Gitlab::Tracking.event(self.class.name, 'import_project', user: current_user) else # Skip writing the config for project imports/forks because it # will always fail since the Git directory doesn't exist until diff --git a/app/views/shared/groups/_visibility_level.html.haml b/app/views/shared/groups/_visibility_level.html.haml deleted file mode 100644 index 1a13de9b76ac5..0000000000000 --- a/app/views/shared/groups/_visibility_level.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= f.label :visibility_level, class: 'label-bold' do - = _('Visibility level') -.js-visibility-level-dropdown{ data: { visibility_level_options: visibility_level_options(@group).to_json, default_level: f.object.visibility_level } } diff --git a/config/feature_flags/experiment/combined_registration.yml b/config/feature_flags/experiment/combined_registration.yml deleted file mode 100644 index 0b867353946cf..0000000000000 --- a/config/feature_flags/experiment/combined_registration.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: combined_registration -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67614 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285533 -milestone: '14.3' -type: experiment -group: group::acquisition -default_enabled: false diff --git a/config/routes.rb b/config/routes.rb index ddc7b77460c9f..704405bbcbdd4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -70,8 +70,11 @@ Gitlab.ee do resource :company, only: [:new, :create], controller: 'company' - resources :groups, only: [:new, :create] - resources :projects, only: [:new, :create] + + # legacy - to be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/371996 + get 'groups/new', to: redirect('users/sign_up/groups_projects/new') + get 'projects/new', to: redirect('users/sign_up/groups_projects/new') + resources :groups_projects, only: [:new, :create] do collection do post :import diff --git a/ee/app/assets/javascripts/pages/registrations/groups/new/index.js b/ee/app/assets/javascripts/pages/registrations/groups/new/index.js deleted file mode 100644 index 816fb966493e8..0000000000000 --- a/ee/app/assets/javascripts/pages/registrations/groups/new/index.js +++ /dev/null @@ -1,13 +0,0 @@ -/* eslint-disable no-new */ - -import mountComponents from 'ee/registrations/groups/new'; -import BindInOut from '~/behaviors/bind_in_out'; -import Group from '~/group'; -import { trackSaasTrialGroup } from '~/google_tag_manager'; -import GroupPathValidator from '~/pages/groups/new/group_path_validator'; - -mountComponents(); -new GroupPathValidator(); -BindInOut.initAll(); -new Group(); -trackSaasTrialGroup(); diff --git a/ee/app/assets/javascripts/pages/registrations/projects/new/index.js b/ee/app/assets/javascripts/pages/registrations/projects/new/index.js deleted file mode 100644 index b7c73e49a2c4b..0000000000000 --- a/ee/app/assets/javascripts/pages/registrations/projects/new/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import initProjectVisibilitySelector from '~/projects/project_visibility'; -import initProjectNew from '~/projects/project_new'; -import { trackSaasTrialProject, trackProjectImport } from '~/google_tag_manager'; - -initProjectVisibilitySelector(); -initProjectNew.bindEvents(); - -trackSaasTrialProject(); -trackProjectImport(); diff --git a/ee/app/assets/javascripts/registrations/components/registration_trial_toggle.vue b/ee/app/assets/javascripts/registrations/components/registration_trial_toggle.vue deleted file mode 100644 index 5e9d9841c6222..0000000000000 --- a/ee/app/assets/javascripts/registrations/components/registration_trial_toggle.vue +++ /dev/null @@ -1,45 +0,0 @@ -<script> -import { GlToggle } from '@gitlab/ui'; -import { s__ } from '~/locale'; - -export default { - i18n: { - toggleLabel: s__('Trial|GitLab Ultimate trial (optional)'), - }, - components: { - GlToggle, - }, - props: { - active: { - type: Boolean, - required: false, - default: false, - }, - }, - data() { - return { - trial: this.active, - }; - }, - mounted() { - this.toggleTrial(); - }, - methods: { - toggleTrial() { - this.$emit('changed', { - trial: this.trial, - }); - }, - }, -}; -</script> -<template> - <gl-toggle - v-model="trial" - name="trial" - :label="$options.i18n.toggleLabel" - label-position="hidden" - data-testid="trial" - @change="toggleTrial" - /> -</template> diff --git a/ee/app/assets/javascripts/registrations/groups/new/index.js b/ee/app/assets/javascripts/registrations/groups/new/index.js deleted file mode 100644 index e4440b9e4ff7a..0000000000000 --- a/ee/app/assets/javascripts/registrations/groups/new/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import Vue from 'vue'; -import mountVisibilityLevelDropdown from '~/groups/visibility_level'; -import 'ee/trials/country_select'; -import RegistrationTrialToggle from '../../components/registration_trial_toggle.vue'; - -function toggleTrialForm(trial) { - const form = document.querySelector('.js-trial-form'); - const fields = document.querySelectorAll('.js-trial-field'); - - if (!form) { - return null; - } - - form.classList.toggle('hidden', !trial); - fields.forEach((f) => { - f.disabled = !trial; // eslint-disable-line no-param-reassign - }); - - return trial; -} - -function mountTrialToggle() { - const el = document.querySelector('.js-trial-toggle'); - - if (!el) { - return null; - } - - const { active } = el.dataset; - - return new Vue({ - el, - render(createElement) { - return createElement(RegistrationTrialToggle, { - props: { active }, - on: { - changed: (event) => toggleTrialForm(event.trial), - }, - }); - }, - }); -} - -export default () => { - mountVisibilityLevelDropdown(); - mountTrialToggle(); -}; diff --git a/ee/app/assets/javascripts/trials/country_select.js b/ee/app/assets/javascripts/trials/country_select.js deleted file mode 100644 index 6fbe5a731f1bf..0000000000000 --- a/ee/app/assets/javascripts/trials/country_select.js +++ /dev/null @@ -1,29 +0,0 @@ -import $ from 'jquery'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; -import { __ } from '~/locale'; - -const selectElement = document.getElementById('country_select'); - -if (selectElement?.dataset) { - const { countriesEndPoint, selectedOption } = selectElement.dataset; - - axios - .get(countriesEndPoint) - .then(({ data }) => { - // fill #country_select element with array of <option>s - data.forEach(([name, code]) => { - const option = document.createElement('option'); - option.value = code; - option.text = name; - - selectElement.appendChild(option); - }); - $(selectElement).val(selectedOption).trigger('change.select2'); - }) - .catch(() => - createFlash({ - message: __('Error loading countries data.'), - }), - ); -} diff --git a/ee/app/controllers/concerns/registrations/apply_trial.rb b/ee/app/controllers/concerns/registrations/apply_trial.rb deleted file mode 100644 index aadacc5db6702..0000000000000 --- a/ee/app/controllers/concerns/registrations/apply_trial.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Registrations::ApplyTrial - extend ActiveSupport::Concern - - included do - private - - def apply_trial - apply_trial_params = { - uid: current_user.id, - trial_user: params.permit(:glm_source, :glm_content).merge({ - namespace_id: @group.id, - gitlab_com_trial: true, - sync_to_gl: true - }) - } - - result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params) - flash.now[:alert] = result&.dig(:errors) unless result&.dig(:success) - - result&.dig(:success) - end - end -end diff --git a/ee/app/controllers/concerns/registrations/create_group.rb b/ee/app/controllers/concerns/registrations/create_group.rb deleted file mode 100644 index 62a740d8afe11..0000000000000 --- a/ee/app/controllers/concerns/registrations/create_group.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -module Registrations::CreateGroup - extend ActiveSupport::Concern - - included do - before_action :check_if_gl_com_or_dev - before_action :authorize_create_group!, only: :new - - protected - - def show_confirm_warning? - false - end - - private - - def authorize_create_group! - access_denied! unless can?(current_user, :create_group) - end - - def group_params - params.require(:group).permit( - :name, - :path, - :visibility_level - ).merge( - create_event: true, - setup_for_company: current_user.setup_for_company - ) - end - end -end diff --git a/ee/app/controllers/concerns/registrations/create_project.rb b/ee/app/controllers/concerns/registrations/create_project.rb deleted file mode 100644 index 4b6c7849092ea..0000000000000 --- a/ee/app/controllers/concerns/registrations/create_project.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Registrations::CreateProject - extend ActiveSupport::Concern - include LearnGitlabHelper - - LEARN_GITLAB_ULTIMATE_TEMPLATE = 'learn_gitlab_ultimate.tar.gz' - - included do - private - - def learn_gitlab_template_path - Rails.root.join('vendor', 'project_templates', LEARN_GITLAB_ULTIMATE_TEMPLATE) - end - - def create_learn_gitlab_project(parent_project_namespace_id) - ::Onboarding::CreateLearnGitlabWorker.perform_async(learn_gitlab_template_path, - learn_gitlab_project_name, - parent_project_namespace_id, - current_user.id) - end - - def learn_gitlab_project_name - helpers.in_trial_onboarding_flow? ? LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL : LearnGitlab::Project::PROJECT_NAME - end - - def project_params - params.require(:project).permit(project_params_attributes) - end - - def project_params_attributes - [ - :namespace_id, - :name, - :path, - :visibility_level - ] - end - end -end diff --git a/ee/app/controllers/ee/registrations/welcome_controller.rb b/ee/app/controllers/ee/registrations/welcome_controller.rb index 3b569f14219c6..140806d0afeda 100644 --- a/ee/app/controllers/ee/registrations/welcome_controller.rb +++ b/ee/app/controllers/ee/registrations/welcome_controller.rb @@ -19,10 +19,6 @@ module WelcomeController :trial_onboarding_board ] - before_action only: :show do - publish_combined_registration_experiment - end - before_action only: [:trial_getting_started] do push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) end @@ -90,14 +86,6 @@ def learn_gitlab_project end end - def publish_combined_registration_experiment - combined_registration_experiment.publish if show_signup_onboarding? - end - - def combined_registration_experiment - experiment(:combined_registration, user: current_user) - end - def passed_through_params update_params.slice(:role, :registration_objective).merge(params.permit(:jobs_to_be_done_other)) end @@ -110,7 +98,7 @@ def update_success_path if show_company_form? new_users_sign_up_company_path(passed_through_params) else - experiment(:combined_registration, user: current_user).redirect_path + new_users_sign_up_groups_project_path end end end diff --git a/ee/app/controllers/registrations/groups_controller.rb b/ee/app/controllers/registrations/groups_controller.rb deleted file mode 100644 index 253f4347a1c82..0000000000000 --- a/ee/app/controllers/registrations/groups_controller.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -module Registrations - class GroupsController < ApplicationController - include Registrations::CreateGroup - include Registrations::ApplyTrial - include ::Gitlab::Utils::StrongMemoize - include OneTrustCSP - include GoogleAnalyticsCSP - - layout 'minimal' - - feature_category :onboarding - - def new - @group = Group.new(visibility_level: helpers.default_group_visibility) - experiment(:combined_registration, user: current_user).track(:view_new_group_action) - push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) - end - - def create - @group = Groups::CreateService.new(current_user, group_params).execute - - if @group.persisted? - experiment(:combined_registration, user: current_user).track(:create_group, namespace: @group) - - create_successful_flow - else - render action: :new - end - end - - private - - def create_successful_flow - if helpers.in_trial_onboarding_flow? - apply_trial_for_trial_onboarding_flow - else - registration_onboarding_flow - end - end - - def apply_trial_for_trial_onboarding_flow - if apply_trial - redirect_to new_users_sign_up_project_path(namespace_id: @group.id, trial: helpers.in_trial_during_signup_flow?, trial_onboarding_flow: true) - else - render action: :new - end - end - - def registration_onboarding_flow - if helpers.in_trial_during_signup_flow? - create_lead_and_apply_trial_flow - else - redirect_to new_users_sign_up_project_path(namespace_id: @group.id, trial: false) - end - end - - def create_lead_and_apply_trial_flow - if create_lead && apply_trial - redirect_to new_users_sign_up_project_path(namespace_id: @group.id, trial: true) - else - render action: :new - end - end - - def create_lead - trial_params = { - trial_user: params.permit( - :company_name, - :company_size, - :phone_number, - :country - ).merge( - work_email: current_user.email, - first_name: current_user.first_name, - last_name: current_user.last_name, - uid: current_user.id, - setup_for_company: current_user.setup_for_company, - skip_email_confirmation: true, - gitlab_com_trial: true, - provider: 'gitlab', - newsletter_segment: current_user.email_opted_in - ) - } - result = GitlabSubscriptions::CreateLeadService.new.execute(trial_params) - flash[:alert] = result&.dig(:errors) unless result&.dig(:success) - - result&.dig(:success) - end - end -end diff --git a/ee/app/controllers/registrations/groups_projects_controller.rb b/ee/app/controllers/registrations/groups_projects_controller.rb index 30fa27cd373aa..d3440f527c75f 100644 --- a/ee/app/controllers/registrations/groups_projects_controller.rb +++ b/ee/app/controllers/registrations/groups_projects_controller.rb @@ -2,15 +2,18 @@ module Registrations class GroupsProjectsController < ApplicationController - include Registrations::CreateProject - include Registrations::CreateGroup - include Registrations::ApplyTrial + include LearnGitlabHelper include OneTrustCSP include GoogleAnalyticsCSP skip_before_action :require_verification, only: :new + skip_before_action :set_confirm_warning + before_action :check_if_gl_com_or_dev + before_action :authorize_create_group!, only: :new before_action :set_requires_verification, only: :new, if: -> { helpers.require_verification_experiment.candidate? } - before_action :require_verification, only: [:create, :import], if: -> { current_user.requires_credit_card_verification } + before_action :require_verification, + only: [:create, :import], + if: -> { current_user.requires_credit_card_verification } before_action only: [:new] do push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) end @@ -25,7 +28,7 @@ def new @group = Group.new(visibility_level: helpers.default_group_visibility) @project = Project.new(namespace: @group) - combined_registration_experiment.track(:view_new_group_action) + Gitlab::Tracking.event(self.class.name, 'view_new_group_action', user: current_user) end def create @@ -38,7 +41,7 @@ def create if @group.persisted? if @group.previously_new_record? # project failed validation previously, but group was created or coming from trial creation - combined_registration_experiment.track(:create_group, namespace: @group) + Gitlab::Tracking.event(self.class.name, 'create_group', namespace: @group, user: current_user) helpers.require_verification_experiment.record_conversion(@group) unless apply_trial_when_in_trial_flow @@ -50,7 +53,7 @@ def create @project = ::Projects::CreateService.new(current_user, create_project_params).execute if @project.saved? - combined_registration_experiment.track(:create_project, namespace: @project.namespace) + Gitlab::Tracking.event(self.class.name, 'create_project', namespace: @project.namespace, user: current_user) create_learn_gitlab_project(@project.namespace_id) @@ -77,7 +80,7 @@ def create def import @group = Groups::CreateService.new(current_user, modified_group_params).execute if @group.persisted? && apply_trial_when_in_trial_flow - combined_registration_experiment.track(:create_group, namespace: @group) + Gitlab::Tracking.event(self.class.name, 'create_group_import', namespace: @group, user: current_user) helpers.require_verification_experiment.record_conversion(@group) import_url = URI.join(root_url, params[:import_url], "?namespace_id=#{@group.id}").to_s @@ -100,8 +103,8 @@ def exit private - def combined_registration_experiment - @combined_registration_experiment ||= experiment(:combined_registration, user: current_user) + def authorize_create_group! + access_denied! unless can?(current_user, :create_group) end def create_project_params @@ -122,6 +125,17 @@ def modified_group_params modifed_group_params end + def group_params + params.require(:group).permit( + :name, + :path, + :visibility_level + ).merge( + create_event: true, + setup_for_company: current_user.setup_for_company + ) + end + def offer_trial? current_user.setup_for_company && !helpers.in_trial_onboarding_flow? && !params[:skip_trial].present? end @@ -129,5 +143,51 @@ def offer_trial? def apply_trial_when_in_trial_flow !helpers.in_trial_onboarding_flow? || apply_trial end + + def apply_trial + apply_trial_params = { + uid: current_user.id, + trial_user: params.permit(:glm_source, :glm_content).merge({ + namespace_id: @group.id, + gitlab_com_trial: true, + sync_to_gl: true + }) + } + + result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params) + flash.now[:alert] = result&.dig(:errors) unless result&.dig(:success) + + result&.dig(:success) + end + + LEARN_GITLAB_ULTIMATE_TEMPLATE = 'learn_gitlab_ultimate.tar.gz' + + def learn_gitlab_template_path + Rails.root.join('vendor', 'project_templates', LEARN_GITLAB_ULTIMATE_TEMPLATE) + end + + def create_learn_gitlab_project(parent_project_namespace_id) + ::Onboarding::CreateLearnGitlabWorker.perform_async(learn_gitlab_template_path, # rubocop:disable CodeReuse/Worker + learn_gitlab_project_name, + parent_project_namespace_id, + current_user.id) + end + + def learn_gitlab_project_name + if helpers.in_trial_onboarding_flow? + LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL + else + LearnGitlab::Project::PROJECT_NAME + end + end + + def project_params_attributes + [ + :namespace_id, + :name, + :path, + :visibility_level + ] + end end end diff --git a/ee/app/controllers/registrations/projects_controller.rb b/ee/app/controllers/registrations/projects_controller.rb deleted file mode 100644 index f170666a95a71..0000000000000 --- a/ee/app/controllers/registrations/projects_controller.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -module Registrations - class ProjectsController < ApplicationController - include Registrations::CreateProject - include OneTrustCSP - include GoogleAnalyticsCSP - - layout 'minimal' - - before_action :check_if_gl_com_or_dev - - before_action only: [:new] do - set_namespace - authorize_create_project! - push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops) - end - - feature_category :onboarding - - def new - @project = Project.new(namespace: @namespace) - end - - def create - @project = ::Projects::CreateService.new(current_user, project_params).execute - - if @project.saved? - experiment(:combined_registration, user: current_user).track(:create_project, namespace: @project.namespace) - - @learn_gitlab_project = create_learn_gitlab_project - - if helpers.registration_verification_enabled? - redirect_to new_users_sign_up_verification_path(url_params) - elsif helpers.in_trial_onboarding_flow? - redirect_to trial_getting_started_users_sign_up_welcome_path(url_params) - else - redirect_to continuous_onboarding_getting_started_users_sign_up_welcome_path(url_params) - end - else - render :new - end - end - - private - - def authorize_create_project! - access_denied! unless can?(current_user, :create_projects, @namespace) - end - - def set_namespace - @namespace = Namespace.find_by_id(params[:namespace_id]) - end - - def create_learn_gitlab_project - File.open(learn_gitlab_template_path) do |archive| - ::Projects::GitlabProjectsImportService.new( - current_user, - namespace_id: @project.namespace_id, - file: archive, - name: learn_gitlab_project_name - ).execute - end - end - - def url_params - if helpers.in_trial_onboarding_flow? - { learn_gitlab_project_id: @learn_gitlab_project.id } - else - { project_id: @project.id } - end - end - end -end - -Registrations::ProjectsController.prepend_mod diff --git a/ee/app/controllers/trials_controller.rb b/ee/app/controllers/trials_controller.rb index 45076e54018b4..bbf28f8b626df 100644 --- a/ee/app/controllers/trials_controller.rb +++ b/ee/app/controllers/trials_controller.rb @@ -88,8 +88,7 @@ def show_confirm_warning? private def stored_location_or_provided_path(path) - if current_user.setup_for_company && - experiment(:combined_registration, user: current_user).assigned.name == 'candidate' + if current_user.setup_for_company stored_location_for(:user) || path else path @@ -225,7 +224,7 @@ def apply_trial_and_redirect @result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params) if @result&.dig(:success) - experiment(:combined_registration, user: current_user).track(:create_trial) + Gitlab::Tracking.event(self.class.name, 'create_trial', namespace: @namespace, user: current_user) if discover_group_security_flow? redirect_to group_security_dashboard_url(@namespace, { trial: true }) diff --git a/ee/app/helpers/ee/welcome_helper.rb b/ee/app/helpers/ee/welcome_helper.rb index c911ce8ab07e6..5a12759066464 100644 --- a/ee/app/helpers/ee/welcome_helper.rb +++ b/ee/app/helpers/ee/welcome_helper.rb @@ -16,14 +16,6 @@ def in_trial_onboarding_flow? params[:trial_onboarding_flow] == 'true' end - def show_trial_during_signup? - current_user.setup_for_company - end - - def in_trial_during_signup_flow? - params[:trial] == 'true' - end - def in_oauth_flow? redirect_path&.starts_with?(oauth_authorization_path) end diff --git a/ee/app/views/registrations/groups/new.html.haml b/ee/app/views/registrations/groups/new.html.haml deleted file mode 100644 index 9a7ff6d54b4a3..0000000000000 --- a/ee/app/views/registrations/groups/new.html.haml +++ /dev/null @@ -1,55 +0,0 @@ -- @html_class = "subscriptions-layout-html" -- page_title _('Your GitLab group') -- form_params = { trial_onboarding_flow: params[:trial_onboarding_flow], glm_source: params[:glm_source], glm_content: params[:glm_content] } -- content_for :page_specific_javascripts do - = render "layouts/google_tag_manager_head" - = render "layouts/one_trust" -= render "layouts/google_tag_manager_body" - -.row.gl-flex-grow-1 - .gl-display-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5 - .edit-group.gl-display-flex.gl-flex-direction-column.gl-align-items-center - - unless in_trial_onboarding_flow? - #progress-bar - %h2.center= _('Create your group') - %p= _('A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects.') - = form_for @group, url: users_sign_up_groups_path(form_params), html: { class: 'gl-show-field-errors card gl-w-full gl-p-4 js-saas-trial-group' } do |f| - = form_errors(@group) - = render 'layouts/flash' - .row - .form-group.group-name-holder.col-sm-12 - = f.label :name, class: 'gl-font-weight-bold' do - = _('Group name (your organization)') - = f.text_field :name, class: 'form-control js-autofill-group-name', - required: true, - title: _('Please fill in a descriptive name for your group.'), - autofocus: true - .form-text.text-muted= _('You can always edit this later') - .row - .form-group.col-sm-12 - = f.label :path, class: 'gl-font-weight-bold' do - = _('Group URL') - .input-group.gl-field-error-anchor - .group-root-path.input-group-prepend.has-tooltip{ title: root_url, :'data-placement' => 'bottom' } - .input-group-text - %span= root_url - = f.hidden_field :parent_id - = f.text_field :path, class: 'form-control js-validate-group-path js-autofill-group-path', - required: true, - pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, - title: group_url_error_message, - maxlength: ::Namespace::URL_MAX_LENGTH - %p.validation-error.gl-field-error.field-validation.hide - = _("Group path is already taken. We've suggested one that is available.") - %p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.') - %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group path availability...') - .row - .form-group.col-sm-12 - = render partial: 'shared/groups/visibility_level', locals: { f: f } - - if !in_trial_onboarding_flow? && show_trial_during_signup? - = render partial: 'shared/groups/trial_form' - - .row - .form-group.col-sm-12.gl-mb-0 - = render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { type: 'submit', class: 'gl-w-full' }) do - = _('Create group') diff --git a/ee/app/views/registrations/projects/new.html.haml b/ee/app/views/registrations/projects/new.html.haml deleted file mode 100644 index 83a3f7ddf9c06..0000000000000 --- a/ee/app/views/registrations/projects/new.html.haml +++ /dev/null @@ -1,62 +0,0 @@ -- @html_class = "subscriptions-layout-html" -- page_title _('Your first project') -- visibility_level = selected_visibility_level(@project, params.dig(:project, :visibility_level)) -- content_for :page_specific_javascripts do - = render "layouts/google_tag_manager_head" - = render "layouts/one_trust" -= render "layouts/google_tag_manager_body" - -- if in_trial_during_signup_flow? || in_trial_onboarding_flow? - = render 'registrations/trial_is_activated_banner' -.row.gl-flex-grow-1 - .gl-display-flex.gl-align-items-center.gl-flex-direction-column.gl-w-full.gl-px-5.gl-pb-5 - .new-project.gl-display-flex.gl-flex-direction-column.gl-align-items-center - - unless in_trial_onboarding_flow? - #progress-bar - %h2.gl-text-center= _('Create/import your first project') - %p - .gl-text-center= html_escape(_('This project will live in your group %{strong_open}%{namespace}%{strong_close}. A project is where you store your files (repository), plan your work (issues), publish your documentation (wiki), and so much more.')) % { namespace: html_escape(@project.namespace.name), strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } - - .js-toggle-container.gl-w-full - %ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' } - %li.nav-item{ role: 'presentation' } - %a#blank-project-tab.nav-link.active{ href: '#blank-project-pane', data: { toggle: 'tab', track_label: 'blank_project', track_action: 'click_tab', track_value: '' }, role: 'tab' } - %span= s_('ProjectsNew|Create') - %li.nav-item{ role: 'presentation' } - %a#import-project-tab.nav-link{ href: '#import-project-pane', data: { toggle: 'tab', track_label: 'import_project', track_action: 'click_tab', track_value: '' }, role: 'tab' } - %span= s_('ProjectsNew|Import') - - .tab-content.gitlab-tab-content.gl-bg-white - #blank-project-pane.tab-pane.js-toggle-container.active{ role: 'tabpanel' } - = gitlab_ui_form_for @project, url: users_sign_up_projects_path(trial_onboarding_flow: params[:trial_onboarding_flow]), html: { class: 'new_project' } do |f| - = form_errors(@project) - = f.hidden_field :namespace_id, value: @project.namespace_id - #blank-project-name.row - .form-group.project-name.col-sm-12 - = f.label :name, class: 'gl-font-weight-bold' do - %span= _('Project name') - = f.text_field :name, class: 'form-control', autofocus: true, data: { track_label: 'blank_project', track_action: 'activate_form_input', track_property: 'project_name', track_value: '' } - .form-text.text-muted= _('You can always edit this later') - .form-group.col-sm-12 - = f.label :path, class: 'gl-font-weight-bold' do - %span= _('Project URL') - .input-group.gl-flex-nowrap - .input-group-prepend.gl-flex-shrink-0.has-tooltip{ title: "#{group_url(@project.namespace)}/" } - .input-group-text - #{group_url(@project.namespace)}/ - = f.text_field :path, class: 'form-control', required: true - .form-group.gl-form-group - = f.label :visibility_level, class: 'gl-font-weight-bold' do - = s_('ProjectsNew|Visibility Level') - = link_to sprite_icon('question-o'), help_page_path('user/public_access'), aria: { label: 'Documentation for Visibility Level' }, target: '_blank', rel: 'noopener noreferrer' - = render 'shared/visibility_level', f: f, visibility_level: visibility_level.to_i, can_change_visibility_level: true, form_model: @project, with_label: false - - = f.submit _('Create project'), class: 'btn gl-button btn-confirm btn-block', data: { track_label: 'blank_project', track_action: 'click_button', track_property: 'create_project', track_value: '' } - - #import-project-pane.tab-pane.import-project-pane.js-toggle-container{ role: 'tabpanel' } - - if import_sources_enabled? - = render 'projects/import_project_pane' - - else - .nothing-here-block - %h4= s_('ProjectsNew|No import options available') - %p= s_('ProjectsNew|Contact an administrator to enable options for importing your project.') diff --git a/ee/app/views/shared/groups/_country_or_region_selector.html.haml b/ee/app/views/shared/groups/_country_or_region_selector.html.haml deleted file mode 100644 index 2af2bfa58bef3..0000000000000 --- a/ee/app/views/shared/groups/_country_or_region_selector.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= label_tag :country, s_('Trial|Country'), class: 'col-form-label' -= select_tag :country, options_for_select([[_('Please select a country'), '']]), class: ' js-trial-field select2 gl-transparent-pixel', required: true, id: 'country_select', data: { countries_end_point: countries_path, selected_option: params[:country]} diff --git a/ee/app/views/shared/groups/_trial_form.html.haml b/ee/app/views/shared/groups/_trial_form.html.haml deleted file mode 100644 index dc3ce327919aa..0000000000000 --- a/ee/app/views/shared/groups/_trial_form.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -.row - .form-group.col-sm-12 - = label_tag :trial_toggle, s_('Trial|GitLab Ultimate trial (optional)'), for: :trial_toggle, class: 'col-form-label' - %p= html_escape(('Try all GitLab features for free for 30 days.%{br_tag}No credit card required.')) % { br_tag: '<br/>'.html_safe } - .js-trial-toggle{ data: { active: params[:trial] == 'true' } } - %p.gl-text-gray-500.gl-mt-3= s_('Trial|We will activate your trial on your group after you complete this step. After 30 days, you can:') - %ul.gl-pl-5 - %li.gl-text-gray-500= s_('Trial|Upgrade to Ultimate to keep using GitLab with advanced features.') - %li.gl-text-gray-500= s_('Trial|Continue using the basic features of GitLab for free.') -.js-trial-form.hidden - .row - .form-group.col-sm-12 - = label_tag :company_name, s_('Trial|Company name'), for: :company_name, class: 'col-form-label' - = text_field_tag :company_name, params[:company_name], class: 'form-control js-trial-field', required: true - .row - .form-group.col-sm-12.gl-select2-html5-required-fix - = label_tag :company_size, s_('Trial|Number of employees'), for: :company_size, class: 'col-form-label' - = select_tag :company_size, company_size_options_for_select(params[:company_size]), class: 'js-trial-field select2', required: true - .row - .form-group.col-sm-12 - = label_tag :phone_number, s_('Trial|Telephone number'), for: :phone_number, class: 'col-form-label' - = telephone_field_tag :phone_number, params[:phone_number], pattern: '^(\+)*[0-9-\s]+$', class: 'form-control js-trial-field', required: true - %p.gray-500= _('Allowed characters: +, 0-9, -, and spaces.') - .row - .form-group.col-sm-12.gl-select2-html5-required-fix - = render 'shared/groups/country_or_region_selector' diff --git a/ee/app/views/trials/_select_country.html.haml b/ee/app/views/trials/_select_country.html.haml deleted file mode 100644 index ec5e0084ed1df..0000000000000 --- a/ee/app/views/trials/_select_country.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= label_tag :country, s_('Trial|Country'), class: 'col-form-label' -= select_tag :country, options_for_select([[s_('Trial|Please select a country'), '']]), class: 'select2 gl-transparent-pixel', required: true, id: 'country_select', data: { countries_end_point: countries_path, selected_option: params[:country], qa_selector: 'country' } diff --git a/ee/spec/controllers/registrations/groups_controller_spec.rb b/ee/spec/controllers/registrations/groups_controller_spec.rb deleted file mode 100644 index e84881e000669..0000000000000 --- a/ee/spec/controllers/registrations/groups_controller_spec.rb +++ /dev/null @@ -1,244 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Registrations::GroupsController do - describe 'GET #new' do - it_behaves_like "Registrations::GroupsController GET #new" - end - - describe 'POST #create', :aggregate_failure do - let_it_be(:user) { create(:user) } - let_it_be(:glm_params) { {} } - let_it_be(:trial_form_params) { { trial: 'false' } } - let_it_be(:trial_onboarding_flow_params) { {} } - - let(:com) { true } - let(:group_params) { { name: 'Group name', path: 'group-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s, create_event: true, setup_for_company: setup_for_company } } - let(:setup_for_company) { nil } - let(:params) do - { group: group_params }.merge(glm_params).merge(trial_form_params).merge(trial_onboarding_flow_params) - end - - subject(:post_create) { post :create, params: params } - - context '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) - allow(::Gitlab).to receive(:com?).and_return(com) - end - - context 'when on .com' do - it_behaves_like 'hides email confirmation warning' - - context 'when group can be created' do - it 'creates a group' do - expect { post_create }.to change { Group.count }.by(1) - end - - it 'passes group_params to Groups::CreateService' do - expect(Groups::CreateService).to receive(:new).with(user, ActionController::Parameters.new(group_params).permit!).and_call_original - - post_create - end - - context 'when the user is `setup_for_company: true`' do - let(:user) { create(:user, setup_for_company: setup_for_company) } - let(:setup_for_company) { true } - - it 'passes `setup_for_company: true` to the Groups::CreateService' do - expect(Groups::CreateService).to receive(:new).with(user, ActionController::Parameters.new(group_params).permit!).and_call_original - - post_create - end - end - - context 'when in trial onboarding - apply_trial_for_trial_onboarding_flow' do - let_it_be(:group) { create(:group) } - let_it_be(:trial_onboarding_flow_params) { { trial_onboarding_flow: true, glm_source: 'about.gitlab.com', glm_content: 'content' } } - let_it_be(:apply_trial_params) do - { - uid: user.id, - trial_user: ActionController::Parameters.new( - { - glm_source: 'about.gitlab.com', - glm_content: 'content', - namespace_id: group.id, - gitlab_com_trial: true, - sync_to_gl: true - } - ).permit! - } - end - - before do - expect_next_instance_of(::Groups::CreateService) do |service| - expect(service).to receive(:execute).and_return(group) - end - end - - context 'when trial can be applied' do - before do - expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service| - expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: true }) - end - end - - context 'with redirection to projects page' do - it { is_expected.to redirect_to(new_users_sign_up_project_path(namespace_id: group.id, trial: false, trial_onboarding_flow: true)) } - end - end - - context 'when failing to apply trial' do - before do - expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service| - expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: false }) - end - end - - it { is_expected.to render_template(:new) } - end - end - - context 'when not in the trial onboarding - registration_onboarding_flow' do - let_it_be(:group) { create(:group) } - - context 'when trial_during_signup - trial_during_signup_flow' do - let_it_be(:glm_params) { { glm_source: 'gitlab.com', glm_content: 'content' } } - let_it_be(:trial_form_params) do - { - trial: 'true', - company_name: 'ACME', - company_size: '1-99', - phone_number: '11111111', - country: 'Norway' - } - end - - let_it_be(:trial_user_params) do - { - work_email: user.email, - first_name: user.first_name, - last_name: user.last_name, - uid: user.id, - setup_for_company: nil, - skip_email_confirmation: true, - gitlab_com_trial: true, - provider: 'gitlab', - newsletter_segment: user.email_opted_in - } - end - - let_it_be(:trial_params) do - { - trial_user: ActionController::Parameters.new(trial_form_params.except(:trial).merge(trial_user_params)).permit! - } - end - - let_it_be(:apply_trial_params) do - { - uid: user.id, - trial_user: ActionController::Parameters.new( - { - glm_source: 'gitlab.com', - glm_content: 'content', - namespace_id: group.id, - gitlab_com_trial: true, - sync_to_gl: true - } - ).permit! - } - end - - context 'when a user chooses a trial - create_lead_and_apply_trial_flow' do - context 'when successfully creating a lead and applying trial' do - before do - expect_next_instance_of(Groups::CreateService) do |service| - expect(service).to receive(:execute).and_return(group) - end - expect_next_instance_of(GitlabSubscriptions::CreateLeadService) do |service| - expect(service).to receive(:execute).with(trial_params).and_return(success: true) - end - expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service| - expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: true }) - end - end - - context 'with redirection to projects page' do - it { is_expected.to redirect_to(new_users_sign_up_project_path(namespace_id: group.id, trial: true)) } - end - - it 'tracks for the combined_registration experiment', :experiment do - expect(experiment(:combined_registration)).to track(:create_group, namespace: an_instance_of(Group)).on_next_instance - subject - end - end - - context 'when failing to create a lead and apply trial' do - before do - expect_next_instance_of(Groups::CreateService) do |service| - expect(service).to receive(:execute).and_return(group) - end - expect_next_instance_of(GitlabSubscriptions::CreateLeadService) do |service| - expect(service).to receive(:execute).with(trial_params).and_return(success: false) - end - end - - it { is_expected.to render_template(:new) } - end - end - - context 'when user chooses no trial' do - let_it_be(:trial_form_params) { { trial: 'false' } } - - it 'redirects user to projects page' do - expect_next_instance_of(Groups::CreateService) do |service| - expect(service).to receive(:execute).and_return(group) - end - - expect(post_create).to redirect_to(new_users_sign_up_project_path(namespace_id: group.id, trial: false)) - end - - it 'does not call trial creation methods' do - expect(controller).not_to receive(:create_lead) - expect(controller).not_to receive(:apply_trial) - - post_create - end - end - end - end - end - - context 'when the group cannot be created' do - let(:group_params) { { name: '', path: '' } } - - it 'does not create a group', :aggregate_failures do - expect { post_create }.not_to change { Group.count } - expect(assigns(:group).errors).not_to be_blank - end - - it 'does not call call the successful flow' do - expect(controller).not_to receive(:create_successful_flow) - - post_create - end - - it { is_expected.to have_gitlab_http_status(:ok) } - it { is_expected.to render_template(:new) } - end - end - - context 'when not on .com' do - let(:com) { false } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - end - end -end diff --git a/ee/spec/controllers/registrations/groups_projects_controller_spec.rb b/ee/spec/controllers/registrations/groups_projects_controller_spec.rb index 65635f133e2f2..265ccdfe6c516 100644 --- a/ee/spec/controllers/registrations/groups_projects_controller_spec.rb +++ b/ee/spec/controllers/registrations/groups_projects_controller_spec.rb @@ -3,43 +3,71 @@ require 'spec_helper' RSpec.describe Registrations::GroupsProjectsController, :experiment do + using RSpec::Parameterized::TableSyntax + let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } describe 'GET #new' do - it_behaves_like "Registrations::GroupsController GET #new" + subject { get :new } - context 'not shared behavior' do - subject { get :new } + context '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 - allow(::Gitlab).to receive(:com?).and_return(true) sign_in(user) end - it 'builds a project object' do - subject + context 'when on .com', :saas do + it { is_expected.to have_gitlab_http_status(:ok) } + it { is_expected.to render_template(:new) } - expect(assigns(:project)).to be_a_new(Project) - end + it 'assigns the group variable to a new Group with the default group visibility', :aggregate_failures do + subject - it 'tracks an event for the combined_registration experiment' do - expect(experiment(:combined_registration)).to track(:view_new_group_action).on_next_instance + expect(assigns(:group)).to be_a_new(Group) + expect(assigns(:group).visibility_level).to eq(Gitlab::CurrentSettings.default_group_visibility) + end - subject - end + it 'builds a project object' do + subject - it 'publishes the required verification experiment to the database' do - expect_next_instance_of(RequireVerificationForNamespaceCreationExperiment) do |experiment| - expect(experiment).to receive(:publish_to_database) + expect(assigns(:project)).to be_a_new(Project) end - subject + it 'tracks the new group view event' do + subject + + expect_snowplow_event(category: described_class.name, action: 'view_new_group_action', user: user) + end + + it 'publishes the required verification experiment to the database' do + expect_next_instance_of(RequireVerificationForNamespaceCreationExperiment) do |experiment| + expect(experiment).to receive(:publish_to_database) + end + + subject + end + + context 'when user does not have the ability to create a group' do + let(:user) { create(:user, can_create_group: false) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end end + + context 'when not on .com' do + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + it_behaves_like 'hides email confirmation warning' end end - shared_context 'records a conversion event' do + shared_context 'with recording a conversion event' do let_it_be(:user_created_at) { RequireVerificationForNamespaceCreationExperiment::EXPERIMENT_START_DATE + 1.hour } let_it_be(:user) { create(:user, created_at: user_created_at) } let_it_be(:experiment) { create(:experiment, name: :require_verification_for_namespace_creation) } @@ -51,20 +79,34 @@ it 'records a conversion event for the required verification experiment' do expect { subject }.to change { experiment_subject.reload.converted_at }.from(nil) - .and change { experiment_subject.context }.to include('namespace_id') + .and change(experiment_subject, :context).to include('namespace_id') end end describe 'POST #create' do subject(:post_create) { post :create, params: params } - let(:params) { { group: group_params, project: project_params }.merge(extra_params) } - let(:extra_params) { {} } - let(:group_params) { { name: 'Group name', path: 'group-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s, setup_for_company: setup_for_company } } - let(:project_params) { { name: 'New project', path: 'project-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE, initialize_with_readme: 'true' } } let(:com) { true } let(:setup_for_company) { nil } - let(:combined_registration?) { true } + let(:params) { { group: group_params, project: project_params }.merge(extra_params) } + let(:extra_params) { {} } + let(:group_params) do + { + name: 'Group name', + path: 'group-path', + visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s, + setup_for_company: setup_for_company + } + end + + let(:project_params) do + { + name: 'New project', + path: 'project-path', + visibility_level: Gitlab::VisibilityLevel::PRIVATE, + initialize_with_readme: 'true' + } + end context 'with an unauthenticated user' do it { is_expected.to have_gitlab_http_status(:redirect) } @@ -79,15 +121,18 @@ it_behaves_like 'hides email confirmation warning' - it_behaves_like 'records a conversion event' + it_behaves_like 'with recording a conversion event' context 'when group and project can be created' do it 'creates a group' do - expect { post_create }.to change { Group.count }.by(1) + expect { post_create }.to change(Group, :count).by(1) end it 'passes create_event: true to the Groups::CreateService' do - expect(Groups::CreateService).to receive(:new).with(user, ActionController::Parameters.new(group_params.merge(create_event: true)).permit!).and_call_original + expect(Groups::CreateService).to receive(:new) + .with(user, ActionController::Parameters + .new(group_params.merge(create_event: true)).permit!) + .and_call_original post_create end @@ -103,17 +148,21 @@ post_create end - it 'tracks create events for the combined_registration experiment' do + it 'tracks group and project creation events' do allow_next_instance_of(::Projects::CreateService) do |service| allow(service).to receive(:after_create_actions) end - wrapped_experiment(experiment(:combined_registration)) do |e| - expect(e).to receive(:track).with(:create_group, namespace: an_instance_of(Group)) - expect(e).to receive(:track).with(:create_project, namespace: an_instance_of(Group)) - end - post_create + + expect_snowplow_event(category: described_class.name, + action: 'create_group', + namespace: an_instance_of(Group), + user: user) + expect_snowplow_event(category: described_class.name, + action: 'create_project', + namespace: an_instance_of(Group), + user: user) end end @@ -121,7 +170,7 @@ let(:group_params) { { name: '⛄⛄⛄', path: '' } } it 'creates a group' do - expect { subject }.to change { Group.count }.by(1) + expect { subject }.to change(Group, :count).by(1) end end @@ -129,20 +178,18 @@ let(:group_params) { { name: '', path: '' } } it 'does not create a group', :aggregate_failures do - expect { post_create }.not_to change { Group.count } + expect { post_create }.not_to change(Group, :count) expect(assigns(:group).errors).not_to be_blank end - it 'does not tracks events for the combined_registration experiment' do - wrapped_experiment(experiment(:combined_registration)) do |e| - expect(e).not_to receive(:track).with(:create_group) - expect(e).not_to receive(:track).with(:create_project) - end - + it 'does not track events for group or project creation' do post_create + + expect_no_snowplow_event(category: described_class.name, action: 'create_group') + expect_no_snowplow_event(category: described_class.name, action: 'create_project') end - it 'the project is not disgarded completely' do + it 'the project is not disregarded completely' do post_create expect(assigns(:project).name).to eq('New project') @@ -162,18 +209,19 @@ let(:project_params) { { name: '', path: '', visibility_level: Gitlab::VisibilityLevel::PRIVATE } } it 'does not create a project', :aggregate_failures do - expect { post_create }.to change { Group.count } - expect { post_create }.not_to change { Project.count } + expect { post_create }.to change(Group, :count) + expect { post_create }.not_to change(Project, :count) expect(assigns(:project).errors).not_to be_blank end - it 'selectively tracks events for the combined_registration experiment' do - wrapped_experiment(experiment(:combined_registration)) do |e| - expect(e).to receive(:track).with(:create_group, namespace: an_instance_of(Group)) - expect(e).not_to receive(:track).with(:create_project) - end - + it 'selectively tracks events for group and project creation' do post_create + + expect_snowplow_event(category: described_class.name, + action: 'create_group', + namespace: an_instance_of(Group), + user: user) + expect_no_snowplow_event(category: described_class.name, action: 'create_project') end it { is_expected.to have_gitlab_http_status(:ok) } @@ -188,25 +236,26 @@ let(:group_params) { { id: group.id } } it 'creates a project and not another group', :aggregate_failures do - expect { post_create }.to change { Project.count } - expect { post_create }.not_to change { Group.count } + expect { post_create }.to change(Project, :count) + expect { post_create }.not_to change(Group, :count) end - it 'selectively tracks events for the combined_registration experiment' do + it 'selectively tracks events group and project creation' do allow_next_instance_of(::Projects::CreateService) do |service| allow(service).to receive(:after_create_actions) end - wrapped_experiment(experiment(:combined_registration)) do |e| - expect(e).not_to receive(:track).with(:create_group, namespace: an_instance_of(Group)) - expect(e).to receive(:track).with(:create_project, namespace: an_instance_of(Group)) - end - post_create + + expect_no_snowplow_event(category: described_class.name, action: 'create_group') + expect_snowplow_event(category: described_class.name, + action: 'create_project', + namespace: an_instance_of(Group), + user: user) end end - context 'it redirects' do + context 'when redirecting' do let_it_be(:project) { create(:project) } let(:success_path) { continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: project.id) } @@ -285,7 +334,7 @@ end expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service| - expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: success }) + expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: success }) # rubocop:disable RSpec/ExpectInHook end end @@ -301,8 +350,6 @@ end context 'with learn gitlab project' do - using RSpec::Parameterized::TableSyntax - where(:trial, :project_name, :template) do false | 'Learn GitLab' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE true | 'Learn GitLab - Ultimate trial' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE @@ -331,9 +378,16 @@ describe 'POST #import' do subject(:post_import) { post :import, params: params } - let(:params) { { group: group_params, import_url: new_import_github_path } } - let(:group_params) { { name: 'Group name', path: 'group-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s, setup_for_company: nil } } let(:com) { true } + let(:params) { { group: group_params, import_url: new_import_github_path } } + let(:group_params) do + { + name: 'Group name', + path: 'group-path', + visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s, + setup_for_company: nil + } + end context 'with an unauthenticated user' do it { is_expected.to have_gitlab_http_status(:redirect) } @@ -348,7 +402,7 @@ it_behaves_like 'hides email confirmation warning' - it_behaves_like 'records a conversion event' + it_behaves_like 'with recording a conversion event' context "when a group can't be created" do before do @@ -357,10 +411,10 @@ end end - it "doesn't track for the combined_registration experiment" do - expect(experiment(:combined_registration)).not_to track(:create_group) - + it "doesn't track for group creation" do post_import + + expect_no_snowplow_event(category: described_class.name, action: 'create_group_import') end it { is_expected.to render_template(:new) } @@ -370,27 +424,32 @@ let(:group_params) { { name: '⛄⛄⛄', path: '' } } it 'creates a group, and redirects' do - expect { subject }.to change { Group.count }.by(1) + expect { subject }.to change(Group, :count).by(1) expect(subject).to have_gitlab_http_status(:redirect) end end context 'when group can be created' do it 'creates a group' do - expect { post_import }.to change { Group.count }.by(1) + expect { post_import }.to change(Group, :count).by(1) end it 'passes create_event: true to the Groups::CreateService' do - expect(Groups::CreateService).to receive(:new).with(user, ActionController::Parameters.new(group_params.merge(create_event: true)).permit!).and_call_original + expect(Groups::CreateService).to receive(:new) + .with(user, ActionController::Parameters + .new(group_params.merge(create_event: true)).permit!) + .and_call_original post_import end - it 'tracks an event for the combined_registration experiment' do - expect(experiment(:combined_registration)).to track(:create_group, namespace: an_instance_of(Group)) - .on_next_instance - + it 'tracks an event for group creation' do post_import + + expect_snowplow_event(category: described_class.name, + action: 'create_group_import', + namespace: an_instance_of(Group), + user: user) end it 'redirects to the import url with a namespace_id parameter' do diff --git a/ee/spec/controllers/registrations/projects_controller_spec.rb b/ee/spec/controllers/registrations/projects_controller_spec.rb deleted file mode 100644 index 5058f6209cb6c..0000000000000 --- a/ee/spec/controllers/registrations/projects_controller_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Registrations::ProjectsController do - let_it_be(:user) { create(:user) } - let_it_be(:namespace) { create(:group) } - let_it_be(:project) { create(:project) } - - describe 'GET #new' do - subject { get :new } - - context '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 - let(:com) { true } - - before do - sign_in(user) - allow(::Gitlab).to receive(:com?).and_return(com) - end - - context 'when on .com' do - it { is_expected.to have_gitlab_http_status(:not_found) } - - context 'with a namespace in the URL' do - subject { get :new, params: { namespace_id: namespace.id } } - - it { is_expected.to have_gitlab_http_status(:not_found) } - - context 'with sufficient access' do - before do - namespace.add_owner(user) - end - - it { is_expected.to have_gitlab_http_status(:ok) } - it { is_expected.to render_template(:new) } - end - end - end - - context 'when not on .com' do - let(:com) { false } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - end - end - - describe 'POST #create' do - let(:combined_registration?) { false } - - it_behaves_like "Registrations::ProjectsController POST #create" - end -end diff --git a/ee/spec/controllers/registrations/welcome_controller_spec.rb b/ee/spec/controllers/registrations/welcome_controller_spec.rb index ed90616668c5b..ad143ee636aa0 100644 --- a/ee/spec/controllers/registrations/welcome_controller_spec.rb +++ b/ee/spec/controllers/registrations/welcome_controller_spec.rb @@ -7,19 +7,6 @@ let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project) } - describe '#show' do - it 'publishes combined_registration experiment data to the client' do - sign_in(user) - allow(controller.helpers).to receive(:signup_onboarding_enabled?).and_return(true) - - wrapped_experiment(experiment(:combined_registration)) do |e| - expect(e).to receive(:publish) - end - - get :show - end - end - describe '#continuous_onboarding_getting_started' do let_it_be(:project) { create(:project, group: group) } @@ -273,12 +260,9 @@ end context 'when joining_project is "false"' do - context 'when combined_registration is candidate variant' do + context 'with group and project creation' do before do stub_feature_flags(about_your_company_registration_flow: false) - - allow(controller).to receive(:experiment).and_call_original - stub_experiments(combined_registration: :candidate) end it { is_expected.to redirect_to new_users_sign_up_groups_project_path } @@ -301,7 +285,7 @@ context 'when setup_for_company is "false"' do let(:setup_for_company) { 'false' } - it { is_expected.to redirect_to new_users_sign_up_group_path } + it { is_expected.to redirect_to new_users_sign_up_groups_project_path } end context 'when in subscription flow' do @@ -309,7 +293,7 @@ allow(controller.helpers).to receive(:in_subscription_flow?).and_return(true) end - it { is_expected.not_to redirect_to new_users_sign_up_group_path } + it { is_expected.not_to redirect_to new_users_sign_up_groups_project_path } end context 'when in invitation flow' do @@ -317,7 +301,7 @@ allow(controller.helpers).to receive(:user_has_memberships?).and_return(true) end - it { is_expected.not_to redirect_to new_users_sign_up_group_path } + it { is_expected.not_to redirect_to new_users_sign_up_groups_project_path } end context 'when in trial flow' do @@ -325,7 +309,7 @@ allow(controller.helpers).to receive(:in_trial_flow?).and_return(true) end - it { is_expected.not_to redirect_to new_users_sign_up_group_path } + it { is_expected.not_to redirect_to new_users_sign_up_groups_project_path } end end end diff --git a/ee/spec/controllers/trials_controller_spec.rb b/ee/spec/controllers/trials_controller_spec.rb index 85fbbc6873ef6..fcc5f04649b10 100644 --- a/ee/spec/controllers/trials_controller_spec.rb +++ b/ee/spec/controllers/trials_controller_spec.rb @@ -113,10 +113,13 @@ post_create_lead end - it 'tracks for the combined_registration experiment' do - expect(experiment(:combined_registration)).to track(:create_trial).on_next_instance - + it 'tracks for the trial creation' do post_create_lead + + expect_snowplow_event(category: described_class.name, + action: 'create_trial', + namespace: namespace, + user: user) end context 'when the user is `setup_for_company: true`' do @@ -129,15 +132,7 @@ controller.store_location_for(:user, stored_location_for) end - context 'when the user is receiving the combined_registration candidate', :experiment do - before do - stub_experiments(combined_registration: :candidate) - end - - it { is_expected.to redirect_to(stored_location_for) } - end - - it { is_expected.to redirect_to(group_url(namespace, { trial: true })) } + it { is_expected.to redirect_to(stored_location_for) } end it { is_expected.to redirect_to(group_url(namespace, { trial: true })) } @@ -332,15 +327,18 @@ it_behaves_like 'an authenticated endpoint' it_behaves_like 'a dot-com only feature' - context 'on success', :experiment do + context 'on success' do let(:apply_trial_result) { true } it { is_expected.to redirect_to("/#{namespace.path}?trial=true") } - it 'calls tracking event for combined_registration experiment', :experiment do - expect(experiment(:combined_registration)).to track(:create_trial).on_next_instance - + it 'tracks the trial creation event' do subject + + expect_snowplow_event(category: described_class.name, + action: 'create_trial', + namespace: namespace, + user: user) end context 'redirect trial user to feature' do @@ -567,15 +565,7 @@ controller.store_location_for(:user, new_trial_path) end - it { is_expected.to redirect_to(dashboard_projects_path) } - - context 'when the user is receiving the combined_registration candidate', :experiment do - before do - stub_experiments(combined_registration: :candidate) - end - - it { is_expected.to redirect_to(new_trial_path) } - end + it { is_expected.to redirect_to(new_trial_path) } end end diff --git a/ee/spec/experiments/combined_registration_experiment_spec.rb b/ee/spec/experiments/combined_registration_experiment_spec.rb deleted file mode 100644 index 4adc66cd0ad8d..0000000000000 --- a/ee/spec/experiments/combined_registration_experiment_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe CombinedRegistrationExperiment, :experiment do - subject { described_class.new(user: user) } - - let_it_be(:user) { create(:user) } - - describe '#signature' do - let(:force_company_trial) { experiment(:force_company_trial, user: user) } - - it 'returns the same context key for force_company_trial' do - expect(subject.signature[:key]).not_to be_nil - expect(subject.signature[:key]).to eq(force_company_trial.signature[:key]) - end - end - - describe '#redirect_path' do - it 'control returns path' do - stub_experiments(combined_registration: :control) - - expect(subject.redirect_path).to eq(Rails.application.routes.url_helpers.new_users_sign_up_group_path) - end - - it 'candidate returns path' do - stub_experiments(combined_registration: :candidate) - - expect(subject.redirect_path).to eq(Rails.application.routes.url_helpers.new_users_sign_up_groups_project_path) - end - end -end diff --git a/ee/spec/features/google_analytics_datalayer_spec.rb b/ee/spec/features/google_analytics_datalayer_spec.rb index 7f07027cd00e6..89a51b76529c2 100644 --- a/ee/spec/features/google_analytics_datalayer_spec.rb +++ b/ee/spec/features/google_analytics_datalayer_spec.rb @@ -83,43 +83,4 @@ expect(last_event_in_data_layer["event"]).to eq("saasTrialGroup") end end - - context 'on new registration groups page' do - it 'tracks saasTrialGroup events in the dataLayer' do - sign_in user - visit new_users_sign_up_group_path - - prevent_submit_for('#new_group') - - fill_in 'group_name', with: 'Test Group' - - click_button 'Create group' - - data_layer = execute_script('return window.dataLayer') - last_event_in_data_layer = data_layer[-1] - - expect(last_event_in_data_layer["event"]).to eq("saasTrialGroup") - end - end - - context 'on new registration projects page' do - context 'when creating a new project through the form' do - it 'tracks saasTrialProject events in the dataLayer' do - sign_in user - group.add_owner(user) - visit new_users_sign_up_project_path(namespace_id: group.id) - - prevent_submit_for('#new_project') - - fill_in 'project_name', with: 'Test Project' - - click_button 'Create project' - - data_layer = execute_script('return window.dataLayer') - last_event_in_data_layer = data_layer[-1] - - expect(last_event_in_data_layer["event"]).to eq("saasTrialProject") - end - end - end end diff --git a/ee/spec/features/registrations/combined_registration_spec.rb b/ee/spec/features/registrations/combined_registration_spec.rb index ecbbf944251fb..305584b18653b 100644 --- a/ee/spec/features/registrations/combined_registration_spec.rb +++ b/ee/spec/features/registrations/combined_registration_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' -RSpec.describe 'Combined registration flow', :js do +RSpec.describe 'Registration group and project creation flow', :js do let_it_be(:user) { create(:user) } - let(:feature_flags) { {} } + let(:feature_flags) { { about_your_company_registration_flow: false } } before do # https://gitlab.com/gitlab-org/gitlab/-/issues/340302 @@ -15,89 +15,79 @@ sign_in(user) visit users_sign_up_welcome_path - expect(page).to have_content('Welcome to GitLab') + expect(page).to have_content('Welcome to GitLab') # rubocop:disable RSpec/ExpectInHook choose 'My company or team' choose 'Create a new project' click_on 'Continue' end - context 'when combined_registration experiment variant is candidate' do - let(:feature_flags) do - { - combined_registration: true, - about_your_company_registration_flow: false - } + it 'A user can create a group and project' do + page.within '.js-group-path-display' do + expect(page).to have_content('{group}') end - it 'A user can create a group and project' do - page.within '.js-group-path-display' do - expect(page).to have_content('{group}') - end + page.within '.js-project-path-display' do + expect(page).to have_content('{project}') + end - page.within '.js-project-path-display' do - expect(page).to have_content('{project}') - end + fill_in 'group_name', with: 'test group' + + fill_in 'blank_project_name', with: 'test project' - fill_in 'group_name', with: 'test group' + page.within '.js-group-path-display' do + expect(page).to have_content('test-group') + end - fill_in 'blank_project_name', with: 'test project' + page.within '.js-project-path-display' do + expect(page).to have_content('test-project') + end - page.within '.js-group-path-display' do - expect(page).to have_content('test-group') - end + click_on 'Create project' - page.within '.js-project-path-display' do - expect(page).to have_content('test-project') - end + expect(page).to have_content('Start your Free Ultimate Trial') + end - click_on 'Create project' + it 'a user can create a group and import a project' do + click_on 'Import' - expect(page).to have_content('Start your Free Ultimate Trial') + page.within '.js-import-group-path-display' do + expect(page).to have_content('{group}') end - it 'a user can create a group and import a project' do - click_on 'Import' - - page.within '.js-import-group-path-display' do - expect(page).to have_content('{group}') - end + click_on 'GitHub' - click_on 'GitHub' + page.within('.gl-field-error') do + expect(page).to have_content('This field is required.') + end - page.within('.gl-field-error') do - expect(page).to have_content('This field is required.') - end + fill_in 'import_group_name', with: 'test group' - fill_in 'import_group_name', with: 'test group' + page.within '.js-import-group-path-display' do + expect(page).to have_content('test-group') + end - page.within '.js-import-group-path-display' do - expect(page).to have_content('test-group') - end + click_on 'GitHub' - click_on 'GitHub' + expect(page).to have_content('To connect GitHub repositories, you first need to authorize GitLab to') + end - expect(page).to have_content('To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories.') + describe 'exiting onboarding' do + it 'does not show a link to exit the page' do + expect(page).not_to have_link('Exit.') end - describe 'exiting onboarding' do - it 'does not show a link to exit the page' do - expect(page).not_to have_link('Exit.') + context 'when require_verification_for_namespace_creation experiment is enabled' do + let(:feature_flags) do + { + about_your_company_registration_flow: false, + require_verification_for_namespace_creation: true + } end - context 'when require_verification_for_namespace_creation experiment is enabled' do - let(:feature_flags) do - { - combined_registration: true, - about_your_company_registration_flow: false, - require_verification_for_namespace_creation: true - } - end - - it 'shows a link to exit the page' do - expect(page).to have_link('Exit.', href: exit_users_sign_up_groups_projects_path) - expect(page).to have_content('You can always verify your account at a later time to create a group.') - end + it 'shows a link to exit the page' do + expect(page).to have_link('Exit.', href: exit_users_sign_up_groups_projects_path) + expect(page).to have_content('You can always verify your account at a later time to create a group.') end end end diff --git a/ee/spec/features/registrations/one_trust_spec.rb b/ee/spec/features/registrations/one_trust_spec.rb index 8b07fccae408e..8ddaa03d655ba 100644 --- a/ee/spec/features/registrations/one_trust_spec.rb +++ b/ee/spec/features/registrations/one_trust_spec.rb @@ -22,23 +22,6 @@ end end - context 'when user visits /users/sign_up/groups/new' do - before do - visit new_users_sign_up_group_path - end - - it_behaves_like 'one trust settings' - end - - context 'when user visits /users/sign_up/projects/new' do - before do - group.add_owner(user) - visit new_users_sign_up_project_path(namespace_id: group.id) - end - - it_behaves_like 'one trust settings' - end - context 'when user visits /users/sign_up/groups_projects/new' do before do visit new_users_sign_up_groups_project_path diff --git a/ee/spec/features/registrations/saas_user_registration_spec.rb b/ee/spec/features/registrations/saas_user_registration_spec.rb index f215ff49d6e0f..00a3e33f5e340 100644 --- a/ee/spec/features/registrations/saas_user_registration_spec.rb +++ b/ee/spec/features/registrations/saas_user_registration_spec.rb @@ -14,11 +14,6 @@ before do stub_feature_flags( - # This is an experiment that we want to clean up, but can't yet because of - # query limit concerns: - # https://gitlab.com/gitlab-org/gitlab/-/issues/350754 - combined_registration: true, - # This is the feature flag for the new registration flows where the user is # required to provide company details when registering for their company in # both the standard registration and trial flows. @@ -229,8 +224,6 @@ def company_params_trial_false end context "wanting to create a project" do - # This flow is behind the combined_registration feature flag. - before do choose 'Create a new project' @@ -281,8 +274,7 @@ def company_params_trial_false end context "wanting to create a project" do - # This flow is behind the combined_registration and the - # about_your_company_registration_flow feature flags. + # This flow is behind the about_your_company_registration_flow feature flag. before do choose 'Create a new project' @@ -309,6 +301,41 @@ def company_params_trial_false end it_behaves_like 'creates new group and project' + + it 'creates group but fails to apply a trial, then resubmits and does not apply trial', :sidekiq_inline do + apply_trial_response = { + success: false, + errors: 'BAD STUFF HAPPENED' + } + + fill_in 'group_name', with: 'Test Group' + fill_in 'blank_project_name', with: 'Test Project' + + expect_next(GitlabSubscriptions::ApplyTrialService) + .to receive(:execute).with({ + uid: user.id, + trial_user: hash_including( + namespace_id: anything, + gitlab_com_trial: true, + sync_to_gl: true + ) + }).and_return(apply_trial_response) + + click_on 'Create project' + + expect(page).to have_content 'Create or import your first project' + expect(page).to have_content apply_trial_response[:errors] + expect(GitlabSubscriptions::ApplyTrialService).not_to receive(:new) + + click_on 'Create project' + + expect(page).to have_content 'Get started with GitLab' + + click_on "Ok, let's go" + + expect(page).to have_content('Learn GitLab') + expect(page).to have_content('GitLab is better with colleagues!') + end end context "without a trial" do diff --git a/ee/spec/features/registrations/trial_during_signup_flow_spec.rb b/ee/spec/features/registrations/trial_during_signup_flow_spec.rb deleted file mode 100644 index dc7381fc8d8a1..0000000000000 --- a/ee/spec/features/registrations/trial_during_signup_flow_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -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', 'Telephone number', 'Country'] } - - before do - stub_feature_flags(about_your_company_registration_flow: false) - allow(Gitlab).to receive(:com?).and_return(true) - sign_in(user) - visit users_sign_up_welcome_path - - expect(page).to have_content('Welcome to GitLab') - - choose 'My company or team' - choose 'Create a new project' - click_on 'Continue' - - expect(page).to have_content('GitLab Ultimate trial (optional)') - end - - it 'shows the expected behavior with no trial chosen', :aggregate_failures do - fill_in 'group_name', with: 'test' - - click_on 'Create group' - - expect(page).not_to have_content('Congratulations, your free trial is activated.') - expect(page).to have_content('Create/import your first project') - end - - it 'shows the expected behavior with trial chosen' do - fill_in 'group_name', with: 'test' - - # fields initially invisible - trial_fields.each { |field| expect(page).not_to have_content(field) } - - # fields become visible with trial toggle - click_button class: 'gl-toggle' - - trial_fields.each { |field| expect(page).to have_content(field) } - - # fields are required - click_on 'Create group' - - expect(page).to have_content('This field is required') - - # make fields invisible again - click_button class: 'gl-toggle' - - trial_fields.each { |field| expect(page).not_to have_content(field) } - - # make fields visible again - click_button class: 'gl-toggle' - - trial_fields.each { |field| expect(page).to have_content(field) } - - # submit the trial form - fill_in 'company_name', with: 'GitLab' - select2 '1-99', from: '#company_size' - fill_in 'phone_number', with: '+1234567890' - select2 'US', from: '#country_select' - - expect_next_instance_of(GitlabSubscriptions::CreateLeadService) do |service| - expect(service).to receive(:execute).and_return(success: true) - end - expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service| - expect(service).to receive(:execute).and_return({ success: true }) - end - - click_on 'Create group' - - expect(page).to have_content('Congratulations, your free trial is activated.') - expect(page).to have_content('Create/import your first project') - end -end diff --git a/ee/spec/features/registrations/user_sees_new_onboarding_flow_spec.rb b/ee/spec/features/registrations/user_sees_new_onboarding_flow_spec.rb deleted file mode 100644 index 29d0f66f607ba..0000000000000 --- a/ee/spec/features/registrations/user_sees_new_onboarding_flow_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'User sees new onboarding flow', :js do - before do - stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 200) - allow(Gitlab).to receive(:com?).and_return(true) - end - - it 'shows continuous onboarding flow pages' do - visit '/' - gitlab_sign_in(:user) - visit users_sign_up_welcome_path - - expect(page).to have_content('Welcome to GitLab') - - choose 'Just me' - choose 'Create a new project' - click_on 'Continue' - - expect(page).to have_content('Create your group') - - fill_in 'group_name', with: 'test' - - expect(page).to have_field('group_path', with: 'test') - - click_on 'Create group' - - expect(page).to have_content('Create/import your first project') - - fill_in 'project_name', with: 'test' - - expect(page).to have_field('project_path', with: 'test') - - click_on 'Create project' - - expect(page).to have_content('Get started with GitLab') - - Sidekiq::Worker.drain_all - click_on "Ok, let's go" - - expect(page).to have_content('Learn GitLab') - expect(page).to have_content('GitLab is better with colleagues!') - end -end diff --git a/ee/spec/frontend/groups/components/registration_trial_toggle_spec.js b/ee/spec/frontend/groups/components/registration_trial_toggle_spec.js deleted file mode 100644 index e8a18aecdf3a6..0000000000000 --- a/ee/spec/frontend/groups/components/registration_trial_toggle_spec.js +++ /dev/null @@ -1,51 +0,0 @@ -import { GlToggle } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import RegistrationTrialToggle from 'ee/registrations/components/registration_trial_toggle.vue'; - -describe('Registration Trial Toggle', () => { - let wrapper; - - const createComponent = (propsData) => { - wrapper = shallowMount(RegistrationTrialToggle, { - propsData, - }); - }; - - beforeEach(() => { - createComponent({ active: false }); - }); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('Default state', () => { - it('renders component properly', () => { - expect(wrapper.findComponent(RegistrationTrialToggle).exists()).toBe(true); - }); - - it('shows the toggle component', () => { - expect(wrapper.findComponent(GlToggle).props('label')).toBe( - RegistrationTrialToggle.i18n.toggleLabel, - ); - }); - - it('sets the default value to be false', () => { - expect(wrapper.vm.trial).toBe(false); - }); - }); - - describe('Emits events', () => { - it('emits initial event', () => { - expect(wrapper.emitted().changed).toEqual([[{ trial: false }]]); - }); - - it('emits another event', () => { - wrapper.findComponent(GlToggle).vm.$emit('change', true); - - expect(wrapper.vm.trial).toBe(true); - expect(wrapper.emitted().changed).toEqual([[{ trial: false }], [{ trial: true }]]); - }); - }); -}); diff --git a/ee/spec/helpers/ee/welcome_helper_spec.rb b/ee/spec/helpers/ee/welcome_helper_spec.rb index 5d2fcaf2492d2..4a10b1c744fcd 100644 --- a/ee/spec/helpers/ee/welcome_helper_spec.rb +++ b/ee/spec/helpers/ee/welcome_helper_spec.rb @@ -42,25 +42,6 @@ end end - describe '#show_trial_during_signup?' do - before do - allow(helper).to receive(:current_user).and_return(user) - end - - where(:setup_for_company, :expected_result) do - true | true - false | false - end - - with_them do - let(:user) { create(:user, setup_for_company: setup_for_company) } - - it 'returns the expected_result' do - expect(helper.show_trial_during_signup?).to eq(expected_result) - end - end - end - describe '#in_oauth_flow?' do where(:user_return_to_path, :expected_result) do '/oauth/authorize?client_id=x&redirect_uri=y&response_type=code&state=z' | true diff --git a/ee/spec/requests/registrations/project_creation_spec.rb b/ee/spec/requests/registrations/project_creation_spec.rb index e7fb747f67940..a50282e633fda 100644 --- a/ee/spec/requests/registrations/project_creation_spec.rb +++ b/ee/spec/requests/registrations/project_creation_spec.rb @@ -33,7 +33,7 @@ context 'when group and project can be created' do it 'creates a group' do - stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 128) # 204 before creating learn gitlab in worker + stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 138) # 204 before creating learn gitlab in worker expect { post users_sign_up_groups_projects_path, params: params }.to change(Group, :count).by(1) end diff --git a/ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb b/ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb index 87a396bab1d11..82869a35218d3 100644 --- a/ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb +++ b/ee/spec/support/shared_examples/controllers/registrations/groups_controller_shared_examples.rb @@ -2,8 +2,10 @@ RSpec.shared_examples 'hides email confirmation warning' do RSpec::Matchers.define :set_confirm_warning_for do |email| - match do |response| - expect(controller).to set_flash.now[:warning].to include("Please check your email (#{email}) to verify that you own this address and unlock the power of CI/CD.") + match do |_response| + msg = "Please check your email (#{email}) to verify that you own this address and unlock the power of CI/CD." + + expect(controller).to set_flash.now[:warning].to include(msg) end end @@ -19,56 +21,3 @@ it { is_expected.not_to set_confirm_warning_for(user.email) } end end - -RSpec.shared_examples "Registrations::GroupsController GET #new" do - using RSpec::Parameterized::TableSyntax - - let_it_be(:user) { create(:user) } - let(:com) { true } - - subject { get :new } - - context '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) - allow(::Gitlab).to receive(:com?).and_return(com) - end - - context 'when on .com' do - it { is_expected.to have_gitlab_http_status(:ok) } - it { is_expected.to render_template(:new) } - - it 'assigns the group variable to a new Group with the default group visibility', :aggregate_failures do - subject - expect(assigns(:group)).to be_a_new(Group) - - expect(assigns(:group).visibility_level).to eq(Gitlab::CurrentSettings.default_group_visibility) - end - - context 'user without the ability to create a group' do - let(:user) { create(:user, can_create_group: false) } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - it 'tracks an event for the combined_registration experiment', :experiment do - expect(experiment(:combined_registration)).to track(:view_new_group_action).on_next_instance - - subject - end - end - - context 'when not on .com' do - let(:com) { false } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - it_behaves_like 'hides email confirmation warning' - end -end diff --git a/ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb b/ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb deleted file mode 100644 index c3a36f78514a7..0000000000000 --- a/ee/spec/support/shared_examples/controllers/registrations/projects_controller_shared_examples.rb +++ /dev/null @@ -1,140 +0,0 @@ -# frozen_string_literal: true - -RSpec.shared_examples "Registrations::ProjectsController POST #create" do - include AfterNextHelpers - - subject { post :create, params: { project: params }.merge(trial_onboarding_flow_params).merge(extra_params) } - - let_it_be(:trial_onboarding_flow_params) { {} } - let_it_be(:first_project) { create(:project) } - - let(:params) { { namespace_id: namespace.id, name: 'New project', path: 'project-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE } } - let(:com) { true } - let(:extra_params) { {} } - let(:success_path) { nil } - let(:stored_location_for) { nil } - - context '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', :sidekiq_inline do - before do - namespace.add_owner(user) - sign_in(user) - allow(::Gitlab).to receive(:com?).and_return(com) - allow(controller).to receive(:experiment).and_call_original - end - - it 'creates a new project, a "Learn GitLab" project, sets a cookie and redirects to the success_path' do - allow_next_instance_of(::Projects::CreateService) do |service| - allow(service).to receive(:execute).and_return(first_project) - end - allow_next_instance_of(::Projects::GitlabProjectsImportService) do |service| - allow(service).to receive(:execute).and_return(project) - end - - expect(subject).to have_gitlab_http_status(:redirect) - expect(subject).to redirect_to(success_path || continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: first_project.id)) - expect(controller.stored_location_for(:user)).to eq(stored_location_for) - end - - context 'when the `registration_verification` experiment is enabled' do - before do - stub_experiments(registration_verification: :candidate) - - allow_next_instance_of(::Projects::CreateService) do |service| - allow(service).to receive(:execute).and_return(first_project) - end - end - - it 'is expected to redirect to the verification page' do - params = { project_id: first_project.id } - params[:combined] = true if combined_registration? - expect(subject).to redirect_to(new_users_sign_up_verification_path(params)) - end - end - - context 'learn gitlab project' do - using RSpec::Parameterized::TableSyntax - - where(:trial, :project_name, :template) do - false | 'Learn GitLab' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE - true | 'Learn GitLab - Ultimate trial' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE - end - - with_them do - let(:path) { Rails.root.join('vendor', 'project_templates', template) } - let(:expected_arguments) { { namespace_id: namespace.id, file: handle, name: project_name } } - let(:handle) { double } - let(:trial_onboarding_flow_params) { { trial_onboarding_flow: trial } } - - before do - allow(File).to receive(:open).and_call_original - expect(File).to receive(:open).with(path).and_yield(handle) - end - - specify do - expect_next(::Projects::GitlabProjectsImportService, user, expected_arguments) - .to receive(:execute).and_return(project) - - subject - end - end - end - - context 'when the trial onboarding is active' do - let_it_be(:trial_onboarding_flow_params) { { trial_onboarding_flow: true } } - - it 'creates a new project, a "Learn GitLab - Ultimate trial" project, does not set a cookie' do - expect { subject }.to change { namespace.projects.pluck(:name).sort }.from([]).to(['New project', s_('Learn GitLab - Ultimate trial')].sort) - expect(subject).to have_gitlab_http_status(:redirect) - expect(namespace.projects.find_by_name(s_('Learn GitLab - Ultimate trial'))).to be_import_finished - end - - it 'records context and redirects to the success page' do - expect_next_instance_of(::Projects::CreateService) do |service| - expect(service).to receive(:execute).and_return(first_project) - end - expect_next_instance_of(::Projects::GitlabProjectsImportService) do |service| - expect(service).to receive(:execute).and_return(project) - end - expect(subject).to redirect_to(trial_getting_started_users_sign_up_welcome_path(learn_gitlab_project_id: project.id)) - end - - context 'when the `registration_verification` experiment is enabled' do - before do - stub_experiments(registration_verification: :candidate) - - allow_next_instance_of(::Projects::GitlabProjectsImportService) do |service| - allow(service).to receive(:execute).and_return(project) - end - end - - it 'is expected to redirect to the verification page' do - params = { learn_gitlab_project_id: project.id } - params[:combined] = true if combined_registration? - expect(subject).to redirect_to(new_users_sign_up_verification_path(params)) - end - end - end - - context 'when the project cannot be saved' do - let(:params) { { name: '', path: '' } } - - it 'does not create a project' do - expect { subject }.not_to change { Project.count } - end - - it { is_expected.to have_gitlab_http_status(:ok) } - it { is_expected.to render_template(:new) } - end - - context 'with signup onboarding not enabled' do - let(:com) { false } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - end -end diff --git a/ee/spec/views/registrations/groups/new.html.haml_spec.rb b/ee/spec/views/registrations/groups/new.html.haml_spec.rb deleted file mode 100644 index e2fc2c857878a..0000000000000 --- a/ee/spec/views/registrations/groups/new.html.haml_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'registrations/groups/new' do - let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group) } - let_it_be(:trial_onboarding_flow) { false } - let_it_be(:show_trial_during_signup) { true } - - before do - assign(:group, group) - allow(view).to receive(:current_user).and_return(user) - allow(view).to receive(:in_trial_onboarding_flow?).and_return(trial_onboarding_flow) - allow(view).to receive(:show_trial_during_signup?).and_return(show_trial_during_signup) - - render - end - - subject { rendered } - - it 'shows trial form and hides invite members' do - is_expected.to have_content('Company name') - is_expected.not_to have_selector('.js-invite-members') - end - - it 'shows the progress bar' do - expect(rendered).to have_selector('#progress-bar') - end - - it 'shows the trial during signup form' do - expect(rendered).to have_content('GitLab Ultimate trial (optional)') - end - - context 'in trial onboarding' do - let_it_be(:trial_onboarding_flow) { true } - - it 'hides trial form' do - is_expected.not_to have_content('Company name') - end - - it 'hides the progress bar' do - expect(rendered).not_to have_selector('#progress-bar') - end - end - - context 'not showing trial during signup' do - let_it_be(:show_trial_during_signup) { false } - - it 'shows the trial during signup form' do - expect(rendered).not_to have_content('GitLab Ultimate trial (optional)') - end - end -end diff --git a/ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb b/ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb index 0c986195ec454..c16939bde4bc2 100644 --- a/ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb +++ b/ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb @@ -12,7 +12,11 @@ before do assign(:group, group) assign(:project, project) - stub_config(extra: { google_tag_manager_id: google_tag_manager_id, google_tag_manager_nonce_id: google_tag_manager_id }) + stub_config(extra: + { + google_tag_manager_id: google_tag_manager_id, + google_tag_manager_nonce_id: google_tag_manager_id + }) allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:import_sources_enabled?).and_return(false) end diff --git a/ee/spec/views/registrations/projects/new.html.haml_spec.rb b/ee/spec/views/registrations/projects/new.html.haml_spec.rb deleted file mode 100644 index ea6559808cb5e..0000000000000 --- a/ee/spec/views/registrations/projects/new.html.haml_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'registrations/projects/new' do - let_it_be(:user) { create(:user) } - let_it_be(:namespace) { create(:namespace) } - let_it_be(:project) { create(:project, namespace: namespace) } - let_it_be(:trial_onboarding_flow) { false } - let_it_be(:trial_during_signup_flow) { false } - - before do - assign(:project, project) - allow(view).to receive(:current_user).and_return(user) - allow(view).to receive(:in_trial_onboarding_flow?).and_return(trial_onboarding_flow) - allow(view).to receive(:in_trial_during_signup_flow?).and_return(trial_during_signup_flow) - allow(view).to receive(:import_sources_enabled?).and_return(false) - - render - end - - it 'shows the progress bar' do - expect(rendered).to have_selector('#progress-bar') - end - - context 'in trial onboarding' do - let_it_be(:trial_onboarding_flow) { true } - - it 'hides the progress bar in trial onboarding' do - expect(rendered).not_to have_selector('#progress-bar') - end - - it 'show the trial activation' do - expect(rendered).to have_content('Congratulations, your free trial is activated.') - end - end - - context 'in trial flow' do - let_it_be(:trial_during_signup_flow) { true } - - it 'show the trial activation' do - expect(rendered).to have_content('Congratulations, your free trial is activated.') - end - end -end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 37843b8bb12e0..72c3111909c8a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -3910,9 +3910,6 @@ msgstr "" msgid "Allowed" msgstr "" -msgid "Allowed characters: +, 0-9, -, and spaces." -msgstr "" - msgid "Allowed email domain restriction only permitted for top-level groups" msgstr "" @@ -11043,9 +11040,6 @@ msgstr "" msgid "Create, update, or delete a merge request." msgstr "" -msgid "Create/import your first project" -msgstr "" - msgid "CreateGroup|You don’t have permission to create a subgroup in this group." msgstr "" @@ -15178,9 +15172,6 @@ msgstr "" msgid "Error loading burndown chart data" msgstr "" -msgid "Error loading countries data." -msgstr "" - msgid "Error loading file viewer." msgstr "" @@ -23232,9 +23223,6 @@ msgstr "" msgid "Learn GitLab" msgstr "" -msgid "Learn GitLab - Ultimate trial" -msgstr "" - msgid "Learn More" msgstr "" @@ -40517,9 +40505,6 @@ msgstr "" msgid "This project will be deleted on %{date} since its parent group '%{parent_group_name}' has been scheduled for deletion." msgstr "" -msgid "This project will live in your group %{strong_open}%{namespace}%{strong_close}. A project is where you store your files (repository), plan your work (issues), publish your documentation (wiki), and so much more." -msgstr "" - msgid "This release was created with a date in the past. Evidence collection at the moment of the release is unavailable." msgstr "" @@ -41463,39 +41448,12 @@ msgstr "" msgid "Trial|Allowed characters: +, 0-9, -, and spaces." msgstr "" -msgid "Trial|Company name" -msgstr "" - msgid "Trial|Continue" msgstr "" -msgid "Trial|Continue using the basic features of GitLab for free." -msgstr "" - -msgid "Trial|Country" -msgstr "" - msgid "Trial|Dismiss" msgstr "" -msgid "Trial|GitLab Ultimate trial (optional)" -msgstr "" - -msgid "Trial|Number of employees" -msgstr "" - -msgid "Trial|Please select a country" -msgstr "" - -msgid "Trial|Telephone number" -msgstr "" - -msgid "Trial|Upgrade to Ultimate to keep using GitLab with advanced features." -msgstr "" - -msgid "Trial|We will activate your trial on your group after you complete this step. After 30 days, you can:" -msgstr "" - msgid "Trial|Your GitLab Ultimate trial lasts for 30 days, but you can keep your free GitLab account forever. We just need some additional information to activate your trial." msgstr "" @@ -45602,9 +45560,6 @@ msgstr "" msgid "Your file must contain a column named %{codeStart}title%{codeEnd}. A %{codeStart}description%{codeEnd} column is optional. The maximum file size allowed is 10 MB." msgstr "" -msgid "Your first project" -msgstr "" - msgid "Your free group is now limited to %d member" msgid_plural "Your free group is now limited to %d members" msgstr[0] "" diff --git a/spec/frontend/google_tag_manager/index_spec.js b/spec/frontend/google_tag_manager/index_spec.js index 9c4b23e3a7040..ec9e1ef8e5fa8 100644 --- a/spec/frontend/google_tag_manager/index_spec.js +++ b/spec/frontend/google_tag_manager/index_spec.js @@ -8,7 +8,6 @@ import { trackSaasTrialSubmit, trackSaasTrialSkip, trackSaasTrialGroup, - trackSaasTrialProject, trackSaasTrialGetStarted, trackTrialAcceptTerms, trackCheckout, @@ -150,9 +149,6 @@ describe('~/google_tag_manager/index', () => { createTestCase(trackSaasTrialGroup, { forms: [{ cls: 'js-saas-trial-group', expectation: { event: 'saasTrialGroup' } }], }), - createTestCase(trackSaasTrialProject, { - forms: [{ id: 'new_project', expectation: { event: 'saasTrialProject' } }], - }), createTestCase(trackProjectImport, { links: [ { @@ -481,11 +477,11 @@ describe('~/google_tag_manager/index', () => { }); it('no ops', () => { - setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] })); + setHTMLFixture(createHTML({ forms: [{ cls: 'js-saas-trial-group' }] })); - trackSaasTrialProject(); + trackSaasTrialGroup(); - triggerEvent('#new_project', 'submit'); + triggerEvent('.js-saas-trial-group', 'submit'); expect(spy).not.toHaveBeenCalled(); expect(logError).not.toHaveBeenCalled(); @@ -506,11 +502,11 @@ describe('~/google_tag_manager/index', () => { }); it('logs error', () => { - setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] })); + setHTMLFixture(createHTML({ forms: [{ cls: 'js-saas-trial-group' }] })); - trackSaasTrialProject(); + trackSaasTrialGroup(); - triggerEvent('#new_project', 'submit'); + triggerEvent('.js-saas-trial-group', 'submit'); expect(logError).toHaveBeenCalledWith( 'Unexpected error while pushing to dataLayer', diff --git a/spec/frontend/groups/components/visibility_level_dropdown_spec.js b/spec/frontend/groups/components/visibility_level_dropdown_spec.js deleted file mode 100644 index 49d0b182f7fcf..0000000000000 --- a/spec/frontend/groups/components/visibility_level_dropdown_spec.js +++ /dev/null @@ -1,70 +0,0 @@ -import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import Component from '~/groups/components/visibility_level_dropdown.vue'; - -describe('Visibility Level Dropdown', () => { - let wrapper; - - const options = [ - { level: 0, label: 'Private', description: 'Private description' }, - { level: 20, label: 'Public', description: 'Public description' }, - ]; - const defaultLevel = 0; - - const createComponent = (propsData) => { - wrapper = shallowMount(Component, { - propsData, - }); - }; - - beforeEach(() => { - createComponent({ - visibilityLevelOptions: options, - defaultLevel, - }); - }); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - const hiddenInputValue = () => - wrapper.find("input[name='group[visibility_level]']").attributes('value'); - const dropdownText = () => wrapper.findComponent(GlDropdown).props('text'); - const findDropdownItems = () => - wrapper.findAllComponents(GlDropdownItem).wrappers.map((option) => ({ - text: option.text(), - secondaryText: option.props('secondaryText'), - })); - - describe('Default values', () => { - it('sets the value of the hidden input to the default value', () => { - expect(hiddenInputValue()).toBe(options[0].level.toString()); - }); - - it('sets the text of the dropdown to the default value', () => { - expect(dropdownText()).toBe(options[0].label); - }); - - it('shows all dropdown options', () => { - expect(findDropdownItems()).toEqual( - options.map(({ label, description }) => ({ text: label, secondaryText: description })), - ); - }); - }); - - describe('Selecting an option', () => { - beforeEach(() => { - wrapper.findAllComponents(GlDropdownItem).at(1).vm.$emit('click'); - }); - - it('sets the value of the hidden input to the selected value', () => { - expect(hiddenInputValue()).toBe(options[1].level.toString()); - }); - - it('sets the text of the dropdown to the selected value', () => { - expect(dropdownText()).toBe(options[1].label); - }); - }); -}); diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index e112c1e2497a4..edde2e0a24768 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -417,10 +417,10 @@ def wiki_repo(project) expect(imported_project.import_url).to eq('http://import-url') end - it 'tracks for the combined_registration experiment', :experiment do - expect(experiment(:combined_registration)).to track(:import_project).on_next_instance - + it 'tracks for imported project' do imported_project + + expect_snowplow_event(category: described_class.name, action: 'import_project', user: user) end describe 'import scheduling' do diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index bcd83c431e4ee..f297734b4b701 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -216,7 +216,6 @@ - './ee/spec/elastic/migrate/20220512150000_pause_indexing_for_unsupported_es_versions_spec.rb' - './ee/spec/elastic/migrate/20220613120500_migrate_commits_to_separate_index_spec.rb' - './ee/spec/elastic/migrate/20220713103500_delete_commits_from_original_index_spec.rb' -- './ee/spec/experiments/combined_registration_experiment_spec.rb' - './ee/spec/factories/lfs_object_spec.rb' - './ee/spec/features/account_recovery_regular_check_spec.rb' - './ee/spec/features/admin/admin_audit_logs_spec.rb' -- GitLab