Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-03 00:12:50 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-03 00:12:50 +0300
commit3a72ac775065b61bbdb285a8f4f6f152ccb4db49 (patch)
tree3e03be3d792b6693a57f7ef3da8b228c694fb45a
parent0cea0a8f44d2cef1d4d132c72a07f8995962115c (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/as-if-foss.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml4
-rw-r--r--.rubocop_todo/layout/space_in_lambda_literal.yml2
-rw-r--r--.rubocop_todo/rspec/before_all_role_assignment.yml2
-rw-r--r--.rubocop_todo/rspec/context_wording.yml3
-rw-r--r--.rubocop_todo/rspec/named_subject.yml3
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_title_with_edit.vue6
-rw-r--r--app/controllers/ldap/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb12
-rw-r--r--app/models/merge_request.rb15
-rw-r--r--app/models/organizations/organization.rb2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml14
-rw-r--r--app/views/devise/shared/_omniauth_provider_button.haml7
-rw-r--r--app/views/devise/shared/_signup_omniauth_provider_button.haml14
-rw-r--r--app/views/profiles/emails/index.html.haml10
-rw-r--r--app/views/profiles/gpg_keys/_key_table.html.haml2
-rw-r--r--app/views/user_settings/passwords/edit.html.haml8
-rw-r--r--app/views/user_settings/passwords/new.html.haml8
-rw-r--r--config/feature_flags/development/truncate_ci_merge_request_description.yml8
-rw-r--r--db/docs/batched_background_migrations/backfill_vs_code_settings_uuid.yml2
-rw-r--r--doc/api/graphql/reference/index.md4
-rw-r--r--doc/ci/variables/predefined_variables.md3
-rw-r--r--doc/user/project/requirements/index.md8
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml2
-rw-r--r--qa/gdk/Dockerfile.gdk2
-rw-r--r--qa/qa/page/profile/emails.rb22
-rw-r--r--qa/qa/page/profile/password.rb32
-rwxr-xr-xscripts/setup/generate-as-if-foss-env.rb79
-rw-r--r--spec/controllers/omniauth_callbacks_controller_spec.rb111
-rw-r--r--spec/features/admin/users/admin_impersonates_user_spec.rb (renamed from spec/features/admin/users/user_impersonation_spec.rb)2
-rw-r--r--spec/features/admin/users/admin_manages_user_identities_spec.rb (renamed from spec/features/admin/users/user_identities_spec.rb)2
-rw-r--r--spec/features/admin/users/admin_sees_unconfirmed_user_spec.rb52
-rw-r--r--spec/features/admin/users/admin_sees_user_spec.rb (renamed from spec/features/admin/users/user_spec.rb)75
-rw-r--r--spec/features/projects/members/manage_members_spec.rb2
-rw-r--r--spec/frontend/work_items/components/work_item_title_with_edit_spec.js (renamed from spec/frontend/work_items/components/work_item_with_title_edit_spec.js)2
-rw-r--r--spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb45
-rw-r--r--spec/scripts/setup/generate_as_if_foss_env_spec.rb84
-rw-r--r--spec/support/shared_examples/features/work_items_shared_examples.rb43
41 files changed, 453 insertions, 248 deletions
diff --git a/.gitlab/ci/as-if-foss.gitlab-ci.yml b/.gitlab/ci/as-if-foss.gitlab-ci.yml
index c1ba9d01c77..0c496ebacd8 100644
--- a/.gitlab/ci/as-if-foss.gitlab-ci.yml
+++ b/.gitlab/ci/as-if-foss.gitlab-ci.yml
@@ -64,6 +64,7 @@ start-as-if-foss:
ENABLE_RSPEC_MIGRATION: $ENABLE_RSPEC_MIGRATION
ENABLE_RSPEC_BACKGROUND_MIGRATION: $ENABLE_RSPEC_BACKGROUND_MIGRATION
ENABLE_RSPEC_SYSTEM: $ENABLE_RSPEC_SYSTEM
+ ENABLE_JEST: $ENABLE_JEST
trigger:
project: gitlab-org/gitlab-foss
branch: as-if-foss/${CI_COMMIT_REF_NAME}
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 8817f8707e9..104c972f894 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -21,7 +21,7 @@
if: '$FORCE_GITLAB_CI'
.if-default-refs: &if-default-refs
- if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/ || $CI_COMMIT_REF_NAME =~ /^\d+-\d+-auto-deploy-\d+$/ || $CI_COMMIT_REF_NAME =~ /^security\// || $CI_COMMIT_REF_NAME =~ "^ruby\d+(_\d)*$" || ($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached") || $CI_COMMIT_TAG || $FORCE_GITLAB_CI'
+ if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable(-ee)?$/ || $CI_COMMIT_REF_NAME =~ /^\d+-\d+-auto-deploy-\d+$/ || $CI_COMMIT_REF_NAME =~ /^security\// || $CI_COMMIT_REF_NAME =~ /^ruby\d+(_\d)*$/ || ($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached") || $CI_COMMIT_TAG || $FORCE_GITLAB_CI'
.if-default-branch-refs: &if-default-branch-refs
if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_MERGE_REQUEST_IID == null'
@@ -1250,6 +1250,7 @@
rules:
- <<: *if-merge-request-labels-pipeline-expedite
when: never
+ - if: '$ENABLE_JEST == "true"'
- <<: *if-merge-request-labels-run-all-rspec
- <<: *if-merge-request-labels-frontend-and-feature-flag
- <<: *if-default-refs
@@ -1300,6 +1301,7 @@
when: never
- <<: *if-fork-merge-request
when: never
+ - if: '$ENABLE_JEST == "true"'
- <<: *if-merge-request-labels-run-all-jest
- <<: *if-merge-request-labels-frontend-and-feature-flag
- <<: *if-merge-request
diff --git a/.rubocop_todo/layout/space_in_lambda_literal.yml b/.rubocop_todo/layout/space_in_lambda_literal.yml
index e0113d2628d..bd901e40016 100644
--- a/.rubocop_todo/layout/space_in_lambda_literal.yml
+++ b/.rubocop_todo/layout/space_in_lambda_literal.yml
@@ -358,7 +358,7 @@ Layout/SpaceInLambdaLiteral:
- 'lib/gitlab/metrics/exporter/base_exporter.rb'
- 'lib/gitlab/visibility_level.rb'
- 'spec/deprecation_toolkit_env.rb'
- - 'spec/features/admin/users/user_spec.rb'
+ - 'spec/features/admin/users/admin_sees_unconfirmed_user_spec.rb'
- 'spec/helpers/namespaces_helper_spec.rb'
- 'spec/lib/backup/gitaly_backup_spec.rb'
- 'spec/lib/container_registry/client_spec.rb'
diff --git a/.rubocop_todo/rspec/before_all_role_assignment.yml b/.rubocop_todo/rspec/before_all_role_assignment.yml
index 3436cffc2ff..22eebde9389 100644
--- a/.rubocop_todo/rspec/before_all_role_assignment.yml
+++ b/.rubocop_todo/rspec/before_all_role_assignment.yml
@@ -800,7 +800,7 @@ RSpec/BeforeAllRoleAssignment:
- 'spec/controllers/projects_controller_spec.rb'
- 'spec/controllers/repositories/lfs_storage_controller_spec.rb'
- 'spec/features/admin/admin_projects_spec.rb'
- - 'spec/features/admin/users/user_spec.rb'
+ - 'spec/features/admin/users/admin_sees_user_spec.rb'
- 'spec/features/admin/users/users_spec.rb'
- 'spec/features/boards/board_filters_spec.rb'
- 'spec/features/boards/new_issue_spec.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index 0a50fc4485d..fe7e9f045e7 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -1040,8 +1040,7 @@ RSpec/ContextWording:
- 'spec/features/admin/admin_mode_spec.rb'
- 'spec/features/admin/admin_settings_spec.rb'
- 'spec/features/admin/dashboard_spec.rb'
- - 'spec/features/admin/users/user_impersonation_spec.rb'
- - 'spec/features/admin/users/user_spec.rb'
+ - 'spec/features/admin/users/admin_impersonates_user_spec.rb'
- 'spec/features/admin/users/users_spec.rb'
- 'spec/features/atom/dashboard_issues_spec.rb'
- 'spec/features/atom/dashboard_spec.rb'
diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml
index 885fd554ad6..b1835f31c63 100644
--- a/.rubocop_todo/rspec/named_subject.yml
+++ b/.rubocop_todo/rspec/named_subject.yml
@@ -1414,8 +1414,7 @@ RSpec/NamedSubject:
- 'spec/controllers/users/callouts_controller_spec.rb'
- 'spec/experiments/application_experiment_spec.rb'
- 'spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb'
- - 'spec/features/admin/users/user_impersonation_spec.rb'
- - 'spec/features/admin/users/user_spec.rb'
+ - 'spec/features/admin/users/admin_impersonates_user_spec.rb'
- 'spec/features/groups/clusters/user_spec.rb'
- 'spec/features/merge_request/user_sees_merge_widget_spec.rb'
- 'spec/features/user_settings/password_spec.rb'
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index 485d85b8872..85b981d9370 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -449,6 +449,7 @@ export default {
class="gl-mt-3 gl-sm-display-block!"
:is-editing="editMode"
:title="workItem.title"
+ @updateWorkItem="updateWorkItem"
@updateDraft="updateDraft('title', $event)"
/>
<work-item-title
@@ -518,6 +519,7 @@ export default {
:is-editing="editMode"
:class="titleClassComponent"
:title="workItem.title"
+ @updateWorkItem="updateWorkItem"
@updateDraft="updateDraft('title', $event)"
/>
<work-item-title
diff --git a/app/assets/javascripts/work_items/components/work_item_title_with_edit.vue b/app/assets/javascripts/work_items/components/work_item_title_with_edit.vue
index 02ed25f98e4..6af564a6a91 100644
--- a/app/assets/javascripts/work_items/components/work_item_title_with_edit.vue
+++ b/app/assets/javascripts/work_items/components/work_item_title_with_edit.vue
@@ -27,10 +27,12 @@ export default {
<template>
<gl-form-group v-if="isEditing" :label="$options.i18n.titleLabel" label-for="work-item-title">
<gl-form-input
- id="work-item-title"
class="gl-w-full"
:value="title"
- @change="$emit('updateDraft', $event)"
+ data-testid="work-item-title-with-edit"
+ @keydown.meta.enter="$emit('updateWorkItem')"
+ @keydown.ctrl.enter="$emit('updateWorkItem')"
+ @input="$emit('updateDraft', $event)"
/>
</gl-form-group>
<h1
diff --git a/app/controllers/ldap/omniauth_callbacks_controller.rb b/app/controllers/ldap/omniauth_callbacks_controller.rb
index 955dfe58449..1c79bd3a668 100644
--- a/app/controllers/ldap/omniauth_callbacks_controller.rb
+++ b/app/controllers/ldap/omniauth_callbacks_controller.rb
@@ -28,7 +28,7 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
define_providers!
override :set_remember_me
- def set_remember_me(user)
+ def set_remember_me(user, _auth_user)
user.remember_me = params[:remember_me] if user.persisted?
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 907ece1a06e..0701b1ee977 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -139,9 +139,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
identity_linker ||= auth_module::IdentityLinker.new(current_user, oauth, session)
link_identity(identity_linker)
- set_remember_me(current_user)
- store_idp_two_factor_status(build_auth_user(auth_module::User).bypass_two_factor?)
+ current_auth_user = build_auth_user(auth_module::User)
+ set_remember_me(current_user, current_auth_user)
+
+ store_idp_two_factor_status(current_auth_user.bypass_two_factor?)
if identity_linker.changed?
redirect_identity_linked
@@ -193,7 +195,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
track_event(@user, oauth['provider'], 'succeeded')
Gitlab::Tracking.event(self.class.name, "#{oauth['provider']}_sso", user: @user) if new_user
- set_remember_me(@user)
+ set_remember_me(@user, auth_user)
set_session_active_since(oauth['provider']) if ::AuthHelper.saml_providers.include?(oauth['provider'].to_sym)
if @user.two_factor_enabled? && !auth_user.bypass_two_factor?
@@ -278,10 +280,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
.for_authentication.security_event
end
- def set_remember_me(user)
+ def set_remember_me(user, auth_user)
return unless remember_me?
- if user.two_factor_enabled?
+ if user.two_factor_enabled? && !auth_user.bypass_two_factor?
params[:remember_me] = '1'
else
remember_me(user)
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index f863c1e5093..aa8bea1bd83 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1712,8 +1712,6 @@ class MergeRequest < ApplicationRecord
actual_head_pipeline&.complete_and_has_reports?(Ci::JobArtifact.of_report_type(:test))
end
- # rubocop: disable Metrics/AbcSize
- # Delete a rubocop annotation once FF truncate_ci_merge_request_description is cleaned up
def predefined_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'CI_MERGE_REQUEST_ID', value: id.to_s)
@@ -1726,14 +1724,9 @@ class MergeRequest < ApplicationRecord
variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED', value: ProtectedBranch.protected?(target_project, target_branch).to_s)
variables.append(key: 'CI_MERGE_REQUEST_TITLE', value: title)
- if ::Feature.enabled?(:truncate_ci_merge_request_description)
- mr_description, mr_description_truncated = truncate_mr_description
- variables.append(key: 'CI_MERGE_REQUEST_DESCRIPTION', value: mr_description)
- variables.append(key: 'CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED', value: mr_description_truncated)
- else
- variables.append(key: 'CI_MERGE_REQUEST_DESCRIPTION', value: description)
- end
-
+ mr_description, mr_description_truncated = truncate_mr_description
+ variables.append(key: 'CI_MERGE_REQUEST_DESCRIPTION', value: mr_description)
+ variables.append(key: 'CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED', value: mr_description_truncated)
variables.append(key: 'CI_MERGE_REQUEST_ASSIGNEES', value: assignee_username_list) if assignees.present?
variables.append(key: 'CI_MERGE_REQUEST_MILESTONE', value: milestone.title) if milestone
variables.append(key: 'CI_MERGE_REQUEST_LABELS', value: label_names.join(',')) if labels.present?
@@ -1741,8 +1734,6 @@ class MergeRequest < ApplicationRecord
variables.concat(source_project_variables)
end
end
- # rubocop: enable Metrics/AbcSize
- # Delete a rubocop annotation once FF truncate_ci_merge_request_description is cleaned up
def compare_test_reports
unless has_test_reports?
diff --git a/app/models/organizations/organization.rb b/app/models/organizations/organization.rb
index 4a30cfc8f0e..be96939daa8 100644
--- a/app/models/organizations/organization.rb
+++ b/app/models/organizations/organization.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Organizations
- class Organization < ApplicationRecord
+ class Organization < MainClusterwide::ApplicationRecord
DEFAULT_ORGANIZATION_ID = 1
scope :without_default, -> { where.not(id: DEFAULT_ORGANIZATION_ID) }
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 5ba58ecb974..be559b30ce9 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -4,14 +4,14 @@
.omniauth-divider.gl-display-flex.gl-align-items-center
= _("or sign in with")
-.gl-mt-5.gl-px-5.omniauth-container.gl-text-center.gl-ml-auto.gl-mr-auto
+.gl-mt-5.gl-px-5.omniauth-container.gl-text-center.gl-display-flex.gl-flex-direction-column.gl-gap-3
- enabled_button_based_providers.each do |provider|
- - has_icon = provider_has_icon?(provider)
- = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", data: { testid: "#{test_id_for_provider(provider)}" }, class: "btn gl-button btn-default gl-mb-2 js-oauth-login gl-w-full", form: { class: 'gl-mb-3' } do
- - if has_icon
- = provider_image_tag(provider)
- %span.gl-button-text
- = label_for_provider(provider)
+ = render 'devise/shared/omniauth_provider_button',
+ href: omniauth_authorize_path(:user, provider),
+ provider: provider,
+ classes: 'js-oauth-login',
+ data: { testid: test_id_for_provider(provider) },
+ id: "oauth-login-#{provider}"
- if render_remember_me
= render Pajamas::CheckboxTagComponent.new(name: 'remember_me_omniauth', value: nil) do |c|
- c.with_label do
diff --git a/app/views/devise/shared/_omniauth_provider_button.haml b/app/views/devise/shared/_omniauth_provider_button.haml
new file mode 100644
index 00000000000..e92b41a6254
--- /dev/null
+++ b/app/views/devise/shared/_omniauth_provider_button.haml
@@ -0,0 +1,7 @@
+- button_options = { class: classes, data: data, id: id }
+
+= render Pajamas::ButtonComponent.new(href: href, method: :post, form: true, block: true, button_options: button_options) do
+ - if provider_has_icon?(provider)
+ = provider_image_tag(provider)
+ %span.gl-button-text
+ = label_for_provider(provider)
diff --git a/app/views/devise/shared/_signup_omniauth_provider_button.haml b/app/views/devise/shared/_signup_omniauth_provider_button.haml
index e280259ca49..9870e90cfff 100644
--- a/app/views/devise/shared/_signup_omniauth_provider_button.haml
+++ b/app/views/devise/shared/_signup_omniauth_provider_button.haml
@@ -1,8 +1,6 @@
-- data = { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label }
-- button_options = { class: 'js-track-omni-auth', data: data, id: "oauth-login-#{provider}" }
-
-= render Pajamas::ButtonComponent.new(href: href, method: :post, form: true, block: true, button_options: button_options) do
- - if provider_has_icon?(provider)
- = provider_image_tag(provider)
- %span.gl-button-text
- = label_for_provider(provider)
+= render 'devise/shared/omniauth_provider_button',
+ href: href,
+ provider: provider,
+ classes: 'js-track-omni-auth',
+ data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label },
+ id: "oauth-login-#{provider}"
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index 6dcd661ecdb..3f18a7bbda6 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -24,7 +24,7 @@
= sprite_icon('mail', css_class: 'gl-mr-2')
= @emails.load.size
.gl-new-card-actions
- = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content", data: { testid: 'toggle_email_address_field' } }) do
+ = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content", data: { testid: 'toggle-email-address-field' } }) do
= s_('Profiles|Add new email')
- c.with_body do
.gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content
@@ -33,9 +33,9 @@
= gitlab_ui_form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, s_('Profiles|Email address'), class: 'label-bold'
- = f.text_field :email, class: 'form-control gl-form-input gl-form-input-xl', data: { qa_selector: 'email_address_field' }
+ = f.text_field :email, class: 'form-control gl-form-input gl-form-input-xl', data: { testid: 'email-address-field' }
.gl-mt-3
- = f.submit s_('Profiles|Add email address'), data: { qa_selector: 'add_email_address_button' }, pajamas_button: true
+ = f.submit s_('Profiles|Add email address'), data: { testid: 'add-email-address-button' }, pajamas_button: true
= render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do
= _('Cancel')
- if @emails.any?
@@ -59,7 +59,7 @@
= s_('Profiles|Default notification email')
.gl-text-secondary.gl-font-sm= notification_message.html_safe
- @emails.reject(&:user_primary_email?).each do |email|
- %li{ class: 'gl-px-5!', data: { qa_selector: 'email_row_content' } }
+ %li{ class: 'gl-px-5!', data: { testid: 'email-row-content' } }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-gap-3
%div
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
@@ -81,4 +81,4 @@
- confirm_title = "#{email.confirmation_sent_at ? s_('Profiles|Resend confirmation email') : s_('Profiles|Send confirmation email')}"
= link_button_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, size: :small
- = link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), confirm_btn_variant: 'danger', qa_selector: 'delete_email_link'}, method: :delete, size: :small, icon: 'remove', 'aria-label': _('Remove')
+ = link_button_to nil, profile_email_path(email), data: { confirm: _('Are you sure?'), confirm_btn_variant: 'danger', testid: 'delete-email-link'}, method: :delete, size: :small, icon: 'remove', 'aria-label': _('Remove')
diff --git a/app/views/profiles/gpg_keys/_key_table.html.haml b/app/views/profiles/gpg_keys/_key_table.html.haml
index 0a50ce55b50..ea7068e0484 100644
--- a/app/views/profiles/gpg_keys/_key_table.html.haml
+++ b/app/views/profiles/gpg_keys/_key_table.html.haml
@@ -3,7 +3,7 @@
- if @gpg_keys.any?
.table-holder
- %table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list{ data: { qa_selector: 'ssh_keys_list' } }
+ %table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list
%thead.d-none.d-md-table-header-group
%tr
%th= s_('Profiles|Key')
diff --git a/app/views/user_settings/passwords/edit.html.haml b/app/views/user_settings/passwords/edit.html.haml
index afe6ee2c0b3..179f54ac45e 100644
--- a/app/views/user_settings/passwords/edit.html.haml
+++ b/app/views/user_settings/passwords/edit.html.haml
@@ -18,18 +18,18 @@
- unless @user.password_automatically_set?
.form-group
= f.label :password, _('Current password'), class: 'label-bold'
- = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'current_password_field' }
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input gl-max-w-80', data: { testid: 'current-password-field' }
%p.form-text.text-muted
= _('You must provide your current password in order to change it.')
.form-group
= f.label :new_password, _('New password'), class: 'label-bold'
- = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-max-w-80', data: { qa_selector: 'new_password_field' }
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-max-w-80', data: { testid: 'new-password-field' }
= render_if_exists 'shared/password_requirements_list'
.form-group
= f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
- = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-80', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-80', data: { testid: 'confirm-password-field' }
.gl-mt-3.gl-mb-3
- = f.submit _('Save password'), class: "gl-mr-3", data: { qa_selector: 'save_password_button' }, pajamas_button: true
+ = f.submit _('Save password'), class: "gl-mr-3", data: { testid: 'save-password-button' }, pajamas_button: true
- unless @user.password_automatically_set?
= render Pajamas::ButtonComponent.new(href: reset_user_settings_password_path, variant: :link, method: :put) do
= _('I forgot my password')
diff --git a/app/views/user_settings/passwords/new.html.haml b/app/views/user_settings/passwords/new.html.haml
index 3616c9ec252..4b47dfa3e83 100644
--- a/app/views/user_settings/passwords/new.html.haml
+++ b/app/views/user_settings/passwords/new.html.haml
@@ -16,17 +16,17 @@
.col-sm-2.col-form-label
= f.label :password, _('Current password')
.col-sm-10
- = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { testid: 'current-password-field' }
.form-group.row
.col-sm-2.col-form-label
= f.label :new_password, _('New password')
.col-sm-10
- = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { qa_selector: 'new_password_field' }
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { testid: 'new-password-field' }
= render_if_exists 'shared/password_requirements_list'
.form-group.row
.col-sm-2.col-form-label
= f.label :password_confirmation, _('Password confirmation')
.col-sm-10
- = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { testid: 'confirm-password-field' }
.form-actions
- = f.submit _('Set new password'), data: { qa_selector: 'set_new_password_button' }, pajamas_button: true
+ = f.submit _('Set new password'), data: { testid: 'set-new-password-button' }, pajamas_button: true
diff --git a/config/feature_flags/development/truncate_ci_merge_request_description.yml b/config/feature_flags/development/truncate_ci_merge_request_description.yml
deleted file mode 100644
index 816632f0da2..00000000000
--- a/config/feature_flags/development/truncate_ci_merge_request_description.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: truncate_ci_merge_request_description
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139605
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435099
-milestone: '16.7'
-type: development
-group: group::pipeline security
-default_enabled: false \ No newline at end of file
diff --git a/db/docs/batched_background_migrations/backfill_vs_code_settings_uuid.yml b/db/docs/batched_background_migrations/backfill_vs_code_settings_uuid.yml
index 022752a06a7..fc793594203 100644
--- a/db/docs/batched_background_migrations/backfill_vs_code_settings_uuid.yml
+++ b/db/docs/batched_background_migrations/backfill_vs_code_settings_uuid.yml
@@ -5,5 +5,5 @@ feature_category: web_ide
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138355
milestone: '16.7'
queued_migration_version: 20231130140901
-finalize_after: '2023-12-17'
+finalize_after: '2023-01-31'
finalized_by: # version of the migration that finalized this BBM
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 56fd41b43fc..57a33473b19 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -24256,8 +24256,8 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectcicdsettings"></a>`ciCdSettings` | [`ProjectCiCdSetting`](#projectcicdsetting) | CI/CD settings for the project. |
| <a id="projectciconfigpathordefault"></a>`ciConfigPathOrDefault` | [`String!`](#string) | Path of the CI configuration file. |
| <a id="projectcijobtokenscope"></a>`ciJobTokenScope` | [`CiJobTokenScopeType`](#cijobtokenscopetype) | The CI Job Tokens scope of access. |
-| <a id="projectcisubscribedprojects"></a>`ciSubscribedProjects` | [`CiSubscriptionsProjectConnection`](#cisubscriptionsprojectconnection) | Triggers a new pipeline in the downstream project when a pipeline successfullycompletes on the(upstream) project. (see [Connections](#connections)) |
-| <a id="projectcisubscriptionsprojects"></a>`ciSubscriptionsProjects` | [`CiSubscriptionsProjectConnection`](#cisubscriptionsprojectconnection) | Triggers a new pipeline in the(downstream) project when a pipeline successfullycompletes on the upstream project. (see [Connections](#connections)) |
+| <a id="projectcisubscribedprojects"></a>`ciSubscribedProjects` | [`CiSubscriptionsProjectConnection`](#cisubscriptionsprojectconnection) | Pipeline subscriptions for projects subscribed to the project. (see [Connections](#connections)) |
+| <a id="projectcisubscriptionsprojects"></a>`ciSubscriptionsProjects` | [`CiSubscriptionsProjectConnection`](#cisubscriptionsprojectconnection) | Pipeline subscriptions for the project. (see [Connections](#connections)) |
| <a id="projectcodecoveragesummary"></a>`codeCoverageSummary` | [`CodeCoverageSummary`](#codecoveragesummary) | Code coverage summary associated with the project. |
| <a id="projectcomplianceframeworks"></a>`complianceFrameworks` | [`ComplianceFrameworkConnection`](#complianceframeworkconnection) | Compliance frameworks associated with the project. (see [Connections](#connections)) |
| <a id="projectcontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | Container expiration policy of the project. |
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index e8ed47cedd0..7c62e133958 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -165,7 +165,8 @@ These variables are available when:
| `CI_MERGE_REQUEST_DIFF_ID` | 13.7 | all | The version of the merge request diff. |
| `CI_MERGE_REQUEST_EVENT_TYPE` | 12.3 | all | The event type of the merge request. Can be `detached`, `merged_result` or `merge_train`. |
| `CI_MERGE_REQUEST_ID` | 11.6 | all | The instance-level ID of the merge request. This is a unique ID across all projects on the GitLab instance. |
-| `CI_MERGE_REQUEST_DESCRIPTION` | 16.7 | all | The description of the merge request. |
+| `CI_MERGE_REQUEST_DESCRIPTION` | 16.7 | all | The description of the merge request. If the description is more than 2700 characters long, only the first 2700 characters are stored in the variable. |
+| `CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED` | 16.8 | all | `true` if `CI_MERGE_REQUEST_DESCRIPTION` is truncated down to 2700 characters because the description of the merge request is too long. |
| `CI_MERGE_REQUEST_IID` | 11.6 | all | The project-level IID (internal ID) of the merge request. This ID is unique for the current project, and is the number used in the merge request URL, page title, and other visible locations. |
| `CI_MERGE_REQUEST_LABELS` | 11.9 | all | Comma-separated label names of the merge request. |
| `CI_MERGE_REQUEST_MILESTONE` | 11.9 | all | The milestone title of the merge request. |
diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md
index 0594f3fe2ee..e489f19585c 100644
--- a/doc/user/project/requirements/index.md
+++ b/doc/user/project/requirements/index.md
@@ -50,7 +50,7 @@ To create a requirement:
1. In a project, go to **Plan > Requirements**.
1. Select **New requirement**.
-1. Enter a title and description and select **Create requirement**.
+1. Enter a title and description and select **New requirement**.
![requirement create view](img/requirement_create_v13_5.png)
@@ -240,7 +240,8 @@ To import requirements:
1. In a project, go to **Plan > Requirements**.
- For a project with requirements, in the
- upper-right corner, select the import icon (**{import}**).
+ upper-right corner, select the vertical ellipsis (**{ellipsis_v}**),
+ then select **Import requirements** (**{import}**).
- For a project without requirements, in the middle of the page, select **Import CSV**.
1. Select the file and select **Import requirements**.
@@ -300,7 +301,8 @@ Prerequisites:
To export requirements:
1. In a project, go to **Plan > Requirements**.
-1. In the upper-right corner, select **Export as CSV** (**{export}**).
+1. In the upper-right corner, select the vertical ellipsis (**{ellipsis_v}**),
+ then select **Export as CSV** (**{export}**).
A confirmation modal appears.
diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
index dd0802c14f6..467d4629010 100644
--- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.72.0'
+ DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.76.0'
.dast-auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 37e77c3ed25..0744a5a6321 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.72.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.76.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
index 813a94dde08..b3e44dbf4be 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.72.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.76.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk
index b3443049875..f55b10e62d9 100644
--- a/qa/gdk/Dockerfile.gdk
+++ b/qa/gdk/Dockerfile.gdk
@@ -5,7 +5,7 @@ ENV GITLAB_LICENSE_MODE=test \
# Clone GDK at specific sha and bootstrap packages
#
-ARG GDK_SHA=221d3cc81d3ffc17beb178fd5021cd0d93ca55b6
+ARG GDK_SHA=88c3231079278a49ba59d37362357e5908fb7179
RUN set -eux; \
git clone --depth 1 https://gitlab.com/gitlab-org/gitlab-development-kit.git && cd gitlab-development-kit; \
git fetch --depth 1 origin ${GDK_SHA} && git -c advice.detachedHead=false checkout ${GDK_SHA}; \
diff --git a/qa/qa/page/profile/emails.rb b/qa/qa/page/profile/emails.rb
index 1e6b7518e55..f9340445276 100644
--- a/qa/qa/page/profile/emails.rb
+++ b/qa/qa/page/profile/emails.rb
@@ -7,27 +7,27 @@ module QA
include QA::Page::Component::ConfirmModal
view 'app/views/profiles/emails/index.html.haml' do
- element :email_address_field
- element :add_email_address_button
- element :email_row_content
- element :delete_email_link
- element :toggle_email_address_field
+ element 'email-address-field'
+ element 'add-email-address-button'
+ element 'email-row-content'
+ element 'delete-email-link'
+ element 'toggle-email-address-field'
end
def expand_email_input
- click_element(:toggle_email_address_field) if has_no_element?(:email_address_field)
- has_element?(:email_address_field)
+ click_element('toggle-email-address-field') if has_no_element?('email-address-field')
+ has_element?('email-address-field')
end
def add_email_address(email_address)
expand_email_input
- find_element(:email_address_field).set email_address
- click_element(:add_email_address_button)
+ find_element('email-address-field').set email_address
+ click_element('add-email-address-button')
end
def delete_email_address(email_address)
- within_element(:email_row_content, text: email_address) do
- click_element(:delete_email_link)
+ within_element('email-row-content', text: email_address) do
+ click_element('delete-email-link')
end
click_confirmation_ok_button
end
diff --git a/qa/qa/page/profile/password.rb b/qa/qa/page/profile/password.rb
index 5f07cdb6f25..d70dcbabd49 100644
--- a/qa/qa/page/profile/password.rb
+++ b/qa/qa/page/profile/password.rb
@@ -5,31 +5,31 @@ module QA
module Profile
class Password < Page::Base
view 'app/views/user_settings/passwords/edit.html.haml' do
- element :current_password_field
- element :new_password_field
- element :confirm_password_field
- element :save_password_button
+ element 'current-password-field'
+ element 'new-password-field'
+ element 'confirm-password-field'
+ element 'save-password-button'
end
view 'app/views/user_settings/passwords/new.html.haml' do
- element :current_password_field
- element :new_password_field
- element :confirm_password_field
- element :set_new_password_button
+ element 'current-password-field'
+ element 'new-password-field'
+ element 'confirm-password-field'
+ element 'set-new-password-button'
end
def update_password(new_password, current_password)
- find_element(:current_password_field).set current_password
- find_element(:new_password_field).set new_password
- find_element(:confirm_password_field).set new_password
- click_element(:save_password_button)
+ find_element('current-password-field').set current_password
+ find_element('new-password-field').set new_password
+ find_element('confirm-password-field').set new_password
+ click_element('save-password-button')
end
def set_new_password(new_password, current_password)
- fill_element :current_password_field, current_password
- fill_element :new_password_field, new_password
- fill_element :confirm_password_field, new_password
- click_element :set_new_password_button
+ fill_element('current-password-field', current_password)
+ fill_element('new-password-field', new_password)
+ fill_element('confirm-password-field', new_password)
+ click_element('set-new-password-button')
end
end
end
diff --git a/scripts/setup/generate-as-if-foss-env.rb b/scripts/setup/generate-as-if-foss-env.rb
index 68b869287a6..ee688e4f1d0 100755
--- a/scripts/setup/generate-as-if-foss-env.rb
+++ b/scripts/setup/generate-as-if-foss-env.rb
@@ -1,22 +1,79 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
-require 'gitlab'
+# In spec/scripts/setup/generate_as_if_foss_env_spec.rb we completely stub it
+require 'gitlab' unless Object.const_defined?(:Gitlab)
require 'set'
-client = Gitlab.client(endpoint: ENV['CI_API_V4_URL'], private_token: '')
+class GenerateAsIfFossEnv
+ def initialize
+ @client = Gitlab.client(endpoint: ENV['CI_API_V4_URL'], private_token: '')
+ @rspec_jobs = Set.new
+ @jest_jobs = Set.new
+ end
-rspec_jobs = Set.new
+ def variables
+ @variables ||= generate_variables
+ end
-client.pipeline_jobs(ENV['CI_PROJECT_ID'], ENV['CI_PIPELINE_ID']).auto_paginate do |job|
- rspec_type = job.name[/^rspec ([\w\-]+)/, 1]
+ def display
+ variables.each do |key, value|
+ puts "#{key}=#{value}"
+ end
+ end
- rspec_jobs << rspec_type if rspec_type
-end
+ private
+
+ attr_reader :client, :rspec_jobs, :jest_jobs
+
+ def generate_variables
+ scan_jobs
+
+ {
+ START_AS_IF_FOSS: 'true',
+ RUBY_VERSION: ENV['RUBY_VERSION']
+ }.merge(rspec_variables).merge(jest_variables)
+ end
+
+ def scan_jobs
+ each_job do |job|
+ detect_rspec(job) || detect_jest(job)
+ end
+ end
+
+ def each_job
+ client.pipeline_jobs(ENV['CI_PROJECT_ID'], ENV['CI_PIPELINE_ID']).auto_paginate do |job|
+ yield(job)
+ end
+ end
+
+ def detect_rspec(job)
+ rspec_type = job.name[/^rspec ([\w\-]+)/, 1]
-puts 'START_AS_IF_FOSS=true', "RUBY_VERSION=#{ENV['RUBY_VERSION']}"
-puts 'ENABLE_RSPEC=true' if rspec_jobs.any?
+ rspec_jobs << rspec_type if rspec_type
+ end
-rspec_jobs.each do |rspec|
- puts "ENABLE_RSPEC_#{rspec.upcase.tr('-', '_')}=true"
+ def detect_jest(job)
+ jest_type = job.name[/^jest([\w\-]*)/, 1]
+
+ jest_jobs << jest_type if jest_type
+ end
+
+ def rspec_variables
+ return {} if rspec_jobs.empty?
+
+ rspec_jobs.inject({ ENABLE_RSPEC: 'true' }) do |result, rspec|
+ result.merge("ENABLE_RSPEC_#{rspec.upcase.tr('-', '_')}": 'true')
+ end
+ end
+
+ def jest_variables
+ return {} if jest_jobs.empty?
+
+ jest_jobs.inject({ ENABLE_JEST: 'true' }) do |result, jest|
+ result.merge("ENABLE_JEST#{jest.upcase.tr('-', '_')}": 'true')
+ end
+ end
end
+
+GenerateAsIfFossEnv.new.display if $PROGRAM_NAME == __FILE__
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 5b1fdd6388a..e99d9e949a8 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -31,6 +31,67 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
end
end
+ shared_examples 'omniauth sign in that remembers user' do
+ before do
+ stub_omniauth_setting(allow_bypass_two_factor: allow_bypass_two_factor)
+ (request.env['omniauth.params'] ||= {}).deep_merge!('remember_me' => omniauth_params_remember_me)
+ end
+
+ if params[:call_remember_me]
+ it 'calls devise method remember_me' do
+ expect(controller).to receive(:remember_me).with(user).and_call_original
+
+ post_action
+ end
+ else
+ it 'does not calls devise method remember_me' do
+ expect(controller).not_to receive(:remember_me)
+
+ post_action
+ end
+ end
+ end
+
+ shared_examples 'omniauth sign in that remembers user with two factor enabled' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:post_action) { post provider }
+
+ where(:allow_bypass_two_factor, :omniauth_params_remember_me, :call_remember_me) do
+ true | '1' | true
+ true | '0' | false
+ true | nil | false
+ false | '1' | false
+ false | '0' | false
+ false | nil | false
+ end
+
+ with_them do
+ it_behaves_like 'omniauth sign in that remembers user'
+ end
+ end
+
+ shared_examples 'omniauth sign in that remembers user with two factor disabled' do
+ context "when user selects remember me for omniauth sign in flow" do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:post_action) { post provider }
+
+ where(:allow_bypass_two_factor, :omniauth_params_remember_me, :call_remember_me) do
+ true | '1' | true
+ true | '0' | false
+ true | nil | false
+ false | '1' | true
+ false | '0' | false
+ false | nil | false
+ end
+
+ with_them do
+ it_behaves_like 'omniauth sign in that remembers user'
+ end
+ end
+ end
+
describe 'omniauth' do
let(:user) { create(:omniauth_user, extern_uid: extern_uid, provider: provider) }
let(:additional_info) { {} }
@@ -190,6 +251,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
request.env['omniauth.params'] = { 'redirect_fragment' => 'L101' }
end
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled'
+
context 'when a redirect url is stored' do
it 'redirects with fragment' do
post provider, session: { user_return_to: '/fake/url' }
@@ -214,6 +277,12 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
expect(response.location).not_to include('#L101')
end
end
+
+ context 'when a user has 2FA enabled' do
+ let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) }
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled'
+ end
end
context 'with strategies' do
@@ -271,6 +340,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
end
end
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled'
+
context 'when a user has 2FA enabled' do
render_views
@@ -296,6 +367,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
expect(response).to have_gitlab_http_status(:ok)
end
end
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled'
end
context 'for sign up' do
@@ -357,6 +430,10 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
let(:extern_uid) { '' }
let(:provider) { :auth0 }
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled' do
+ let(:extern_uid) { 'my-uid' }
+ end
+
it 'does not allow sign in without extern_uid' do
post 'auth0'
@@ -364,6 +441,14 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
expect(response).to have_gitlab_http_status(:found)
expect(controller).to set_flash[:alert].to('Wrong extern UID provided. Make sure Auth0 is configured correctly.')
end
+
+ context 'when a user has 2FA enabled' do
+ let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) }
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled' do
+ let(:extern_uid) { 'my-uid' }
+ end
+ end
end
context 'for atlassian_oauth2' do
@@ -373,6 +458,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
context 'when the user and identity already exist' do
let(:user) { create(:atlassian_user, extern_uid: extern_uid) }
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled'
+
it 'allows sign-in' do
post :atlassian_oauth2
@@ -391,6 +478,12 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
post :atlassian_oauth2
end
+
+ context 'when a user has 2FA enabled' do
+ let(:user) { create(:atlassian_user, :two_factor, extern_uid: extern_uid) }
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled'
+ end
end
context 'for a new user' do
@@ -443,11 +536,21 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
include_context 'with sign_up'
let(:additional_info) { { extra: { email_verified: true } } }
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled' do
+ let(:user) { create(:omniauth_user, extern_uid: extern_uid, provider: provider) }
+ end
+
it 'allows sign in' do
post 'salesforce'
expect(request.env['warden']).to be_authenticated
end
+
+ context 'when a user has 2FA enabled' do
+ let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) }
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled'
+ end
end
end
end
@@ -497,11 +600,19 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
let(:post_action) { post provider }
end
+ it_behaves_like 'omniauth sign in that remembers user with two factor disabled'
+
it 'allows sign in' do
post provider
expect(request.env['warden']).to be_authenticated
end
+
+ context 'when a user has 2FA enabled' do
+ let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) }
+
+ it_behaves_like 'omniauth sign in that remembers user with two factor enabled'
+ end
end
describe '#saml' do
diff --git a/spec/features/admin/users/user_impersonation_spec.rb b/spec/features/admin/users/admin_impersonates_user_spec.rb
index 215afc40d80..44b67abcc80 100644
--- a/spec/features/admin/users/user_impersonation_spec.rb
+++ b/spec/features/admin/users/admin_impersonates_user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::Users::UserImpersonation', feature_category: :user_management do
+RSpec.describe 'Admin impersonates user', feature_category: :user_management do
let_it_be(:user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
let_it_be(:current_user) { create(:admin) }
diff --git a/spec/features/admin/users/user_identities_spec.rb b/spec/features/admin/users/admin_manages_user_identities_spec.rb
index 6db94750761..42d0c2e9ab8 100644
--- a/spec/features/admin/users/user_identities_spec.rb
+++ b/spec/features/admin/users/admin_manages_user_identities_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin::Users::UserIdentities', feature_category: :user_management do
+RSpec.describe 'Admin manages user identities', feature_category: :user_management do
let_it_be(:user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
let_it_be(:current_user) { create(:admin) }
diff --git a/spec/features/admin/users/admin_sees_unconfirmed_user_spec.rb b/spec/features/admin/users/admin_sees_unconfirmed_user_spec.rb
new file mode 100644
index 00000000000..7b45e5b5cde
--- /dev/null
+++ b/spec/features/admin/users/admin_sees_unconfirmed_user_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Admin sees unconfirmed user', feature_category: :user_management do
+ include Spec::Support::Helpers::ModalHelpers
+
+ let_it_be(:user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
+ let_it_be(:current_user) { create(:admin) }
+
+ before do
+ sign_in(current_user)
+ enable_admin_mode!(current_user, use_ui: true)
+ end
+
+ context 'when user has an unconfirmed email', :js do
+ # Email address contains HTML to ensure email address is displayed in an HTML safe way.
+ let_it_be(:unconfirmed_email) { "#{generate(:email)}<h2>testing<img/src=http://localhost:8000/test.png>" }
+ let_it_be(:unconfirmed_user) { create(:user, :unconfirmed, unconfirmed_email: unconfirmed_email) }
+
+ where(:path_helper) do
+ [
+ [-> (user) { admin_user_path(user) }],
+ [-> (user) { projects_admin_user_path(user) }],
+ [-> (user) { keys_admin_user_path(user) }],
+ [-> (user) { admin_user_identities_path(user) }],
+ [-> (user) { admin_user_impersonation_tokens_path(user) }]
+ ]
+ end
+
+ with_them do
+ it "allows an admin to force confirmation of the user's email", :aggregate_failures do
+ visit path_helper.call(unconfirmed_user)
+
+ click_button 'Confirm user'
+
+ within_modal do
+ expect(page).to have_content("Confirm user #{unconfirmed_user.name}?")
+ expect(page).to(
+ have_content(
+ "This user has an unconfirmed email address (#{unconfirmed_email}). You may force a confirmation.")
+ )
+
+ click_button 'Confirm user'
+ end
+
+ expect(page).to have_content('Successfully confirmed')
+ expect(page).not_to have_button('Confirm user')
+ end
+ end
+ end
+end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/admin_sees_user_spec.rb
index b7e7a037ffc..d8c142d402f 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/admin_sees_user_spec.rb
@@ -193,34 +193,6 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do
end
end
- describe 'show user identities' do
- it 'shows user identities', :aggregate_failures do
- visit admin_user_identities_path(user)
-
- expect(page).to have_content(user.name)
- expect(page).to have_content('twitter')
- end
- end
-
- describe 'update user identities' do
- before do
- allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated])
- end
-
- it 'modifies twitter identity', :aggregate_failures do
- visit admin_user_identities_path(user)
-
- find('.table').find(:link, 'Edit').click
- fill_in 'identity_extern_uid', with: '654321'
- select 'twitter_updated', from: 'identity_provider'
- click_button 'Save changes'
-
- expect(page).to have_content(user.name)
- expect(page).to have_content('twitter_updated')
- expect(page).to have_content('654321')
- end
- end
-
describe 'remove users secondary email', :js do
let_it_be(:secondary_email) do
create :email, email: 'secondary@example.com', user: user
@@ -237,17 +209,6 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do
end
end
- describe 'remove user with identities' do
- it 'removes user with twitter identity', :aggregate_failures do
- visit admin_user_identities_path(user)
-
- click_link 'Delete'
-
- expect(page).to have_content(user.name)
- expect(page).not_to have_content('twitter')
- end
- end
-
describe 'show user keys', :js do
it do
key1 = create(:key, user: user, title: 'ssh-rsa Key1')
@@ -284,40 +245,4 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do
end
end
end
-
- context 'when user has an unconfirmed email', :js do
- # Email address contains HTML to ensure email address is displayed in an HTML safe way.
- let_it_be(:unconfirmed_email) { "#{generate(:email)}<h2>testing<img/src=http://localhost:8000/test.png>" }
- let_it_be(:unconfirmed_user) { create(:user, :unconfirmed, unconfirmed_email: unconfirmed_email) }
-
- where(:path_helper) do
- [
- [-> (user) { admin_user_path(user) }],
- [-> (user) { projects_admin_user_path(user) }],
- [-> (user) { keys_admin_user_path(user) }],
- [-> (user) { admin_user_identities_path(user) }],
- [-> (user) { admin_user_impersonation_tokens_path(user) }]
- ]
- end
-
- with_them do
- it "allows an admin to force confirmation of the user's email", :aggregate_failures do
- visit path_helper.call(unconfirmed_user)
-
- click_button 'Confirm user'
-
- within_modal do
- expect(page).to have_content("Confirm user #{unconfirmed_user.name}?")
- expect(page).to have_content(
- "This user has an unconfirmed email address (#{unconfirmed_email}). You may force a confirmation."
- )
-
- click_button 'Confirm user'
- end
-
- expect(page).to have_content('Successfully confirmed')
- expect(page).not_to have_button('Confirm user')
- end
- end
- end
end
diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb
index 2ab0e63d840..8bd97566acf 100644
--- a/spec/features/projects/members/manage_members_spec.rb
+++ b/spec/features/projects/members/manage_members_spec.rb
@@ -118,7 +118,7 @@ RSpec.describe 'Projects > Members > Manage members', :js, feature_category: :on
context 'when maintainer' do
let(:current_user) { project_maintainer }
- it 'does not show the Owner option' do
+ it 'does not show the Owner option', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/436958' do
within_modal do
toggle_listbox
expect_listbox_items(%w[Guest Reporter Developer Maintainer])
diff --git a/spec/frontend/work_items/components/work_item_with_title_edit_spec.js b/spec/frontend/work_items/components/work_item_title_with_edit_spec.js
index db9551b6ec3..7868e241821 100644
--- a/spec/frontend/work_items/components/work_item_with_title_edit_spec.js
+++ b/spec/frontend/work_items/components/work_item_title_with_edit_spec.js
@@ -51,7 +51,7 @@ describe('Work Item title with edit', () => {
});
it('emits `updateDraft` event on change of the input', () => {
- findEditableTitleInput().vm.$emit('change', 'updated title');
+ findEditableTitleInput().vm.$emit('input', 'updated title');
expect(wrapper.emitted('updateDraft')).toEqual([['updated title']]);
});
diff --git a/spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb b/spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb
index f8d67a6f0b4..18ad723b75c 100644
--- a/spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb
+++ b/spec/lib/gitlab/ci/variables/builder/pipeline_spec.rb
@@ -152,51 +152,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder::Pipeline, feature_category: :secr
end
end
- context 'when truncate_ci_merge_request_description feature flag is disabled' do
- before do
- stub_feature_flags(truncate_ci_merge_request_description: false)
- end
-
- context 'when merge request description hits the limit' do
- let(:merge_request_description) { 'a' * (MergeRequest::CI_MERGE_REQUEST_DESCRIPTION_MAX_LENGTH + 1) }
-
- it 'does not truncate the exposed description' do
- expect(subject.to_hash)
- .to include(
- 'CI_MERGE_REQUEST_DESCRIPTION' => merge_request.description
- )
- expect(subject.to_hash)
- .not_to have_key('CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED')
- end
- end
-
- context 'when merge request description fits the length limit' do
- let(:merge_request_description) { 'a' * (MergeRequest::CI_MERGE_REQUEST_DESCRIPTION_MAX_LENGTH - 1) }
-
- it 'does not truncate the exposed description' do
- expect(subject.to_hash)
- .to include(
- 'CI_MERGE_REQUEST_DESCRIPTION' => merge_request.description
- )
- expect(subject.to_hash)
- .not_to have_key('CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED')
- end
- end
-
- context 'when merge request description does not exist' do
- let(:merge_request_description) { nil }
-
- it 'does not truncate the exposed description' do
- expect(subject.to_hash)
- .to include(
- 'CI_MERGE_REQUEST_DESCRIPTION' => merge_request.description
- )
- expect(subject.to_hash)
- .not_to have_key('CI_MERGE_REQUEST_DESCRIPTION_IS_TRUNCATED')
- end
- end
- end
-
it 'exposes diff variables' do
expect(subject.to_hash)
.to include(
diff --git a/spec/scripts/setup/generate_as_if_foss_env_spec.rb b/spec/scripts/setup/generate_as_if_foss_env_spec.rb
new file mode 100644
index 00000000000..bd4c741ffad
--- /dev/null
+++ b/spec/scripts/setup/generate_as_if_foss_env_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'gitlab/rspec/stub_env'
+
+# NOTE: Under the context of fast_spec_helper, when we `require 'gitlab'`
+# we do not load the Gitlab client, but our own Gitlab module.
+# Keep this in mind and just stub anything which might touch it!
+require_relative '../../../scripts/setup/generate-as-if-foss-env'
+
+RSpec.describe GenerateAsIfFossEnv, feature_category: :tooling do
+ include StubENV
+
+ subject(:generate) { described_class.new }
+
+ before do
+ stub_env(RUBY_VERSION: '3.1')
+ end
+
+ shared_context 'when there are all jobs' do
+ let(:jobs) do
+ [
+ 'rspec fast_spec_helper',
+ 'rspec unit',
+ 'rspec integration',
+ 'rspec system',
+ 'rspec migration',
+ 'rspec background-migration',
+ 'jest',
+ 'jest-integration'
+ ]
+ end
+
+ before do
+ messages = receive_message_chain(:client, :pipeline_jobs, :auto_paginate)
+
+ yield_jobs = jobs.inject(messages) do |stub, job|
+ stub.and_yield(double(name: job)) # rubocop:disable RSpec/VerifiedDoubles -- As explained at the top of this file, we do not load the Gitlab client
+ end
+
+ allow(Gitlab).to yield_jobs
+ end
+ end
+
+ describe '#variables' do
+ include_context 'when there are all jobs'
+
+ it 'returns correct variables' do
+ expect(generate.variables).to eq({
+ START_AS_IF_FOSS: 'true',
+ RUBY_VERSION: ENV['RUBY_VERSION'],
+ ENABLE_RSPEC: 'true',
+ ENABLE_RSPEC_FAST_SPEC_HELPER: 'true',
+ ENABLE_RSPEC_UNIT: 'true',
+ ENABLE_RSPEC_INTEGRATION: 'true',
+ ENABLE_RSPEC_SYSTEM: 'true',
+ ENABLE_RSPEC_MIGRATION: 'true',
+ ENABLE_RSPEC_BACKGROUND_MIGRATION: 'true',
+ ENABLE_JEST: 'true',
+ ENABLE_JEST_INTEGRATION: 'true'
+ })
+ end
+ end
+
+ describe '#display' do
+ include_context 'when there are all jobs'
+
+ it 'puts correct variables' do
+ expect { generate.display }.to output(<<~ENV).to_stdout
+ START_AS_IF_FOSS=true
+ RUBY_VERSION=#{ENV['RUBY_VERSION']}
+ ENABLE_RSPEC=true
+ ENABLE_RSPEC_FAST_SPEC_HELPER=true
+ ENABLE_RSPEC_UNIT=true
+ ENABLE_RSPEC_INTEGRATION=true
+ ENABLE_RSPEC_SYSTEM=true
+ ENABLE_RSPEC_MIGRATION=true
+ ENABLE_RSPEC_BACKGROUND_MIGRATION=true
+ ENABLE_JEST=true
+ ENABLE_JEST_INTEGRATION=true
+ ENV
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/work_items_shared_examples.rb b/spec/support/shared_examples/features/work_items_shared_examples.rb
index a5b467da45d..049809f5edd 100644
--- a/spec/support/shared_examples/features/work_items_shared_examples.rb
+++ b/spec/support/shared_examples/features/work_items_shared_examples.rb
@@ -2,22 +2,45 @@
RSpec.shared_examples 'work items title' do
let(:title_selector) { '[data-testid="work-item-title"]' }
+ let(:title_with_edit_selector) { '[data-testid="work-item-title-with-edit"]' }
- before do
- stub_feature_flags(work_items_mvc_2: false)
+ context 'when the work_items_mvc_2 FF is disabled' do
+ before do
+ stub_feature_flags(work_items_mvc_2: false)
- page.refresh
- wait_for_all_requests
+ page.refresh
+ wait_for_all_requests
+ end
+
+ it 'successfully shows and changes the title of the work item' do
+ expect(work_item.reload.title).to eq work_item.title
+
+ find(title_selector).set("Work item title")
+ find(title_selector).native.send_keys(:return)
+ wait_for_requests
+
+ expect(work_item.reload.title).to eq 'Work item title'
+ end
end
- it 'successfully shows and changes the title of the work item' do
- expect(work_item.reload.title).to eq work_item.title
+ context 'when the work_items_mvc_2 FF is enabled' do
+ before do
+ stub_feature_flags(work_items_mvc_2: true)
- find(title_selector).set("Work item title")
- find(title_selector).native.send_keys(:return)
- wait_for_requests
+ page.refresh
+ wait_for_all_requests
+ end
- expect(work_item.reload.title).to eq 'Work item title'
+ it 'successfully shows and changes the title of the work item' do
+ expect(work_item.reload.title).to eq work_item.title
+
+ click_button 'Edit'
+ find(title_with_edit_selector).set("Work item title")
+ send_keys([:command, :enter])
+ wait_for_requests
+
+ expect(work_item.reload.title).to eq 'Work item title'
+ end
end
end