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:
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml4
-rw-r--r--.gitlab/ci/setup.gitlab-ci.yml14
-rw-r--r--app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue12
-rw-r--r--app/assets/javascripts/frequent_items/components/frequent_items_list.vue2
-rw-r--r--app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue9
-rw-r--r--app/controllers/profiles/personal_access_tokens_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb13
-rw-r--r--app/finders/context_commits_finder.rb11
-rw-r--r--app/finders/groups/accepting_group_transfers_finder.rb34
-rw-r--r--app/models/ci/pipeline.rb12
-rw-r--r--app/models/ci/pipeline_artifact.rb5
-rw-r--r--app/models/ci/runner.rb6
-rw-r--r--app/models/commit_status.rb6
-rw-r--r--app/models/group_group_link.rb4
-rw-r--r--app/models/repository.rb12
-rw-r--r--app/serializers/access_token_entity_base.rb8
-rw-r--r--app/serializers/group_access_token_entity.rb2
-rw-r--r--app/serializers/impersonation_access_token_entity.rb2
-rw-r--r--app/serializers/personal_access_token_entity.rb2
-rw-r--r--app/serializers/project_access_token_entity.rb2
-rw-r--r--app/services/ci/pipeline_artifacts/coverage_report_service.rb8
-rw-r--r--app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb20
-rw-r--r--app/services/ci/runners/set_runner_associated_projects_service.rb68
-rw-r--r--app/services/ci/unlock_artifacts_service.rb17
-rw-r--r--app/services/concerns/ci/downstream_pipeline_helpers.rb3
-rw-r--r--app/services/merge_requests/refresh_service.rb1
-rw-r--r--app/views/projects/tags/new.html.haml20
-rw-r--r--config/feature_flags/development/ci_update_unlocked_pipeline_artifacts.yml (renamed from config/feature_flags/development/ci_read_stage_records.yml)8
-rw-r--r--config/feature_flags/development/include_groups_from_group_shares_in_group_transfer_locations.yml8
-rw-r--r--db/post_migrate/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb.rb33
-rw-r--r--db/schema_migrations/202209060744491
-rw-r--r--doc/development/documentation/styleguide/word_list.md16
-rw-r--r--doc/user/project/merge_requests/cherry_pick_changes.md26
-rw-r--r--lib/api/entities/personal_access_token_with_details.rb13
-rw-r--r--lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb.rb21
-rw-r--r--lib/gitlab/git/repository.rb18
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb15
-rw-r--r--locale/gitlab.pot3
-rw-r--r--scripts/utils.sh6
-rw-r--r--spec/controllers/profiles/personal_access_tokens_controller_spec.rb16
-rw-r--r--spec/features/tags/developer_creates_tag_spec.rb2
-rw-r--r--spec/finders/context_commits_finder_spec.rb26
-rw-r--r--spec/finders/groups/accepting_group_transfers_finder_spec.rb42
-rw-r--r--spec/frontend/__helpers__/shared_test_setup.js3
-rw-r--r--spec/frontend/add_context_commits_modal/components/review_tab_container_spec.js2
-rw-r--r--spec/frontend/alerts_settings/components/alerts_integrations_list_spec.js2
-rw-r--r--spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js4
-rw-r--r--spec/frontend/analytics/usage_trends/components/app_spec.js2
-rw-r--r--spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js4
-rw-r--r--spec/frontend/batch_comments/components/diff_file_drafts_spec.js4
-rw-r--r--spec/frontend/batch_comments/components/publish_dropdown_spec.js2
-rw-r--r--spec/frontend/branches/components/divergence_graph_spec.js4
-rw-r--r--spec/frontend/cascading_settings/components/lock_popovers_spec.js2
-rw-r--r--spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js2
-rw-r--r--spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js2
-rw-r--r--spec/frontend/clusters_list/components/install_agent_modal_spec.js2
-rw-r--r--spec/frontend/confidential_merge_request/components/dropdown_spec.js2
-rw-r--r--spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js4
-rw-r--r--spec/frontend/diffs/components/app_spec.js4
-rw-r--r--spec/frontend/diffs/components/compare_dropdown_layout_spec.js2
-rw-r--r--spec/frontend/diffs/components/diff_discussions_spec.js6
-rw-r--r--spec/frontend/diffs/components/diff_stats_spec.js2
-rw-r--r--spec/frontend/diffs/components/diff_view_spec.js2
-rw-r--r--spec/frontend/emoji/components/category_spec.js2
-rw-r--r--spec/frontend/error_tracking_settings/components/project_dropdown_spec.js2
-rw-r--r--spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js12
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_list_item_spec.js14
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_list_spec.js10
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js4
-rw-r--r--spec/frontend/incidents/components/incidents_list_spec.js4
-rw-r--r--spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js2
-rw-r--r--spec/frontend/integrations/edit/components/trigger_fields_spec.js2
-rw-r--r--spec/frontend/issuable/components/issue_assignees_spec.js2
-rw-r--r--spec/frontend/issues/new/components/title_suggestions_item_spec.js2
-rw-r--r--spec/frontend/issues/new/components/title_suggestions_spec.js2
-rw-r--r--spec/frontend/issues/related_merge_requests/components/related_merge_requests_spec.js4
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js6
-rw-r--r--spec/frontend/issues/show/components/incidents/incident_tabs_spec.js2
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js2
-rw-r--r--spec/frontend/issues/show/components/pinned_links_spec.js2
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js2
-rw-r--r--spec/frontend/jira_import/components/jira_import_form_spec.js2
-rw-r--r--spec/frontend/milestones/components/milestone_combobox_spec.js4
-rw-r--r--spec/frontend/notifications/components/custom_notifications_modal_spec.js2
-rw-r--r--spec/frontend/notifications/components/notifications_dropdown_spec.js3
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js2
-rw-r--r--spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js2
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_form_spec.js4
-rw-r--r--spec/frontend/pages/projects/graphs/code_coverage_spec.js2
-rw-r--r--spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js2
-rw-r--r--spec/frontend/pipeline_editor/components/file-tree/container_spec.js2
-rw-r--r--spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js2
-rw-r--r--spec/frontend/pipeline_new/components/refs_dropdown_spec.js2
-rw-r--r--spec/frontend/pipelines/components/dag/dag_spec.js2
-rw-r--r--spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js2
-rw-r--r--spec/frontend/pipelines/graph/graph_component_spec.js4
-rw-r--r--spec/frontend/pipelines/graph/linked_pipelines_column_spec.js2
-rw-r--r--spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js2
-rw-r--r--spec/frontend/pipelines/pipelines_actions_spec.js4
-rw-r--r--spec/frontend/pipelines/pipelines_artifacts_spec.js3
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js3
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_source_token_spec.js3
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_status_token_spec.js5
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js3
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js3
-rw-r--r--spec/frontend/popovers/components/popovers_spec.js4
-rw-r--r--spec/frontend/profile/preferences/components/profile_preferences_spec.js4
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js2
-rw-r--r--spec/frontend/projects/compare/components/app_spec.js2
-rw-r--r--spec/frontend/projects/compare/components/repo_dropdown_spec.js2
-rw-r--r--spec/frontend/projects/compare/components/revision_card_spec.js4
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js2
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_spec.js2
-rw-r--r--spec/frontend/projects/pipelines/charts/components/app_spec.js2
-rw-r--r--spec/frontend/projects/settings_service_desk/components/service_desk_template_dropdown_spec.js4
-rw-r--r--spec/frontend/ref/components/ref_selector_spec.js6
-rw-r--r--spec/frontend/releases/components/release_block_milestone_info_spec.js2
-rw-r--r--spec/frontend/reports/components/grouped_issues_list_spec.js2
-rw-r--r--spec/frontend/repository/components/blob_button_group_spec.js6
-rw-r--r--spec/frontend/repository/components/breadcrumbs_spec.js10
-rw-r--r--spec/frontend/repository/components/table/index_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_type_tabs_spec.js2
-rw-r--r--spec/frontend/search/sidebar/components/radio_filter_spec.js2
-rw-r--r--spec/frontend/search/sort/components/app_spec.js2
-rw-r--r--spec/frontend/sidebar/components/assignees/collapsed_assignee_list_spec.js2
-rw-r--r--spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js8
-rw-r--r--spec/frontend/sidebar/components/date/sidebar_inherit_date_spec.js12
-rw-r--r--spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js4
-rw-r--r--spec/frontend/snippets/components/show_spec.js2
-rw-r--r--spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js2
-rw-r--r--spec/frontend/snippets/components/snippet_visibility_edit_spec.js2
-rw-r--r--spec/frontend/terraform/components/states_table_spec.js2
-rw-r--r--spec/frontend/tooltips/components/tooltips_spec.js4
-rw-r--r--spec/frontend/vue_merge_request_widget/components/artifacts_list_spec.js6
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_commit_message_dropdown_spec.js2
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js2
-rw-r--r--spec/frontend/vue_merge_request_widget/components/terraform/mr_widget_terraform_container_spec.js3
-rw-r--r--spec/frontend/work_items_hierarchy/components/hierarchy_spec.js2
-rw-r--r--spec/lib/api/entities/personal_access_token_with_details_spec.rb29
-rw-r--r--spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb59
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb19
-rw-r--r--spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb62
-rw-r--r--spec/models/ci/pipeline_artifact_spec.rb13
-rw-r--r--spec/models/ci/pipeline_spec.rb63
-rw-r--r--spec/models/ci/runner_spec.rb19
-rw-r--r--spec/models/commit_status_spec.rb11
-rw-r--r--spec/models/group_group_link_spec.rb11
-rw-r--r--spec/models/repository_spec.rb48
-rw-r--r--spec/requests/api/groups_spec.rb11
-rw-r--r--spec/serializers/access_token_entity_base_spec.rb26
-rw-r--r--spec/services/ci/create_downstream_pipeline_service_spec.rb14
-rw-r--r--spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb24
-rw-r--r--spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb24
-rw-r--r--spec/services/ci/runners/set_runner_associated_projects_service_spec.rb70
-rw-r--r--spec/services/ci/unlock_artifacts_service_spec.rb34
161 files changed, 1121 insertions, 294 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f832b88b821..9c6b84d3931 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -67,7 +67,7 @@ variables:
RAILS_ENV: "test"
NODE_ENV: "test"
BUNDLE_WITHOUT: "production:development"
- BUNDLE_INSTALL_FLAGS: "--jobs=$(nproc) --retry=3 --quiet"
+ BUNDLE_INSTALL_FLAGS: "--jobs=$(nproc) --retry=3"
BUNDLE_FROZEN: "true"
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index a214959deab..bb6ebaa42d5 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -1801,6 +1801,10 @@
when: never
- <<: *if-default-branch-or-tag
changes: *code-backstage-qa-patterns
+ - <<: *if-dot-com-gitlab-org-merge-request
+ changes: [".gitlab/ci/setup.gitlab-ci.yml"]
+ when: manual
+ allow_failure: true
.setup:rules:dont-interrupt-me:
rules:
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index 437b02e4819..4f3111de2bf 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -3,16 +3,20 @@
cache gems:
extends:
- .default-retry
- - .rails-cache
+ - .ruby-cache
- .default-before_script
- .setup:rules:cache-gems
- stage: test
- needs: ["setup-test-env"]
+ stage: prepare
+ needs: []
variables:
- BUNDLE_INSTALL_FLAGS: --with=production --with=development --with=test --jobs=2 --path=vendor --retry=3 --quiet
+ BUNDLE_WITHOUT: ""
+ BUNDLE_WITH: "production:development:test"
SETUP_DB: "false"
script:
- - bundle package --all --all-platforms
+ - echo -e "\e[0Ksection_start:`date +%s`:bundle-package[collapsed=true]\r\e[0KPackaging gems"
+ - bundle config set cache_all true
+ - run_timed_command "bundle package --all-platforms"
+ - echo -e "\e[0Ksection_end:`date +%s`:bundle-package\r\e[0K"
artifacts:
paths:
- vendor/cache
diff --git a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
index 4c2f55fd174..679c8caffdb 100644
--- a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
+++ b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
@@ -69,14 +69,18 @@ export default {
</script>
<template>
<div>
- <div v-if="!isLocalStorageAvailable" ref="localStorageNote" class="dropdown-info-note">
+ <div
+ v-if="!isLocalStorageAvailable"
+ data-testid="local-storage-note"
+ class="dropdown-info-note"
+ >
{{ __('This feature requires local storage to be enabled') }}
</div>
<ul v-else-if="hasItems">
<li
v-for="(item, index) in processedItems"
- ref="dropdownItem"
:key="`processed-items-${index}`"
+ data-testid="dropdown-item"
>
<button
type="button"
@@ -100,7 +104,7 @@ export default {
<li class="divider"></li>
<li>
<button
- ref="clearButton"
+ data-testid="clear-button"
type="button"
class="filtered-search-history-clear-button"
@click="onRequestClearRecentSearches($event)"
@@ -109,7 +113,7 @@ export default {
</button>
</li>
</ul>
- <div v-else ref="dropdownNote" class="dropdown-info-note">
+ <div v-else data-testid="dropdown-note" class="dropdown-info-note">
{{ __("You don't have any recent searches") }}
</div>
</div>
diff --git a/app/assets/javascripts/frequent_items/components/frequent_items_list.vue b/app/assets/javascripts/frequent_items/components/frequent_items_list.vue
index 1da0b88c9e9..c0bfcf9c4a9 100644
--- a/app/assets/javascripts/frequent_items/components/frequent_items_list.vue
+++ b/app/assets/javascripts/frequent_items/components/frequent_items_list.vue
@@ -58,7 +58,7 @@ export default {
<template>
<div class="frequent-items-list-container">
- <ul ref="frequentItemsList" class="list-unstyled">
+ <ul data-testid="frequent-items-list" class="list-unstyled">
<li
v-if="isListEmpty"
:class="{ 'section-failure': isFetchFailed }"
diff --git a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
index 9fb69a3cae3..33ab1d5cd7f 100644
--- a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
+++ b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
@@ -79,16 +79,19 @@ export default {
:project-name="itemName"
aria-hidden="true"
/>
- <div ref="frequentItemsItemMetadataContainer" class="frequent-items-item-metadata-container">
+ <div
+ data-testid="frequent-items-item-metadata-container"
+ class="frequent-items-item-metadata-container"
+ >
<div
- ref="frequentItemsItemTitle"
v-safe-html="highlightedItemName"
+ data-testid="frequent-items-item-title"
:title="itemName"
class="frequent-items-item-title"
></div>
<div
v-if="namespace"
- ref="frequentItemsItemNamespace"
+ data-testid="frequent-items-item-namespace"
:title="namespace"
class="frequent-items-item-namespace"
>
diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb
index 07d786ab060..8ed67c26f19 100644
--- a/app/controllers/profiles/personal_access_tokens_controller.rb
+++ b/app/controllers/profiles/personal_access_tokens_controller.rb
@@ -65,7 +65,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController
add_pagination_headers(tokens)
end
- ::API::Entities::PersonalAccessTokenWithDetails.represent(tokens)
+ ::PersonalAccessTokenSerializer.new.represent(tokens)
end
def add_pagination_headers(relation)
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 7474485a09b..5a212e9a152 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -220,7 +220,13 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def context_commits
# Get commits from repository
# or from cache if already merged
- commits = ContextCommitsFinder.new(project, @merge_request, { search: params[:search], limit: params[:limit], offset: params[:offset] }).execute
+ commits = ContextCommitsFinder.new(project, @merge_request, {
+ search: params[:search],
+ author: params[:author],
+ committed_before: convert_date_to_epoch(params[:committed_before]),
+ committed_after: convert_date_to_epoch(params[:committed_after]),
+ limit: params[:limit]
+ }).execute
render json: CommitEntity.represent(commits, { type: :full, request: merge_request })
end
@@ -553,6 +559,11 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
diffs_metadata_project_json_merge_request_path(project, merge_request, 'json', params)
end
+
+ def convert_date_to_epoch(date)
+ Date.strptime(date, "%Y-%m-%d")&.to_time&.to_i if date
+ rescue Date::Error, TypeError
+ end
end
Projects::MergeRequestsController.prepend_mod_with('Projects::MergeRequestsController')
diff --git a/app/finders/context_commits_finder.rb b/app/finders/context_commits_finder.rb
index d623854ada4..4a45817cc61 100644
--- a/app/finders/context_commits_finder.rb
+++ b/app/finders/context_commits_finder.rb
@@ -5,8 +5,10 @@ class ContextCommitsFinder
@project = project
@merge_request = merge_request
@search = params[:search]
+ @author = params[:author]
+ @committed_before = params[:committed_before]
+ @committed_after = params[:committed_after]
@limit = (params[:limit] || 40).to_i
- @offset = (params[:offset] || 0).to_i
end
def execute
@@ -16,13 +18,13 @@ class ContextCommitsFinder
private
- attr_reader :project, :merge_request, :search, :limit, :offset
+ attr_reader :project, :merge_request, :search, :author, :committed_before, :committed_after, :limit
def init_collection
if search.present?
search_commits
else
- project.repository.commits(merge_request.target_branch, { limit: limit, offset: offset })
+ project.repository.commits(merge_request.target_branch, { limit: limit })
end
end
@@ -41,7 +43,8 @@ class ContextCommitsFinder
commits = [commit_by_sha] if commit_by_sha
end
else
- commits = project.repository.find_commits_by_message(search, merge_request.target_branch, nil, 20)
+ commits = project.repository.list_commits_by(search, merge_request.target_branch,
+ author: author, before: committed_before, after: committed_after, limit: limit)
end
commits
diff --git a/app/finders/groups/accepting_group_transfers_finder.rb b/app/finders/groups/accepting_group_transfers_finder.rb
index 03f5e492d27..df67f940d20 100644
--- a/app/finders/groups/accepting_group_transfers_finder.rb
+++ b/app/finders/groups/accepting_group_transfers_finder.rb
@@ -2,6 +2,8 @@
module Groups
class AcceptingGroupTransfersFinder < Base
+ include Gitlab::Utils::StrongMemoize
+
def initialize(current_user, group_to_be_transferred, params = {})
@current_user = current_user
@group_to_be_transferred = group_to_be_transferred
@@ -11,7 +13,12 @@ module Groups
def execute
return Group.none unless can_transfer_group?
- items = find_groups
+ items = if Feature.enabled?(:include_groups_from_group_shares_in_group_transfer_locations)
+ find_all_groups
+ else
+ find_groups
+ end
+
items = by_search(items)
sort(items)
@@ -29,11 +36,30 @@ module Groups
).execute.without_order
end
+ def find_all_groups
+ ::Namespace.from_union(
+ [
+ find_groups,
+ groups_originating_from_group_shares_with_owner_access
+ ]
+ )
+ end
+
+ def groups_originating_from_group_shares_with_owner_access
+ GroupGroupLink
+ .with_owner_access
+ .groups_accessible_via(
+ current_user.owned_groups.select(:id)
+ ).id_not_in(exclude_groups)
+ end
+
def exclude_groups
- exclude_groups = group_to_be_transferred.self_and_descendants.pluck_primary_key
- exclude_groups << group_to_be_transferred.parent_id if group_to_be_transferred.parent_id
+ strong_memoize(:exclude_groups) do
+ exclude_groups = group_to_be_transferred.self_and_descendants.pluck_primary_key
+ exclude_groups << group_to_be_transferred.parent_id if group_to_be_transferred.parent_id
- exclude_groups
+ exclude_groups
+ end
end
def can_transfer_group?
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index ef01ef4697f..eb17770ab62 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -977,6 +977,11 @@ module Ci
end
# With multi-project and parent-child pipelines
+ def self_and_downstreams
+ object_hierarchy.base_and_descendants
+ end
+
+ # With multi-project and parent-child pipelines
def upstream_and_all_downstreams
object_hierarchy.all_objects
end
@@ -1012,7 +1017,12 @@ module Ci
# Follow the upstream pipeline relationships, regardless of multi-project or
# parent-child, and return the top-level ancestor.
def upstream_root
- object_hierarchy.base_and_ancestors(hierarchy_order: :desc).first
+ @upstream_root ||= object_hierarchy.base_and_ancestors(hierarchy_order: :desc).first
+ end
+
+ # Applies to all parent-child and multi-project pipelines
+ def complete_hierarchy_count
+ upstream_root.self_and_downstreams.count
end
def bridge_triggered?
diff --git a/app/models/ci/pipeline_artifact.rb b/app/models/ci/pipeline_artifact.rb
index 4954463a37a..6d22a875aab 100644
--- a/app/models/ci/pipeline_artifact.rb
+++ b/app/models/ci/pipeline_artifact.rb
@@ -53,7 +53,7 @@ module Ci
find_by(file_type: file_type)
end
- def create_or_replace_for_pipeline!(pipeline:, file_type:, file:, size:)
+ def create_or_replace_for_pipeline!(pipeline:, file_type:, file:, size:, locked: :unknown)
transaction do
pipeline.pipeline_artifacts.find_by_file_type(file_type)&.destroy!
@@ -63,7 +63,8 @@ module Ci
size: size,
file: file,
file_format: REPORT_TYPES[file_type],
- expire_at: EXPIRATION_DATE.from_now
+ expire_at: EXPIRATION_DATE.from_now,
+ locked: locked
)
end
rescue ActiveRecord::ActiveRecordError => err
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 60a9eade5a5..28d9edcc135 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -348,6 +348,12 @@ module Ci
end
end
+ def owner_project
+ return unless project_type?
+
+ runner_projects.order(:id).first.project
+ end
+
def belongs_to_one_project?
runner_projects.count == 1
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index d8ca68eb2a5..7df0525fa35 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -319,11 +319,7 @@ class CommitStatus < Ci::ApplicationRecord
end
def stage_name
- if Feature.enabled?(:ci_read_stage_records, project)
- ci_stage&.name
- else
- stage
- end
+ ci_stage&.name
end
private
diff --git a/app/models/group_group_link.rb b/app/models/group_group_link.rb
index 8dd245a6ab5..7005c8593bd 100644
--- a/app/models/group_group_link.rb
+++ b/app/models/group_group_link.rb
@@ -19,6 +19,10 @@ class GroupGroupLink < ApplicationRecord
where(group_access: [Gitlab::Access::OWNER, Gitlab::Access::MAINTAINER])
end
+ scope :with_owner_access, -> do
+ where(group_access: [Gitlab::Access::OWNER])
+ end
+
scope :groups_accessible_via, -> (shared_with_group_ids) do
links = where(shared_with_group_id: shared_with_group_ids)
# a group share also gives you access to the descendants of the group being shared,
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 63fbb86544c..5aa9267b00e 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -194,6 +194,18 @@ class Repository
CommitCollection.new(container, commits, ref)
end
+ def list_commits_by(query, ref, author: nil, before: nil, after: nil, limit: 1000)
+ return [] unless exists?
+ return [] unless has_visible_content?
+ return [] unless query.present? && ref.present?
+
+ commits = raw_repository.list_commits_by(
+ query, ref, author: author, before: before, after: after, limit: limit).map do |c|
+ commit(c)
+ end
+ CommitCollection.new(container, commits, ref)
+ end
+
def find_branch(name)
raw_repository.find_branch(name)
end
diff --git a/app/serializers/access_token_entity_base.rb b/app/serializers/access_token_entity_base.rb
new file mode 100644
index 00000000000..db22dbf1302
--- /dev/null
+++ b/app/serializers/access_token_entity_base.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+# rubocop: disable Gitlab/NamespacedClass
+class AccessTokenEntityBase < API::Entities::PersonalAccessToken
+ expose :expired?, as: :expired
+ expose :expires_soon?, as: :expires_soon
+end
+# rubocop: enable Gitlab/NamespacedClass
diff --git a/app/serializers/group_access_token_entity.rb b/app/serializers/group_access_token_entity.rb
index 76dc3999a61..ab1fbb8ab46 100644
--- a/app/serializers/group_access_token_entity.rb
+++ b/app/serializers/group_access_token_entity.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# rubocop: disable Gitlab/NamespacedClass
-class GroupAccessTokenEntity < API::Entities::PersonalAccessToken
+class GroupAccessTokenEntity < AccessTokenEntityBase
include Gitlab::Routing
expose :revoke_path do |token, options|
diff --git a/app/serializers/impersonation_access_token_entity.rb b/app/serializers/impersonation_access_token_entity.rb
index 9c59ed58bd8..b4ed62a890d 100644
--- a/app/serializers/impersonation_access_token_entity.rb
+++ b/app/serializers/impersonation_access_token_entity.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# rubocop: disable Gitlab/NamespacedClass
-class ImpersonationAccessTokenEntity < API::Entities::PersonalAccessToken
+class ImpersonationAccessTokenEntity < AccessTokenEntityBase
include Gitlab::Routing
expose :revoke_path do |token, _options|
diff --git a/app/serializers/personal_access_token_entity.rb b/app/serializers/personal_access_token_entity.rb
index acd06fecd12..49dcdf12a6f 100644
--- a/app/serializers/personal_access_token_entity.rb
+++ b/app/serializers/personal_access_token_entity.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# rubocop: disable Gitlab/NamespacedClass
-class PersonalAccessTokenEntity < API::Entities::PersonalAccessToken
+class PersonalAccessTokenEntity < AccessTokenEntityBase
include Gitlab::Routing
expose :revoke_path do |token, options|
diff --git a/app/serializers/project_access_token_entity.rb b/app/serializers/project_access_token_entity.rb
index 695a5122348..52bb7b05d4e 100644
--- a/app/serializers/project_access_token_entity.rb
+++ b/app/serializers/project_access_token_entity.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# rubocop: disable Gitlab/NamespacedClass
-class ProjectAccessTokenEntity < API::Entities::PersonalAccessToken
+class ProjectAccessTokenEntity < AccessTokenEntityBase
include Gitlab::Routing
expose :revoke_path do |token, options|
diff --git a/app/services/ci/pipeline_artifacts/coverage_report_service.rb b/app/services/ci/pipeline_artifacts/coverage_report_service.rb
index c11a8f7a0fd..99877603554 100644
--- a/app/services/ci/pipeline_artifacts/coverage_report_service.rb
+++ b/app/services/ci/pipeline_artifacts/coverage_report_service.rb
@@ -27,12 +27,18 @@ module Ci
end
def pipeline_artifact_params
- {
+ attributes = {
pipeline: pipeline,
file_type: :code_coverage,
file: carrierwave_file,
size: carrierwave_file['tempfile'].size
}
+
+ if ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, pipeline.project)
+ attributes[:locked] = pipeline.locked
+ end
+
+ attributes
end
def carrierwave_file
diff --git a/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb b/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
index d6865efac9f..aeb68a75f88 100644
--- a/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
+++ b/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
@@ -13,21 +13,31 @@ module Ci
return if pipeline.has_codequality_mr_diff_report?
return unless new_errors_introduced?
+ pipeline.pipeline_artifacts.create!(**artifact_attributes)
+ end
+
+ private
+
+ attr_reader :pipeline
+
+ def artifact_attributes
file = build_carrierwave_file!
- pipeline.pipeline_artifacts.create!(
+ attributes = {
project_id: pipeline.project_id,
file_type: :code_quality_mr_diff,
file_format: Ci::PipelineArtifact::REPORT_TYPES.fetch(:code_quality_mr_diff),
size: file["tempfile"].size,
file: file,
expire_at: Ci::PipelineArtifact::EXPIRATION_DATE.from_now
- )
- end
+ }
- private
+ if ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, pipeline.project)
+ attributes[:locked] = pipeline.locked
+ end
- attr_reader :pipeline
+ attributes
+ end
def merge_requests
strong_memoize(:merge_requests) do
diff --git a/app/services/ci/runners/set_runner_associated_projects_service.rb b/app/services/ci/runners/set_runner_associated_projects_service.rb
new file mode 100644
index 00000000000..759bd2ffb16
--- /dev/null
+++ b/app/services/ci/runners/set_runner_associated_projects_service.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class SetRunnerAssociatedProjectsService
+ # @param [Ci::Runner] runner: the project runner to assign/unassign projects from
+ # @param [User] current_user: the user performing the operation
+ # @param [Array<Integer>] project_ids: the IDs of the associated projects to assign the runner to
+ def initialize(runner:, current_user:, project_ids:)
+ @runner = runner
+ @current_user = current_user
+ @project_ids = project_ids
+ end
+
+ def execute
+ unless current_user&.can?(:assign_runner, runner)
+ return ServiceResponse.error(message: 'user not allowed to assign runner', http_status: :forbidden)
+ end
+
+ set_associated_projects
+ end
+
+ private
+
+ def set_associated_projects
+ new_project_ids = [runner.owner_project.id] + project_ids
+
+ response = ServiceResponse.success
+ runner.transaction do
+ # rubocop:disable CodeReuse/ActiveRecord
+ current_project_ids = runner.projects.ids
+ # rubocop:enable CodeReuse/ActiveRecord
+
+ unless associate_new_projects(new_project_ids, current_project_ids)
+ response = ServiceResponse.error(message: 'failed to assign projects to runner')
+ raise ActiveRecord::Rollback, response.errors
+ end
+
+ unless disassociate_old_projects(new_project_ids, current_project_ids)
+ response = ServiceResponse.error(message: 'failed to destroy runner project')
+ raise ActiveRecord::Rollback, response.errors
+ end
+ end
+
+ response
+ end
+
+ def associate_new_projects(new_project_ids, current_project_ids)
+ missing_projects = Project.id_in(new_project_ids - current_project_ids)
+ missing_projects.each do |project|
+ return false unless runner.assign_to(project, current_user)
+ end
+
+ true
+ end
+
+ def disassociate_old_projects(new_project_ids, current_project_ids)
+ Ci::RunnerProject
+ .destroy_by(project_id: current_project_ids - new_project_ids)
+ .all?(&:destroyed?)
+ end
+
+ attr_reader :runner, :current_user, :project_ids
+ end
+ end
+end
+
+Ci::Runners::SetRunnerAssociatedProjectsService.prepend_mod
diff --git a/app/services/ci/unlock_artifacts_service.rb b/app/services/ci/unlock_artifacts_service.rb
index 30da31ba8ec..1fee31da4fc 100644
--- a/app/services/ci/unlock_artifacts_service.rb
+++ b/app/services/ci/unlock_artifacts_service.rb
@@ -7,9 +7,12 @@ module Ci
def execute(ci_ref, before_pipeline = nil)
results = {
unlocked_pipelines: 0,
- unlocked_job_artifacts: 0
+ unlocked_job_artifacts: 0,
+ unlocked_pipeline_artifacts: 0
}
+ unlock_pipeline_artifacts_enabled = ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, ci_ref.project)
+
if ::Feature.enabled?(:ci_update_unlocked_job_artifacts, ci_ref.project)
loop do
unlocked_pipelines = []
@@ -18,6 +21,10 @@ module Ci
::Ci::Pipeline.transaction do
unlocked_pipelines = unlock_pipelines(ci_ref, before_pipeline)
unlocked_job_artifacts = unlock_job_artifacts(unlocked_pipelines)
+
+ if unlock_pipeline_artifacts_enabled
+ results[:unlocked_pipeline_artifacts] += unlock_pipeline_artifacts(unlocked_pipelines)
+ end
end
break if unlocked_pipelines.empty?
@@ -100,6 +107,14 @@ module Ci
)
end
+ # rubocop:disable CodeReuse/ActiveRecord
+ def unlock_pipeline_artifacts(pipelines)
+ return 0 if pipelines.empty?
+
+ ::Ci::PipelineArtifact.where(pipeline_id: pipelines.rows.flatten).update_all(locked: :unlocked)
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
+
def unlock_pipelines(ci_ref, before_pipeline)
::Ci::Pipeline.connection.exec_query(unlock_pipelines_query(ci_ref, before_pipeline))
end
diff --git a/app/services/concerns/ci/downstream_pipeline_helpers.rb b/app/services/concerns/ci/downstream_pipeline_helpers.rb
index 557bfe2534b..26d7eb97151 100644
--- a/app/services/concerns/ci/downstream_pipeline_helpers.rb
+++ b/app/services/concerns/ci/downstream_pipeline_helpers.rb
@@ -5,7 +5,6 @@ module Ci
def log_downstream_pipeline_creation(downstream_pipeline)
return unless downstream_pipeline&.persisted?
- hierarchy_size = downstream_pipeline.upstream_and_all_downstreams.count
root_pipeline = downstream_pipeline.upstream_root
::Gitlab::AppLogger.info(
@@ -14,7 +13,7 @@ module Ci
root_pipeline_id: root_pipeline.id,
downstream_pipeline_id: downstream_pipeline.id,
downstream_pipeline_relationship: downstream_pipeline.parent_pipeline? ? :parent_child : :multi_project,
- hierarchy_size: hierarchy_size,
+ hierarchy_size: downstream_pipeline.complete_hierarchy_count,
root_pipeline_plan: root_pipeline.project.actual_plan_name,
root_pipeline_namespace_path: root_pipeline.project.namespace.full_path,
root_pipeline_project_path: root_pipeline.project.full_path
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index 5205d34baae..533d0052fb8 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -234,6 +234,7 @@ module MergeRequests
end
# Add comment about pushing new commits to merge requests and send nofitication emails
+ #
def notify_about_push(merge_request)
return unless @commits.present?
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index d64089ea58a..79fc1a64790 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -8,16 +8,15 @@
%h1.page-title.gl-font-size-h-display
= s_('TagsPage|New Tag')
-%hr
= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "common-note-form tag-form js-quick-submit js-requires-input" do
.form-group.row
- = label_tag :tag_name, nil, class: 'col-form-label col-sm-2'
- .col-sm-10
+ .col-sm-12
+ = label_tag :tag_name, nil
= text_field_tag :tag_name, params[:tag_name], required: true, autofocus: true, class: 'form-control', data: { qa_selector: "tag_name_field" }
.form-group.row
- = label_tag :ref, 'Create from', class: 'col-form-label col-sm-2'
- .col-sm-10.create-from
+ .col-sm-12.create-from
+ = label_tag :ref, 'Create from'
.dropdown
= hidden_field_tag :ref, default_ref
= button_tag type: 'button', title: default_ref, class: 'dropdown-menu-toggle wide js-branch-select monospace', required: true, data: { toggle: 'dropdown', selected: default_ref, field_name: 'ref' } do
@@ -27,15 +26,14 @@
.form-text.text-muted
= s_('TagsPage|Existing branch name, tag, or commit SHA')
.form-group.row
- = label_tag :message, nil, class: 'col-form-label col-sm-2'
- .col-sm-10
+ .col-sm-12
+ = label_tag :message, nil
= text_area_tag :message, @message, required: false, class: 'form-control', rows: 5, data: { qa_selector: "tag_message_field" }
.form-text.text-muted
= tag_description_help_text
- %hr
.form-group.row
- = label_tag :release_description, s_('TagsPage|Release notes'), class: 'col-form-label col-sm-2'
- .col-sm-10
+ .col-sm-12
+ = label_tag :release_description, s_('TagsPage|Release notes'), class: 'gl-mb-0'
.form-text.mb-3
- link_start = '<a href="%{url}" rel="noopener noreferrer" target="_blank">'.html_safe
- releases_page_path = project_releases_path(@project)
@@ -49,7 +47,7 @@
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'shared/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description, qa_selector: 'release_notes_field'
= render 'shared/notes/hints'
- .form-actions.gl-display-flex
+ .gl-display-flex
= render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { class: 'gl-mr-3', data: { qa_selector: "create_tag_button" }, type: 'submit' }) do
= s_('TagsPage|Create tag')
= render Pajamas::ButtonComponent.new(href: project_tags_path(@project)) do
diff --git a/config/feature_flags/development/ci_read_stage_records.yml b/config/feature_flags/development/ci_update_unlocked_pipeline_artifacts.yml
index 2a7e6ecf5ad..ffcd5352751 100644
--- a/config/feature_flags/development/ci_read_stage_records.yml
+++ b/config/feature_flags/development/ci_update_unlocked_pipeline_artifacts.yml
@@ -1,8 +1,8 @@
---
-name: ci_read_stage_records
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94941
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371486
+name: ci_update_unlocked_pipeline_artifacts
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97228
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372835
milestone: '15.4'
type: development
-group: group::pipeline execution
+group: group::pipeline insights
default_enabled: false
diff --git a/config/feature_flags/development/include_groups_from_group_shares_in_group_transfer_locations.yml b/config/feature_flags/development/include_groups_from_group_shares_in_group_transfer_locations.yml
new file mode 100644
index 00000000000..f92a6b2b1b0
--- /dev/null
+++ b/config/feature_flags/development/include_groups_from_group_shares_in_group_transfer_locations.yml
@@ -0,0 +1,8 @@
+---
+name: include_groups_from_group_shares_in_group_transfer_locations
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96347
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371961
+milestone: '15.4'
+type: development
+group: group::workspace
+default_enabled: false
diff --git a/db/post_migrate/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb.rb b/db/post_migrate/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb.rb
new file mode 100644
index 00000000000..ee48ace13e0
--- /dev/null
+++ b/db/post_migrate/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class ScheduleDisableLegacyOpenSourceLicenseForProjectsLessThanOneMb < Gitlab::Database::Migration[2.0]
+ MIGRATION = 'DisableLegacyOpenSourceLicenseForProjectsLessThanOneMb'
+ INTERVAL = 2.minutes
+ BATCH_SIZE = 4_000
+ MAX_BATCH_SIZE = 50_000
+ SUB_BATCH_SIZE = 250
+
+ disable_ddl_transaction!
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ return unless Gitlab.com?
+
+ queue_batched_background_migration(
+ MIGRATION,
+ :project_settings,
+ :project_id,
+ job_interval: INTERVAL,
+ batch_size: BATCH_SIZE,
+ max_batch_size: MAX_BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ return unless Gitlab.com?
+
+ delete_batched_background_migration(MIGRATION, :project_settings, :project_id, [])
+ end
+end
diff --git a/db/schema_migrations/20220906074449 b/db/schema_migrations/20220906074449
new file mode 100644
index 00000000000..df657642eb3
--- /dev/null
+++ b/db/schema_migrations/20220906074449
@@ -0,0 +1 @@
+fc34cdbddc61ee9c23b790101f911d21892cf2ace34e3615b920817374c803f9 \ No newline at end of file
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index 94c12f80fda..4b75141ac43 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -147,6 +147,18 @@ Do not use **and so on**. Instead, be more specific. For details, see
Use [**section**](#section) instead of **area**. The only exception is [the Admin Area](#admin-area).
+## as
+
+Do not use **as** to mean **because**.
+
+Use:
+
+- Because none of the endpoints return an ID...
+
+Instead of:
+
+- As none of the endpoints return an ID...
+
## associate
Do not use **associate** when describing adding issues to epics, or users to issues, merge requests,
@@ -619,6 +631,10 @@ Instead of:
- Buy a license.
- Purchase a license.
+## limitations
+
+Do not use **limitations**. Use **known issues** instead.
+
## log in, log on
Do not use **log in** or **log on**. Use [sign in](#sign-in) instead. If the user interface has **Log in**, you can use it.
diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md
index ade0277efa8..f238678b662 100644
--- a/doc/user/project/merge_requests/cherry_pick_changes.md
+++ b/doc/user/project/merge_requests/cherry_pick_changes.md
@@ -20,6 +20,32 @@ NOTE:
Support for tracking commits cherry-picked from the command line
is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/202215).
+## Cherry-pick example
+
+In this example of cherry-picking, a Git repository has two branches: `develop` and `main`.
+
+```mermaid
+gitGraph
+ commit id: "A"
+ branch develop
+ commit id:"B"
+ checkout main
+ commit id:"C"
+ checkout develop
+ commit id:"D"
+ checkout main
+ commit id:"E"
+ cherry-pick id:"B"
+ commit id:"G"
+ checkout develop
+ commit id:"H"
+```
+
+The example shows a cherry-pick of commit `B` from the `develop` branch, which is added
+after commit `E` in the `main` branch.
+
+Commit `G` is added after the cherry-pick.
+
## Cherry-pick all changes from a merge request
After a merge request is merged, you can cherry-pick all changes introduced
diff --git a/lib/api/entities/personal_access_token_with_details.rb b/lib/api/entities/personal_access_token_with_details.rb
deleted file mode 100644
index 5654bd4a1e1..00000000000
--- a/lib/api/entities/personal_access_token_with_details.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-module API
- module Entities
- class PersonalAccessTokenWithDetails < Entities::PersonalAccessToken
- expose :expired?, as: :expired
- expose :expires_soon?, as: :expires_soon
- expose :revoke_path do |token|
- Gitlab::Routing.url_helpers.revoke_profile_personal_access_token_path(token)
- end
- end
- end
-end
diff --git a/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb.rb b/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb.rb
new file mode 100644
index 00000000000..6e4d5d8ddcb
--- /dev/null
+++ b/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Set `project_settings.legacy_open_source_license_available` to false for projects less than 1 MB
+ class DisableLegacyOpenSourceLicenseForProjectsLessThanOneMb < ::Gitlab::BackgroundMigration::BatchedMigrationJob
+ scope_to ->(relation) { relation.where(legacy_open_source_license_available: true) }
+
+ def perform
+ each_sub_batch(operation_name: :disable_legacy_open_source_license_for_projects_less_than_one_mb) do |sub_batch|
+ updates = { legacy_open_source_license_available: false, updated_at: Time.current }
+
+ sub_batch
+ .joins('INNER JOIN project_statistics ON project_statistics.project_id = project_settings.project_id')
+ .where('project_statistics.repository_size < ?', 1.megabyte)
+ .update_all(updates)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index d26834089b4..a68218f84b7 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -1056,6 +1056,24 @@ module Gitlab
end
end
+ def list_commits_by(query, ref, author: nil, before: nil, after: nil, limit: 1000)
+ params = {
+ author: author,
+ ignore_case: true,
+ commit_message_patterns: query,
+ before: before,
+ after: after,
+ reverse: false,
+ pagination_params: { limit: limit }
+ }
+
+ wrapped_gitaly_errors do
+ gitaly_commit_client
+ .list_commits([ref], params)
+ .map { |c| commit(c) }
+ end
+ end
+
def list_last_commits_for_tree(sha, path, offset: 0, limit: 25, literal_pathspec: false)
wrapped_gitaly_errors do
gitaly_commit_client.list_last_commits_for_tree(sha, path, offset: offset, limit: limit, literal_pathspec: literal_pathspec)
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index d76a1131160..312d1dddff1 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -251,14 +251,23 @@ module Gitlab
consume_commits_response(response)
end
- def list_commits(revisions, reverse: false, pagination_params: nil)
+ def list_commits(revisions, params = {})
request = Gitaly::ListCommitsRequest.new(
repository: @gitaly_repo,
revisions: Array.wrap(revisions),
- reverse: reverse,
- pagination_params: pagination_params
+ reverse: !!params[:reverse],
+ ignore_case: params[:ignore_case],
+ pagination_params: params[:pagination_params]
)
+ if params[:commit_message_patterns]
+ request.commit_message_patterns += Array.wrap(params[:commit_message_patterns])
+ end
+
+ request.author = encode_binary(params[:author]) if params[:author]
+ request.before = GitalyClient.timestamp(params[:before]) if params[:before]
+ request.after = GitalyClient.timestamp(params[:after]) if params[:after]
+
response = GitalyClient.call(@repository.storage, :commit_service, :list_commits, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index bea2ef2c9c4..769e0c90d4f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -43942,9 +43942,6 @@ msgstr ""
msgid "Vulnerability|Information related to how the vulnerability was discovered and its impact on the system."
msgstr ""
-msgid "Vulnerability|Learn more about this vulnerability and the best way to resolve it."
-msgstr ""
-
msgid "Vulnerability|Links"
msgstr ""
diff --git a/scripts/utils.sh b/scripts/utils.sh
index 8db525abc93..10b7f856ee6 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -38,6 +38,8 @@ function bundle_install_script() {
exit 1;
fi;
+ echo -e "section_start:`date +%s`:bundle-install[collapsed=true]\r\e[0KInstalling gems"
+
gem --version
bundle --version
gem install bundler --no-document --conservative --version 2.3.15
@@ -48,7 +50,7 @@ function bundle_install_script() {
echo "${BUNDLE_WITHOUT}"
bundle config
- run_timed_command "bundle install ${BUNDLE_INSTALL_FLAGS} ${extra_install_args} && bundle check"
+ run_timed_command "bundle install ${BUNDLE_INSTALL_FLAGS} ${extra_install_args}"
if [[ $(bundle info pg) ]]; then
# When we test multiple versions of PG in the same pipeline, we have a single `setup-test-env`
@@ -56,6 +58,8 @@ function bundle_install_script() {
# Uncomment the following line if multiple versions of PG are tested in the same pipeline.
run_timed_command "bundle pristine pg"
fi
+
+ echo -e "section_end:`date +%s`:bundle-install\r\e[0K"
}
function setup_db_user_only() {
diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
index 0e531dbaf4b..99e9644da66 100644
--- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
+++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
@@ -48,8 +48,8 @@ RSpec.describe Profiles::PersonalAccessTokensController do
end
it "only includes details of the active personal access token" do
- active_personal_access_tokens_detail = ::API::Entities::PersonalAccessTokenWithDetails
- .represent([active_personal_access_token])
+ active_personal_access_tokens_detail =
+ ::PersonalAccessTokenSerializer.new.represent([active_personal_access_token])
expect(assigns(:active_personal_access_tokens).to_json).to eq(active_personal_access_tokens_detail.to_json)
end
@@ -100,8 +100,8 @@ RSpec.describe Profiles::PersonalAccessTokensController do
get :index
first_token = assigns(:active_personal_access_tokens).first.as_json
- expect(first_token[:name]).to eq("Token1")
- expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
+ expect(first_token['name']).to eq("Token1")
+ expect(first_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
end
it "orders tokens on id in case token has same expires_at" do
@@ -110,12 +110,12 @@ RSpec.describe Profiles::PersonalAccessTokensController do
get :index
first_token = assigns(:active_personal_access_tokens).first.as_json
- expect(first_token[:name]).to eq("Token3")
- expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
+ expect(first_token['name']).to eq("Token3")
+ expect(first_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
second_token = assigns(:active_personal_access_tokens).second.as_json
- expect(second_token[:name]).to eq("Token1")
- expect(second_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
+ expect(second_token['name']).to eq("Token1")
+ expect(second_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d"))
end
end
diff --git a/spec/features/tags/developer_creates_tag_spec.rb b/spec/features/tags/developer_creates_tag_spec.rb
index b0219cb546d..ca76a94092e 100644
--- a/spec/features/tags/developer_creates_tag_spec.rb
+++ b/spec/features/tags/developer_creates_tag_spec.rb
@@ -60,7 +60,7 @@ RSpec.describe 'Developer creates tag' do
it 'opens dropdown for ref', :js do
click_link 'New tag'
- ref_row = find('.form-group:nth-of-type(2) .col-sm-10')
+ ref_row = find('.form-group:nth-of-type(2) .col-sm-12')
page.within ref_row do
ref_input = find('[name="ref"]', visible: false)
expect(ref_input.value).to eq 'master'
diff --git a/spec/finders/context_commits_finder_spec.rb b/spec/finders/context_commits_finder_spec.rb
index 95c685aea24..c22675bc67d 100644
--- a/spec/finders/context_commits_finder_spec.rb
+++ b/spec/finders/context_commits_finder_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ContextCommitsFinder do
describe "#execute" do
let(:project) { create(:project, :repository) }
- let(:merge_request) { create(:merge_request) }
+ let(:merge_request) { create(:merge_request, source_branch: 'feature', target_branch: 'master') }
let(:commit) { create(:commit, id: '6d394385cf567f80a8fd85055db1ab4c5295806f') }
it 'filters commits by valid sha/commit message' do
@@ -24,5 +24,29 @@ RSpec.describe ContextCommitsFinder do
expect(commits).to be_empty
end
+
+ it 'returns commits based in author filter' do
+ params = { search: 'test text', author: 'Job van der Voort' }
+ commits = described_class.new(project, merge_request, params).execute
+
+ expect(commits.length).to eq(1)
+ expect(commits[0].id).to eq('b83d6e391c22777fca1ed3012fce84f633d7fed0')
+ end
+
+ it 'returns commits based in before filter' do
+ params = { search: 'test text', committed_before: 1474828200 }
+ commits = described_class.new(project, merge_request, params).execute
+
+ expect(commits.length).to eq(1)
+ expect(commits[0].id).to eq('498214de67004b1da3d820901307bed2a68a8ef6')
+ end
+
+ it 'returns commits based in after filter' do
+ params = { search: 'test text', committed_after: 1474828200 }
+ commits = described_class.new(project, merge_request, params).execute
+
+ expect(commits.length).to eq(1)
+ expect(commits[0].id).to eq('b83d6e391c22777fca1ed3012fce84f633d7fed0')
+ end
end
end
diff --git a/spec/finders/groups/accepting_group_transfers_finder_spec.rb b/spec/finders/groups/accepting_group_transfers_finder_spec.rb
index 6c1ceb4f7ad..1a6c6f9243b 100644
--- a/spec/finders/groups/accepting_group_transfers_finder_spec.rb
+++ b/spec/finders/groups/accepting_group_transfers_finder_spec.rb
@@ -29,9 +29,27 @@ RSpec.describe Groups::AcceptingGroupTransfersFinder do
end
end
+ let_it_be(:shared_with_group_where_direct_owner_as_guest) { create(:group) }
+ let_it_be(:shared_with_group_where_direct_owner_as_owner) { create(:group) }
+ let_it_be(:subgroup_of_shared_with_group_where_direct_owner_as_owner) do
+ create(:group, parent: shared_with_group_where_direct_owner_as_owner)
+ end
+
let(:params) { {} }
describe '#execute' do
+ before_all do
+ create(:group_group_link, :owner,
+ shared_with_group: group_where_user_has_owner_access,
+ shared_group: shared_with_group_where_direct_owner_as_owner
+ )
+
+ create(:group_group_link, :guest,
+ shared_with_group: group_where_user_has_owner_access,
+ shared_group: shared_with_group_where_direct_owner_as_guest
+ )
+ end
+
let(:group_to_be_transferred) { parent_group }
subject(:result) do
@@ -69,6 +87,10 @@ RSpec.describe Groups::AcceptingGroupTransfersFinder do
expect(result).not_to include(group_where_user_has_developer_access)
end
+ it 'excludes the groups arising from group shares where the user does not have OWNER access' do
+ expect(result).not_to include(shared_with_group_where_direct_owner_as_guest)
+ end
+
it 'includes ancestors, except immediate parent of the group to be transferred' do
expect(result).to include(great_grandparent_group)
end
@@ -81,6 +103,13 @@ RSpec.describe Groups::AcceptingGroupTransfersFinder do
expect(result).to include(subgroup_of_group_where_user_has_owner_access)
end
+ it 'includes the groups where the user has OWNER access through group shares' do
+ expect(result).to include(
+ shared_with_group_where_direct_owner_as_owner,
+ subgroup_of_shared_with_group_where_direct_owner_as_owner
+ )
+ end
+
context 'on searching with a specific term' do
let(:params) { { search: 'great grandparent group' } }
@@ -88,6 +117,19 @@ RSpec.describe Groups::AcceptingGroupTransfersFinder do
expect(result).to contain_exactly(great_grandparent_group)
end
end
+
+ context 'when the feature flag `include_groups_from_group_shares_in_group_transfer_locations` is turned off' do
+ before do
+ stub_feature_flags(include_groups_from_group_shares_in_group_transfer_locations: false)
+ end
+
+ it 'excludes the groups where the user has OWNER access through group shares' do
+ expect(result).not_to include(
+ shared_with_group_where_direct_owner_as_owner,
+ subgroup_of_shared_with_group_where_direct_owner_as_owner
+ )
+ end
+ end
end
end
end
diff --git a/spec/frontend/__helpers__/shared_test_setup.js b/spec/frontend/__helpers__/shared_test_setup.js
index 4d6486544ca..45a7b8e0352 100644
--- a/spec/frontend/__helpers__/shared_test_setup.js
+++ b/spec/frontend/__helpers__/shared_test_setup.js
@@ -48,9 +48,6 @@ testUtilsConfig.deprecationWarningHandler = (method, message) => {
const ALLOWED_DEPRECATED_METHODS = [
// https://gitlab.com/gitlab-org/gitlab/-/issues/295679
'finding components with `find` or `get`',
-
- // https://gitlab.com/gitlab-org/gitlab/-/issues/295680
- 'finding components with `findAll`',
];
if (!ALLOWED_DEPRECATED_METHODS.includes(method)) {
global.console.error(message);
diff --git a/spec/frontend/add_context_commits_modal/components/review_tab_container_spec.js b/spec/frontend/add_context_commits_modal/components/review_tab_container_spec.js
index 1a92b9ee536..f679576182f 100644
--- a/spec/frontend/add_context_commits_modal/components/review_tab_container_spec.js
+++ b/spec/frontend/add_context_commits_modal/components/review_tab_container_spec.js
@@ -46,6 +46,6 @@ describe('ReviewTabContainer', () => {
it('renders all passed commits as list', () => {
createWrapper({ commits: [commit] });
- expect(wrapper.findAll(CommitItem).length).toBe(1);
+ expect(wrapper.findAllComponents(CommitItem).length).toBe(1);
});
});
diff --git a/spec/frontend/alerts_settings/components/alerts_integrations_list_spec.js b/spec/frontend/alerts_settings/components/alerts_integrations_list_spec.js
index 6658db92524..9983af873c2 100644
--- a/spec/frontend/alerts_settings/components/alerts_integrations_list_spec.js
+++ b/spec/frontend/alerts_settings/components/alerts_integrations_list_spec.js
@@ -67,7 +67,7 @@ describe('AlertIntegrationsList', () => {
});
it('renders an an edit and delete button for each integration', () => {
- expect(findTableComponent().findAll(GlButton).length).toBe(4);
+ expect(findTableComponent().findAllComponents(GlButton).length).toBe(4);
});
it('renders an highlighted row when a current integration is selected to edit', () => {
diff --git a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
index b3e0d77a40f..3871fd530d8 100644
--- a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
+++ b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js
@@ -83,7 +83,7 @@ describe('ProjectsDropdownFilter component', () => {
const findDropdownItems = () =>
findDropdown()
- .findAll(GlDropdownItem)
+ .findAllComponents(GlDropdownItem)
.filter((w) => w.text() !== 'No matching results');
const findDropdownAtIndex = (index) => findDropdownItems().at(index);
@@ -106,7 +106,7 @@ describe('ProjectsDropdownFilter component', () => {
};
// NOTE: Selected items are now visually separated from unselected items
- const findSelectedDropdownItems = () => findHighlightedItems().findAll(GlDropdownItem);
+ const findSelectedDropdownItems = () => findHighlightedItems().findAllComponents(GlDropdownItem);
const findSelectedDropdownAtIndex = (index) => findSelectedDropdownItems().at(index);
const findSelectedButtonIdentIconAtIndex = (index) =>
diff --git a/spec/frontend/analytics/usage_trends/components/app_spec.js b/spec/frontend/analytics/usage_trends/components/app_spec.js
index 4d8107adf33..c732dc22322 100644
--- a/spec/frontend/analytics/usage_trends/components/app_spec.js
+++ b/spec/frontend/analytics/usage_trends/components/app_spec.js
@@ -27,7 +27,7 @@ describe('UsageTrendsApp', () => {
['Total projects & groups', 'Pipelines', 'Issues & merge requests'].forEach((usage) => {
it(`displays the ${usage} chart`, () => {
const chartTitles = wrapper
- .findAll(UsageTrendsCountChart)
+ .findAllComponents(UsageTrendsCountChart)
.wrappers.map((chartComponent) => chartComponent.props('chartTitle'));
expect(chartTitles).toContain(usage);
diff --git a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
index beb9efd00ed..0d9196b88ed 100644
--- a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
+++ b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
@@ -35,7 +35,9 @@ describe('RecoveryCodes', () => {
const findRecoveryCodes = () => wrapper.findByTestId('recovery-codes');
const findCopyButton = () => wrapper.findComponent(ClipboardButton);
const findButtonByText = (text) =>
- wrapper.findAll(GlButton).wrappers.find((buttonWrapper) => buttonWrapper.text() === text);
+ wrapper
+ .findAllComponents(GlButton)
+ .wrappers.find((buttonWrapper) => buttonWrapper.text() === text);
const findDownloadButton = () => findButtonByText('Download codes');
const findPrintButton = () => findButtonByText('Print codes');
const findProceedButton = () => findButtonByText('Proceed');
diff --git a/spec/frontend/batch_comments/components/diff_file_drafts_spec.js b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
index 6a5ff1af7c9..c922d6a9809 100644
--- a/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
+++ b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
@@ -35,13 +35,13 @@ describe('Batch comments diff file drafts component', () => {
it('renders list of draft notes', () => {
factory();
- expect(vm.findAll(DraftNote).length).toEqual(2);
+ expect(vm.findAllComponents(DraftNote).length).toEqual(2);
});
it('renders index of draft note', () => {
factory();
- const elements = vm.findAll(DesignNotePin);
+ const elements = vm.findAllComponents(DesignNotePin);
expect(elements.length).toEqual(2);
diff --git a/spec/frontend/batch_comments/components/publish_dropdown_spec.js b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
index 7506dc49a18..d1b7160d231 100644
--- a/spec/frontend/batch_comments/components/publish_dropdown_spec.js
+++ b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
@@ -28,7 +28,7 @@ describe('Batch comments publish dropdown component', () => {
it('renders list of drafts', () => {
createComponent();
- expect(wrapper.findAll(GlDropdownItem).length).toBe(2);
+ expect(wrapper.findAllComponents(GlDropdownItem).length).toBe(2);
});
it('renders draft count in dropdown title', () => {
diff --git a/spec/frontend/branches/components/divergence_graph_spec.js b/spec/frontend/branches/components/divergence_graph_spec.js
index 3b565539f87..9429a6e982c 100644
--- a/spec/frontend/branches/components/divergence_graph_spec.js
+++ b/spec/frontend/branches/components/divergence_graph_spec.js
@@ -21,7 +21,7 @@ describe('Branch divergence graph component', () => {
maxCommits: 100,
});
- expect(vm.findAll(GraphBar).length).toBe(2);
+ expect(vm.findAllComponents(GraphBar).length).toBe(2);
expect(vm.element).toMatchSnapshot();
});
@@ -45,7 +45,7 @@ describe('Branch divergence graph component', () => {
maxCommits: 100,
});
- expect(vm.findAll(GraphBar).length).toBe(1);
+ expect(vm.findAllComponents(GraphBar).length).toBe(1);
expect(vm.element).toMatchSnapshot();
});
diff --git a/spec/frontend/cascading_settings/components/lock_popovers_spec.js b/spec/frontend/cascading_settings/components/lock_popovers_spec.js
index ff6ce18ead8..9d3275a1ff2 100644
--- a/spec/frontend/cascading_settings/components/lock_popovers_spec.js
+++ b/spec/frontend/cascading_settings/components/lock_popovers_spec.js
@@ -143,7 +143,7 @@ describe('LockPopovers', () => {
});
it('mounts multiple popovers', () => {
- const popovers = wrapper.findAll(GlPopover).wrappers;
+ const popovers = wrapper.findAllComponents(GlPopover).wrappers;
expectCorrectPopoverTarget(popoverMountEl1, popovers[0]);
expectCorrectPopoverTarget(popoverMountEl2, popovers[1]);
diff --git a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
index a8fec9b23dd..914f2d78d3a 100644
--- a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
+++ b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
@@ -65,7 +65,7 @@ describe('Ci variable modal', () => {
const findAddorUpdateButton = () => wrapper.findByTestId('ciUpdateOrAddVariableBtn');
const deleteVariableButton = () =>
findModal()
- .findAll(GlButton)
+ .findAllComponents(GlButton)
.wrappers.find((button) => button.props('variant') === 'danger');
const findProtectedVariableCheckbox = () =>
wrapper.findByTestId('ci-variable-protected-checkbox');
diff --git a/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js b/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js
index d8d2cbc764f..b607232907b 100644
--- a/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js
+++ b/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js
@@ -45,7 +45,7 @@ describe('Ci variable modal', () => {
const findAddorUpdateButton = () => findModal().find('[data-testid="ciUpdateOrAddVariableBtn"]');
const deleteVariableButton = () =>
findModal()
- .findAll(GlButton)
+ .findAllComponents(GlButton)
.wrappers.find((button) => button.props('variant') === 'danger');
afterEach(() => {
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
index 964dd005a27..10264d6a011 100644
--- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js
+++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
@@ -65,7 +65,7 @@ describe('InstallAgentModal', () => {
const findAgentInstructions = () => findModal().findComponent(AgentToken);
const findButtonByVariant = (variant) =>
findModal()
- .findAll(GlButton)
+ .findAllComponents(GlButton)
.wrappers.find((button) => button.props('variant') === variant);
const findActionButton = () => findButtonByVariant('confirm');
const findCancelButton = () => findButtonByVariant('default');
diff --git a/spec/frontend/confidential_merge_request/components/dropdown_spec.js b/spec/frontend/confidential_merge_request/components/dropdown_spec.js
index bbb6d4f9a26..770f2636648 100644
--- a/spec/frontend/confidential_merge_request/components/dropdown_spec.js
+++ b/spec/frontend/confidential_merge_request/components/dropdown_spec.js
@@ -30,7 +30,7 @@ describe('Confidential merge request project dropdown component', () => {
},
]);
- expect(vm.findAll(GlDropdownItem).length).toBe(2);
+ expect(vm.findAllComponents(GlDropdownItem).length).toBe(2);
});
it('shows lock icon', () => {
diff --git a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
index 304c8250151..567d18f8b92 100644
--- a/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
+++ b/spec/frontend/deploy_freeze/components/timezone_dropdown_spec.js
@@ -30,8 +30,8 @@ describe('Deploy freeze timezone dropdown', () => {
wrapper.setData({ searchTerm });
};
- const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
- const findDropdownItemByIndex = (index) => wrapper.findAll(GlDropdownItem).at(index);
+ const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findDropdownItemByIndex = (index) => wrapper.findAllComponents(GlDropdownItem).at(index);
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 65831b71fd4..2b1bf19471a 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -274,7 +274,7 @@ describe('diffs/components/app', () => {
});
expect(wrapper.findComponent(NoChanges).exists()).toBe(false);
- expect(wrapper.findAll(DiffFile).length).toBe(1);
+ expect(wrapper.findAllComponents(DiffFile).length).toBe(1);
});
});
@@ -636,7 +636,7 @@ describe('diffs/components/app', () => {
await nextTick();
- expect(wrapper.findAll(DiffFile).length).toBe(1);
+ expect(wrapper.findAllComponents(DiffFile).length).toBe(1);
});
describe('pagination', () => {
diff --git a/spec/frontend/diffs/components/compare_dropdown_layout_spec.js b/spec/frontend/diffs/components/compare_dropdown_layout_spec.js
index 98f88226742..09128b04caa 100644
--- a/spec/frontend/diffs/components/compare_dropdown_layout_spec.js
+++ b/spec/frontend/diffs/components/compare_dropdown_layout_spec.js
@@ -34,7 +34,7 @@ describe('CompareDropdownLayout', () => {
findListItems().wrappers.map((listItem) => ({
href: listItem.find('a').attributes('href'),
text: trimText(listItem.text()),
- createdAt: listItem.findAll(TimeAgo).wrappers[0]?.props('time'),
+ createdAt: listItem.findAllComponents(TimeAgo).wrappers[0]?.props('time'),
isActive: listItem.classes().includes('is-active'),
}));
diff --git a/spec/frontend/diffs/components/diff_discussions_spec.js b/spec/frontend/diffs/components/diff_discussions_spec.js
index b3945257fbd..e9a0e0745fd 100644
--- a/spec/frontend/diffs/components/diff_discussions_spec.js
+++ b/spec/frontend/diffs/components/diff_discussions_spec.js
@@ -34,9 +34,9 @@ describe('DiffDiscussions', () => {
expect(wrapper.findComponent(NoteableDiscussion).exists()).toBe(true);
expect(wrapper.findComponent(DiscussionNotes).exists()).toBe(true);
- expect(wrapper.findComponent(DiscussionNotes).findAll(TimelineEntryItem).length).toBe(
- discussionsMockData.notes.length,
- );
+ expect(
+ wrapper.findComponent(DiscussionNotes).findAllComponents(TimelineEntryItem).length,
+ ).toBe(discussionsMockData.notes.length);
});
});
diff --git a/spec/frontend/diffs/components/diff_stats_spec.js b/spec/frontend/diffs/components/diff_stats_spec.js
index 09fe69e97de..3a04547fa69 100644
--- a/spec/frontend/diffs/components/diff_stats_spec.js
+++ b/spec/frontend/diffs/components/diff_stats_spec.js
@@ -87,7 +87,7 @@ describe('diff_stats', () => {
describe('files changes', () => {
const findIcon = (name) =>
wrapper
- .findAll(GlIcon)
+ .findAllComponents(GlIcon)
.filter((c) => c.attributes('name') === name)
.at(0).element.parentNode;
diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js
index 33b6acd5fd5..e7fa8a574cb 100644
--- a/spec/frontend/diffs/components/diff_view_spec.js
+++ b/spec/frontend/diffs/components/diff_view_spec.js
@@ -88,7 +88,7 @@ describe('DiffView', () => {
diffLines: [{ renderCommentRow: true, ...sides }],
inline: type === 'inline',
});
- expect(wrapper.findAll(DiffCommentCell).length).toBe(total);
+ expect(wrapper.findAllComponents(DiffCommentCell).length).toBe(total);
expect(wrapper.find(container).findComponent(DiffCommentCell).exists()).toBe(true);
},
);
diff --git a/spec/frontend/emoji/components/category_spec.js b/spec/frontend/emoji/components/category_spec.js
index b72aa659d56..90816f28d5b 100644
--- a/spec/frontend/emoji/components/category_spec.js
+++ b/spec/frontend/emoji/components/category_spec.js
@@ -22,7 +22,7 @@ describe('Emoji category component', () => {
});
it('renders emoji groups', () => {
- expect(wrapper.findAll(EmojiGroup).length).toBe(2);
+ expect(wrapper.findAllComponents(EmojiGroup).length).toBe(2);
});
it('renders group', async () => {
diff --git a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
index d210f15ea6f..c9095441d41 100644
--- a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
+++ b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
@@ -76,7 +76,7 @@ describe('error tracking settings project dropdown', () => {
it('contains a number of dropdown items', () => {
expect(wrapper.findComponent(GlDropdownItem).exists()).toBe(true);
- expect(wrapper.findAll(GlDropdownItem).length).toBe(2);
+ expect(wrapper.findAllComponents(GlDropdownItem).length).toBe(2);
});
});
diff --git a/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
index 878cf5ed43b..91457f10bf8 100644
--- a/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
+++ b/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from '@vue/test-utils';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content.vue';
import eventHub from '~/filtered_search/event_hub';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
@@ -6,12 +6,12 @@ import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered
describe('Recent Searches Dropdown Content', () => {
let wrapper;
- const findLocalStorageNote = () => wrapper.findComponent({ ref: 'localStorageNote' });
- const findDropdownItems = () => wrapper.findAll({ ref: 'dropdownItem' });
- const findDropdownNote = () => wrapper.findComponent({ ref: 'dropdownNote' });
+ const findLocalStorageNote = () => wrapper.findByTestId('local-storage-note');
+ const findDropdownItems = () => wrapper.findAllByTestId('dropdown-item');
+ const findDropdownNote = () => wrapper.findByTestId('dropdown-note');
const createComponent = (props) => {
- wrapper = shallowMount(RecentSearchesDropdownContent, {
+ wrapper = shallowMountExtended(RecentSearchesDropdownContent, {
propsData: {
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
items: [],
@@ -94,7 +94,7 @@ describe('Recent Searches Dropdown Content', () => {
});
it('emits requestClearRecentSearches on Clear resent searches button', () => {
- wrapper.findComponent({ ref: 'clearButton' }).trigger('click');
+ wrapper.findByTestId('clear-button').trigger('click');
expect(onRequestClearRecentSearchesSpy).toHaveBeenCalled();
});
diff --git a/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js b/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
index 85e5e2273a5..e6673fa78ec 100644
--- a/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
@@ -1,7 +1,7 @@
import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trimText } from 'helpers/text_helper';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue';
@@ -16,18 +16,18 @@ describe('FrequentItemsListItemComponent', () => {
let trackingSpy;
let store;
- const findTitle = () => wrapper.findComponent({ ref: 'frequentItemsItemTitle' });
+ const findTitle = () => wrapper.findByTestId('frequent-items-item-title');
const findAvatar = () => wrapper.findComponent(ProjectAvatar);
- const findAllTitles = () => wrapper.findAll({ ref: 'frequentItemsItemTitle' });
- const findNamespace = () => wrapper.findComponent({ ref: 'frequentItemsItemNamespace' });
+ const findAllTitles = () => wrapper.findAllByTestId('frequent-items-item-title');
+ const findNamespace = () => wrapper.findByTestId('frequent-items-item-namespace');
const findAllButtons = () => wrapper.findAllComponents(GlButton);
- const findAllNamespace = () => wrapper.findAll({ ref: 'frequentItemsItemNamespace' });
+ const findAllNamespace = () => wrapper.findAllByTestId('frequent-items-item-namespace');
const findAllAvatars = () => wrapper.findAllComponents(ProjectAvatar);
const findAllMetadataContainers = () =>
- wrapper.findAll({ ref: 'frequentItemsItemMetadataContainer' });
+ wrapper.findAllByTestId('frequent-items-item-metadata-container');
const createComponent = (props = {}) => {
- wrapper = shallowMount(frequentItemsListItemComponent, {
+ wrapper = shallowMountExtended(frequentItemsListItemComponent, {
store,
propsData: {
itemId: mockProject.id,
diff --git a/spec/frontend/frequent_items/components/frequent_items_list_spec.js b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
index beaab1913d0..9f08a432a3d 100644
--- a/spec/frontend/frequent_items/components/frequent_items_list_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
@@ -1,6 +1,6 @@
-import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import frequentItemsListComponent from '~/frequent_items/components/frequent_items_list.vue';
import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue';
import { createStore } from '~/frequent_items/store';
@@ -12,7 +12,7 @@ describe('FrequentItemsListComponent', () => {
let wrapper;
const createComponent = (props = {}) => {
- wrapper = mount(frequentItemsListComponent, {
+ wrapper = mountExtended(frequentItemsListComponent, {
store: createStore(),
propsData: {
namespace: 'projects',
@@ -94,8 +94,8 @@ describe('FrequentItemsListComponent', () => {
await nextTick();
expect(wrapper.classes('frequent-items-list-container')).toBe(true);
- expect(wrapper.findAll({ ref: 'frequentItemsList' })).toHaveLength(1);
- expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(5);
+ expect(wrapper.findAllByTestId('frequent-items-list')).toHaveLength(1);
+ expect(wrapper.findAllComponents(frequentItemsListItemComponent)).toHaveLength(5);
});
it('should render component element with empty message', async () => {
@@ -105,7 +105,7 @@ describe('FrequentItemsListComponent', () => {
await nextTick();
expect(wrapper.vm.$el.querySelectorAll('li.section-empty')).toHaveLength(1);
- expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(0);
+ expect(wrapper.findAllComponents(frequentItemsListItemComponent)).toHaveLength(0);
});
});
});
diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
index 8060fb9af7f..c0ae4294e3d 100644
--- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
@@ -30,7 +30,7 @@ describe('ImportProjectsTable', () => {
const findImportAllButton = () =>
wrapper
- .findAll(GlButton)
+ .findAllComponents(GlButton)
.filter((w) => w.props().variant === 'confirm')
.at(0);
const findImportAllModal = () => wrapper.findComponent({ ref: 'importAllModal' });
@@ -118,7 +118,7 @@ describe('ImportProjectsTable', () => {
.exists(),
).toBe(true);
- expect(wrapper.findAll(ProviderRepoTableRow)).toHaveLength(repositories.length);
+ expect(wrapper.findAllComponents(ProviderRepoTableRow)).toHaveLength(repositories.length);
});
it.each`
diff --git a/spec/frontend/incidents/components/incidents_list_spec.js b/spec/frontend/incidents/components/incidents_list_spec.js
index 5f71fde934f..e8d222dc2e9 100644
--- a/spec/frontend/incidents/components/incidents_list_spec.js
+++ b/spec/frontend/incidents/components/incidents_list_spec.js
@@ -44,12 +44,12 @@ describe('Incidents List', () => {
const findTableRows = () => wrapper.findAll('table tbody tr');
const findAlert = () => wrapper.findComponent(GlAlert);
const findLoader = () => wrapper.findComponent(GlLoadingIcon);
- const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip);
+ const findTimeAgo = () => wrapper.findAllComponents(TimeAgoTooltip);
const findAssignees = () => wrapper.findAll('[data-testid="incident-assignees"]');
const findCreateIncidentBtn = () => wrapper.find('[data-testid="createIncidentBtn"]');
const findClosedIcon = () => wrapper.findAll("[data-testid='incident-closed']");
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
- const findSeverity = () => wrapper.findAll(SeverityToken);
+ const findSeverity = () => wrapper.findAllComponents(SeverityToken);
const findEscalationStatus = () => wrapper.findAll('[data-testid="incident-escalation-status"]');
const findIncidentLink = () => wrapper.findByTestId('incident-link');
diff --git a/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js b/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js
index e0ebebf1c7d..394d1f12bcb 100644
--- a/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js
+++ b/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js
@@ -23,7 +23,7 @@ describe('IncidentsSettingTabs', () => {
const findToggleButton = () => wrapper.findComponent({ ref: 'toggleBtn' });
const findSectionHeader = () => wrapper.findComponent({ ref: 'sectionHeader' });
- const findIntegrationTabs = () => wrapper.findAll(GlTab);
+ const findIntegrationTabs = () => wrapper.findAllComponents(GlTab);
it('renders header text', () => {
expect(findSectionHeader().text()).toBe('Incidents');
});
diff --git a/spec/frontend/integrations/edit/components/trigger_fields_spec.js b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
index e13fd39999b..c329ca8522f 100644
--- a/spec/frontend/integrations/edit/components/trigger_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
@@ -24,7 +24,7 @@ describe('TriggerFields', () => {
});
const findTriggerLabel = () => wrapper.findByTestId('trigger-fields-group').find('label');
- const findAllGlFormGroups = () => wrapper.find('#trigger-fields').findAll(GlFormGroup);
+ const findAllGlFormGroups = () => wrapper.find('#trigger-fields').findAllComponents(GlFormGroup);
const findAllGlFormCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
const findAllGlFormInputs = () => wrapper.findAllComponents(GlFormInput);
diff --git a/spec/frontend/issuable/components/issue_assignees_spec.js b/spec/frontend/issuable/components/issue_assignees_spec.js
index 713c8b1dfdd..9a33bfae240 100644
--- a/spec/frontend/issuable/components/issue_assignees_spec.js
+++ b/spec/frontend/issuable/components/issue_assignees_spec.js
@@ -27,7 +27,7 @@ describe('IssueAssigneesComponent', () => {
});
const findTooltipText = () => wrapper.find('.js-assignee-tooltip').text();
- const findAvatars = () => wrapper.findAll(UserAvatarLink);
+ const findAvatars = () => wrapper.findAllComponents(UserAvatarLink);
const findOverflowCounter = () => wrapper.find('.avatar-counter');
it('returns default data props', () => {
diff --git a/spec/frontend/issues/new/components/title_suggestions_item_spec.js b/spec/frontend/issues/new/components/title_suggestions_item_spec.js
index eee6804528f..c54a762440f 100644
--- a/spec/frontend/issues/new/components/title_suggestions_item_spec.js
+++ b/spec/frontend/issues/new/components/title_suggestions_item_spec.js
@@ -20,7 +20,7 @@ describe('Issue title suggestions item component', () => {
}
const findLink = () => wrapper.findComponent(GlLink);
- const findAuthorLink = () => wrapper.findAll(GlLink).at(1);
+ const findAuthorLink = () => wrapper.findAllComponents(GlLink).at(1);
const findIcon = () => wrapper.findComponent(GlIcon);
const findTooltip = () => wrapper.findComponent(GlTooltip);
const findUserAvatar = () => wrapper.findComponent(UserAvatarImage);
diff --git a/spec/frontend/issues/new/components/title_suggestions_spec.js b/spec/frontend/issues/new/components/title_suggestions_spec.js
index 0a64890e4ca..1cd6576967a 100644
--- a/spec/frontend/issues/new/components/title_suggestions_spec.js
+++ b/spec/frontend/issues/new/components/title_suggestions_spec.js
@@ -83,7 +83,7 @@ describe('Issue title suggestions component', () => {
wrapper.setData(data);
await nextTick();
- expect(wrapper.findAll(TitleSuggestionsItem).length).toBe(2);
+ expect(wrapper.findAllComponents(TitleSuggestionsItem).length).toBe(2);
});
it('adds margin class to first item', async () => {
diff --git a/spec/frontend/issues/related_merge_requests/components/related_merge_requests_spec.js b/spec/frontend/issues/related_merge_requests/components/related_merge_requests_spec.js
index 4df04cd5257..d30a8c081cc 100644
--- a/spec/frontend/issues/related_merge_requests/components/related_merge_requests_spec.js
+++ b/spec/frontend/issues/related_merge_requests/components/related_merge_requests_spec.js
@@ -65,9 +65,9 @@ describe('RelatedMergeRequests', () => {
describe('template', () => {
it('should render related merge request items', () => {
expect(wrapper.find('[data-testid="count"]').text()).toBe('2');
- expect(wrapper.findAll(RelatedIssuableItem)).toHaveLength(2);
+ expect(wrapper.findAllComponents(RelatedIssuableItem)).toHaveLength(2);
- const props = wrapper.findAll(RelatedIssuableItem).at(1).props();
+ const props = wrapper.findAllComponents(RelatedIssuableItem).at(1).props();
const data = mockData[1];
expect(props.idKey).toEqual(data.id);
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index d7fa1fa41da..dc2b3c6fc48 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -70,12 +70,12 @@ describe('HeaderActions component', () => {
const findDropdownBy = (dataTestId) => wrapper.find(`[data-testid="${dataTestId}"]`);
const findMobileDropdown = () => findDropdownBy('mobile-dropdown');
const findDesktopDropdown = () => findDropdownBy('desktop-dropdown');
- const findMobileDropdownItems = () => findMobileDropdown().findAll(GlDropdownItem);
- const findDesktopDropdownItems = () => findDesktopDropdown().findAll(GlDropdownItem);
+ const findMobileDropdownItems = () => findMobileDropdown().findAllComponents(GlDropdownItem);
+ const findDesktopDropdownItems = () => findDesktopDropdown().findAllComponents(GlDropdownItem);
const findModal = () => wrapper.findComponent(GlModal);
- const findModalLinkAt = (index) => findModal().findAll(GlLink).at(index);
+ const findModalLinkAt = (index) => findModal().findAllComponents(GlLink).at(index);
const mountComponent = ({
props = {},
diff --git a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
index 6960eb1416e..d92aeabba0f 100644
--- a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
+++ b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
@@ -61,7 +61,7 @@ describe('Incident Tabs component', () => {
);
};
- const findTabs = () => wrapper.findAll(GlTab);
+ const findTabs = () => wrapper.findAllComponents(GlTab);
const findSummaryTab = () => findTabs().at(0);
const findAlertDetailsTab = () => wrapper.find('[data-testid="alert-details-tab"]');
const findAlertDetailsComponent = () => wrapper.findComponent(AlertDetailsTable);
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
index 549b819fa19..dff1c429d07 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
@@ -59,7 +59,7 @@ describe('IncidentTimelineEventList', () => {
};
const findTimelineEventGroups = () => wrapper.findAllByTestId('timeline-group');
- const findItems = (base = wrapper) => base.findAll(IncidentTimelineEventItem);
+ const findItems = (base = wrapper) => base.findAllComponents(IncidentTimelineEventItem);
const findFirstTimelineEventGroup = () => findTimelineEventGroups().at(0);
const findSecondTimelineEventGroup = () => findTimelineEventGroups().at(1);
const findDates = () => wrapper.findAllByTestId('event-date');
diff --git a/spec/frontend/issues/show/components/pinned_links_spec.js b/spec/frontend/issues/show/components/pinned_links_spec.js
index aac720df6e9..208baac7124 100644
--- a/spec/frontend/issues/show/components/pinned_links_spec.js
+++ b/spec/frontend/issues/show/components/pinned_links_spec.js
@@ -9,7 +9,7 @@ const plainStatusUrl = 'https://status.com';
describe('PinnedLinks', () => {
let wrapper;
- const findButtons = () => wrapper.findAll(GlButton);
+ const findButtons = () => wrapper.findAllComponents(GlButton);
const createComponent = (props) => {
wrapper = shallowMount(PinnedLinks, {
diff --git a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
index d871b1e1dcc..f1fc5e4d90b 100644
--- a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
@@ -50,7 +50,7 @@ describe('GroupsList', () => {
const findGlAlert = () => wrapper.findComponent(GlAlert);
const findGlLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findAllItems = () => wrapper.findAll(GroupsListItem);
+ const findAllItems = () => wrapper.findAllComponents(GroupsListItem);
const findFirstItem = () => findAllItems().at(0);
const findSecondItem = () => findAllItems().at(1);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
diff --git a/spec/frontend/jira_import/components/jira_import_form_spec.js b/spec/frontend/jira_import/components/jira_import_form_spec.js
index 783ecec14a2..ca91ce90a02 100644
--- a/spec/frontend/jira_import/components/jira_import_form_spec.js
+++ b/spec/frontend/jira_import/components/jira_import_form_spec.js
@@ -288,7 +288,7 @@ describe('JiraImportForm', () => {
});
it('updates the user list', () => {
- expect(getUserDropdown().findAll(GlDropdownItem)).toHaveLength(1);
+ expect(getUserDropdown().findAllComponents(GlDropdownItem)).toHaveLength(1);
expect(getUserDropdown().findComponent(GlDropdownItem).text()).toContain(
'fchopin (Frederic Chopin)',
);
diff --git a/spec/frontend/milestones/components/milestone_combobox_spec.js b/spec/frontend/milestones/components/milestone_combobox_spec.js
index aee13beacbb..ce5b2a1000b 100644
--- a/spec/frontend/milestones/components/milestone_combobox_spec.js
+++ b/spec/frontend/milestones/components/milestone_combobox_spec.js
@@ -103,12 +103,12 @@ describe('Milestone combobox component', () => {
const findProjectMilestonesSection = () =>
wrapper.find('[data-testid="project-milestones-section"]');
const findProjectMilestonesDropdownItems = () =>
- findProjectMilestonesSection().findAll(GlDropdownItem);
+ findProjectMilestonesSection().findAllComponents(GlDropdownItem);
const findFirstProjectMilestonesDropdownItem = () => findProjectMilestonesDropdownItems().at(0);
const findGroupMilestonesSection = () => wrapper.find('[data-testid="group-milestones-section"]');
const findGroupMilestonesDropdownItems = () =>
- findGroupMilestonesSection().findAll(GlDropdownItem);
+ findGroupMilestonesSection().findAllComponents(GlDropdownItem);
const findFirstGroupMilestonesDropdownItem = () => findGroupMilestonesDropdownItems().at(0);
//
diff --git a/spec/frontend/notifications/components/custom_notifications_modal_spec.js b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
index 02de67f788d..9bde80e930f 100644
--- a/spec/frontend/notifications/components/custom_notifications_modal_spec.js
+++ b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
@@ -57,7 +57,7 @@ describe('CustomNotificationsModal', () => {
}
const findModalBodyDescription = () => wrapper.findComponent(GlSprintf);
- const findAllCheckboxes = () => wrapper.findAll(GlFormCheckbox);
+ const findAllCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
const findCheckboxAt = (index) => findAllCheckboxes().at(index);
beforeEach(() => {
diff --git a/spec/frontend/notifications/components/notifications_dropdown_spec.js b/spec/frontend/notifications/components/notifications_dropdown_spec.js
index 1f950683630..8a6fd72fbeb 100644
--- a/spec/frontend/notifications/components/notifications_dropdown_spec.js
+++ b/spec/frontend/notifications/components/notifications_dropdown_spec.js
@@ -42,7 +42,8 @@ describe('NotificationsDropdown', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
- const findAllNotificationsDropdownItems = () => wrapper.findAll(NotificationsDropdownItem);
+ const findAllNotificationsDropdownItems = () =>
+ wrapper.findAllComponents(NotificationsDropdownItem);
const findDropdownItemAt = (index) =>
findAllNotificationsDropdownItems().at(index).findComponent(GlDropdownItem);
const findNotificationsModal = () => wrapper.findComponent(CustomNotificationsModal);
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
index 88979ea2b25..96c670eaad2 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
@@ -32,7 +32,7 @@ describe('tags list row', () => {
const findShortRevision = () => wrapper.find('[data-testid="digest"]');
const findClipboardButton = () => wrapper.findComponent(ClipboardButton);
const findTimeAgoTooltip = () => wrapper.findComponent(TimeAgoTooltip);
- const findDetailsRows = () => wrapper.findAll(DetailsRow);
+ const findDetailsRows = () => wrapper.findAllComponents(DetailsRow);
const findPublishedDateDetail = () => wrapper.find('[data-testid="published-date-detail"]');
const findManifestDetail = () => wrapper.find('[data-testid="manifest-detail"]');
const findConfigurationDetail = () => wrapper.find('[data-testid="configuration-detail"]');
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
index e5df260a260..3f5d4c3dbf7 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
@@ -5,7 +5,7 @@ import { GlSkeletonLoader } from '../../stubs';
describe('TagsLoader component', () => {
let wrapper;
- const findGlSkeletonLoaders = () => wrapper.findAll(GlSkeletonLoader);
+ const findGlSkeletonLoaders = () => wrapper.findAllComponents(GlSkeletonLoader);
const mountComponent = () => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
index 4d33f75a5fd..042b8383571 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
@@ -8,7 +8,7 @@ import { imagesListResponse, pageInfo as defaultPageInfo } from '../../mock_data
describe('Image List', () => {
let wrapper;
- const findRow = () => wrapper.findAll(ImageListRow);
+ const findRow = () => wrapper.findAllComponents(ImageListRow);
const findPagination = () => wrapper.findComponent(GlKeysetPagination);
const mountComponent = (props) => {
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js
index 304878fe5df..e7e74a0da58 100644
--- a/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js
@@ -7,7 +7,7 @@ import { harborImagesList } from '../../mock_data';
describe('Harbor List', () => {
let wrapper;
- const findHarborListRow = () => wrapper.findAll(HarborListRow);
+ const findHarborListRow = () => wrapper.findAllComponents(HarborListRow);
const mountComponent = (props) => {
wrapper = shallowMount(HarborList, {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
index e2af06416b4..9268dd0b049 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
@@ -7,7 +7,7 @@ describe('packages_filter', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findFilteredSearchSuggestions = () => wrapper.findAllComponents(GlFilteredSearchSuggestion);
const mountComponent = ({ attrs, listeners } = {}) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
index dfa91fd8740..18084766db9 100644
--- a/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
@@ -23,7 +23,7 @@ describe('cli_commands', () => {
let wrapper;
const findDropdownButton = () => wrapper.findComponent(GlDropdown);
- const findCodeInstruction = () => wrapper.findAll(CodeInstruction);
+ const findCodeInstruction = () => wrapper.findAllComponents(CodeInstruction);
const mountComponent = () => {
wrapper = mount(QuickstartDropdown, {
diff --git a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
index b393a855a9f..b020caa3010 100644
--- a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
+++ b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
@@ -14,7 +14,7 @@ describe('BitbucketServerStatusTable', () => {
const findReconfigureButton = () =>
wrapper
- .findAll(GlButton)
+ .findAllComponents(GlButton)
.filter((w) => w.props().variant === 'info')
.at(0);
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
index ebb254b49c1..f221a90da61 100644
--- a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
+++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
@@ -200,7 +200,7 @@ describe('ForkForm component', () => {
it('displays the correct description', () => {
createComponent();
- const formRadios = wrapper.findAll(GlFormRadio);
+ const formRadios = wrapper.findAllComponents(GlFormRadio);
Object.keys(PROJECT_VISIBILITY_TYPE).forEach((visibilityType, index) => {
expect(formRadios.at(index).text()).toBe(PROJECT_VISIBILITY_TYPE[visibilityType]);
@@ -210,7 +210,7 @@ describe('ForkForm component', () => {
it('displays all 3 visibility levels', () => {
createComponent();
- expect(wrapper.findAll(GlFormRadio)).toHaveLength(3);
+ expect(wrapper.findAllComponents(GlFormRadio)).toHaveLength(3);
});
describe('when the namespace is changed', () => {
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
index c9c0e406c46..2f2edd6b025 100644
--- a/spec/frontend/pages/projects/graphs/code_coverage_spec.js
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -22,7 +22,7 @@ describe('Code Coverage', () => {
const findAlert = () => wrapper.findComponent(GlAlert);
const findAreaChart = () => wrapper.findComponent(GlAreaChart);
- const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findFirstDropdownItem = () => findAllDropdownItems().at(0);
const findSecondDropdownItem = () => findAllDropdownItems().at(1);
const findDownloadButton = () => wrapper.find('[data-testid="download-button"]');
diff --git a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
index 7dbacad34bf..8f6f4d8cff9 100644
--- a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
+++ b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
@@ -119,7 +119,7 @@ describe('Pipeline editor branch switcher', () => {
};
const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const findInfiniteScroll = () => wrapper.findComponent(GlInfiniteScroll);
diff --git a/spec/frontend/pipeline_editor/components/file-tree/container_spec.js b/spec/frontend/pipeline_editor/components/file-tree/container_spec.js
index 04a93e8db25..f79074f1e0f 100644
--- a/spec/frontend/pipeline_editor/components/file-tree/container_spec.js
+++ b/spec/frontend/pipeline_editor/components/file-tree/container_spec.js
@@ -31,7 +31,7 @@ describe('Pipeline editor file nav', () => {
const findTip = () => wrapper.findComponent(GlAlert);
const findCurrentConfigFilename = () => wrapper.findByTestId('current-config-filename');
- const fileTreeItems = () => wrapper.findAll(PipelineEditorFileTreeItem);
+ const fileTreeItems = () => wrapper.findAllComponents(PipelineEditorFileTreeItem);
afterEach(() => {
localStorage.clear();
diff --git a/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js b/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
index 3a40ce32a24..24f27e8c5fb 100644
--- a/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
+++ b/spec/frontend/pipeline_editor/components/ui/editor_tab_spec.js
@@ -58,7 +58,7 @@ describe('~/pipeline_editor/components/ui/editor_tab.vue', () => {
const findSlotComponent = () => wrapper.findComponent(MockSourceEditor);
const findAlert = () => wrapper.findComponent(GlAlert);
- const findBadges = () => wrapper.findAll(GlBadge);
+ const findBadges = () => wrapper.findAllComponents(GlBadge);
beforeEach(() => {
mockChildMounted = jest.fn();
diff --git a/spec/frontend/pipeline_new/components/refs_dropdown_spec.js b/spec/frontend/pipeline_new/components/refs_dropdown_spec.js
index 01d4bd7786f..8cba876c688 100644
--- a/spec/frontend/pipeline_new/components/refs_dropdown_spec.js
+++ b/spec/frontend/pipeline_new/components/refs_dropdown_spec.js
@@ -20,7 +20,7 @@ describe('Pipeline New Form', () => {
let mock;
const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findRefsDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findRefsDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const createComponent = (props = {}, mountFn = shallowMount) => {
diff --git a/spec/frontend/pipelines/components/dag/dag_spec.js b/spec/frontend/pipelines/components/dag/dag_spec.js
index 5cc6537e964..b0c26976c85 100644
--- a/spec/frontend/pipelines/components/dag/dag_spec.js
+++ b/spec/frontend/pipelines/components/dag/dag_spec.js
@@ -19,7 +19,7 @@ import {
describe('Pipeline DAG graph wrapper', () => {
let wrapper;
const getAlert = () => wrapper.findComponent(GlAlert);
- const getAllAlerts = () => wrapper.findAll(GlAlert);
+ const getAllAlerts = () => wrapper.findAllComponents(GlAlert);
const getGraph = () => wrapper.findComponent(DagGraph);
const getNotes = () => wrapper.findComponent(DagAnnotations);
const getErrorText = (type) => wrapper.vm.$options.errorTexts[type];
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js b/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js
index 03eca50c460..bfb780d5d39 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js
+++ b/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js
@@ -8,7 +8,7 @@ const mockStages = pipelines[0].details.stages;
describe('Pipeline Stages', () => {
let wrapper;
- const findPipelineStages = () => wrapper.findAll(PipelineStage);
+ const findPipelineStages = () => wrapper.findAllComponents(PipelineStage);
const findPipelineStagesAt = (i) => findPipelineStages().at(i);
const createComponent = (props = {}) => {
diff --git a/spec/frontend/pipelines/graph/graph_component_spec.js b/spec/frontend/pipelines/graph/graph_component_spec.js
index 3ab58882786..2abb5f7dc58 100644
--- a/spec/frontend/pipelines/graph/graph_component_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_spec.js
@@ -15,9 +15,9 @@ import {
describe('graph component', () => {
let wrapper;
- const findLinkedColumns = () => wrapper.findAll(LinkedPipelinesColumn);
+ const findLinkedColumns = () => wrapper.findAllComponents(LinkedPipelinesColumn);
const findLinksLayer = () => wrapper.findComponent(LinksLayer);
- const findStageColumns = () => wrapper.findAll(StageColumnComponent);
+ const findStageColumns = () => wrapper.findAllComponents(StageColumnComponent);
const findStageNameInJob = () => wrapper.find('[data-testid="stage-name-in-job"]');
const defaultProps = {
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
index 50fae3ee495..63e2d8707ea 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
@@ -38,7 +38,7 @@ describe('Linked Pipelines Column', () => {
let wrapper;
const findLinkedColumnTitle = () => wrapper.find('[data-testid="linked-column-title"]');
- const findLinkedPipelineElements = () => wrapper.findAll(LinkedPipeline);
+ const findLinkedPipelineElements = () => wrapper.findAllComponents(LinkedPipeline);
const findPipelineGraph = () => wrapper.findComponent(PipelineGraph);
const findExpandButton = () => wrapper.find('[data-testid="expand-pipeline-button"]');
diff --git a/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js b/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js
index 1b89e322d31..d9199f3b0f7 100644
--- a/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js
+++ b/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js
@@ -34,7 +34,7 @@ describe('pipeline graph component', () => {
};
const findAlert = () => wrapper.findComponent(GlAlert);
- const findAllJobPills = () => wrapper.findAll(JobPill);
+ const findAllJobPills = () => wrapper.findAllComponents(JobPill);
const findAllStageNames = () => wrapper.findAllComponents(StageName);
const findLinksLayer = () => wrapper.findComponent(LinksLayer);
const findPipelineGraph = () => wrapper.find('[data-testid="graph-container"]');
diff --git a/spec/frontend/pipelines/pipelines_actions_spec.js b/spec/frontend/pipelines/pipelines_actions_spec.js
index ac4be04fc41..fdfced38dca 100644
--- a/spec/frontend/pipelines/pipelines_actions_spec.js
+++ b/spec/frontend/pipelines/pipelines_actions_spec.js
@@ -32,8 +32,8 @@ describe('Pipelines Actions dropdown', () => {
};
const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
- const findAllCountdowns = () => wrapper.findAll(GlCountdown);
+ const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findAllCountdowns = () => wrapper.findAllComponents(GlCountdown);
beforeEach(() => {
mock = new MockAdapter(axios);
diff --git a/spec/frontend/pipelines/pipelines_artifacts_spec.js b/spec/frontend/pipelines/pipelines_artifacts_spec.js
index 481d98fcba7..e3e54716a7b 100644
--- a/spec/frontend/pipelines/pipelines_artifacts_spec.js
+++ b/spec/frontend/pipelines/pipelines_artifacts_spec.js
@@ -31,7 +31,8 @@ describe('Pipelines Artifacts dropdown', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findFirstGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
- const findAllGlDropdownItems = () => wrapper.findComponent(GlDropdown).findAll(GlDropdownItem);
+ const findAllGlDropdownItems = () =>
+ wrapper.findComponent(GlDropdown).findAllComponents(GlDropdownItem);
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
index 497d03bff51..caa66502e11 100644
--- a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
@@ -10,7 +10,8 @@ describe('Pipeline Branch Name Token', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllFilteredSearchSuggestions = () =>
+ wrapper.findAllComponents(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const getBranchSuggestions = () =>
findAllFilteredSearchSuggestions().wrappers.map((w) => w.text());
diff --git a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
index 7d60a961621..60abb63a7e0 100644
--- a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
@@ -8,7 +8,8 @@ describe('Pipeline Source Token', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllFilteredSearchSuggestions = () =>
+ wrapper.findAllComponents(GlFilteredSearchSuggestion);
const defaultProps = {
config: {
diff --git a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
index 1a51d8b251d..94f9a37f707 100644
--- a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
@@ -7,8 +7,9 @@ describe('Pipeline Status Token', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
- const findAllGlIcons = () => wrapper.findAll(GlIcon);
+ const findAllFilteredSearchSuggestions = () =>
+ wrapper.findAllComponents(GlFilteredSearchSuggestion);
+ const findAllGlIcons = () => wrapper.findAllComponents(GlIcon);
const defaultProps = {
config: {
diff --git a/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
index 8dd79bcfb88..7311a5d2f5a 100644
--- a/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
@@ -8,7 +8,8 @@ describe('Pipeline Branch Name Token', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllFilteredSearchSuggestions = () =>
+ wrapper.findAllComponents(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const stubs = {
diff --git a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
index 39986ca7904..c763bfe1b27 100644
--- a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
@@ -9,7 +9,8 @@ describe('Pipeline Trigger Author Token', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllFilteredSearchSuggestions = () =>
+ wrapper.findAllComponents(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const defaultProps = {
diff --git a/spec/frontend/popovers/components/popovers_spec.js b/spec/frontend/popovers/components/popovers_spec.js
index 0d00cb043d5..eba6b95214d 100644
--- a/spec/frontend/popovers/components/popovers_spec.js
+++ b/spec/frontend/popovers/components/popovers_spec.js
@@ -31,7 +31,7 @@ describe('popovers/components/popovers.vue', () => {
return target;
};
- const allPopovers = () => wrapper.findAll(GlPopover);
+ const allPopovers = () => wrapper.findAllComponents(GlPopover);
afterEach(() => {
wrapper.destroy();
@@ -52,7 +52,7 @@ describe('popovers/components/popovers.vue', () => {
await nextTick();
- expect(wrapper.findAll(GlPopover)).toHaveLength(1);
+ expect(wrapper.findAllComponents(GlPopover)).toHaveLength(1);
});
describe('supports HTML content', () => {
diff --git a/spec/frontend/profile/preferences/components/profile_preferences_spec.js b/spec/frontend/profile/preferences/components/profile_preferences_spec.js
index 4d2dcf83d3b..89ce838a383 100644
--- a/spec/frontend/profile/preferences/components/profile_preferences_spec.js
+++ b/spec/frontend/profile/preferences/components/profile_preferences_spec.js
@@ -90,7 +90,7 @@ describe('ProfilePreferences component', () => {
it('should not render Integrations section', () => {
wrapper = createComponent();
- const views = wrapper.findAll(IntegrationView);
+ const views = wrapper.findAllComponents(IntegrationView);
const divider = findIntegrationsDivider();
const heading = findIntegrationsHeading();
@@ -103,7 +103,7 @@ describe('ProfilePreferences component', () => {
wrapper = createComponent({ provide: { integrationViews } });
const divider = findIntegrationsDivider();
const heading = findIntegrationsHeading();
- const views = wrapper.findAll(IntegrationView);
+ const views = wrapper.findAllComponents(IntegrationView);
expect(divider.exists()).toBe(true);
expect(heading.exists()).toBe(true);
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index 287bfe1c14d..907e0e226b6 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -62,7 +62,7 @@ describe('Author Select', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownHeader = () => wrapper.findComponent(GlDropdownSectionHeader);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
- const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
describe('user is searching via "filter by commit message"', () => {
it('disables dropdown container', async () => {
diff --git a/spec/frontend/projects/compare/components/app_spec.js b/spec/frontend/projects/compare/components/app_spec.js
index a24e40b842c..2dbecf7cc61 100644
--- a/spec/frontend/projects/compare/components/app_spec.js
+++ b/spec/frontend/projects/compare/components/app_spec.js
@@ -58,7 +58,7 @@ describe('CompareApp component', () => {
});
it('render Source and Target BranchDropdown components', () => {
- const revisionCards = wrapper.findAll(RevisionCard);
+ const revisionCards = wrapper.findAllComponents(RevisionCard);
expect(revisionCards.length).toBe(2);
expect(revisionCards.at(0).props('revisionText')).toBe('Source');
diff --git a/spec/frontend/projects/compare/components/repo_dropdown_spec.js b/spec/frontend/projects/compare/components/repo_dropdown_spec.js
index 8e720b40e6f..21cca857c6a 100644
--- a/spec/frontend/projects/compare/components/repo_dropdown_spec.js
+++ b/spec/frontend/projects/compare/components/repo_dropdown_spec.js
@@ -73,7 +73,7 @@ describe('RepoDropdown component', () => {
});
it('emits `selectProject` event when another target project is selected', async () => {
- findGlDropdown().findAll(GlDropdownItem).at(0).vm.$emit('click');
+ findGlDropdown().findAllComponents(GlDropdownItem).at(0).vm.$emit('click');
await nextTick();
expect(wrapper.emitted('selectProject')[0][0]).toEqual({
diff --git a/spec/frontend/projects/compare/components/revision_card_spec.js b/spec/frontend/projects/compare/components/revision_card_spec.js
index a741393fcf3..b23bd91ceda 100644
--- a/spec/frontend/projects/compare/components/revision_card_spec.js
+++ b/spec/frontend/projects/compare/components/revision_card_spec.js
@@ -32,10 +32,10 @@ describe('RepoDropdown component', () => {
});
it('renders RepoDropdown component', () => {
- expect(wrapper.findAll(RepoDropdown).exists()).toBe(true);
+ expect(wrapper.findAllComponents(RepoDropdown).exists()).toBe(true);
});
it('renders RevisionDropdown component', () => {
- expect(wrapper.findAll(RevisionDropdown).exists()).toBe(true);
+ expect(wrapper.findAllComponents(RevisionDropdown).exists()).toBe(true);
});
});
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
index 8d4711a79ed..f64af1aa994 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
@@ -99,7 +99,7 @@ describe('RevisionDropdown component', () => {
});
it('emits a "selectRevision" event when a revision is selected', async () => {
- const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findGlDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_spec.js
index bd8c0d2784f..35e32fd3da0 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_spec.js
@@ -144,7 +144,7 @@ describe('RevisionDropdown component', () => {
wrapper.vm.branches = ['some-branch'];
await nextTick();
- findGlDropdown().findAll(GlDropdownItem).at(0).vm.$emit('click');
+ findGlDropdown().findAllComponents(GlDropdownItem).at(0).vm.$emit('click');
expect(wrapper.emitted('selectRevision')[0][0]).toEqual({
direction: 'to',
diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js
index db9d7eb9a8a..e3aaf760d1e 100644
--- a/spec/frontend/projects/pipelines/charts/components/app_spec.js
+++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js
@@ -48,7 +48,7 @@ describe('ProjectsPipelinesChartsApp', () => {
});
const findGlTabs = () => wrapper.findComponent(GlTabs);
- const findAllGlTabs = () => wrapper.findAll(GlTab);
+ const findAllGlTabs = () => wrapper.findAllComponents(GlTab);
const findGlTabAtIndex = (index) => findAllGlTabs().at(index);
const findLeadTimeCharts = () => wrapper.findComponent(LeadTimeChartsStub);
const findTimeToRestoreServiceCharts = () =>
diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_template_dropdown_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_template_dropdown_spec.js
index dde06d40a4d..6adcfbe8157 100644
--- a/spec/frontend/projects/settings_service_desk/components/service_desk_template_dropdown_spec.js
+++ b/spec/frontend/projects/settings_service_desk/components/service_desk_template_dropdown_spec.js
@@ -53,7 +53,7 @@ describe('ServiceDeskTemplateDropdown', () => {
props: { templates: TEMPLATES },
});
- const headerItems = wrapper.findAll(GlDropdownSectionHeader);
+ const headerItems = wrapper.findAllComponents(GlDropdownSectionHeader);
expect(headerItems).toHaveLength(1);
expect(headerItems.at(0).text()).toBe(TEMPLATES[0]);
@@ -68,7 +68,7 @@ describe('ServiceDeskTemplateDropdown', () => {
const expectedTemplates = templates[1];
- const items = wrapper.findAll(GlDropdownItem);
+ const items = wrapper.findAllComponents(GlDropdownItem);
const dropdownList = expectedTemplates.map((_, index) => items.at(index).text());
expect(items).toHaveLength(expectedTemplates.length);
diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js
index 851a3fcaf33..6c5af5a2625 100644
--- a/spec/frontend/ref/components/ref_selector_spec.js
+++ b/spec/frontend/ref/components/ref_selector_spec.js
@@ -98,15 +98,15 @@ describe('Ref selector component', () => {
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const findBranchesSection = () => wrapper.find('[data-testid="branches-section"]');
- const findBranchDropdownItems = () => findBranchesSection().findAll(GlDropdownItem);
+ const findBranchDropdownItems = () => findBranchesSection().findAllComponents(GlDropdownItem);
const findFirstBranchDropdownItem = () => findBranchDropdownItems().at(0);
const findTagsSection = () => wrapper.find('[data-testid="tags-section"]');
- const findTagDropdownItems = () => findTagsSection().findAll(GlDropdownItem);
+ const findTagDropdownItems = () => findTagsSection().findAllComponents(GlDropdownItem);
const findFirstTagDropdownItem = () => findTagDropdownItems().at(0);
const findCommitsSection = () => wrapper.find('[data-testid="commits-section"]');
- const findCommitDropdownItems = () => findCommitsSection().findAll(GlDropdownItem);
+ const findCommitDropdownItems = () => findCommitsSection().findAllComponents(GlDropdownItem);
const findFirstCommitDropdownItem = () => findCommitDropdownItems().at(0);
//
diff --git a/spec/frontend/releases/components/release_block_milestone_info_spec.js b/spec/frontend/releases/components/release_block_milestone_info_spec.js
index 89ae556f906..541d487091c 100644
--- a/spec/frontend/releases/components/release_block_milestone_info_spec.js
+++ b/spec/frontend/releases/components/release_block_milestone_info_spec.js
@@ -58,7 +58,7 @@ describe('Release block milestone info', () => {
expect(milestoneListContainer().text()).toMatchInterpolatedText('Milestones 12.3 • 12.4');
milestones.forEach((m, i) => {
- const milestoneLink = milestoneListContainer().findAll(GlLink).at(i);
+ const milestoneLink = milestoneListContainer().findAllComponents(GlLink).at(i);
expect(milestoneLink.text()).toBe(m.title);
expect(milestoneLink.attributes('href')).toBe(m.webUrl);
diff --git a/spec/frontend/reports/components/grouped_issues_list_spec.js b/spec/frontend/reports/components/grouped_issues_list_spec.js
index 74c17b0b8fc..6c0275dc47d 100644
--- a/spec/frontend/reports/components/grouped_issues_list_spec.js
+++ b/spec/frontend/reports/components/grouped_issues_list_spec.js
@@ -67,7 +67,7 @@ describe('Grouped Issues List', () => {
propsData: { [`${issueName}Issues`]: issues },
});
- expect(wrapper.findAll(ReportItem)).toHaveLength(issues.length);
+ expect(wrapper.findAllComponents(ReportItem)).toHaveLength(issues.length);
});
it('renders a report item with the correct props', () => {
diff --git a/spec/frontend/repository/components/blob_button_group_spec.js b/spec/frontend/repository/components/blob_button_group_spec.js
index d5b882bd715..a00f49ec4f8 100644
--- a/spec/frontend/repository/components/blob_button_group_spec.js
+++ b/spec/frontend/repository/components/blob_button_group_spec.js
@@ -66,12 +66,12 @@ describe('BlobButtonGroup component', () => {
});
it('renders both the replace and delete button', () => {
- expect(wrapper.findAll(GlButton)).toHaveLength(2);
+ expect(wrapper.findAllComponents(GlButton)).toHaveLength(2);
});
it('renders the buttons in the correct order', () => {
- expect(wrapper.findAll(GlButton).at(0).text()).toBe('Replace');
- expect(wrapper.findAll(GlButton).at(1).text()).toBe('Delete');
+ expect(wrapper.findAllComponents(GlButton).at(0).text()).toBe('Replace');
+ expect(wrapper.findAllComponents(GlButton).at(1).text()).toBe('Delete');
});
it('triggers the UploadBlobModal from the replace button', () => {
diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js
index a1a292e9678..c2f34f79f89 100644
--- a/spec/frontend/repository/components/breadcrumbs_spec.js
+++ b/spec/frontend/repository/components/breadcrumbs_spec.js
@@ -55,7 +55,7 @@ describe('Repository breadcrumbs component', () => {
`('renders $linkCount links for path $path', ({ path, linkCount }) => {
factory(path);
- expect(wrapper.findAll(RouterLinkStub).length).toEqual(linkCount);
+ expect(wrapper.findAllComponents(RouterLinkStub).length).toEqual(linkCount);
});
it.each`
@@ -68,14 +68,14 @@ describe('Repository breadcrumbs component', () => {
'links to the correct router path when routeName is $routeName',
({ routeName, path, linkTo }) => {
factory(path, {}, { name: routeName });
- expect(wrapper.findAll(RouterLinkStub).at(3).props('to')).toEqual(linkTo);
+ expect(wrapper.findAllComponents(RouterLinkStub).at(3).props('to')).toEqual(linkTo);
},
);
it('escapes hash in directory path', () => {
factory('app/assets/javascripts#');
- expect(wrapper.findAll(RouterLinkStub).at(3).props('to')).toEqual(
+ expect(wrapper.findAllComponents(RouterLinkStub).at(3).props('to')).toEqual(
'/-/tree/app/assets/javascripts%23',
);
});
@@ -83,7 +83,9 @@ describe('Repository breadcrumbs component', () => {
it('renders last link as active', () => {
factory('app/assets');
- expect(wrapper.findAll(RouterLinkStub).at(2).attributes('aria-current')).toEqual('page');
+ expect(wrapper.findAllComponents(RouterLinkStub).at(2).attributes('aria-current')).toEqual(
+ 'page',
+ );
});
it('does not render add to tree dropdown when permissions are false', async () => {
diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js
index ff0371b5c07..57b481634ca 100644
--- a/spec/frontend/repository/components/table/index_spec.js
+++ b/spec/frontend/repository/components/table/index_spec.js
@@ -115,7 +115,7 @@ describe('Repository table component', () => {
commits: MOCK_COMMITS,
});
- const rows = vm.findAll(TableRow);
+ const rows = vm.findAllComponents(TableRow);
expect(rows.length).toEqual(3);
expect(rows.at(2).attributes().mode).toEqual('120000');
diff --git a/spec/frontend/runner/components/runner_type_tabs_spec.js b/spec/frontend/runner/components/runner_type_tabs_spec.js
index 22d2a9e60f7..45ab8684332 100644
--- a/spec/frontend/runner/components/runner_type_tabs_spec.js
+++ b/spec/frontend/runner/components/runner_type_tabs_spec.js
@@ -28,7 +28,7 @@ const mockCount = (type, multiplier = 1) => {
describe('RunnerTypeTabs', () => {
let wrapper;
- const findTabs = () => wrapper.findAll(GlTab);
+ const findTabs = () => wrapper.findAllComponents(GlTab);
const findActiveTab = () =>
findTabs()
.filter((tab) => tab.attributes('active') === 'true')
diff --git a/spec/frontend/search/sidebar/components/radio_filter_spec.js b/spec/frontend/search/sidebar/components/radio_filter_spec.js
index 39d5ee581ec..c0a8259b4fe 100644
--- a/spec/frontend/search/sidebar/components/radio_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/radio_filter_spec.js
@@ -44,7 +44,7 @@ describe('RadioFilter', () => {
});
const findGlRadioButtonGroup = () => wrapper.find(GlFormRadioGroup);
- const findGlRadioButtons = () => findGlRadioButtonGroup().findAll(GlFormRadio);
+ const findGlRadioButtons = () => findGlRadioButtonGroup().findAllComponents(GlFormRadio);
const findGlRadioButtonsText = () => findGlRadioButtons().wrappers.map((w) => w.text());
describe('template', () => {
diff --git a/spec/frontend/search/sort/components/app_spec.js b/spec/frontend/search/sort/components/app_spec.js
index 04520a3e704..0e8eebba3cb 100644
--- a/spec/frontend/search/sort/components/app_spec.js
+++ b/spec/frontend/search/sort/components/app_spec.js
@@ -46,7 +46,7 @@ describe('GlobalSearchSort', () => {
const findSortButtonGroup = () => wrapper.find(GlButtonGroup);
const findSortDropdown = () => wrapper.find(GlDropdown);
const findSortDirectionButton = () => wrapper.find(GlButton);
- const findDropdownItems = () => findSortDropdown().findAll(GlDropdownItem);
+ const findDropdownItems = () => findSortDropdown().findAllComponents(GlDropdownItem);
const findDropdownItemsText = () => findDropdownItems().wrappers.map((w) => w.text());
describe('template', () => {
diff --git a/spec/frontend/sidebar/components/assignees/collapsed_assignee_list_spec.js b/spec/frontend/sidebar/components/assignees/collapsed_assignee_list_spec.js
index 5aa8264b98c..81ff51133bf 100644
--- a/spec/frontend/sidebar/components/assignees/collapsed_assignee_list_spec.js
+++ b/spec/frontend/sidebar/components/assignees/collapsed_assignee_list_spec.js
@@ -23,7 +23,7 @@ describe('CollapsedAssigneeList component', () => {
const findNoUsersIcon = () => wrapper.find(GlIcon);
const findAvatarCounter = () => wrapper.find('.avatar-counter');
- const findAssignees = () => wrapper.findAll(CollapsedAssignee);
+ const findAssignees = () => wrapper.findAllComponents(CollapsedAssignee);
const getTooltipTitle = () => wrapper.attributes('title');
afterEach(() => {
diff --git a/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js b/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
index f7437386814..b902d7313fd 100644
--- a/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
+++ b/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
@@ -42,7 +42,7 @@ describe('UncollapsedAssigneeList component', () => {
});
it('only has one user', () => {
- expect(wrapper.findAll(AssigneeAvatarLink).length).toBe(1);
+ expect(wrapper.findAllComponents(AssigneeAvatarLink).length).toBe(1);
});
it('calls the AssigneeAvatarLink with the proper props', () => {
@@ -79,7 +79,7 @@ describe('UncollapsedAssigneeList component', () => {
});
it('shows truncated users', () => {
- expect(wrapper.findAll(AssigneeAvatarLink).length).toBe(DEFAULT_RENDER_COUNT);
+ expect(wrapper.findAllComponents(AssigneeAvatarLink).length).toBe(DEFAULT_RENDER_COUNT);
});
describe('when more button is clicked', () => {
@@ -94,7 +94,9 @@ describe('UncollapsedAssigneeList component', () => {
});
it('shows all users', () => {
- expect(wrapper.findAll(AssigneeAvatarLink).length).toBe(DEFAULT_RENDER_COUNT + 1);
+ expect(wrapper.findAllComponents(AssigneeAvatarLink).length).toBe(
+ DEFAULT_RENDER_COUNT + 1,
+ );
});
});
});
diff --git a/spec/frontend/sidebar/components/date/sidebar_inherit_date_spec.js b/spec/frontend/sidebar/components/date/sidebar_inherit_date_spec.js
index fda21e06987..a7556b9110c 100644
--- a/spec/frontend/sidebar/components/date/sidebar_inherit_date_spec.js
+++ b/spec/frontend/sidebar/components/date/sidebar_inherit_date_spec.js
@@ -5,10 +5,10 @@ import SidebarInheritDate from '~/sidebar/components/date/sidebar_inherit_date.v
describe('SidebarInheritDate', () => {
let wrapper;
- const findFixedFormattedDate = () => wrapper.findAll(SidebarFormattedDate).at(0);
- const findInheritFormattedDate = () => wrapper.findAll(SidebarFormattedDate).at(1);
- const findFixedRadio = () => wrapper.findAll(GlFormRadio).at(0);
- const findInheritRadio = () => wrapper.findAll(GlFormRadio).at(1);
+ const findFixedFormattedDate = () => wrapper.findAllComponents(SidebarFormattedDate).at(0);
+ const findInheritFormattedDate = () => wrapper.findAllComponents(SidebarFormattedDate).at(1);
+ const findFixedRadio = () => wrapper.findAllComponents(GlFormRadio).at(0);
+ const findInheritRadio = () => wrapper.findAllComponents(GlFormRadio).at(1);
const createComponent = ({ dueDateIsFixed = false } = {}) => {
wrapper = shallowMount(SidebarInheritDate, {
@@ -36,8 +36,8 @@ describe('SidebarInheritDate', () => {
});
it('displays formatted fixed and inherited dates with radio buttons', () => {
- expect(wrapper.findAll(SidebarFormattedDate)).toHaveLength(2);
- expect(wrapper.findAll(GlFormRadio)).toHaveLength(2);
+ expect(wrapper.findAllComponents(SidebarFormattedDate)).toHaveLength(2);
+ expect(wrapper.findAllComponents(GlFormRadio)).toHaveLength(2);
expect(findFixedFormattedDate().props('formattedDate')).toBe('Apr 15, 2021');
expect(findInheritFormattedDate().props('formattedDate')).toBe('May 15, 2021');
expect(findFixedRadio().text()).toBe('Fixed:');
diff --git a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
index 2c24df2436a..d00c8dcb653 100644
--- a/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/uncollapsed_reviewer_list_spec.js
@@ -52,7 +52,7 @@ describe('UncollapsedReviewerList component', () => {
});
it('only has one user', () => {
- expect(wrapper.findAll(ReviewerAvatarLink).length).toBe(1);
+ expect(wrapper.findAllComponents(ReviewerAvatarLink).length).toBe(1);
});
it('shows one user with avatar, and author name', () => {
@@ -96,7 +96,7 @@ describe('UncollapsedReviewerList component', () => {
});
it('has both users', () => {
- expect(wrapper.findAll(ReviewerAvatarLink).length).toBe(2);
+ expect(wrapper.findAllComponents(ReviewerAvatarLink).length).toBe(2);
});
it('shows both users with avatar, and author name', () => {
diff --git a/spec/frontend/snippets/components/show_spec.js b/spec/frontend/snippets/components/show_spec.js
index b29ed97099f..d3b5c0e69db 100644
--- a/spec/frontend/snippets/components/show_spec.js
+++ b/spec/frontend/snippets/components/show_spec.js
@@ -85,7 +85,7 @@ describe('Snippet view app', () => {
},
},
});
- const blobs = wrapper.findAll(SnippetBlob);
+ const blobs = wrapper.findAllComponents(SnippetBlob);
expect(blobs.length).toBe(2);
expect(blobs.at(0).props('blob')).toEqual(Blob);
expect(blobs.at(1).props('blob')).toEqual(BinaryBlob);
diff --git a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
index df98312b498..a650353093d 100644
--- a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
@@ -32,7 +32,7 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
};
const findLabel = () => wrapper.findComponent(GlFormGroup);
- const findBlobEdits = () => wrapper.findAll(SnippetBlobEdit);
+ const findBlobEdits = () => wrapper.findAllComponents(SnippetBlobEdit);
const findBlobsData = () =>
findBlobEdits().wrappers.map((x) => ({
blob: x.props('blob'),
diff --git a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js
index 62d1ac9b476..a86ff566683 100644
--- a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js
+++ b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js
@@ -38,7 +38,7 @@ describe('Snippet Visibility Edit component', () => {
}
const findLink = () => wrapper.find('label').find(GlLink);
- const findRadios = () => wrapper.find(GlFormRadioGroup).findAll(GlFormRadio);
+ const findRadios = () => wrapper.find(GlFormRadioGroup).findAllComponents(GlFormRadio);
const findRadiosData = () =>
findRadios().wrappers.map((x) => {
return {
diff --git a/spec/frontend/terraform/components/states_table_spec.js b/spec/frontend/terraform/components/states_table_spec.js
index 16ffd2b7013..12a44452717 100644
--- a/spec/frontend/terraform/components/states_table_spec.js
+++ b/spec/frontend/terraform/components/states_table_spec.js
@@ -134,7 +134,7 @@ describe('StatesTable', () => {
await nextTick();
};
- const findActions = () => wrapper.findAll(StateActions);
+ const findActions = () => wrapper.findAllComponents(StateActions);
beforeEach(() => {
return createComponent();
diff --git a/spec/frontend/tooltips/components/tooltips_spec.js b/spec/frontend/tooltips/components/tooltips_spec.js
index eef352a72ff..998bb2a9ea2 100644
--- a/spec/frontend/tooltips/components/tooltips_spec.js
+++ b/spec/frontend/tooltips/components/tooltips_spec.js
@@ -28,7 +28,7 @@ describe('tooltips/components/tooltips.vue', () => {
return target;
};
- const allTooltips = () => wrapper.findAll(GlTooltip);
+ const allTooltips = () => wrapper.findAllComponents(GlTooltip);
afterEach(() => {
wrapper.destroy();
@@ -68,7 +68,7 @@ describe('tooltips/components/tooltips.vue', () => {
await nextTick();
- expect(wrapper.findAll(GlTooltip)).toHaveLength(1);
+ expect(wrapper.findAllComponents(GlTooltip)).toHaveLength(1);
});
it('sets tooltip content from title attribute', async () => {
diff --git a/spec/frontend/vue_merge_request_widget/components/artifacts_list_spec.js b/spec/frontend/vue_merge_request_widget/components/artifacts_list_spec.js
index 712abfe228a..d519ad2cdb0 100644
--- a/spec/frontend/vue_merge_request_widget/components/artifacts_list_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/artifacts_list_spec.js
@@ -39,10 +39,12 @@ describe('Artifacts List', () => {
});
it('renders job url', () => {
- expect(wrapper.findAll(GlLink).at(1).attributes('href')).toEqual(data.artifacts[0].job_path);
+ expect(wrapper.findAllComponents(GlLink).at(1).attributes('href')).toEqual(
+ data.artifacts[0].job_path,
+ );
});
it('renders job name', () => {
- expect(wrapper.findAll(GlLink).at(1).text()).toEqual(data.artifacts[0].job_name);
+ expect(wrapper.findAllComponents(GlLink).at(1).text()).toEqual(data.artifacts[0].job_name);
});
});
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commit_message_dropdown_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commit_message_dropdown_spec.js
index 663fabb761c..5d2d1fdd6f1 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commit_message_dropdown_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commit_message_dropdown_spec.js
@@ -40,7 +40,7 @@ describe('Commits message dropdown component', () => {
wrapper.destroy();
});
- const findDropdownElements = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownElements = () => wrapper.findAllComponents(GlDropdownItem);
const findFirstDropdownElement = () => findDropdownElements().at(0);
it('should have 3 elements in dropdown list', () => {
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
index 6e89cd41559..bc3dbe8c351 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -111,7 +111,7 @@ const createComponent = (
};
const findCheckboxElement = () => wrapper.find(SquashBeforeMerge);
-const findCommitEditElements = () => wrapper.findAll(CommitEdit);
+const findCommitEditElements = () => wrapper.findAllComponents(CommitEdit);
const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown);
const findFirstCommitEditLabel = () => findCommitEditElements().at(0).props('label');
const findTipLink = () => wrapper.find(GlSprintf);
diff --git a/spec/frontend/vue_merge_request_widget/components/terraform/mr_widget_terraform_container_spec.js b/spec/frontend/vue_merge_request_widget/components/terraform/mr_widget_terraform_container_spec.js
index 8f20d6a8fc9..7a868eb8cc9 100644
--- a/spec/frontend/vue_merge_request_widget/components/terraform/mr_widget_terraform_container_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/terraform/mr_widget_terraform_container_spec.js
@@ -16,7 +16,8 @@ describe('MrWidgetTerraformConainer', () => {
const propsData = { endpoint: '/path/to/terraform/report.json' };
const findHeader = () => wrapper.find('[data-testid="terraform-header-text"]');
- const findPlans = () => wrapper.findAll(TerraformPlan).wrappers.map((x) => x.props('plan'));
+ const findPlans = () =>
+ wrapper.findAllComponents(TerraformPlan).wrappers.map((x) => x.props('plan'));
const mockPollingApi = (response, body, header) => {
mock.onGet(propsData.endpoint).reply(response, body, header);
diff --git a/spec/frontend/work_items_hierarchy/components/hierarchy_spec.js b/spec/frontend/work_items_hierarchy/components/hierarchy_spec.js
index 67420e7fc2a..dca016dc317 100644
--- a/spec/frontend/work_items_hierarchy/components/hierarchy_spec.js
+++ b/spec/frontend/work_items_hierarchy/components/hierarchy_spec.js
@@ -74,7 +74,7 @@ describe('WorkItemsHierarchy Hierarchy', () => {
});
it('renders license badges for all work items', () => {
- expect(wrapper.findAll(GlBadge)).toHaveLength(items.length);
+ expect(wrapper.findAllComponents(GlBadge)).toHaveLength(items.length);
});
it('does not render svg icon for linking', () => {
diff --git a/spec/lib/api/entities/personal_access_token_with_details_spec.rb b/spec/lib/api/entities/personal_access_token_with_details_spec.rb
deleted file mode 100644
index a53d6febba1..00000000000
--- a/spec/lib/api/entities/personal_access_token_with_details_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe API::Entities::PersonalAccessTokenWithDetails do
- describe '#as_json' do
- let_it_be(:user) { create(:user) }
- let_it_be(:token) { create(:personal_access_token, user: user, expires_at: nil) }
-
- let(:entity) { described_class.new(token) }
-
- it 'returns token data' do
- expect(entity.as_json).to eq({
- id: token.id,
- name: token.name,
- revoked: false,
- created_at: token.created_at,
- scopes: ['api'],
- user_id: user.id,
- last_used_at: nil,
- active: true,
- expires_at: nil,
- expired: false,
- expires_soon: false,
- revoke_path: Gitlab::Routing.url_helpers.revoke_profile_personal_access_token_path(token)
- })
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb
new file mode 100644
index 00000000000..205350f9df4
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanOneMb,
+ :migration,
+ schema: 20220906074449 do
+ let(:namespaces_table) { table(:namespaces) }
+ let(:projects_table) { table(:projects) }
+ let(:project_settings_table) { table(:project_settings) }
+ let(:project_statistics_table) { table(:project_statistics) }
+
+ subject(:perform_migration) do
+ described_class.new(start_id: project_settings_table.minimum(:project_id),
+ end_id: project_settings_table.maximum(:project_id),
+ batch_table: :project_settings,
+ batch_column: :project_id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection)
+ .perform
+ end
+
+ it 'sets `legacy_open_source_license_available` to false only for projects less than 1 MB',
+ :aggregate_failures do
+ project_setting_1_mb = create_legacy_license_project_setting(repo_size: 1)
+ project_setting_2_mb = create_legacy_license_project_setting(repo_size: 2)
+ project_setting_quarter_mb = create_legacy_license_project_setting(repo_size: 0.25)
+ project_setting_half_mb = create_legacy_license_project_setting(repo_size: 0.5)
+
+ queries = ActiveRecord::QueryRecorder.new { perform_migration }
+
+ expect(queries.count).to eq(7)
+ expect(migrated_attribute(project_setting_1_mb)).to be_truthy
+ expect(migrated_attribute(project_setting_2_mb)).to be_truthy
+ expect(migrated_attribute(project_setting_quarter_mb)).to be_falsey
+ expect(migrated_attribute(project_setting_half_mb)).to be_falsey
+ end
+
+ private
+
+ # @param repo_size: Repo size in MB
+ def create_legacy_license_project_setting(repo_size:)
+ path = "path-for-repo-size-#{repo_size}"
+ namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}")
+ project_namespace =
+ namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project')
+ project = projects_table
+ .create!(name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id)
+
+ size_in_bytes = 1.megabyte * repo_size
+ project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: size_in_bytes)
+ project_settings_table.create!(project_id: project.id, legacy_open_source_license_available: true)
+ end
+
+ def migrated_attribute(project_setting)
+ project_settings_table.find(project_setting.project_id).legacy_open_source_license_available
+ end
+end
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index ed6a87cda6f..ff3cade07c0 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -297,6 +297,11 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
describe '#list_commits' do
let(:revisions) { 'master' }
let(:reverse) { false }
+ let(:author) { nil }
+ let(:ignore_case) { nil }
+ let(:commit_message_patterns) { nil }
+ let(:before) { nil }
+ let(:after) { nil }
let(:pagination_params) { nil }
shared_examples 'a ListCommits request' do
@@ -309,13 +314,18 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
expected_request = gitaly_request_with_params(
Array.wrap(revisions),
reverse: reverse,
+ author: author,
+ ignore_case: ignore_case,
+ commit_message_patterns: commit_message_patterns,
+ before: before,
+ after: after,
pagination_params: pagination_params
)
expect(service).to receive(:list_commits).with(expected_request, kind_of(Hash)).and_return([])
end
- client.list_commits(revisions, reverse: reverse, pagination_params: pagination_params)
+ client.list_commits(revisions, { reverse: reverse, author: author, ignore_case: ignore_case, commit_message_patterns: commit_message_patterns, before: before, after: after, pagination_params: pagination_params })
end
end
@@ -333,7 +343,12 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
it_behaves_like 'a ListCommits request'
end
- context 'with pagination params' do
+ context 'with commit message, author, before and after' do
+ let(:author) { "Dmitriy" }
+ let(:before) { 1474828200 }
+ let(:after) { 1474828200 }
+ let(:commit_message_patterns) { "Initial commit" }
+ let(:ignore_case) { true }
let(:pagination_params) { { limit: 1, page_token: 'foo' } }
it_behaves_like 'a ListCommits request'
diff --git a/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb b/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb
new file mode 100644
index 00000000000..e4ac094ab48
--- /dev/null
+++ b/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForProjectsLessThanOneMb do
+ let_it_be(:migration) { described_class.new }
+ let_it_be(:post_migration) { described_class::MIGRATION }
+
+ context 'when on gitlab.com' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of project_settings' do
+ migration.up
+
+ expect(post_migration).to(
+ have_scheduled_batched_migration(
+ table_name: :project_settings,
+ column_name: :project_id,
+ interval: described_class::INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ max_batch_size: described_class::MAX_BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ )
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migration.down
+
+ expect(post_migration).not_to have_scheduled_batched_migration
+ end
+ end
+ end
+
+ context 'when on self-managed instance' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ describe '#up' do
+ it 'does not schedule background job' do
+ expect(migration).not_to receive(:queue_batched_background_migration)
+
+ migration.up
+ end
+ end
+
+ describe '#down' do
+ it 'does not delete background job' do
+ expect(migration).not_to receive(:delete_batched_background_migration)
+
+ migration.down
+ end
+ end
+ end
+end
diff --git a/spec/models/ci/pipeline_artifact_spec.rb b/spec/models/ci/pipeline_artifact_spec.rb
index b051f646bd4..3038cdc944b 100644
--- a/spec/models/ci/pipeline_artifact_spec.rb
+++ b/spec/models/ci/pipeline_artifact_spec.rb
@@ -227,6 +227,19 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
expect(subject.size).to eq(size)
expect(subject.file_format).to eq(Ci::PipelineArtifact::REPORT_TYPES[file_type].to_s)
expect(subject.expire_at).to eq(Ci::PipelineArtifact::EXPIRATION_DATE.from_now)
+ expect(subject.locked).to eq('unknown')
+ end
+
+ it "creates a new pipeline artifact with pipeline's locked state" do
+ artifact = Ci::PipelineArtifact.create_or_replace_for_pipeline!(
+ pipeline: pipeline,
+ file_type: file_type,
+ file: file,
+ size: size,
+ locked: pipeline.locked
+ )
+
+ expect(artifact.locked).to eq(pipeline.locked)
end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 48c37713430..c475b510e62 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -4967,6 +4967,56 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
+ describe '#self_and_downstreams' do
+ subject(:self_and_downstreams) { pipeline.self_and_downstreams }
+
+ let(:pipeline) { create(:ci_pipeline, :created) }
+
+ context 'when pipeline is not child nor parent' do
+ it 'returns just the pipeline itself' do
+ expect(self_and_downstreams).to contain_exactly(pipeline)
+ end
+ end
+
+ context 'when pipeline is child' do
+ let(:parent) { create(:ci_pipeline) }
+ let!(:pipeline) { create(:ci_pipeline, child_of: parent) }
+
+ it 'returns self and no ancestors' do
+ expect(self_and_downstreams).to contain_exactly(pipeline)
+ end
+ end
+
+ context 'when pipeline is parent' do
+ let(:child) { create(:ci_pipeline, child_of: pipeline) }
+
+ it 'returns self and child' do
+ expect(self_and_downstreams).to contain_exactly(pipeline, child)
+ end
+ end
+
+ context 'when pipeline is a grandparent pipeline' do
+ let(:child) { create(:ci_pipeline, child_of: pipeline) }
+ let(:grandchild) { create(:ci_pipeline, child_of: child) }
+
+ it 'returns self, child, and grandchild' do
+ expect(self_and_downstreams).to contain_exactly(pipeline, child, grandchild)
+ end
+ end
+
+ context 'when pipeline is a triggered pipeline from a different project' do
+ let(:downstream) { create(:ci_pipeline) }
+
+ before do
+ create_source_pipeline(pipeline, downstream)
+ end
+
+ it 'returns self and cross-project downstream' do
+ expect(self_and_downstreams).to contain_exactly(pipeline, downstream)
+ end
+ end
+ end
+
describe '#self_and_project_ancestors' do
subject(:self_and_project_ancestors) { pipeline.self_and_project_ancestors }
@@ -5000,6 +5050,19 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
+ describe '#complete_hierarchy_count' do
+ context 'with a combination of ancestor, descendant and sibling pipelines' do
+ let!(:pipeline) { create(:ci_pipeline) }
+ let!(:child_pipeline) { create(:ci_pipeline, child_of: pipeline) }
+ let!(:sibling_pipeline) { create(:ci_pipeline, child_of: pipeline) }
+ let!(:grandchild_pipeline) { create(:ci_pipeline, child_of: child_pipeline) }
+
+ it 'counts the whole tree' do
+ expect(sibling_pipeline.complete_hierarchy_count).to eq(4)
+ end
+ end
+ end
+
describe '#reset_source_bridge!' do
let(:pipeline) { create(:ci_pipeline, :created, project: project) }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index cb5c43a5270..7226c9db15d 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -1186,6 +1186,25 @@ RSpec.describe Ci::Runner do
end
end
+ describe '#owner_project' do
+ let_it_be(:project1) { create(:project) }
+ let_it_be(:project2) { create(:project) }
+
+ subject(:owner_project) { project_runner.owner_project }
+
+ context 'with project1 as first project associated with runner' do
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project1, project2]) }
+
+ it { is_expected.to eq project1 }
+ end
+
+ context 'with project2 as first project associated with runner' do
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project2, project1]) }
+
+ it { is_expected.to eq project2 }
+ end
+ end
+
describe "belongs_to_one_project?" do
it "returns false if there are two projects runner assigned to" do
project1 = create(:project)
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 1de00518a13..ec6f2bda79a 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -1017,16 +1017,5 @@ RSpec.describe CommitStatus do
it { is_expected.to be_nil }
end
-
- context 'when ci_read_stage_records is disabled' do
- before do
- stub_feature_flags(ci_read_stage_records: false)
- end
-
- it 'does not read from Ci::Stage', :aggregate_failures do
- expect(commit_status).not_to receive(:ci_stage)
- expect(stage_name).to eq('test')
- end
- end
end
end
diff --git a/spec/models/group_group_link_spec.rb b/spec/models/group_group_link_spec.rb
index 969987c7e64..eec8fe0ef71 100644
--- a/spec/models/group_group_link_spec.rb
+++ b/spec/models/group_group_link_spec.rb
@@ -44,6 +44,17 @@ RSpec.describe GroupGroupLink do
end
end
+ describe '.with_owner_access' do
+ let_it_be(:group_group_link_maintainer) { create :group_group_link, :maintainer }
+ let_it_be(:group_group_link_owner) { create :group_group_link, :owner }
+ let_it_be(:group_group_link_reporter) { create :group_group_link, :reporter }
+ let_it_be(:group_group_link_guest) { create :group_group_link, :guest }
+
+ it 'returns all records which have OWNER access' do
+ expect(described_class.with_owner_access).to match_array([group_group_link_owner])
+ end
+ end
+
context 'for access via group shares' do
let_it_be(:shared_with_group_1) { create(:group) }
let_it_be(:shared_with_group_2) { create(:group) }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 839f862322d..4e386bf584f 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -545,6 +545,54 @@ RSpec.describe Repository do
end
end
+ describe '#list_commits_by' do
+ it 'returns commits with messages containing a given string' do
+ commit_ids = repository.list_commits_by('test text', 'master').map(&:id)
+
+ expect(commit_ids).to include(
+ 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
+ '498214de67004b1da3d820901307bed2a68a8ef6'
+ )
+ expect(commit_ids).not_to include('c84ff944ff4529a70788a5e9003c2b7feae29047')
+ end
+
+ it 'is case insensitive' do
+ commit_ids = repository.list_commits_by('TEST TEXT', 'master').map(&:id)
+
+ expect(commit_ids).to include('b83d6e391c22777fca1ed3012fce84f633d7fed0')
+ end
+
+ it 'returns commits based in before filter' do
+ commit_ids = repository.list_commits_by('test text', 'master', before: 1474828200).map(&:id)
+ expect(commit_ids).to include(
+ '498214de67004b1da3d820901307bed2a68a8ef6'
+ )
+ expect(commit_ids).not_to include('b83d6e391c22777fca1ed3012fce84f633d7fed0')
+ end
+
+ it 'returns commits based in after filter' do
+ commit_ids = repository.list_commits_by('test text', 'master', after: 1474828200).map(&:id)
+ expect(commit_ids).to include(
+ 'b83d6e391c22777fca1ed3012fce84f633d7fed0'
+ )
+ expect(commit_ids).not_to include('498214de67004b1da3d820901307bed2a68a8ef6')
+ end
+
+ it 'returns commits based in author filter' do
+ commit_ids = repository.list_commits_by('test text', 'master', author: 'Job van der Voort').map(&:id)
+ expect(commit_ids).to include(
+ 'b83d6e391c22777fca1ed3012fce84f633d7fed0'
+ )
+ expect(commit_ids).not_to include('498214de67004b1da3d820901307bed2a68a8ef6')
+ end
+
+ describe 'when storage is broken', :broken_storage do
+ it 'raises a storage error' do
+ expect_to_raise_storage_error { broken_repository.list_commits_by('s') }
+ end
+ end
+ end
+
describe '#blob_at' do
context 'blank sha' do
subject { repository.blob_at(Gitlab::Git::BLANK_SHA, '.gitignore') }
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 031e1a6c918..c4eae233f3b 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -2060,6 +2060,7 @@ RSpec.describe API::Groups do
let_it_be(:maintainer_group) { create(:group, name: 'maintainer group', path: 'maintainer-group') }
let_it_be(:owner_group_1) { create(:group, name: 'owner group', path: 'owner-group') }
let_it_be(:owner_group_2) { create(:group, name: 'gitlab group', path: 'gitlab-group') }
+ let_it_be(:shared_with_group_where_direct_owner_as_owner) { create(:group) }
before do
source_group.add_owner(user)
@@ -2067,6 +2068,10 @@ RSpec.describe API::Groups do
maintainer_group.add_maintainer(user)
owner_group_1.add_owner(user)
owner_group_2.add_owner(user)
+ create(:group_group_link, :owner,
+ shared_with_group: owner_group_1,
+ shared_group: shared_with_group_where_direct_owner_as_owner
+ )
end
it 'returns 200' do
@@ -2079,7 +2084,11 @@ RSpec.describe API::Groups do
it 'only includes groups where the user has permissions to transfer a group to' do
request
- expect(group_ids_from_response).to contain_exactly(owner_group_1.id, owner_group_2.id)
+ expect(group_ids_from_response).to contain_exactly(
+ owner_group_1.id,
+ owner_group_2.id,
+ shared_with_group_where_direct_owner_as_owner.id
+ )
end
context 'with search' do
diff --git a/spec/serializers/access_token_entity_base_spec.rb b/spec/serializers/access_token_entity_base_spec.rb
new file mode 100644
index 00000000000..e14a07a346a
--- /dev/null
+++ b/spec/serializers/access_token_entity_base_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe AccessTokenEntityBase do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { create(:personal_access_token, user: user, expires_at: nil) }
+
+ subject(:json) { described_class.new(token).as_json }
+
+ it 'has the correct attributes' do
+ expect(json).to(
+ include(
+ id: token.id,
+ name: token.name,
+ revoked: false,
+ created_at: token.created_at,
+ scopes: token.scopes,
+ expires_at: nil,
+ expired: false,
+ expires_soon: false
+ ))
+
+ expect(json).not_to include(:token)
+ end
+end
diff --git a/spec/services/ci/create_downstream_pipeline_service_spec.rb b/spec/services/ci/create_downstream_pipeline_service_spec.rb
index e2c42ab04d0..10aa839214c 100644
--- a/spec/services/ci/create_downstream_pipeline_service_spec.rb
+++ b/spec/services/ci/create_downstream_pipeline_service_spec.rb
@@ -819,5 +819,19 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
end
end
end
+
+ context 'when a downstream pipeline has sibling pipelines' do
+ it_behaves_like 'logs downstream pipeline creation' do
+ let(:expected_root_pipeline) { upstream_pipeline }
+ let(:expected_downstream_relationship) { :multi_project }
+
+ # New downstream, plus upstream, plus two children of upstream created below
+ let(:expected_hierarchy_size) { 4 }
+
+ before do
+ create_list(:ci_pipeline, 2, child_of: upstream_pipeline)
+ end
+ end
+ end
end
end
diff --git a/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb b/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
index 31548793bac..6d4dcf28108 100644
--- a/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
+++ b/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
@@ -51,6 +51,30 @@ RSpec.describe Ci::PipelineArtifacts::CoverageReportService do
let!(:pipeline) { create(:ci_pipeline, :with_coverage_reports, project: project) }
it_behaves_like 'creating or updating a pipeline coverage report'
+
+ context 'when ci_update_unlocked_pipeline_artifacts feature flag is enabled' do
+ it "artifact has pipeline's locked status" do
+ subject
+
+ artifact = Ci::PipelineArtifact.first
+
+ expect(artifact.locked).to eq(pipeline.locked)
+ end
+ end
+
+ context 'when ci_update_unlocked_pipeline_artifacts is disabled' do
+ before do
+ stub_feature_flags(ci_update_unlocked_pipeline_artifacts: false)
+ end
+
+ it 'artifact has unknown locked status' do
+ subject
+
+ artifact = Ci::PipelineArtifact.first
+
+ expect(artifact.locked).to eq('unknown')
+ end
+ end
end
context 'when pipeline has coverage report from child pipeline' do
diff --git a/spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb b/spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb
index 5568052e346..75233248113 100644
--- a/spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb
+++ b/spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb
@@ -51,6 +51,30 @@ RSpec.describe ::Ci::PipelineArtifacts::CreateCodeQualityMrDiffReportService do
end
end
+ context 'when ci_update_unlocked_pipeline_artifacts feature flag is enabled' do
+ it "artifact has pipeline's locked status" do
+ subject
+
+ artifact = Ci::PipelineArtifact.first
+
+ expect(artifact.locked).to eq(head_pipeline.locked)
+ end
+ end
+
+ context 'when ci_update_unlocked_pipeline_artifacts is disabled' do
+ before do
+ stub_feature_flags(ci_update_unlocked_pipeline_artifacts: false)
+ end
+
+ it 'artifact has unknown locked status' do
+ subject
+
+ artifact = Ci::PipelineArtifact.first
+
+ expect(artifact.locked).to eq('unknown')
+ end
+ end
+
it 'does not persist the same artifact twice' do
2.times { described_class.new(head_pipeline).execute }
diff --git a/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb b/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb
new file mode 100644
index 00000000000..b3fee24e09d
--- /dev/null
+++ b/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute' do
+ subject(:execute) { described_class.new(runner: runner, current_user: user, project_ids: project_ids).execute }
+
+ let_it_be(:owner_project) { create(:project) }
+ let_it_be(:project2) { create(:project) }
+ let_it_be(:original_projects) { [owner_project, project2] }
+ let_it_be(:runner) { create(:ci_runner, :project, projects: original_projects) }
+
+ context 'without user' do
+ let(:user) { nil }
+ let(:project_ids) { [project2.id] }
+
+ it 'does not call assign_to on runner and returns error response', :aggregate_failures do
+ expect(runner).not_to receive(:assign_to)
+
+ expect(execute).to be_error
+ expect(execute.message).to eq('user not allowed to assign runner')
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:user) { build(:user) }
+ let(:project_ids) { [project2.id] }
+
+ it 'does not call assign_to on runner and returns error message' do
+ expect(runner).not_to receive(:assign_to)
+
+ expect(execute).to be_error
+ expect(execute.message).to eq('user not allowed to assign runner')
+ end
+ end
+
+ context 'with admin user', :enable_admin_mode do
+ let(:user) { create_default(:user, :admin) }
+ let(:project_ids) { [project3.id, project4.id] }
+ let(:project3) { create(:project) }
+ let(:project4) { create(:project) }
+
+ context 'with successful requests' do
+ it 'calls assign_to on runner and returns success response' do
+ expect(execute).to be_success
+ expect(runner.reload.projects.ids).to match_array([owner_project.id] + project_ids)
+ end
+ end
+
+ context 'with failing assign_to requests' do
+ it 'returns error response and rolls back transaction' do
+ expect(runner).to receive(:assign_to).with(project4, user).once.and_return(false)
+
+ expect(execute).to be_error
+ expect(runner.reload.projects).to match_array(original_projects)
+ end
+ end
+
+ context 'with failing destroy calls' do
+ it 'returns error response and rolls back transaction' do
+ allow_next_found_instance_of(Ci::RunnerProject) do |runner_project|
+ allow(runner_project).to receive(:destroy).and_return(false)
+ end
+
+ expect(execute).to be_error
+ expect(runner.reload.projects).to match_array(original_projects)
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/unlock_artifacts_service_spec.rb b/spec/services/ci/unlock_artifacts_service_spec.rb
index 94d39fc9f14..776019f03f8 100644
--- a/spec/services/ci/unlock_artifacts_service_spec.rb
+++ b/spec/services/ci/unlock_artifacts_service_spec.rb
@@ -5,11 +5,15 @@ require 'spec_helper'
RSpec.describe Ci::UnlockArtifactsService do
using RSpec::Parameterized::TableSyntax
- where(:tag, :ci_update_unlocked_job_artifacts) do
- false | false
- false | true
- true | false
- true | true
+ where(:tag, :ci_update_unlocked_job_artifacts, :ci_update_unlocked_pipeline_artifacts) do
+ false | false | false
+ false | true | false
+ true | false | false
+ true | true | false
+ false | false | true
+ false | true | true
+ true | false | true
+ true | true | true
end
with_them do
@@ -22,6 +26,7 @@ RSpec.describe Ci::UnlockArtifactsService do
let!(:old_unlocked_pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: tag, project: project, locked: :unlocked) }
let!(:older_pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: tag, project: project, locked: :artifacts_locked) }
let!(:older_ambiguous_pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: !tag, project: project, locked: :artifacts_locked) }
+ let!(:code_coverage_pipeline) { create(:ci_pipeline, :with_coverage_report_artifact, ref: ref, tag: tag, project: project, locked: :artifacts_locked) }
let!(:pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: tag, project: project, locked: :artifacts_locked) }
let!(:child_pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: tag, project: project, locked: :artifacts_locked) }
let!(:newer_pipeline) { create(:ci_pipeline, :with_persisted_artifacts, ref: ref, tag: tag, project: project, locked: :artifacts_locked) }
@@ -30,7 +35,8 @@ RSpec.describe Ci::UnlockArtifactsService do
before do
stub_const("#{described_class}::BATCH_SIZE", 1)
- stub_feature_flags(ci_update_unlocked_job_artifacts: ci_update_unlocked_job_artifacts)
+ stub_feature_flags(ci_update_unlocked_job_artifacts: ci_update_unlocked_job_artifacts,
+ ci_update_unlocked_pipeline_artifacts: ci_update_unlocked_pipeline_artifacts)
end
describe '#execute' do
@@ -72,6 +78,14 @@ RSpec.describe Ci::UnlockArtifactsService do
expect { execute }.to change { ::Ci::JobArtifact.artifact_unlocked.count }.from(0).to(2)
end
+
+ it 'unlocks pipeline artifact records' do
+ if ci_update_unlocked_job_artifacts && ci_update_unlocked_pipeline_artifacts
+ expect { execute }.to change { ::Ci::PipelineArtifact.artifact_unlocked.count }.from(0).to(1)
+ else
+ expect { execute }.not_to change { ::Ci::PipelineArtifact.artifact_unlocked.count }
+ end
+ end
end
context 'when running on just the ref' do
@@ -106,6 +120,14 @@ RSpec.describe Ci::UnlockArtifactsService do
expect { execute }.to change { ::Ci::JobArtifact.artifact_unlocked.count }.from(0).to(8)
end
+
+ it 'unlocks pipeline artifact records' do
+ if ci_update_unlocked_job_artifacts && ci_update_unlocked_pipeline_artifacts
+ expect { execute }.to change { ::Ci::PipelineArtifact.artifact_unlocked.count }.from(0).to(1)
+ else
+ expect { execute }.not_to change { ::Ci::PipelineArtifact.artifact_unlocked.count }
+ end
+ end
end
end