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--.rubocop_todo/layout/first_array_element_indentation.yml20
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb3
-rw-r--r--app/graphql/types/work_items/widgets/labels_update_input_type.rb20
-rw-r--r--app/helpers/appearances_helper.rb8
-rw-r--r--app/helpers/wiki_helper.rb5
-rw-r--r--app/models/wiki.rb116
-rw-r--r--app/models/wiki_page.rb11
-rw-r--r--app/services/concerns/work_items/widgetable_service.rb12
-rw-r--r--app/services/issuable_base_service.rb5
-rw-r--r--app/services/work_items/update_service.rb11
-rw-r--r--app/services/work_items/widgets/base_service.rb5
-rw-r--r--app/services/work_items/widgets/labels_service/update_service.rb15
-rw-r--r--app/views/layouts/devise.html.haml4
-rw-r--r--app/views/shared/wikis/pages.html.haml3
-rw-r--r--config/feature_flags/development/wiki_list_pages_with_normal_repository_rpcs.yml8
-rw-r--r--doc/api/graphql/reference/index.md11
-rw-r--r--lib/gitlab/git/wiki_page.rb5
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/features/projects/wikis_spec.rb43
-rw-r--r--spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb9
-rw-r--r--spec/helpers/appearances_helper_spec.rb58
-rw-r--r--spec/helpers/wiki_helper_spec.rb69
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb5
-rw-r--r--spec/lib/gitlab/serializer/ci/variables_spec.rb9
-rw-r--r--spec/lib/gitlab/sidekiq_config_spec.rb4
-rw-r--r--spec/lib/gitlab/ssh_public_key_spec.rb24
-rw-r--r--spec/lib/gitlab/usage_data/topology_spec.rb278
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb13
-rw-r--r--spec/lib/gitlab/utils_spec.rb11
-rw-r--r--spec/lib/gitlab/webpack/manifest_spec.rb9
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb18
-rw-r--r--spec/lib/peek/views/bullet_detailed_spec.rb9
-rw-r--r--spec/lib/system_check/incoming_email_check_spec.rb20
-rw-r--r--spec/lib/unnested_in_filters/rewriter_spec.rb34
-rw-r--r--spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb14
-rw-r--r--spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb59
-rw-r--r--spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb13
-rw-r--r--spec/models/analytics/cycle_analytics/project_stage_spec.rb9
-rw-r--r--spec/models/application_setting_spec.rb22
-rw-r--r--spec/models/ci/build_spec.rb25
-rw-r--r--spec/models/ci/build_trace_spec.rb7
-rw-r--r--spec/models/ci/daily_build_group_report_result_spec.rb37
-rw-r--r--spec/models/ci/pipeline_spec.rb9
-rw-r--r--spec/requests/api/graphql/mutations/work_items/update_spec.rb72
-rw-r--r--spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb45
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb89
-rw-r--r--spec/views/layouts/devise.html.haml_spec.rb18
47 files changed, 841 insertions, 456 deletions
diff --git a/.rubocop_todo/layout/first_array_element_indentation.yml b/.rubocop_todo/layout/first_array_element_indentation.yml
index 8c4dfa12c2e..7b90488a5c4 100644
--- a/.rubocop_todo/layout/first_array_element_indentation.yml
+++ b/.rubocop_todo/layout/first_array_element_indentation.yml
@@ -5,26 +5,6 @@ Layout/FirstArrayElementIndentation:
Exclude:
- 'spec/lib/gitlab/github_import/importer/issues_importer_spec.rb'
- 'spec/lib/gitlab/search/found_blob_spec.rb'
- - 'spec/lib/gitlab/serializer/ci/variables_spec.rb'
- - 'spec/lib/gitlab/sidekiq_config_spec.rb'
- - 'spec/lib/gitlab/ssh_public_key_spec.rb'
- - 'spec/lib/gitlab/usage_data/topology_spec.rb'
- - 'spec/lib/gitlab/usage_data_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- - 'spec/lib/gitlab/webpack/manifest_spec.rb'
- - 'spec/lib/google_api/cloud_platform/client_spec.rb'
- - 'spec/lib/peek/views/bullet_detailed_spec.rb'
- - 'spec/lib/system_check/incoming_email_check_spec.rb'
- - 'spec/lib/unnested_in_filters/rewriter_spec.rb'
- - 'spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb'
- - 'spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb'
- - 'spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb'
- - 'spec/models/analytics/cycle_analytics/project_stage_spec.rb'
- - 'spec/models/application_setting_spec.rb'
- - 'spec/models/ci/build_spec.rb'
- - 'spec/models/ci/build_trace_spec.rb'
- - 'spec/models/ci/daily_build_group_report_result_spec.rb'
- - 'spec/models/ci/pipeline_spec.rb'
- 'spec/models/ci/runner_version_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/user_preference_spec.rb'
diff --git a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
index 1f90f394521..e42e59de78f 100644
--- a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
+++ b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
@@ -30,6 +30,9 @@ module Mutations
argument :start_and_due_date_widget, ::Types::WorkItems::Widgets::StartAndDueDateUpdateInputType,
required: false,
description: 'Input for start and due date widget.'
+ argument :labels_widget, ::Types::WorkItems::Widgets::LabelsUpdateInputType,
+ required: false,
+ description: 'Input for labels widget.'
end
end
end
diff --git a/app/graphql/types/work_items/widgets/labels_update_input_type.rb b/app/graphql/types/work_items/widgets/labels_update_input_type.rb
new file mode 100644
index 00000000000..d38b8cefa63
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/labels_update_input_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ class LabelsUpdateInputType < BaseInputObject
+ graphql_name 'WorkItemWidgetLabelsUpdateInput'
+
+ argument :add_label_ids, [Types::GlobalIDType[::Label]],
+ required: false,
+ description: 'Global IDs of labels to be added to the work item.',
+ prepare: ->(label_ids, _ctx) { label_ids.map(&:model_id) }
+ argument :remove_label_ids, [Types::GlobalIDType[::Label]],
+ required: false,
+ description: 'Global IDs of labels to be removed from the work item.',
+ prepare: ->(label_ids, _ctx) { label_ids.map(&:model_id) }
+ end
+ end
+ end
+end
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb
index 6dbd0f7bd7b..957c2afb6d2 100644
--- a/app/helpers/appearances_helper.rb
+++ b/app/helpers/appearances_helper.rb
@@ -14,7 +14,13 @@ module AppearancesHelper
end
def brand_image
- image_tag(current_appearance.logo_path) if current_appearance&.logo?
+ image_tag(brand_image_path, alt: brand_title, class: 'gl-w-10')
+ end
+
+ def brand_image_path
+ return current_appearance.logo_path if current_appearance&.logo?
+
+ image_path('logo.svg')
end
def brand_text
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index d6ffd3deafe..c42e3a5ff99 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -65,7 +65,10 @@ module WikiHelper
reversed_direction = direction == 'desc' ? 'asc' : 'desc'
icon_class = direction == 'desc' ? 'highest' : 'lowest'
- link_to(wiki_path(wiki, action: :pages, sort: sort, direction: reversed_direction),
+ link_options = { action: :pages, direction: reversed_direction }
+ link_options[:sort] = sort unless wiki.disable_sorting?
+
+ link_to(wiki_path(wiki, **link_options),
type: 'button', class: link_class, title: _('Sort direction')) do
sprite_icon("sort-#{icon_class}")
end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index afdac86d9c7..11ff4333a07 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -173,7 +173,7 @@ class Wiki
end
def empty?
- !repository_exists? || list_pages(limit: 1).empty?
+ !repository_exists? || list_page_paths.empty?
end
def exists?
@@ -191,13 +191,11 @@ class Wiki
# Returns an Array of GitLab WikiPage instances or an
# empty Array if this Wiki has no pages.
def list_pages(limit: 0, sort: nil, direction: DIRECTION_ASC, load_content: false)
- wiki.list_pages(
- limit: limit,
- sort: sort,
- direction_desc: direction == DIRECTION_DESC,
- load_content: load_content
- ).map do |page|
- WikiPage.new(self, page)
+ if list_pages_with_repository_rpcs?
+ create_wiki_repository unless repository_exists?
+ list_pages_with_repository_rpcs(limit: limit, sort: sort, direction: direction, load_content: load_content)
+ else
+ list_pages_with_legacy_wiki_service(limit: limit, sort: sort, direction: direction, load_content: load_content)
end
end
@@ -383,6 +381,10 @@ class Wiki
false
end
+ def disable_sorting?
+ list_pages_with_repository_rpcs?
+ end
+
private
def multi_commit_options(action, message = nil, title = nil)
@@ -452,14 +454,7 @@ class Wiki
def find_matched_file(title, version)
escaped_path = RE2::Regexp.escape(sluggified_title(title))
- # We could not use ALLOWED_EXTENSIONS_REGEX constant or similar regexp with
- # Regexp.union. The result combination complicated modifiers:
- # /(?i-mx:md|mkdn?|mdown|markdown)|(?i-mx:rdoc).../
- # Regexp used by Gitaly is Go's Regexp package. It does not support those
- # features. So, we have to compose another more-friendly regexp to pass to
- # Gitaly side.
- extension_regexp = Wiki::MARKUPS.map { |_, format| format[:extension_regex].source }.join("|")
- path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{extension_regexp})$")
+ path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{file_extension_regexp})$")
matched_files = repository.search_files_by_regexp(path_regexp, version)
return if matched_files.blank?
@@ -487,7 +482,7 @@ class Wiki
format = find_page_format(path)
page = Gitlab::Git::WikiPage.new(
- url_path: sluggified_title(path.sub(/\.[^.]+\z/, "")),
+ url_path: sluggified_title(strip_extension(path)),
title: canonicalize_filename(path),
format: format,
path: sluggified_title(path),
@@ -509,6 +504,93 @@ class Wiki
Feature.enabled?(:wiki_find_page_with_normal_repository_rpcs, group, type: :development)
end
+
+ def file_extension_regexp
+ # We could not use ALLOWED_EXTENSIONS_REGEX constant or similar regexp with
+ # Regexp.union. The result combination complicated modifiers:
+ # /(?i-mx:md|mkdn?|mdown|markdown)|(?i-mx:rdoc).../
+ # Regexp used by Gitaly is Go's Regexp package. It does not support those
+ # features. So, we have to compose another more-friendly regexp to pass to
+ # Gitaly side.
+ Wiki::MARKUPS.map { |_, format| format[:extension_regex].source }.join("|")
+ end
+
+ def strip_extension(path)
+ path.sub(/\.[^.]+\z/, "")
+ end
+
+ def list_pages_with_repository_rpcs?
+ group =
+ if container.is_a?(::Group)
+ container
+ else
+ container.group
+ end
+
+ Feature.enabled?(:wiki_list_pages_with_normal_repository_rpcs, group, type: :development)
+ end
+
+ def list_page_paths
+ return [] if repository.empty?
+
+ path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)\\.(#{file_extension_regexp})$")
+ repository.search_files_by_regexp(path_regexp, default_branch)
+ end
+
+ def list_pages_with_repository_rpcs(limit:, sort:, direction:, load_content:)
+ paths = list_page_paths
+ return [] if paths.empty?
+
+ pages = paths.map do |path|
+ page = Gitlab::Git::WikiPage.new(
+ url_path: sluggified_title(strip_extension(path)),
+ title: canonicalize_filename(path),
+ format: find_page_format(path),
+ path: sluggified_title(path),
+ raw_data: '',
+ name: canonicalize_filename(path),
+ historical: false
+ )
+ WikiPage.new(self, page)
+ end
+ sort_pages!(pages, sort, direction)
+ pages = pages.take(limit) if limit > 0
+ fetch_pages_content!(pages) if load_content
+
+ pages
+ end
+
+ def list_pages_with_legacy_wiki_service(limit:, sort:, direction:, load_content:)
+ wiki.list_pages(
+ limit: limit,
+ sort: sort,
+ direction_desc: direction == DIRECTION_DESC,
+ load_content: load_content
+ ).map do |page|
+ WikiPage.new(self, page)
+ end
+ end
+
+ # After migrating to normal repository RPCs, it's very expensive to sort the
+ # pages by created_at. We have to either ListLastCommitsForTree RPC call or
+ # N+1 LastCommitForPath. Either are efficient for a large repository.
+ # Therefore, we decide to sort the title only.
+ def sort_pages!(pages, _sort, direction)
+ # Sort by path to ensure the files inside a sub-folder are grouped and sorted together
+ pages.sort_by!(&:path)
+ pages.reverse! if direction == DIRECTION_DESC
+ end
+
+ def fetch_pages_content!(pages)
+ blobs =
+ repository
+ .blobs_at(pages.map { |page| [default_branch, page.path] } )
+ .to_h { |blob| [blob.path, blob.data] }
+
+ pages.each do |page|
+ page.raw_content = blobs[page.path]
+ end
+ end
end
Wiki.prepend_mod_with('Wiki')
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 5cdd1fdadcb..ad07e0269f6 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -99,6 +99,13 @@ class WikiPage
attributes[:content] ||= page&.text_data
end
+ def raw_content=(content)
+ return if page.nil?
+
+ page.raw_data = content
+ attributes[:content] = page.text_data
+ end
+
# The hierarchy of the directory this page is contained in.
def directory
wiki.page_title_and_dir(slug)&.last.to_s
@@ -118,7 +125,7 @@ class WikiPage
def version
return unless persisted?
- @version ||= @page.version
+ @version ||= @page.version || last_version
end
def path
@@ -151,7 +158,7 @@ class WikiPage
end
def last_version
- @last_version ||= versions(limit: 1).first
+ @last_version ||= wiki.repository.last_commit_for_path(wiki.default_branch, page.path) if page
end
def last_commit_sha
diff --git a/app/services/concerns/work_items/widgetable_service.rb b/app/services/concerns/work_items/widgetable_service.rb
index beb614c7b76..24ade9336b2 100644
--- a/app/services/concerns/work_items/widgetable_service.rb
+++ b/app/services/concerns/work_items/widgetable_service.rb
@@ -2,18 +2,22 @@
module WorkItems
module WidgetableService
- def execute_widgets(work_item:, callback:, widget_params: {})
+ def execute_widgets(work_item:, callback:, widget_params: {}, service_params: {})
work_item.widgets.each do |widget|
- widget_service(widget).try(callback, params: widget_params[widget.class.api_symbol])
+ widget_service(widget, service_params).try(callback, params: widget_params[widget.class.api_symbol])
end
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
- def widget_service(widget)
+ def widget_service(widget, service_params)
@widget_services ||= {}
return @widget_services[widget] if @widget_services.has_key?(widget)
- @widget_services[widget] = widget_service_class(widget)&.new(widget: widget, current_user: current_user)
+ @widget_services[widget] = widget_service_class(widget)&.new(
+ widget: widget,
+ current_user: current_user,
+ service_params: service_params
+ )
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index febb2f56e86..40c7742a3aa 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -266,6 +266,10 @@ class IssuableBaseService < ::BaseProjectService
# To be overridden by subclasses
end
+ def prepare_update_params(issuable)
+ # To be overridden by subclasses
+ end
+
def after_update(issuable)
handle_description_updated(issuable)
end
@@ -277,6 +281,7 @@ class IssuableBaseService < ::BaseProjectService
end
def update(issuable)
+ prepare_update_params(issuable)
handle_quick_actions(issuable)
filter_params(issuable)
diff --git a/app/services/work_items/update_service.rb b/app/services/work_items/update_service.rb
index 2deb8c82741..e87a19422cb 100644
--- a/app/services/work_items/update_service.rb
+++ b/app/services/work_items/update_service.rb
@@ -26,6 +26,17 @@ module WorkItems
private
+ def prepare_update_params(work_item)
+ execute_widgets(
+ work_item: work_item,
+ callback: :prepare_update_params,
+ widget_params: @widget_params,
+ service_params: params
+ )
+
+ super
+ end
+
def before_update(work_item, skip_spam_check: false)
execute_widgets(work_item: work_item, callback: :before_update_callback, widget_params: @widget_params)
diff --git a/app/services/work_items/widgets/base_service.rb b/app/services/work_items/widgets/base_service.rb
index 37ed2bf4b05..1ff03a09f9f 100644
--- a/app/services/work_items/widgets/base_service.rb
+++ b/app/services/work_items/widgets/base_service.rb
@@ -5,12 +5,13 @@ module WorkItems
class BaseService < ::BaseService
WidgetError = Class.new(StandardError)
- attr_reader :widget, :work_item, :current_user
+ attr_reader :widget, :work_item, :current_user, :service_params
- def initialize(widget:, current_user:)
+ def initialize(widget:, current_user:, service_params: {})
@widget = widget
@work_item = widget.work_item
@current_user = current_user
+ @service_params = service_params
end
private
diff --git a/app/services/work_items/widgets/labels_service/update_service.rb b/app/services/work_items/widgets/labels_service/update_service.rb
new file mode 100644
index 00000000000..f00ea5c95ca
--- /dev/null
+++ b/app/services/work_items/widgets/labels_service/update_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module WorkItems
+ module Widgets
+ module LabelsService
+ class UpdateService < WorkItems::Widgets::BaseService
+ def prepare_update_params(params: {})
+ return if params.blank?
+
+ service_params.merge!(params.slice(:add_label_ids, :remove_label_ids))
+ end
+ end
+ end
+ end
+end
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 6650e07be2a..3532c6638ce 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -13,9 +13,9 @@
= render "layouts/flash"
.mt-3
.col-sm-12.gl-text-center
- %img.gl-w-10{ :alt => _("GitLab Logo"), :src => image_path('logo.svg') }
+ = brand_image
%h1.mb-3.gl-font-size-h2
- = current_appearance&.title.presence || _('GitLab')
+ = brand_title
- if current_appearance&.description?
= brand_text
= render_if_exists 'layouts/devise_help_text'
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index 21d63a6db3d..79c5bb62f28 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -15,7 +15,8 @@
.dropdown.inline.wiki-sort-dropdown
.btn-group{ role: 'group' }
- = gl_redirect_listbox_tag wiki_sort_options, params[:sort], data: { right: true }
+ - unless @wiki.disable_sorting?
+ = gl_redirect_listbox_tag wiki_sort_options, params[:sort], data: { right: true }
= wiki_sort_controls(@wiki, params[:sort], params[:direction])
%ul.wiki-pages-list.content-list
diff --git a/config/feature_flags/development/wiki_list_pages_with_normal_repository_rpcs.yml b/config/feature_flags/development/wiki_list_pages_with_normal_repository_rpcs.yml
new file mode 100644
index 00000000000..4be550b5046
--- /dev/null
+++ b/config/feature_flags/development/wiki_list_pages_with_normal_repository_rpcs.yml
@@ -0,0 +1,8 @@
+---
+name: wiki_list_pages_with_normal_repository_rpcs
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96461
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372259
+milestone: '15.4'
+type: development
+group: group::gitaly
+default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 0e387d1b2dc..337c5c077f8 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -5839,6 +5839,7 @@ Input type: `WorkItemUpdateInput`
| <a id="mutationworkitemupdatehierarchywidget"></a>`hierarchyWidget` | [`WorkItemWidgetHierarchyUpdateInput`](#workitemwidgethierarchyupdateinput) | Input for hierarchy widget. |
| <a id="mutationworkitemupdateid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
| <a id="mutationworkitemupdateiterationwidget"></a>`iterationWidget` | [`WorkItemWidgetIterationInput`](#workitemwidgetiterationinput) | Input for iteration widget. |
+| <a id="mutationworkitemupdatelabelswidget"></a>`labelsWidget` | [`WorkItemWidgetLabelsUpdateInput`](#workitemwidgetlabelsupdateinput) | Input for labels widget. |
| <a id="mutationworkitemupdatestartandduedatewidget"></a>`startAndDueDateWidget` | [`WorkItemWidgetStartAndDueDateUpdateInput`](#workitemwidgetstartandduedateupdateinput) | Input for start and due date widget. |
| <a id="mutationworkitemupdatestateevent"></a>`stateEvent` | [`WorkItemStateEvent`](#workitemstateevent) | Close or reopen a work item. |
| <a id="mutationworkitemupdatetitle"></a>`title` | [`String`](#string) | Title of the work item. |
@@ -23494,6 +23495,7 @@ A time-frame defined as a closed inclusive range of two dates.
| <a id="workitemupdatedtaskinputdescriptionwidget"></a>`descriptionWidget` | [`WorkItemWidgetDescriptionInput`](#workitemwidgetdescriptioninput) | Input for description widget. |
| <a id="workitemupdatedtaskinputhierarchywidget"></a>`hierarchyWidget` | [`WorkItemWidgetHierarchyUpdateInput`](#workitemwidgethierarchyupdateinput) | Input for hierarchy widget. |
| <a id="workitemupdatedtaskinputid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
+| <a id="workitemupdatedtaskinputlabelswidget"></a>`labelsWidget` | [`WorkItemWidgetLabelsUpdateInput`](#workitemwidgetlabelsupdateinput) | Input for labels widget. |
| <a id="workitemupdatedtaskinputstartandduedatewidget"></a>`startAndDueDateWidget` | [`WorkItemWidgetStartAndDueDateUpdateInput`](#workitemwidgetstartandduedateupdateinput) | Input for start and due date widget. |
| <a id="workitemupdatedtaskinputstateevent"></a>`stateEvent` | [`WorkItemStateEvent`](#workitemstateevent) | Close or reopen a work item. |
| <a id="workitemupdatedtaskinputtitle"></a>`title` | [`String`](#string) | Title of the work item. |
@@ -23539,6 +23541,15 @@ A time-frame defined as a closed inclusive range of two dates.
| ---- | ---- | ----------- |
| <a id="workitemwidgetiterationinputiterationid"></a>`iterationId` | [`IterationID`](#iterationid) | Iteration to assign to the work item. |
+### `WorkItemWidgetLabelsUpdateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemwidgetlabelsupdateinputaddlabelids"></a>`addLabelIds` | [`[LabelID!]`](#labelid) | Global IDs of labels to be added to the work item. |
+| <a id="workitemwidgetlabelsupdateinputremovelabelids"></a>`removeLabelIds` | [`[LabelID!]`](#labelid) | Global IDs of labels to be removed from the work item. |
+
### `WorkItemWidgetStartAndDueDateUpdateInput`
#### Arguments
diff --git a/lib/gitlab/git/wiki_page.rb b/lib/gitlab/git/wiki_page.rb
index 57b7e7d53dd..154c79f56b8 100644
--- a/lib/gitlab/git/wiki_page.rb
+++ b/lib/gitlab/git/wiki_page.rb
@@ -41,6 +41,11 @@ module Gitlab
@text_data = @raw_data && Gitlab::EncodingHelper.encode!(@raw_data.dup)
end
+
+ def raw_data=(data)
+ @raw_data = data
+ @text_data = @raw_data && Gitlab::EncodingHelper.encode!(@raw_data.dup)
+ end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9011df84e10..887c880baab 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -17964,9 +17964,6 @@ msgstr ""
msgid "GitLab KAS"
msgstr ""
-msgid "GitLab Logo"
-msgstr ""
-
msgid "GitLab Pages"
msgstr ""
diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb
index 8ac17413df3..6e130f96999 100644
--- a/spec/features/projects/wikis_spec.rb
+++ b/spec/features/projects/wikis_spec.rb
@@ -12,14 +12,37 @@ RSpec.describe 'Project wikis', :js do
let(:wiki) { create(:project_wiki, user: user, project: project) }
let(:project) { create(:project, namespace: user.namespace, creator: user) }
- it_behaves_like 'User creates wiki page'
- it_behaves_like 'User deletes wiki page'
- it_behaves_like 'User previews wiki changes'
- it_behaves_like 'User updates wiki page'
- it_behaves_like 'User uses wiki shortcuts'
- it_behaves_like 'User views AsciiDoc page with includes'
- it_behaves_like 'User views a wiki page'
- it_behaves_like 'User views wiki pages'
- it_behaves_like 'User views wiki sidebar'
- it_behaves_like 'User views Git access wiki page'
+ context 'with legacy wiki rpcs' do
+ before do
+ stub_feature_flags(wiki_list_pages_with_normal_repository_rpcs: false)
+ end
+
+ it_behaves_like 'User creates wiki page'
+ it_behaves_like 'User deletes wiki page'
+ it_behaves_like 'User previews wiki changes'
+ it_behaves_like 'User updates wiki page'
+ it_behaves_like 'User uses wiki shortcuts'
+ it_behaves_like 'User views AsciiDoc page with includes'
+ it_behaves_like 'User views a wiki page'
+ it_behaves_like 'User views wiki pages'
+ it_behaves_like 'User views wiki sidebar'
+ it_behaves_like 'User views Git access wiki page'
+ end
+
+ context 'with normal repository rpcs' do
+ before do
+ stub_feature_flags(wiki_list_pages_with_normal_repository_rpcs: true)
+ end
+
+ it_behaves_like 'User creates wiki page'
+ it_behaves_like 'User deletes wiki page'
+ it_behaves_like 'User previews wiki changes'
+ it_behaves_like 'User updates wiki page'
+ it_behaves_like 'User uses wiki shortcuts'
+ it_behaves_like 'User views AsciiDoc page with includes'
+ it_behaves_like 'User views a wiki page'
+ it_behaves_like 'User views wiki pages', false
+ it_behaves_like 'User views wiki sidebar'
+ it_behaves_like 'User views Git access wiki page'
+ end
end
diff --git a/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb b/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb
new file mode 100644
index 00000000000..3e5f40bde02
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Types::WorkItems::Widgets::LabelsUpdateInputType do
+ it { expect(described_class.graphql_name).to eq('WorkItemWidgetLabelsUpdateInput') }
+
+ it { expect(described_class.arguments.keys).to contain_exactly('addLabelIds', 'removeLabelIds') }
+end
diff --git a/spec/helpers/appearances_helper_spec.rb b/spec/helpers/appearances_helper_spec.rb
index edd704ce739..2206c1ce2ae 100644
--- a/spec/helpers/appearances_helper_spec.rb
+++ b/spec/helpers/appearances_helper_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe AppearancesHelper do
+ let_it_be(:gitlab_logo) { ActionController::Base.helpers.image_path('logo.svg') }
+
before do
user = create(:user)
allow(helper).to receive(:current_user).and_return(user)
@@ -59,23 +61,59 @@ RSpec.describe AppearancesHelper do
end
describe '#brand_image' do
- let!(:appearance) { create(:appearance, :with_logo) }
-
context 'when there is a logo' do
+ let!(:appearance) { create(:appearance, :with_logo) }
+
it 'returns a path' do
- expect(helper.brand_image).to match(%r(img data-src="/uploads/-/system/appearance/.*png))
+ expect(helper.brand_image).to match(%r(img .* data-src="/uploads/-/system/appearance/.*png))
+ end
+
+ context 'when there is no associated upload' do
+ before do
+ # Legacy attachments were not tracked in the uploads table
+ appearance.logo.upload.destroy!
+ appearance.reload
+ end
+
+ it 'falls back to using the original path' do
+ expect(helper.brand_image).to match(%r(img .* data-src="/uploads/-/system/appearance/.*png))
+ end
end
end
- context 'when there is a logo but no associated upload' do
- before do
- # Legacy attachments were not tracked in the uploads table
- appearance.logo.upload.destroy!
- appearance.reload
+ context 'when there is no logo' do
+ it 'returns path of GitLab logo' do
+ expect(helper.brand_image).to match(%r(img .* data-src="#{gitlab_logo}))
+ end
+ end
+
+ context 'when there is a title' do
+ let!(:appearance) { create(:appearance, title: 'My title') }
+
+ it 'returns the title' do
+ expect(helper.brand_image).to match(%r(img alt="My title"))
end
+ end
+
+ context 'when there is no title' do
+ it 'returns the default title' do
+ expect(helper.brand_image).to match(%r(img alt="GitLab))
+ end
+ end
+ end
+
+ describe '#brand_image_path' do
+ context 'with a custom logo' do
+ let!(:appearance) { create(:appearance, :with_logo) }
+
+ it 'returns path of custom logo' do
+ expect(helper.brand_image_path).to match(%r(/uploads/-/system/appearance/.*/dk.png))
+ end
+ end
- it 'falls back to using the original path' do
- expect(helper.brand_image).to match(%r(img data-src="/uploads/-/system/appearance/.*png))
+ context 'with no custom logo' do
+ it 'returns path of GitLab logo' do
+ expect(helper.brand_image_path).to eq(gitlab_logo)
end
end
end
diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb
index 75128d758f9..e798281ccff 100644
--- a/spec/helpers/wiki_helper_spec.rb
+++ b/spec/helpers/wiki_helper_spec.rb
@@ -79,37 +79,72 @@ RSpec.describe WikiHelper do
let(:classes) { "gl-button btn btn-default btn-icon has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" }
def expected_link(sort, direction, icon_class)
- path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
+ path =
+ if sort
+ "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
+ else
+ "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}"
+ end
helper.link_to(path, type: 'button', class: classes, title: 'Sort direction') do
helper.sprite_icon("sort-#{icon_class}")
end
end
- context 'initial call' do
- let(:sort) { nil }
- let(:direction) { nil }
+ context 'wiki sorting enabled' do
+ before do
+ allow(wiki).to receive(:disable_sorting?).and_return(false)
+ end
+
+ context 'initial call' do
+ let(:sort) { nil }
+ let(:direction) { nil }
- it 'renders with default values' do
- expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest'))
+ it 'renders with default values' do
+ expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest'))
+ end
+ end
+
+ context 'sort by title' do
+ let(:sort) { 'title' }
+ let(:direction) { 'asc' }
+
+ it 'renders a link with opposite direction' do
+ expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest'))
+ end
end
- end
- context 'sort by title' do
- let(:sort) { 'title' }
- let(:direction) { 'asc' }
+ context 'sort by created_at' do
+ let(:sort) { 'created_at' }
+ let(:direction) { 'desc' }
- it 'renders a link with opposite direction' do
- expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest'))
+ it 'renders a link with opposite direction' do
+ expect(wiki_link).to eq(expected_link('created_at', 'asc', 'highest'))
+ end
end
end
- context 'sort by created_at' do
- let(:sort) { 'created_at' }
- let(:direction) { 'desc' }
+ context 'wiki sorting disabled' do
+ before do
+ allow(wiki).to receive(:disable_sorting?).and_return(true)
+ end
+
+ context 'sort by created_at' do
+ let(:sort) { 'created_at' }
+ let(:direction) { 'asc' }
+
+ it 'ignores created_at and renders a link with opposite direction' do
+ expect(wiki_link).to eq(expected_link(nil, 'desc', 'lowest'))
+ end
+ end
+
+ context 'initial call' do
+ let(:sort) { nil }
+ let(:direction) { nil }
- it 'renders a link with opposite direction' do
- expect(wiki_link).to eq(expected_link('created_at', 'asc', 'highest'))
+ it 'renders with default values' do
+ expect(wiki_link).to eq(expected_link(nil, 'desc', 'lowest'))
+ end
end
end
end
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index a9c0262fdb2..a762fdbde6b 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -118,7 +118,7 @@ RSpec.describe Gitlab::ProjectSearchResults do
shared_examples 'blob search repository ref' do |entity_type, blob_type|
let(:query) { 'files' }
let(:file_finder) { double }
- let(:project_branch) { 'project_branch' }
+ let(:project_branch) { blob_type == 'wiki_blobs' ? entity.default_branch : 'project_branch' }
subject(:objects) { results.objects(blob_type) }
@@ -209,8 +209,11 @@ RSpec.describe Gitlab::ProjectSearchResults do
describe 'wiki search' do
let(:project) { create(:project, :public, :wiki_repo) }
+ let(:project_branch) { 'project_branch' }
before do
+ allow(project.wiki).to receive(:root_ref).and_return(project_branch)
+
project.wiki.create_page('Files/Title', 'Content')
project.wiki.create_page('CHANGELOG', 'Files example')
end
diff --git a/spec/lib/gitlab/serializer/ci/variables_spec.rb b/spec/lib/gitlab/serializer/ci/variables_spec.rb
index 9b0475259fe..02f1d543e4b 100644
--- a/spec/lib/gitlab/serializer/ci/variables_spec.rb
+++ b/spec/lib/gitlab/serializer/ci/variables_spec.rb
@@ -13,9 +13,10 @@ RSpec.describe Gitlab::Serializer::Ci::Variables do
end
it 'converts keys into strings and symbolizes hash' do
- is_expected.to eq([
- { key: 'key', value: 'value', public: true },
- { key: 'wee', value: 1, public: false }
- ])
+ is_expected.to eq(
+ [
+ { key: 'key', value: 'value', public: true },
+ { key: 'wee', value: 1, public: false }
+ ])
end
end
diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb
index c62302d8bba..c5b00afe672 100644
--- a/spec/lib/gitlab/sidekiq_config_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config_spec.rb
@@ -193,9 +193,7 @@ RSpec.describe Gitlab::SidekiqConfig do
it 'returns worker queue mappings that have queues in the current Sidekiq options' do
queues = described_class.routing_queues
- expect(queues).to match_array(%w[
- default mailers high_urgency gitaly
- ])
+ expect(queues).to match_array(%w[default mailers high_urgency gitaly])
expect(queues).not_to include('not_exist')
end
end
diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb
index 114a18cf99a..a2524314458 100644
--- a/spec/lib/gitlab/ssh_public_key_spec.rb
+++ b/spec/lib/gitlab/ssh_public_key_spec.rb
@@ -88,12 +88,12 @@ RSpec.describe Gitlab::SSHPublicKey, lib: true, fips_mode: false do
it 'returns all supported algorithms' do
expect(described_class.supported_algorithms).to eq(
%w(
- ssh-rsa
- ssh-dss
- ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
- ssh-ed25519
- sk-ecdsa-sha2-nistp256@openssh.com
- sk-ssh-ed25519@openssh.com
+ ssh-rsa
+ ssh-dss
+ ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
+ ssh-ed25519
+ sk-ecdsa-sha2-nistp256@openssh.com
+ sk-ssh-ed25519@openssh.com
)
)
end
@@ -102,12 +102,12 @@ RSpec.describe Gitlab::SSHPublicKey, lib: true, fips_mode: false do
it 'returns all supported algorithms' do
expect(described_class.supported_algorithms).to eq(
%w(
- ssh-rsa
- ssh-dss
- ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
- ssh-ed25519
- sk-ecdsa-sha2-nistp256@openssh.com
- sk-ssh-ed25519@openssh.com
+ ssh-rsa
+ ssh-dss
+ ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521
+ ssh-ed25519
+ sk-ecdsa-sha2-nistp256@openssh.com
+ sk-ssh-ed25519@openssh.com
)
)
end
diff --git a/spec/lib/gitlab/usage_data/topology_spec.rb b/spec/lib/gitlab/usage_data/topology_spec.rb
index dfdf8eaabe8..3fb87e77457 100644
--- a/spec/lib/gitlab/usage_data/topology_spec.rb
+++ b/spec/lib/gitlab/usage_data/topology_spec.rb
@@ -523,210 +523,210 @@ RSpec.describe Gitlab::UsageData::Topology do
receive(:query)
.with(/gitlab_usage_ping:ops:rate/)
.and_return(result || [
- {
- 'metric' => { 'component' => 'http_requests', 'service' => 'workhorse' },
- 'value' => [1000, '0.01']
- }
- ])
+ {
+ 'metric' => { 'component' => 'http_requests', 'service' => 'workhorse' },
+ 'value' => [1000, '0.01']
+ }
+ ])
end
def receive_query_apdex_ratio_query(result: nil)
receive(:query)
.with(/gitlab_usage_ping:sql_duration_apdex:ratio_rate5m/)
.and_return(result || [
- {
- 'metric' => {},
- 'value' => [1000, '0.996']
- }
- ])
+ {
+ 'metric' => {},
+ 'value' => [1000, '0.996']
+ }
+ ])
end
def receive_node_memory_query(result: nil)
receive(:query)
.with(/node_memory_total_bytes/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance1:8080' },
- 'value' => [1000, '512']
- },
- {
- 'metric' => { 'instance' => 'instance2:8090' },
- 'value' => [1000, '1024']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '512']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '1024']
+ }
+ ])
end
def receive_node_memory_utilization_query(result: nil)
receive(:query)
.with(/node_memory_utilization/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance1:8080' },
- 'value' => [1000, '0.45']
- },
- {
- 'metric' => { 'instance' => 'instance2:8090' },
- 'value' => [1000, '0.25']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '0.45']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '0.25']
+ }
+ ])
end
def receive_node_cpu_count_query(result: nil)
receive(:query)
.with(/node_cpus/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance2:8090' },
- 'value' => [1000, '16']
- },
- {
- 'metric' => { 'instance' => 'instance1:8080' },
- 'value' => [1000, '8']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '16']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '8']
+ }
+ ])
end
def receive_node_cpu_utilization_query(result: nil)
receive(:query)
.with(/node_cpu_utilization/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance2:8090' },
- 'value' => [1000, '0.2']
- },
- {
- 'metric' => { 'instance' => 'instance1:8080' },
- 'value' => [1000, '0.1']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '0.2']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '0.1']
+ }
+ ])
end
def receive_node_uname_info_query(result: nil)
receive(:query)
.with('node_uname_info')
.and_return(result || [
- {
- "metric" => {
- "__name__" => "node_uname_info",
- "domainname" => "(none)",
- "instance" => "instance1:9100",
- "job" => "node_exporter",
- "machine" => "x86_64",
- "nodename" => "instance1",
- "release" => "4.19.76-linuxkit",
- "sysname" => "Linux"
- },
- "value" => [1592463033.359, "1"]
- },
- {
- "metric" => {
- "__name__" => "node_uname_info",
- "domainname" => "(none)",
- "instance" => "instance2:9100",
- "job" => "node_exporter",
- "machine" => "x86_64",
- "nodename" => "instance2",
- "release" => "4.15.0-101-generic",
- "sysname" => "Linux"
- },
- "value" => [1592463033.359, "1"]
- }
- ])
+ {
+ "metric" => {
+ "__name__" => "node_uname_info",
+ "domainname" => "(none)",
+ "instance" => "instance1:9100",
+ "job" => "node_exporter",
+ "machine" => "x86_64",
+ "nodename" => "instance1",
+ "release" => "4.19.76-linuxkit",
+ "sysname" => "Linux"
+ },
+ "value" => [1592463033.359, "1"]
+ },
+ {
+ "metric" => {
+ "__name__" => "node_uname_info",
+ "domainname" => "(none)",
+ "instance" => "instance2:9100",
+ "job" => "node_exporter",
+ "machine" => "x86_64",
+ "nodename" => "instance2",
+ "release" => "4.15.0-101-generic",
+ "sysname" => "Linux"
+ },
+ "value" => [1592463033.359, "1"]
+ }
+ ])
end
def receive_node_service_memory_rss_query(result: nil)
receive(:query)
.with(/process_resident_memory_bytes/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
- 'value' => [1000, '300']
- },
- {
- 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq' },
- 'value' => [1000, '303']
- },
- # instance 2: runs a dedicated Sidekiq + Redis (which uses a different metric name)
- {
- 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
- 'value' => [1000, '400']
- },
- {
- 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis' },
- 'value' => [1000, '402']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
+ 'value' => [1000, '300']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '303']
+ },
+ # instance 2: runs a dedicated Sidekiq + Redis (which uses a different metric name)
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '400']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis' },
+ 'value' => [1000, '402']
+ }
+ ])
end
def receive_node_service_memory_uss_query(result: nil)
receive(:query)
.with(/process_unique_memory_bytes/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
- 'value' => [1000, '301']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
+ 'value' => [1000, '301']
+ }
+ ])
end
def receive_node_service_memory_pss_query(result: nil)
receive(:query)
.with(/process_proportional_memory_bytes/, an_instance_of(Hash))
.and_return(result || [
- {
- 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
- 'value' => [1000, '302']
- },
- {
- 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
- 'value' => [1000, '401']
- }
- ])
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
+ 'value' => [1000, '302']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '401']
+ }
+ ])
end
def receive_node_service_process_count_query(result: nil)
receive(:query)
.with(/service_process:count/, an_instance_of(Hash))
.and_return(result || [
- # instance 1
- {
- 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
- 'value' => [1000, '10']
- },
- {
- 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq' },
- 'value' => [1000, '5']
- },
- # instance 2
- {
- 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
- 'value' => [1000, '15']
- },
- {
- 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis' },
- 'value' => [1000, '1']
- },
- {
- 'metric' => { 'instance' => 'instance2:8080', 'job' => 'registry' },
- 'value' => [1000, '1']
- }
- ])
+ # instance 1
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
+ 'value' => [1000, '10']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '5']
+ },
+ # instance 2
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '15']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis' },
+ 'value' => [1000, '1']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8080', 'job' => 'registry' },
+ 'value' => [1000, '1']
+ }
+ ])
end
def receive_node_service_app_server_workers_query(result: nil)
receive(:query)
.with(/app_server_workers/, an_instance_of(Hash))
.and_return(result || [
- # instance 1
- {
- 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails', 'server' => 'puma' },
- 'value' => [1000, '2']
- },
- # instance 2
- {
- 'metric' => { 'instance' => 'instance2:8080', 'job' => 'gitlab-rails', 'server' => 'puma' },
- 'value' => [1000, '1']
- }
- ])
+ # instance 1
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails', 'server' => 'puma' },
+ 'value' => [1000, '2']
+ },
+ # instance 2
+ {
+ 'metric' => { 'instance' => 'instance2:8080', 'job' => 'gitlab-rails', 'server' => 'puma' },
+ 'value' => [1000, '1']
+ }
+ ])
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 745aa20a6a2..dc34b0b10e0 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -1050,12 +1050,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
before do
allow(described_class).to receive(:operating_system).and_return('ubuntu-20.04')
- expect(prometheus_client).to receive(:query).with(/gitlab_usage_ping:gitaly_apdex:ratio_avg_over_time_5m/).and_return([
- {
- 'metric' => {},
- 'value' => [1616016381.473, '0.95']
- }
- ])
+ expect(prometheus_client).to receive(:query)
+ .with(/gitlab_usage_ping:gitaly_apdex:ratio_avg_over_time_5m/)
+ .and_return(
+ [
+ { 'metric' => {},
+ 'value' => [1616016381.473, '0.95'] }
+ ])
expect(described_class).to receive(:with_prometheus_client).and_yield(prometheus_client)
end
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index 61323f0646b..d1fdaf7a9db 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -582,11 +582,12 @@ RSpec.describe Gitlab::Utils do
end
it 'sorts items like the regular sort_by' do
- expect(sorted_list).to eq([
- { name: 'obj 2', priority: 1 },
- { name: 'obj 1', priority: 2 },
- { name: 'obj 3', priority: 3 }
- ])
+ expect(sorted_list).to eq(
+ [
+ { name: 'obj 2', priority: 1 },
+ { name: 'obj 1', priority: 2 },
+ { name: 'obj 3', priority: 3 }
+ ])
end
end
end
diff --git a/spec/lib/gitlab/webpack/manifest_spec.rb b/spec/lib/gitlab/webpack/manifest_spec.rb
index 08b4774dd67..24a36258379 100644
--- a/spec/lib/gitlab/webpack/manifest_spec.rb
+++ b/spec/lib/gitlab/webpack/manifest_spec.rb
@@ -66,10 +66,11 @@ RSpec.describe Gitlab::Webpack::Manifest do
describe "webpack errors" do
context "when webpack has 'Module build failed' errors in its manifest" do
it "errors" do
- error_manifest = Gitlab::Json.parse(manifest).merge("errors" => [
- "somethingModule build failed something",
- "I am an error"
- ]).to_json
+ error_manifest = Gitlab::Json.parse(manifest).merge("errors" =>
+ [
+ "somethingModule build failed something",
+ "I am an error"
+ ]).to_json
stub_request(:get, "http://hostname:2000/public_path/my_manifest.json").to_return(body: error_manifest, status: 200)
expect { Gitlab::Webpack::Manifest.asset_paths("entry1") }.to raise_error(Gitlab::Webpack::Manifest::WebpackError)
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index 0f117f495d1..0c207161927 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -17,17 +17,19 @@ RSpec.describe GoogleApi::CloudPlatform::Client do
let(:tier) { 'mock-tier' }
let(:database_list) do
- Google::Apis::SqladminV1beta4::ListDatabasesResponse.new(items: [
- Google::Apis::SqladminV1beta4::Database.new(name: 'db_01', instance: database_instance),
- Google::Apis::SqladminV1beta4::Database.new(name: 'db_02', instance: database_instance)
- ])
+ Google::Apis::SqladminV1beta4::ListDatabasesResponse.new(
+ items: [
+ Google::Apis::SqladminV1beta4::Database.new(name: 'db_01', instance: database_instance),
+ Google::Apis::SqladminV1beta4::Database.new(name: 'db_02', instance: database_instance)
+ ])
end
let(:user_list) do
- Google::Apis::SqladminV1beta4::ListUsersResponse.new(items: [
- Google::Apis::SqladminV1beta4::User.new(name: 'user_01', instance: database_instance),
- Google::Apis::SqladminV1beta4::User.new(name: 'user_02', instance: database_instance)
- ])
+ Google::Apis::SqladminV1beta4::ListUsersResponse.new(
+ items: [
+ Google::Apis::SqladminV1beta4::User.new(name: 'user_01', instance: database_instance),
+ Google::Apis::SqladminV1beta4::User.new(name: 'user_02', instance: database_instance)
+ ])
end
describe '.session_key_for_redirect_uri' do
diff --git a/spec/lib/peek/views/bullet_detailed_spec.rb b/spec/lib/peek/views/bullet_detailed_spec.rb
index ec2f798a320..6eaf8c50cc0 100644
--- a/spec/lib/peek/views/bullet_detailed_spec.rb
+++ b/spec/lib/peek/views/bullet_detailed_spec.rb
@@ -44,10 +44,11 @@ RSpec.describe Peek::Views::BulletDetailed do
expect(subject.key).to eq('bullet')
expect(subject.results[:calls]).to eq(2)
expect(subject.results[:warnings]).to eq([Peek::Views::BulletDetailed::WARNING_MESSAGE])
- expect(subject.results[:details]).to eq([
- { notification: 'Title 1: Body 1', backtrace: "first\nsecond\n" },
- { notification: 'Title 2: Body 2', backtrace: "first\nsecond\n" }
- ])
+ expect(subject.results[:details]).to eq(
+ [
+ { notification: 'Title 1: Body 1', backtrace: "first\nsecond\n" },
+ { notification: 'Title 2: Body 2', backtrace: "first\nsecond\n" }
+ ])
end
end
end
diff --git a/spec/lib/system_check/incoming_email_check_spec.rb b/spec/lib/system_check/incoming_email_check_spec.rb
index 5d93b810045..cf3fd3b7967 100644
--- a/spec/lib/system_check/incoming_email_check_spec.rb
+++ b/spec/lib/system_check/incoming_email_check_spec.rb
@@ -26,11 +26,12 @@ RSpec.describe SystemCheck::IncomingEmailCheck do
end
it 'runs IMAP and mailroom checks' do
- expect(SystemCheck).to receive(:run).with('Reply by email', [
- SystemCheck::IncomingEmail::ImapAuthenticationCheck,
- SystemCheck::IncomingEmail::MailRoomEnabledCheck,
- SystemCheck::IncomingEmail::MailRoomRunningCheck
- ])
+ expect(SystemCheck).to receive(:run).with('Reply by email',
+ [
+ SystemCheck::IncomingEmail::ImapAuthenticationCheck,
+ SystemCheck::IncomingEmail::MailRoomEnabledCheck,
+ SystemCheck::IncomingEmail::MailRoomRunningCheck
+ ])
subject.multi_check
end
@@ -42,10 +43,11 @@ RSpec.describe SystemCheck::IncomingEmailCheck do
end
it 'runs mailroom checks' do
- expect(SystemCheck).to receive(:run).with('Reply by email', [
- SystemCheck::IncomingEmail::MailRoomEnabledCheck,
- SystemCheck::IncomingEmail::MailRoomRunningCheck
- ])
+ expect(SystemCheck).to receive(:run).with('Reply by email',
+ [
+ SystemCheck::IncomingEmail::MailRoomEnabledCheck,
+ SystemCheck::IncomingEmail::MailRoomRunningCheck
+ ])
subject.multi_check
end
diff --git a/spec/lib/unnested_in_filters/rewriter_spec.rb b/spec/lib/unnested_in_filters/rewriter_spec.rb
index a808aec7728..21bab42c95c 100644
--- a/spec/lib/unnested_in_filters/rewriter_spec.rb
+++ b/spec/lib/unnested_in_filters/rewriter_spec.rb
@@ -41,14 +41,15 @@ RSpec.describe UnnestedInFilters::Rewriter do
context 'when the order is a Keyset order' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build([
- Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
- attribute_name: 'user_type',
- order_expression: User.arel_table['user_type'].desc,
- nullable: :not_nullable,
- distinct: false
- )
- ])
+ Gitlab::Pagination::Keyset::Order.build(
+ [
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'user_type',
+ order_expression: User.arel_table['user_type'].desc,
+ nullable: :not_nullable,
+ distinct: false
+ )
+ ])
end
it { is_expected.to be_truthy }
@@ -152,14 +153,15 @@ RSpec.describe UnnestedInFilters::Rewriter do
context 'when the order is a Keyset order' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build([
- Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
- attribute_name: 'user_type',
- order_expression: User.arel_table['user_type'].desc,
- nullable: :not_nullable,
- distinct: false
- )
- ])
+ Gitlab::Pagination::Keyset::Order.build(
+ [
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'user_type',
+ order_expression: User.arel_table['user_type'].desc,
+ nullable: :not_nullable,
+ distinct: false
+ )
+ ])
end
it 'changes the query' do
diff --git a/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb b/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb
index fb62fc3ca02..0ae4559ca9f 100644
--- a/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb
+++ b/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb
@@ -72,12 +72,14 @@ RSpec.describe AddPremiumAndUltimatePlanLimits, :migration do
it 'creates plan limits from the source plan' do
migrate!
- expect(AddPremiumAndUltimatePlanLimits::PlanLimits.pluck(:plan_id, :storage_size_limit)).to match_array([
- [silver.id, silver_limits.storage_size_limit],
- [gold.id, gold_limits.storage_size_limit],
- [premium.id, silver_limits.storage_size_limit],
- [ultimate.id, gold_limits.storage_size_limit]
- ])
+ expect(AddPremiumAndUltimatePlanLimits::PlanLimits.pluck(:plan_id, :storage_size_limit))
+ .to match_array(
+ [
+ [silver.id, silver_limits.storage_size_limit],
+ [gold.id, gold_limits.storage_size_limit],
+ [premium.id, silver_limits.storage_size_limit],
+ [ultimate.id, gold_limits.storage_size_limit]
+ ])
end
end
end
diff --git a/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb b/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb
index da32e92ebb0..87855285203 100644
--- a/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb
+++ b/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb
@@ -57,36 +57,39 @@ RSpec.describe BackfillEscalationPoliciesForOncallSchedules do
expect(new_polices).to all have_attributes(name: 'On-call Escalation Policy')
expect(new_policy_b1.description).to eq('Immediately notify Schedule B1')
expect(new_policy_c1.description).to eq('Immediately notify Schedule C1')
- expect(policies.pluck(:project_id)).to eq([
- project_d.id,
- project_e.id,
- project_f.id,
- project_f.id,
- project_b.id,
- project_c.id
- ])
+ expect(policies.pluck(:project_id)).to eq(
+ [
+ project_d.id,
+ project_e.id,
+ project_f.id,
+ project_f.id,
+ project_b.id,
+ project_c.id
+ ])
expect(new_rules).to all have_attributes(status: 1, elapsed_time_seconds: 0)
- expect(rules.pluck(:policy_id)).to eq([
- rule_d1.policy_id,
- rule_e1.policy_id,
- rule_f1.policy_id,
- rule_f2.policy_id,
- rule_f3.policy_id,
- new_policy_b1.id,
- new_policy_c1.id,
- new_policy_c1.id
- ])
- expect(rules.pluck(:oncall_schedule_id)).to eq([
- rule_d1.oncall_schedule_id,
- rule_e1.oncall_schedule_id,
- rule_f1.oncall_schedule_id,
- rule_f2.oncall_schedule_id,
- rule_f3.oncall_schedule_id,
- schedule_b1.id,
- schedule_c1.id,
- schedule_c2.id
- ])
+ expect(rules.pluck(:policy_id)).to eq(
+ [
+ rule_d1.policy_id,
+ rule_e1.policy_id,
+ rule_f1.policy_id,
+ rule_f2.policy_id,
+ rule_f3.policy_id,
+ new_policy_b1.id,
+ new_policy_c1.id,
+ new_policy_c1.id
+ ])
+ expect(rules.pluck(:oncall_schedule_id)).to eq(
+ [
+ rule_d1.oncall_schedule_id,
+ rule_e1.oncall_schedule_id,
+ rule_f1.oncall_schedule_id,
+ rule_f2.oncall_schedule_id,
+ rule_f3.oncall_schedule_id,
+ schedule_b1.id,
+ schedule_c1.id,
+ schedule_c2.id
+ ])
end
end
diff --git a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
index e03dd73ec8b..b03a5c41a11 100644
--- a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
+++ b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
@@ -49,12 +49,13 @@ RSpec.describe SliceMergeRequestDiffCommitMigrations, :migration do
.pending
.to_a
- expect(new_jobs.map(&:arguments)).to eq([
- [1, 5_001],
- [5_001, 10_001],
- [10_001, 15_001],
- [15_001, 20_001]
- ])
+ expect(new_jobs.map(&:arguments)).to eq(
+ [
+ [1, 5_001],
+ [5_001, 10_001],
+ [10_001, 15_001],
+ [15_001, 20_001]
+ ])
end
it 'schedules a background migration for the first job' do
diff --git a/spec/models/analytics/cycle_analytics/project_stage_spec.rb b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
index a67f9fec443..697b7aee022 100644
--- a/spec/models/analytics/cycle_analytics/project_stage_spec.rb
+++ b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
@@ -48,10 +48,11 @@ RSpec.describe Analytics::CycleAnalytics::ProjectStage do
subject(:distinct_start_and_end_event_identifiers) { described_class.distinct_stages_within_hierarchy(top_level_group).to_a.pluck(:start_event_identifier, :end_event_identifier) }
it 'returns distinct stages by start and end events (using stage_event_hash_id)' do
- expect(distinct_start_and_end_event_identifiers).to match_array([
- %w[issue_created issue_deployed_to_production],
- %w[merge_request_created merge_request_merged]
- ])
+ expect(distinct_start_and_end_event_identifiers).to match_array(
+ [
+ %w[issue_created issue_deployed_to_production],
+ %w[merge_request_created merge_request_merged]
+ ])
end
end
end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index db64e8439a5..687ffbe87bf 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -257,11 +257,12 @@ RSpec.describe ApplicationSetting do
subject.grafana_url = ' ' + http
expect(subject.save).to be false
- expect(subject.errors[:grafana_url]).to eq([
- 'must be a valid relative or absolute URL. ' \
- 'Please check your Grafana URL setting in ' \
- 'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
- ])
+ expect(subject.errors[:grafana_url]).to eq(
+ [
+ 'must be a valid relative or absolute URL. ' \
+ 'Please check your Grafana URL setting in ' \
+ 'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
+ ])
end
end
@@ -270,11 +271,12 @@ RSpec.describe ApplicationSetting do
subject.grafana_url = javascript
expect(subject.save).to be false
- expect(subject.errors[:grafana_url]).to eq([
- 'is blocked: Only allowed schemes are http, https. Please check your ' \
- 'Grafana URL setting in ' \
- 'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
- ])
+ expect(subject.errors[:grafana_url]).to eq(
+ [
+ 'is blocked: Only allowed schemes are http, https. Please check your ' \
+ 'Grafana URL setting in ' \
+ 'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
+ ])
end
end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 279556ac75d..ec0fe456d99 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -5275,10 +5275,11 @@ RSpec.describe Ci::Build do
it { expect(matchers.size).to eq(2) }
it 'groups build ids' do
- expect(matchers.map(&:build_ids)).to match_array([
- [build_without_tags.id],
- match_array([build_with_tags.id, other_build_with_tags.id])
- ])
+ expect(matchers.map(&:build_ids)).to match_array(
+ [
+ [build_without_tags.id],
+ match_array([build_with_tags.id, other_build_with_tags.id])
+ ])
end
it { expect(matchers.map(&:tag_list)).to match_array([[], %w[tag1 tag2]]) }
@@ -5475,10 +5476,11 @@ RSpec.describe Ci::Build do
create(:ci_job_variable, job: build, key: 'TEST_KEY', value: 'old value')
create(:ci_job_variable, job: build, key: 'OLD_KEY', value: 'i will not live for long')
- new_build = build.clone(current_user: user, new_job_variables_attributes: [
- { key: 'TEST_KEY', value: 'new value' },
- { key: 'NEW_KEY', value: 'exciting new value' }
- ])
+ new_build = build.clone(current_user: user, new_job_variables_attributes:
+ [
+ { key: 'TEST_KEY', value: 'new value' },
+ { key: 'NEW_KEY', value: 'exciting new value' }
+ ])
new_build.save!
expect(new_build.job_variables.count).to be(2)
@@ -5492,9 +5494,10 @@ RSpec.describe Ci::Build do
build = create(:ci_build)
create(:ci_job_variable, job: build, key: 'TEST_KEY', value: 'old value')
- new_build = build.clone(current_user: user, new_job_variables_attributes: [
- { key: 'TEST_KEY', value: 'new value' }
- ])
+ new_build = build.clone(
+ current_user: user,
+ new_job_variables_attributes: [{ key: 'TEST_KEY', value: 'new value' }]
+ )
new_build.save!
expect(new_build.job_variables.count).to be(1)
diff --git a/spec/models/ci/build_trace_spec.rb b/spec/models/ci/build_trace_spec.rb
index bd24e8be1ac..f2df4874b84 100644
--- a/spec/models/ci/build_trace_spec.rb
+++ b/spec/models/ci/build_trace_spec.rb
@@ -28,9 +28,10 @@ RSpec.describe Ci::BuildTrace do
it_behaves_like 'delegates methods'
it 'returns formatted trace' do
- expect(subject.lines).to eq([
- { offset: 0, content: [{ text: 'the-stream' }] }
- ])
+ expect(subject.lines).to eq(
+ [
+ { offset: 0, content: [{ text: 'the-stream' }] }
+ ])
end
context 'with invalid UTF-8 data' do
diff --git a/spec/models/ci/daily_build_group_report_result_spec.rb b/spec/models/ci/daily_build_group_report_result_spec.rb
index d0141a1469e..cd55817243f 100644
--- a/spec/models/ci/daily_build_group_report_result_spec.rb
+++ b/spec/models/ci/daily_build_group_report_result_spec.rb
@@ -41,24 +41,25 @@ RSpec.describe Ci::DailyBuildGroupReportResult do
let!(:new_pipeline) { create(:ci_pipeline) }
it 'creates or updates matching report results' do
- described_class.upsert_reports([
- {
- project_id: rspec_coverage.project_id,
- ref_path: rspec_coverage.ref_path,
- last_pipeline_id: new_pipeline.id,
- date: rspec_coverage.date,
- group_name: 'rspec',
- data: { 'coverage' => 81.0 }
- },
- {
- project_id: rspec_coverage.project_id,
- ref_path: rspec_coverage.ref_path,
- last_pipeline_id: new_pipeline.id,
- date: rspec_coverage.date,
- group_name: 'karma',
- data: { 'coverage' => 87.0 }
- }
- ])
+ described_class.upsert_reports(
+ [
+ {
+ project_id: rspec_coverage.project_id,
+ ref_path: rspec_coverage.ref_path,
+ last_pipeline_id: new_pipeline.id,
+ date: rspec_coverage.date,
+ group_name: 'rspec',
+ data: { 'coverage' => 81.0 }
+ },
+ {
+ project_id: rspec_coverage.project_id,
+ ref_path: rspec_coverage.ref_path,
+ last_pipeline_id: new_pipeline.id,
+ date: rspec_coverage.date,
+ group_name: 'karma',
+ data: { 'coverage' => 87.0 }
+ }
+ ])
rspec_coverage.reload
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 8bf32527342..d854943e277 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -4531,10 +4531,11 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
it 'returns accessibility report with collected data' do
- expect(subject.urls.keys).to match_array([
- "https://pa11y.org/",
- "https://about.gitlab.com/"
- ])
+ expect(subject.urls.keys).to match_array(
+ [
+ "https://pa11y.org/",
+ "https://about.gitlab.com/"
+ ])
end
context 'when builds are retried' do
diff --git a/spec/requests/api/graphql/mutations/work_items/update_spec.rb b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
index 909d6549fa5..6b0129c457f 100644
--- a/spec/requests/api/graphql/mutations/work_items/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
@@ -144,6 +144,78 @@ RSpec.describe 'Update a work item' do
end
end
+ context 'with labels widget input' do
+ shared_examples 'mutation updating work item labels' do
+ it 'updates labels' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ work_item.reload
+ end.to change { work_item.labels.count }.to(expected_labels.count)
+
+ expect(work_item.labels).to match_array(expected_labels)
+ expect(mutation_response['workItem']['widgets']).to include(
+ 'labels' => {
+ 'nodes' => match_array(expected_labels.map { |l| { 'id' => l.to_gid.to_s } })
+ },
+ 'type' => 'LABELS'
+ )
+ end
+ end
+
+ let_it_be(:existing_label) { create(:label, project: project) }
+ let_it_be(:label1) { create(:label, project: project) }
+ let_it_be(:label2) { create(:label, project: project) }
+
+ let(:fields) do
+ <<~FIELDS
+ workItem {
+ widgets {
+ type
+ ... on WorkItemWidgetLabels {
+ labels {
+ nodes { id }
+ }
+ }
+ }
+ }
+ errors
+ FIELDS
+ end
+
+ let(:input) do
+ { 'labelsWidget' => { 'addLabelIds' => add_label_ids, 'removeLabelIds' => remove_label_ids } }
+ end
+
+ let(:add_label_ids) { [] }
+ let(:remove_label_ids) { [] }
+
+ before_all do
+ work_item.update!(labels: [existing_label])
+ end
+
+ context 'when only removing labels' do
+ let(:remove_label_ids) { [existing_label.to_gid.to_s] }
+ let(:expected_labels) { [] }
+
+ it_behaves_like 'mutation updating work item labels'
+ end
+
+ context 'when only adding labels' do
+ let(:add_label_ids) { [label1.to_gid.to_s, label2.to_gid.to_s] }
+ let(:expected_labels) { [label1, label2, existing_label] }
+
+ it_behaves_like 'mutation updating work item labels'
+ end
+
+ context 'when adding and removing labels' do
+ let(:remove_label_ids) { [existing_label.to_gid.to_s] }
+ let(:add_label_ids) { [label1.to_gid.to_s, label2.to_gid.to_s] }
+ let(:expected_labels) { [label1, label2] }
+
+ it_behaves_like 'mutation updating work item labels'
+ end
+ end
+
context 'with due and start date widget input' do
let(:start_date) { Date.today }
let(:due_date) { 1.week.from_now.to_date }
diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
index 32cb2b1d187..979c8ac2e84 100644
--- a/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
@@ -4,7 +4,7 @@
# wiki
# user
-RSpec.shared_examples 'User views wiki pages' do
+RSpec.shared_examples 'User views wiki pages' do |support_sorting_by_created_at = true|
include WikiHelpers
let!(:wiki_page1) do
@@ -54,34 +54,37 @@ RSpec.shared_examples 'User views wiki pages' do
end
end
- context 'ordered by created_at' do
- let(:pages_ordered_by_created_at) { [wiki_page1, wiki_page2, wiki_page3] }
+ if support_sorting_by_created_at
+ context 'ordered by created_at' do
+ let(:pages_ordered_by_created_at) { [wiki_page1, wiki_page2, wiki_page3] }
- before do
- page.within('.wiki-sort-dropdown') do
- click_button('Title')
- click_button('Created date')
+ before do
+ stub_feature_flags(wiki_list_pages_with_normal_repository_rpcs: false)
+ page.within('.wiki-sort-dropdown') do
+ click_button('Title')
+ click_button('Created date')
+ end
end
- end
- context 'asc' do
- it 'pages are displayed in direct order' do
- pages.each.with_index do |page_title, index|
- expect(page_title.text).to eq(pages_ordered_by_created_at[index].title)
+ context 'asc' do
+ it 'pages are displayed in direct order' do
+ pages.each.with_index do |page_title, index|
+ expect(page_title.text).to eq(pages_ordered_by_created_at[index].title)
+ end
end
end
- end
- context 'desc' do
- before do
- page.within('.wiki-sort-dropdown') do
- page.find('.rspec-reverse-sort').click
+ context 'desc' do
+ before do
+ page.within('.wiki-sort-dropdown') do
+ page.find('.rspec-reverse-sort').click
+ end
end
- end
- it 'pages are displayed in reversed order' do
- pages.reverse_each.with_index do |page_title, index|
- expect(page_title.text).to eq(pages_ordered_by_created_at[index].title)
+ it 'pages are displayed in reversed order' do
+ pages.reverse_each.with_index do |page_title, index|
+ expect(page_title.text).to eq(pages_ordered_by_created_at[index].title)
+ end
end
end
end
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index b9c273b1e1a..7dc36bf227e 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -180,70 +180,71 @@ RSpec.shared_examples 'wiki model' do
it 'returns false' do
expect(subject.empty?).to be(false)
end
-
- it 'only instantiates a Wiki page once' do
- expect(WikiPage).to receive(:new).once.and_call_original
-
- subject.empty?
- end
end
end
end
describe '#list_pages' do
- let(:wiki_pages) { subject.list_pages }
+ shared_examples 'wiki model #list_pages' do
+ let(:wiki_pages) { subject.list_pages }
- before do
- subject.create_page('index', 'This is an index')
- subject.create_page('index2', 'This is an index2')
- subject.create_page('an index3', 'This is an index3')
- end
+ before do
+ subject.create_page('index', 'This is an index')
+ subject.create_page('index2', 'This is an index2')
+ subject.create_page('an index3', 'This is an index3')
+ end
- it 'returns an array of WikiPage instances' do
- expect(wiki_pages).to be_present
- expect(wiki_pages).to all(be_a(WikiPage))
- end
+ it 'returns an array of WikiPage instances' do
+ expect(wiki_pages).to be_present
+ expect(wiki_pages).to all(be_a(WikiPage))
+ end
- it 'does not load WikiPage content by default' do
- wiki_pages.each do |page|
- expect(page.content).to be_empty
+ it 'does not load WikiPage content by default' do
+ wiki_pages.each do |page|
+ expect(page.content).to be_empty
+ end
end
- end
- it 'returns all pages by default' do
- expect(wiki_pages.count).to eq(3)
- end
+ it 'returns all pages by default' do
+ expect(wiki_pages.count).to eq(3)
+ end
- context 'with limit option' do
- it 'returns limited set of pages' do
- expect(subject.list_pages(limit: 1).count).to eq(1)
+ context 'with limit option' do
+ it 'returns limited set of pages' do
+ expect(subject.list_pages(limit: 1).count).to eq(1)
+ end
end
- end
- context 'with sorting options' do
- it 'returns pages sorted by title by default' do
- pages = ['an index3', 'index', 'index2']
+ context 'with sorting options' do
+ it 'returns pages sorted by title by default' do
+ pages = ['an index3', 'index', 'index2']
- expect(subject.list_pages.map(&:title)).to eq(pages)
- expect(subject.list_pages(direction: 'desc').map(&:title)).to eq(pages.reverse)
+ expect(subject.list_pages.map(&:title)).to eq(pages)
+ expect(subject.list_pages(direction: 'desc').map(&:title)).to eq(pages.reverse)
+ end
end
- it 'returns pages sorted by created_at' do
- pages = ['index', 'index2', 'an index3']
+ context 'with load_content option' do
+ let(:pages) { subject.list_pages(load_content: true) }
- expect(subject.list_pages(sort: 'created_at').map(&:title)).to eq(pages)
- expect(subject.list_pages(sort: 'created_at', direction: 'desc').map(&:title)).to eq(pages.reverse)
+ it 'loads WikiPage content' do
+ expect(pages.first.content).to eq('This is an index3')
+ expect(pages.second.content).to eq('This is an index')
+ expect(pages.third.content).to eq('This is an index2')
+ end
end
end
- context 'with load_content option' do
- let(:pages) { subject.list_pages(load_content: true) }
-
- it 'loads WikiPage content' do
- expect(pages.first.content).to eq('This is an index3')
- expect(pages.second.content).to eq('This is an index')
- expect(pages.third.content).to eq('This is an index2')
+ context 'list pages with legacy wiki rpcs' do
+ before do
+ stub_feature_flags(wiki_list_page_with_normal_repository_rpcs: false)
end
+
+ it_behaves_like 'wiki model #list_pages'
+ end
+
+ context 'list pages with normal repository rpcs' do
+ it_behaves_like 'wiki model #list_pages'
end
end
@@ -531,7 +532,7 @@ RSpec.shared_examples 'wiki model' do
it 'sets the correct commit message' do
subject.create_page('test page', 'some content', :markdown, 'commit message')
- expect(subject.list_pages.first.page.version.message).to eq('commit message')
+ expect(subject.list_pages.first.version.message).to eq('commit message')
end
it 'sets the correct commit email' do
diff --git a/spec/views/layouts/devise.html.haml_spec.rb b/spec/views/layouts/devise.html.haml_spec.rb
index e69cf93cfb4..b37bdeceb7e 100644
--- a/spec/views/layouts/devise.html.haml_spec.rb
+++ b/spec/views/layouts/devise.html.haml_spec.rb
@@ -4,4 +4,22 @@ require 'spec_helper'
RSpec.describe 'layouts/devise' do
it_behaves_like 'a layout which reflects the application theme setting'
+
+ describe 'logo' do
+ it 'renders GitLab logo' do
+ render
+
+ expect(rendered).to have_selector('img[alt^="GitLab"]')
+ end
+
+ context 'with custom logo' do
+ let_it_be(:appearance) { create(:appearance, logo: fixture_file_upload('spec/fixtures/dk.png')) }
+
+ it 'renders custom logo' do
+ render
+
+ expect(rendered).to have_selector('img[data-src$="dk.png"]')
+ end
+ end
+ end
end