Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0cea0a8f44
commit
3a72ac7750
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
||||

|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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}; \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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]
|
||||
|
||||
rspec_jobs << rspec_type if rspec_type
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
puts 'START_AS_IF_FOSS=true', "RUBY_VERSION=#{ENV['RUBY_VERSION']}"
|
||||
puts 'ENABLE_RSPEC=true' if rspec_jobs.any?
|
||||
|
||||
rspec_jobs.each do |rspec|
|
||||
puts "ENABLE_RSPEC_#{rspec.upcase.tr('-', '_')}=true"
|
||||
end
|
||||
GenerateAsIfFossEnv.new.display if $PROGRAM_NAME == __FILE__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
||||
|
|
@ -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) }
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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']]);
|
||||
});
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue